Subversion Repositories basico

Rev

Rev 232 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
113 t00mlabs 1
#!/usr/bin/python
2
# -*- coding: utf-8 -*-
3
# File: sapnoteviewvisor.py
4
# Author: Tomás Vírseda
5
# License: GPL v3
133 t00mlabs 6
# Description: SAPNoteViewVisor widget
113 t00mlabs 7
 
217 t00m 8
import os
207 t00m 9
from os.path import sep as SEP
113 t00mlabs 10
from cgi import escape
207 t00m 11
import glob
12
import json
113 t00mlabs 13
 
14
import gi
15
gi.require_version('Gdk', '3.0')
16
gi.require_version('Gtk', '3.0')
17
from gi.repository import Gdk
18
from gi.repository import Gio
19
from gi.repository import Gtk
197 t00m 20
from gi.repository.GdkPixbuf import Pixbuf
113 t00mlabs 21
from gi.repository import Pango
22
 
233 t00m 23
from basico.core.env import LPATH
24
from basico.core.service import Service
25
from basico.widgets.collections import CollectionsMgtView
26
from basico.widgets.annotation import AnnotationWidget
27
from basico.widgets.importwdg import ImportWidget
113 t00mlabs 28
 
156 t00m 29
class SAPNoteViewVisorToolbar(Gtk.HBox, Service):
30
    def __init__(self, app):
31
        Gtk.Box.__init__(self, app)
32
        self.app = app
33
        self.get_services()
34
        self.set_homogeneous(False)
35
        self.tool_bar = Gtk.Toolbar()
36
        self.pack_start(self.tool_bar, False, True, 0)
37
        self.tool_bar.get_style_context().add_class(Gtk.STYLE_CLASS_PRIMARY_TOOLBAR)
203 t00m 38
        self.tool_bar.set_property('margin-bottom', 0)
113 t00mlabs 39
 
203 t00m 40
        # Toggle Views button
213 t00m 41
        tool = self.gui.add_widget('gtk_toogletoolbutton_menu_view', Gtk.ToggleToolButton.new())
203 t00m 42
        tool.set_icon_name('gtk-select-color')
43
        tool.connect('toggled', self.cb.gui_toggle_menu_view)
44
        tool.set_active(False)
45
        tool.set_hexpand(False)
46
        self.tool_bar.insert(tool, -1)
47
 
48
        # View combobox button/popover
49
        tool = Gtk.ToolItem.new()
50
        lhbox = Gtk.HBox()
213 t00m 51
        menuviews = self.gui.add_widget('gtk_button_menu_views', Gtk.Button())
203 t00m 52
        hbox = Gtk.HBox()
213 t00m 53
        label = self.gui.add_widget('gtk_label_current_view', Gtk.Label())
203 t00m 54
        label.set_xalign(0.0)
213 t00m 55
        image = self.gui.add_widget('gtk_image_current_view', Gtk.Image())
203 t00m 56
        hbox.pack_start(image, False, False, 3)
57
        hbox.pack_start(label, True, True, 3)
58
        menuviews.add(hbox)
59
        lhbox.pack_start(menuviews, True, True, 3)
60
        lhbox.show_all()
61
        tool.add(lhbox)
62
        tool.set_expand(False)
63
        self.tool_bar.insert(tool, -1)
64
 
65
        ### Popover menuviews
213 t00m 66
        popover = self.gui.add_widget('gtk_popover_button_menu_views', Gtk.Popover.new(menuviews))
203 t00m 67
        menuviews.connect('clicked', self.cb.gui_show_popover, popover)
68
        box = Gtk.Box(spacing = 0, orientation="vertical")
69
        popover.add(box)
70
 
71
 
217 t00m 72
        box.pack_start(self.uif.create_menuview_button('annotation'), False, False, 0)
203 t00m 73
        separator = Gtk.Separator(orientation = Gtk.Orientation.HORIZONTAL)
74
        box.pack_start(separator, False, False, 0)
229 t00m 75
        box.pack_start(self.uif.create_menuview_button('collection'), False, False, 0)
203 t00m 76
        box.pack_start(self.uif.create_menuview_button('component'), False, False, 0)
77
        box.pack_start(self.uif.create_menuview_button('description'), False, False, 0)
78
        box.pack_start(self.uif.create_menuview_button('bookmarks'), False, False, 0)
79
        box.pack_start(self.uif.create_menuview_button('category'), False, False, 0)
80
        box.pack_start(self.uif.create_menuview_button('chronologic'), False, False, 0)
81
        box.pack_start(self.uif.create_menuview_button('priority'), False, False, 0)
82
        box.pack_start(self.uif.create_menuview_button('type'), False, False, 0)
83
 
201 t00m 84
        # Import button
85
        tool = Gtk.ToolButton()
86
        tool.set_icon_name('basico-add')
213 t00m 87
        popover = self.gui.add_widget('gtk_popover_toolbutton_import', Gtk.Popover.new(tool))
201 t00m 88
        tool.connect('clicked', self.cb.gui_show_popover, popover)
89
        self.tool_bar.insert(tool, -1)
90
 
91
        ## Popover body
92
        box = Gtk.VBox(spacing = 0, orientation="vertical")
93
        box.set_property('margin', 3)
94
        widget_import = self.gui.add_widget('widget_import', ImportWidget(self.app))
95
        box.pack_start(widget_import, True, True, 6)
96
        popover.add(box)
97
 
98
        # Annotation button
99
        tool = Gtk.ToolButton()
100
        tool.set_icon_name('basico-annotation')
213 t00m 101
        popover = self.gui.add_widget('gtk_popover_annotation', Gtk.Popover.new(tool))
207 t00m 102
        # ~ tool.connect('clicked', self.cb.gui_show_popover, popover)
222 t00m 103
        tool.connect('clicked', self.cb.gui_annotation_widget_show)
201 t00m 104
        self.tool_bar.insert(tool, -1)
105
 
106
        ## Popover body
107
        box = Gtk.VBox(spacing = 0, orientation="vertical")
108
        box.set_property('margin', 3)
109
        widget_import = self.gui.add_widget('widget_annotation', AnnotationWidget(self.app))
110
        box.pack_start(widget_import, True, True, 6)
111
        popover.add(box)
112
 
113
 
164 t00m 114
        # Filter entry
115
        tool = Gtk.ToolItem.new()
116
 
117
        hbox = Gtk.HBox()
118
        entry = Gtk.Entry()
188 t00m 119
        entry.connect('activate', self.cb.gui_filter_visor)
213 t00m 120
        self.gui.add_widget('gtk_entry_filter_visor', entry)
164 t00m 121
 
201 t00m 122
        icon = self.im.get_pixbuf_icon('basico-find')
123
        entry.set_icon_from_pixbuf(Gtk.EntryIconPosition.PRIMARY, icon)
124
        entry.set_icon_sensitive(Gtk.EntryIconPosition.PRIMARY, True)
125
        entry.set_icon_tooltip_markup (Gtk.EntryIconPosition.PRIMARY, "Search in the whole database")
126
 
175 t00m 127
        icon = self.im.get_pixbuf_icon('basico-filter')
128
        entry.set_icon_from_pixbuf(Gtk.EntryIconPosition.SECONDARY, icon)
129
        entry.set_icon_sensitive(Gtk.EntryIconPosition.SECONDARY, True)
130
        entry.set_icon_tooltip_markup (Gtk.EntryIconPosition.SECONDARY, "Click here to filter results")
131
        entry.set_placeholder_text("Filter results...")
132
 
133
        def on_icon_pressed(entry, icon_pos, event):
134
            if icon_pos == Gtk.EntryIconPosition.PRIMARY:
201 t00m 135
                self.cb.action_search(entry)
175 t00m 136
            elif icon_pos == Gtk.EntryIconPosition.SECONDARY:
188 t00m 137
                self.cb.gui_filter_visor(entry)
175 t00m 138
 
199 t00m 139
        entry.connect('changed', self.cb.gui_filter_visor)
175 t00m 140
        entry.connect("icon-press", on_icon_pressed)
184 t00m 141
        hbox.pack_start(entry, True, True, 0)
164 t00m 142
        tool.add(hbox)
184 t00m 143
        tool.set_expand(True)
164 t00m 144
        self.tool_bar.insert(tool, -1)
145
 
175 t00m 146
        # ~ Separator
147
        tool = Gtk.SeparatorToolItem.new()
148
        tool.set_draw(False)
149
        tool.set_expand(True)
150
        self.tool_bar.insert(tool, -1)
151
 
203 t00m 152
        # Button Total SAP Notes
153
        tool = Gtk.ToolItem()
154
        tool.set_expand(False)
213 t00m 155
        button = self.gui.add_widget('gtk_button_total_notes', Gtk.Button())
203 t00m 156
        button.set_relief(Gtk.ReliefStyle.NONE)
157
 
213 t00m 158
        popover = self.gui.add_widget('gtk_popover_button_total_notes', Gtk.Popover.new(button))
159
        label = self.gui.add_widget('gtk_label_total_notes', Gtk.Label())
178 t00m 160
        hbox = Gtk.HBox()
161
        hbox.pack_start(label, False, False, 0)
203 t00m 162
        button.add(hbox)
163
        button.connect('clicked', self.cb.gui_show_popover, popover)
164
        tool.add(button)
165
        self.tool_bar.insert(tool, -1)
166
 
167
        ## Popover body
212 t00m 168
        box = self.build_popover(popover)
203 t00m 169
        popover.add(box)
170
 
171
        # Fullscreen toggle button
172
        tool = Gtk.ToolItem()
178 t00m 173
        tool.set_expand(False)
203 t00m 174
        icon = self.im.get_new_image_icon('basico-fullscreen', 24, 24)
213 t00m 175
        box = self.gui.add_widget('gtk_box_container_icon_fullscreen', Gtk.Box())
203 t00m 176
        box.pack_start(icon, False, False, 0)
177
        button = Gtk.ToggleButton()
178
        button.set_relief(Gtk.ReliefStyle.NONE)
179
        button.connect('toggled', self.cb.gui_toggle_fullscreen)
180
        button.add(box)
181
        tool.add(button)
156 t00m 182
        self.tool_bar.insert(tool, -1)
183
 
184
        # Toolbar initial settings
201 t00m 185
        self.set_visible(True)
186
        self.set_no_show_all(False)
156 t00m 187
        self.tool_bar.set_hexpand(True)
188
 
189
 
190
    def get_services(self):
191
        self.gui = self.app.get_service("GUI")
192
        self.cb = self.app.get_service('Callbacks')
193
        self.sap = self.app.get_service('SAP')
194
        self.im = self.app.get_service('IM')
195
        self.settings = self.app.get_service('Settings')
196
        self.db = self.app.get_service('DB')
197
        self.uif = self.app.get_service("UIF")
198
 
164 t00m 199
 
212 t00m 200
    def build_popover(self, popover):
201
        box = Gtk.Box(spacing = 3, orientation="vertical")
202
        sid = '0000000000'
203
 
204
        def get_popover_button(text, icon_name):
205
            button = Gtk.Button()
206
            button.set_relief(Gtk.ReliefStyle.NONE)
207
            hbox = Gtk.HBox()
208
            icon = self.im.get_new_image_icon(icon_name, 24, 24)
209
            lbltext = Gtk.Label()
210
            lbltext.set_xalign(0.0)
211
            lbltext.set_markup('%s' % text)
212
            hbox.pack_start(icon, False, False, 3)
213
            hbox.pack_start(lbltext, True, True, 3)
214
            button.add(hbox)
215
            return button
216
 
217
        # Popover button "Bookmark"
218
        button = get_popover_button("(Un)bookmark SAP Notes", 'basico-bookmarks')
219
        button.connect('clicked', self.cb.switch_bookmark_current_set, popover)
220
        box.pack_start(button, False, False, 0)
221
 
222
        # Separator
223
        separator = Gtk.Separator(orientation = Gtk.Orientation.HORIZONTAL)
224
        box.pack_start(separator, True, True, 0)
225
 
229 t00m 226
        # Popover button Collection Management
227
        button = get_popover_button("Manage collections", 'basico-collection')
212 t00m 228
        box.pack_start(button, False, False, 0)
229 t00m 229
        self.popcollections = self.gui.add_widget('gtk_popover_button_manage_collections_selected_notes', Gtk.Popover.new(button))
230
        self.popcollections.set_position(Gtk.PositionType.RIGHT)
231
        button.connect('clicked', self.cb.gui_show_popover, self.popcollections)
232
        self.popcollections.add(CollectionsMgtView(self.app, sid, self.popcollections))
212 t00m 233
 
234
        # Separator
235
        separator = Gtk.Separator(orientation = Gtk.Orientation.HORIZONTAL)
236
        box.pack_start(separator, True, True, 0)
237
 
238
 
239
        # Popover button "Delete SAP Notes"
240
        button = get_popover_button("Delete SAP Notes", 'basico-delete')
241
        button.connect('clicked', self.cb.sapnote_delete, sid)
242
        box.pack_start(button, False, False, 0)
243
 
244
        return box
245
 
141 t00mlabs 246
class SAPNoteViewVisor(Gtk.Box, Service):
113 t00mlabs 247
    def __init__(self, app):
141 t00mlabs 248
        Gtk.Box.__init__(self, app)
113 t00mlabs 249
        self.app = app
198 t00m 250
        self.bag = []
113 t00mlabs 251
        self.get_services()
197 t00m 252
        self.setup()
113 t00mlabs 253
 
254
 
255
    def get_services(self):
256
        self.gui = self.app.get_service("GUI")
257
        self.cb = self.app.get_service('Callbacks')
258
        self.sap = self.app.get_service('SAP')
259
        self.im = self.app.get_service('IM')
260
        self.settings = self.app.get_service('Settings')
261
        self.db = self.app.get_service('DB')
262
        self.uif = self.app.get_service("UIF")
207 t00m 263
        self.utils = self.app.get_service("Utils")
217 t00m 264
        self.annot = self.app.get_service('Annotation')
113 t00mlabs 265
 
199 t00m 266
    def get_treeview(self):
267
        return self.treeview
113 t00mlabs 268
 
178 t00m 269
 
233 t00m 270
    def sort_by_timestamp(self):
271
        self.sorted_model.set_sort_column_id(11, Gtk.SortType.DESCENDING)
272
 
273
 
197 t00m 274
    def setup(self):
275
        scr = Gtk.ScrolledWindow()
276
        scr.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
277
        scr.set_shadow_type(Gtk.ShadowType.IN)
278
        viewport = Gtk.Viewport()
279
        self.treeview = Gtk.TreeView()
280
        viewport.add(self.treeview)
281
        scr.add(viewport)
282
        self.pack_start(scr, True, True, 6)
178 t00m 283
 
197 t00m 284
        # Setup model
199 t00m 285
        self.model = Gtk.TreeStore(
201 t00m 286
            int,        # key
197 t00m 287
            Pixbuf,     # Icon
288
            int,        # checkbox
201 t00m 289
            str,        # sid
197 t00m 290
            str,        # title
291
            str,        # component
292
            str,        # category
293
            str,        # type
294
            str,        # priority
226 t00m 295
            str,        # last update
217 t00m 296
            str,        # Annotation Id (extra key)
226 t00m 297
            str,        # Timestamp
197 t00m 298
        )
178 t00m 299
 
197 t00m 300
        # Setup columns
228 t00m 301
        def get_column_header_widget(title, icon_name=None, width=24, height=24):
201 t00m 302
            hbox = Gtk.HBox()
303
            icon = self.im.get_new_image_icon(icon_name, width, height)
304
            label = Gtk.Label()
305
            label.set_markup("<b>%s</b>" % title)
228 t00m 306
            label.modify_font(Pango.FontDescription('Monospace 10'))
201 t00m 307
            hbox.pack_start(icon, False, False, 3)
308
            hbox.pack_start(label, True, True, 3)
309
            hbox.show_all()
310
            return hbox
311
 
197 t00m 312
        # SAP Note key
313
        self.renderer_key = Gtk.CellRendererText()
314
        self.renderer_key.set_property('height', 32)
315
        self.column_key = Gtk.TreeViewColumn('Key', self.renderer_key, text=0)
316
        self.column_key.set_visible(False)
317
        self.column_key.set_expand(False)
318
        self.column_key.set_clickable(False)
319
        self.column_key.set_sort_indicator(False)
320
        self.treeview.append_column(self.column_key)
178 t00m 321
 
197 t00m 322
        # Icon
323
        self.renderer_icon = Gtk.CellRendererPixbuf()
324
        self.renderer_icon.set_alignment(0.0, 0.5)
200 t00m 325
        self.column_icon = Gtk.TreeViewColumn('Bookmark', self.renderer_icon, pixbuf=1)
201 t00m 326
        widget = get_column_header_widget('', 'basico-bookmarks')
327
        self.column_icon.set_widget(widget)
197 t00m 328
        self.column_icon.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE)
207 t00m 329
        self.column_icon.set_visible(True)
197 t00m 330
        self.column_icon.set_expand(False)
331
        self.column_icon.set_clickable(False)
332
        self.column_icon.set_sort_indicator(False)
333
        self.treeview.append_column(self.column_icon)
117 t00mlabs 334
 
197 t00m 335
        # SAP Note Checkbox
336
        self.renderer_checkbox = Gtk.CellRendererToggle()
337
        self.renderer_checkbox.connect("toggled", self.toggle_checkbox)
338
        self.column_checkbox = Gtk.TreeViewColumn('', self.renderer_checkbox, active=2)
339
        self.column_checkbox.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE)
198 t00m 340
        self.column_checkbox.set_visible(False)
197 t00m 341
        self.column_checkbox.set_expand(False)
342
        self.column_checkbox.set_clickable(False)
343
        self.column_checkbox.set_sort_indicator(False)
344
        self.column_checkbox.set_property('spacing', 50)
345
        self.treeview.append_column(self.column_checkbox)
117 t00mlabs 346
 
197 t00m 347
        # SAP Note Id
348
        self.renderer_sid = Gtk.CellRendererText()
349
        self.renderer_sid.set_property('xalign', 1.0)
350
        self.renderer_sid.set_property('height', 36)
200 t00m 351
        self.renderer_sid.set_property('background', '#F0E3E3')
199 t00m 352
        self.column_sid = Gtk.TreeViewColumn('SAP Note Id', self.renderer_sid, markup=3)
201 t00m 353
        widget = get_column_header_widget('SAP Note Id', 'basico-sid')
354
        self.column_sid.set_widget(widget)
197 t00m 355
        self.column_sid.set_visible(True)
198 t00m 356
        self.column_sid.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE)
197 t00m 357
        self.column_sid.set_expand(False)
358
        self.column_sid.set_clickable(True)
359
        self.column_sid.set_sort_indicator(True)
201 t00m 360
        self.column_sid.set_sort_column_id(0)
199 t00m 361
        self.column_sid.set_sort_order(Gtk.SortType.ASCENDING)
201 t00m 362
        self.model.set_sort_column_id(0, Gtk.SortType.ASCENDING)
197 t00m 363
        self.treeview.append_column(self.column_sid)
130 t00mlabs 364
 
197 t00m 365
        # SAP Note title
366
        self.renderer_title = Gtk.CellRendererText()
200 t00m 367
        self.renderer_title.set_property('background', '#FFFEEA')
199 t00m 368
        self.renderer_title.set_property('ellipsize', Pango.EllipsizeMode.MIDDLE)
197 t00m 369
        self.column_title = Gtk.TreeViewColumn('Title', self.renderer_title, markup=4)
201 t00m 370
        widget = get_column_header_widget('Title', 'basico-tag')
371
        self.column_title.set_widget(widget)
197 t00m 372
        self.column_title.set_visible(True)
198 t00m 373
        self.column_title.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE)
197 t00m 374
        self.column_title.set_expand(True)
375
        self.column_title.set_clickable(True)
376
        self.column_title.set_sort_indicator(True)
199 t00m 377
        self.column_title.set_sort_column_id(4)
197 t00m 378
        self.treeview.append_column(self.column_title)
117 t00mlabs 379
 
197 t00m 380
        # SAP Note Component
381
        self.renderer_component = Gtk.CellRendererText()
200 t00m 382
        self.renderer_component.set_property('background', '#E3E3F0')
197 t00m 383
        self.column_component = Gtk.TreeViewColumn('Component', self.renderer_component, markup=5)
201 t00m 384
        widget = get_column_header_widget('Component', 'basico-component')
385
        self.column_component.set_widget(widget)
199 t00m 386
        self.column_component.set_visible(True)
387
        self.column_component.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE)
388
        self.column_component.set_expand(False)
197 t00m 389
        self.column_component.set_clickable(True)
390
        self.column_component.set_sort_indicator(True)
199 t00m 391
        self.column_component.set_sort_column_id(5)
197 t00m 392
        self.treeview.append_column(self.column_component)
117 t00mlabs 393
 
197 t00m 394
        # SAP Note Category
395
        self.renderer_category = Gtk.CellRendererText()
200 t00m 396
        self.renderer_category.set_property('background', '#E3F1E3')
197 t00m 397
        self.column_category = Gtk.TreeViewColumn('Category', self.renderer_category, markup=6)
201 t00m 398
        widget = get_column_header_widget('Category', 'basico-category')
399
        self.column_category.set_widget(widget)
223 t00m 400
        self.column_category.set_visible(False)
198 t00m 401
        self.column_category.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE)
197 t00m 402
        self.column_category.set_expand(False)
403
        self.column_category.set_clickable(True)
404
        self.column_category.set_sort_indicator(True)
199 t00m 405
        self.column_category.set_sort_column_id(6)
197 t00m 406
        self.treeview.append_column(self.column_category)
117 t00mlabs 407
 
197 t00m 408
        # SAP Note Type
409
        self.renderer_type = Gtk.CellRendererText()
212 t00m 410
        self.renderer_type.set_property('background', '#e4f1f1')
197 t00m 411
        self.column_type = Gtk.TreeViewColumn('Type', self.renderer_type, markup=7)
207 t00m 412
        self.column_type.set_visible(True)
413
        self.column_type.set_expand(False)
414
        self.column_type.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE)
197 t00m 415
        self.column_type.set_clickable(True)
416
        self.column_type.set_sort_indicator(True)
213 t00m 417
        self.column_type.set_sort_column_id(7)
197 t00m 418
        self.treeview.append_column(self.column_type)
117 t00mlabs 419
 
197 t00m 420
        # SAP Note Priority
421
        self.renderer_priority = Gtk.CellRendererText()
422
        self.column_priority = Gtk.TreeViewColumn('Priority', self.renderer_priority, markup=8)
423
        self.column_priority.set_visible(False)
424
        self.column_priority.set_expand(True)
425
        self.column_priority.set_clickable(True)
426
        self.column_priority.set_sort_indicator(True)
226 t00m 427
        self.column_priority.set_sort_column_id(8)
197 t00m 428
        self.treeview.append_column(self.column_priority)
117 t00mlabs 429
 
226 t00m 430
        # SAP Note UpdatedOn
431
        self.renderer_updated = Gtk.CellRendererText()
432
        self.renderer_updated.set_property('background', '#FFE6D1')
433
        self.column_updated = Gtk.TreeViewColumn('Updated On', self.renderer_updated, markup=9)
434
        self.column_updated.set_visible(True)
435
        self.column_updated.set_expand(False)
436
        self.column_updated.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE)
437
        self.column_updated.set_clickable(True)
438
        self.column_updated.set_sort_indicator(True)
439
        self.column_updated.set_sort_column_id(11)
440
        self.treeview.append_column(self.column_updated)
441
 
217 t00m 442
        # Annotation Id
443
        self.renderer_annotation = Gtk.CellRendererText()
226 t00m 444
        self.column_annotation = Gtk.TreeViewColumn('Annotation Id', self.renderer_annotation, markup=10)
217 t00m 445
        self.column_annotation.set_visible(False)
446
        self.column_annotation.set_expand(False)
447
        self.column_annotation.set_clickable(False)
448
        self.column_annotation.set_sort_indicator(False)
449
        self.treeview.append_column(self.column_annotation)
450
 
226 t00m 451
        # Timestamp
452
        self.renderer_timestamp = Gtk.CellRendererText()
453
        self.column_timestamp = Gtk.TreeViewColumn('Annotation Id', self.renderer_timestamp, text=11)
454
        self.column_timestamp.set_visible(False)
455
        self.column_timestamp.set_expand(False)
456
        self.column_timestamp.set_clickable(False)
457
        self.column_timestamp.set_sort_indicator(False)
458
        self.treeview.append_column(self.column_timestamp)
459
 
199 t00m 460
        # Treeview properties
197 t00m 461
        self.treeview.set_can_focus(False)
462
        self.treeview.set_enable_tree_lines(True)
198 t00m 463
        self.treeview.set_headers_visible(True)
197 t00m 464
        self.treeview.set_enable_search(True)
465
        self.treeview.set_hover_selection(False)
207 t00m 466
        self.treeview.set_grid_lines(Gtk.TreeViewGridLines.NONE)
467
        self.treeview.set_enable_tree_lines(True)
468
        self.treeview.set_level_indentation(10)
228 t00m 469
        self.treeview.modify_font(Pango.FontDescription('Monospace 10'))
197 t00m 470
        self.treeview.connect('button_press_event', self.right_click)
162 t00m 471
 
199 t00m 472
        # DOC: In order to have a Gtk.Widged with sorting and filtering
473
        # capabilities, you have to filter the model first, and use this
474
        # new model to create the sorted model. Then, attach the sorted
475
        # model to the treeview...
476
 
477
        # Treeview filtering:
478
        self.visible_filter = self.model.filter_new()
200 t00m 479
        self.visible_filter.set_visible_func(self.visible_function)
230 t00m 480
        # ~ treeview.set_search_equal_func(self.search_function)
481
        # https://stackoverflow.com/questions/23355866/user-search-collapsed-rows-in-a-gtk-treeview
199 t00m 482
 
483
        # TreeView sorting
484
        self.sorted_model = Gtk.TreeModelSort(model=self.visible_filter)
485
        self.sorted_model.set_sort_func(0, self.sort_function, None)
486
 
197 t00m 487
        # Selection
488
        self.selection = self.treeview.get_selection()
217 t00m 489
        self.selection.set_mode(Gtk.SelectionMode.SINGLE)
197 t00m 490
        self.selection.connect('changed', self.row_changed)
162 t00m 491
 
199 t00m 492
        # Set model (filtered and sorted)
197 t00m 493
        self.treeview.set_model(self.sorted_model)
162 t00m 494
 
197 t00m 495
        self.show_all()
496
 
199 t00m 497
 
197 t00m 498
    def sort_function(self, model, row1, row2, user_data):
199 t00m 499
        sort_column = 0
197 t00m 500
 
501
        value1 = model.get_value(row1, sort_column)
502
        value2 = model.get_value(row2, sort_column)
225 t00m 503
 
197 t00m 504
        if value1 < value2:
505
            return -1
506
        elif value1 == value2:
507
            return 0
508
        else:
509
            return 1
510
 
198 t00m 511
 
200 t00m 512
    def visible_function(self, model, itr, data):
213 t00m 513
        entry = self.gui.get_widget('gtk_entry_filter_visor')
199 t00m 514
        text = entry.get_text()
515
        sid = str(model.get(itr, 3)[0])
230 t00m 516
        if sid.startswith('<'):
517
            sid = sid[3:-4]
199 t00m 518
        title = model.get(itr, 4)[0]
200 t00m 519
        component = str(model.get(itr, 5)[0])
520
        category = model.get(itr, 6)[0]
230 t00m 521
        rtype = model.get(itr, 7)[0]
522
        string = ' '.join(['SAP Note %s' % sid, title, component, category, rtype])
523
        match = text.upper() in string.upper()
524
        # ~ self.debug("%s in %s? %s" % (text, string, match))
199 t00m 525
 
230 t00m 526
        return match
199 t00m 527
 
230 t00m 528
 
202 t00m 529
    def update_total_sapnotes_count(self, count=0):
213 t00m 530
        statusbar = self.gui.get_widget('widget_statusbar')
225 t00m 531
        lblnotescount = self.gui.get_widget('gtk_label_total_notes')
202 t00m 532
        total = self.db.get_total()
225 t00m 533
 
202 t00m 534
        lblnotescount.set_markup("<b>%d/<big>%d</big></b>" % (count, total))
203 t00m 535
        statusbar.message("<b>View populated with %d SAP Notes</b>" % count)
202 t00m 536
 
537
 
199 t00m 538
    def get_visible_filter(self):
539
        return self.visible_filter
540
 
541
 
197 t00m 542
    def row_changed(self, selection):
217 t00m 543
        try:
226 t00m 544
            model, treeiter = selection.get_selected()
545
            if treeiter is not None:
546
                component = model[treeiter][5]
547
                if component == 'Annotation':
548
                    aid = model[treeiter][10]
549
                    is_valid = self.annot.is_valid(aid)
550
                    if is_valid:
551
                        self.cb.action_annotation_edit(aid)
552
                else:
553
                    aid = None
554
                    self.uif.set_widget_visibility('gtk_vbox_container_annotations', False)
217 t00m 555
        except Exception as error:
556
            self.debug(error)
557
            self.print_traceback()
197 t00m 558
 
198 t00m 559
 
197 t00m 560
    def toggle_checkbox(self, cell, path):
561
        self.model[path][2] = not self.model[path][2]
562
 
563
 
226 t00m 564
    def get_node(self, key, icon, checkbox, sid, title, component, category='', sntype='', priority='', updated='', aid='', timestamp=''):
197 t00m 565
        node = []
566
        node.append(key)
567
        node.append(icon)
568
        node.append(checkbox)
569
        node.append(sid)
570
        node.append(title)
571
        node.append(component)
572
        node.append(category)
573
        node.append(sntype)
574
        node.append(priority)
226 t00m 575
        node.append(updated)
217 t00m 576
        node.append(aid) # Extra key for annotations id (aid)
226 t00m 577
        node.append(timestamp)
197 t00m 578
        return node
579
 
580
 
207 t00m 581
    def refresh(self):
582
        self.populate()
233 t00m 583
        self.sort_by_timestamp()
584
        self.debug("Sorted treeview by timestamp")
207 t00m 585
 
212 t00m 586
    def get_bag(self):
587
        return self.bag
588
 
589
 
198 t00m 590
    def populate(self, bag=None, cid=None):
209 t00m 591
        icon_annotation = self.im.get_pixbuf_icon('basico-annotation', 32, 32)
592
        icon_content = self.im.get_pixbuf_icon('basico-logviewer', 32, 32)
210 t00m 593
        icon_link = self.im.get_pixbuf_icon('basico-browser', 32, 32)
228 t00m 594
        icon_empty = self.im.get_pixbuf_icon('basico-empty', 32, 32)
595
        icon_sapnote = self.im.get_pixbuf_icon('basico-sapnote', 32, 32)
596
        icon_bookmark = self.im.get_pixbuf_icon('basico-bookmarks', 32, 32)
230 t00m 597
        self.column_sid.set_visible(True)
210 t00m 598
 
233 t00m 599
        # ~ self.cb.gui_show_dashboard()
600
 
198 t00m 601
        if bag is None:
213 t00m 602
            bag = self.bag
198 t00m 603
        else:
604
            self.bag = bag
212 t00m 605
 
228 t00m 606
 
197 t00m 607
        self.model.clear()
212 t00m 608
 
213 t00m 609
        for sid in self.bag:
197 t00m 610
            metadata = self.db.get_sapnote_metadata(sid)
218 t00m 611
            if metadata is not None:
612
                bookmark = metadata['bookmark']
613
                title = escape(metadata['title'])
614
                sid = str(int(metadata['id']))
615
                if bookmark:
616
                    icon = icon_bookmark
617
                    title = "<b>%s</b>" % title
618
                    sid = "<b>%s</b>" % sid
619
                else:
228 t00m 620
                    icon = icon_sapnote
198 t00m 621
 
226 t00m 622
                timestamp = metadata['releaseon']
623
                timestamp = timestamp.replace('-', '')
624
                timestamp = timestamp.replace(':', '')
625
                timestamp = timestamp.replace('T', '_')
201 t00m 626
 
218 t00m 627
                node = self.get_node(   int(metadata['id']),
628
                                        icon,
629
                                        bookmark,
630
                                        '<b>%s</b>' % sid,
631
                                        title,
632
                                        escape(metadata['componentkey']),
633
                                        escape(metadata['category']),
634
                                        escape(metadata['type']),
635
                                        escape(metadata['priority']),
226 t00m 636
                                        self.utils.fuzzy_date_from_timestamp(timestamp),
637
                                        '',
638
                                        timestamp
218 t00m 639
                                    )
640
                pid = self.model.append(None, node)
179 t00m 641
 
218 t00m 642
                # Load annotations
224 t00m 643
                files = self.annot.get_by_sid(metadata['id'])
218 t00m 644
                for fname in files:
645
                    with open(fname, 'r') as fa:
646
                        annotation = json.load(fa)
225 t00m 647
                        self.debug("Populating annotation: %s" % annotation['aid'])
218 t00m 648
                        node = self.get_node(   0,
649
                                                icon_annotation,
650
                                                False,
226 t00m 651
                                                '',
218 t00m 652
                                                annotation['title'],
653
                                                annotation['component'],
654
                                                '',
225 t00m 655
                                                annotation['type'],
224 t00m 656
                                                '',
226 t00m 657
                                                self.utils.fuzzy_date_from_timestamp(annotation['timestamp']),
658
                                                annotation['aid'],
659
                                                annotation['timestamp']
218 t00m 660
                                            )
225 t00m 661
                        self.model.append(pid, node)
228 t00m 662
        self.treeview.set_model(self.sorted_model)
225 t00m 663
        self.update_total_sapnotes_count(len(self.model))
664
        self.show_widgets()
665
        stack = self.gui.get_widget('gtk_stack_main')
666
        stack.set_visible_child_name('visor')
667
        # ~ self.annot.get_all()
217 t00m 668
 
669
 
226 t00m 670
    def populate_annotations(self, annotations=None):
225 t00m 671
        icon_annotation = self.im.get_pixbuf_icon('basico-annotation', 32, 32)
672
        icon_content = self.im.get_pixbuf_icon('basico-logviewer', 32, 32)
673
        icon_link = self.im.get_pixbuf_icon('basico-browser', 32, 32)
674
        icon_empty = self.im.get_pixbuf_icon('basico-empty', 32, 32)
675
        icon_bookmark = self.im.get_pixbuf_icon('basico-bookmarks', 32, 32)
228 t00m 676
        icon_sapnote = self.im.get_pixbuf_icon('basico-sapnote', 32, 32)
230 t00m 677
        self.column_sid.set_visible(False)
233 t00m 678
        # ~ self.cb.gui_show_dashboard()
225 t00m 679
 
680
        self.model.clear()
226 t00m 681
 
682
        if annotations is None:
683
            annotations = self.annot.get_all()
684
 
230 t00m 685
        snpids = {}
686
 
225 t00m 687
        for fname in annotations:
688
            with open(fname, 'r') as fa:
689
                annotation = json.load(fa)
690
                sid = self.annot.get_sid(annotation['aid'])
691
                node = self.get_node(   0,
692
                                        icon_annotation,
693
                                        False,
230 t00m 694
                                        str(int(sid)),
225 t00m 695
                                        annotation['title'],
696
                                        annotation['component'],
697
                                        '',
698
                                        annotation['type'],
699
                                        '',
226 t00m 700
                                        self.utils.fuzzy_date_from_timestamp(annotation['timestamp']),
701
                                        annotation['aid'],
702
                                        annotation['timestamp']
225 t00m 703
                                    )
230 t00m 704
                self.model.append(None, node)
228 t00m 705
        self.treeview.set_model(self.sorted_model)
233 t00m 706
        self.sort_by_timestamp()
225 t00m 707
        self.treeview.expand_all()
213 t00m 708
        self.update_total_sapnotes_count(len(self.model))
212 t00m 709
        self.show_widgets()
215 t00m 710
        stack = self.gui.get_widget('gtk_stack_main')
711
        stack.set_visible_child_name('visor')
179 t00m 712
 
213 t00m 713
 
212 t00m 714
    def show_widgets(self):
233 t00m 715
        self.uif.set_widget_visibility('gtk_button_total_notes', True)
202 t00m 716
 
222 t00m 717
 
197 t00m 718
    def right_click(self, treeview, event, data=None):
719
        if event.button == 3:
720
            rect = Gdk.Rectangle()
721
            rect.x = x = int(event.x)
722
            rect.y = y = int(event.y)
723
            pthinfo = self.treeview.get_path_at_pos(x,y)
724
            if pthinfo is not None:
725
                path,col,cellx,celly = pthinfo
726
                model = treeview.get_model()
727
                treeiter = model.get_iter(path)
222 t00m 728
                component = model[treeiter][5]
729
                sid = model[treeiter][0]
201 t00m 730
                sid = "0"*(10 - len(str(sid))) + str(sid)
197 t00m 731
                toolbar = self.gui.get_widget('visortoolbar')
225 t00m 732
                popover = self.gui.add_widget('gtk_popover_visor_row', Gtk.Popover.new(treeview))
203 t00m 733
                popover.set_position(Gtk.PositionType.TOP)
197 t00m 734
                popover.set_pointing_to(rect)
225 t00m 735
                box = self.build_popover(sid, popover, component)
197 t00m 736
                popover.add(box)
225 t00m 737
                self.cb.gui_show_popover(None, popover)
179 t00m 738
 
739
 
225 t00m 740
    def build_popover(self, sid, popover, component):
197 t00m 741
        box = Gtk.Box(spacing = 3, orientation="vertical")
162 t00m 742
 
197 t00m 743
        def get_popover_button(text, icon_name):
744
            button = Gtk.Button()
745
            button.set_relief(Gtk.ReliefStyle.NONE)
746
            hbox = Gtk.HBox()
747
            icon = self.im.get_new_image_icon(icon_name, 24, 24)
748
            lbltext = Gtk.Label()
749
            lbltext.set_xalign(0.0)
750
            lbltext.set_markup('%s' % text)
751
            hbox.pack_start(icon, False, False, 3)
752
            hbox.pack_start(lbltext, True, True, 3)
753
            button.add(hbox)
754
            return button
162 t00m 755
 
225 t00m 756
        if component == 'Annotation':
226 t00m 757
            # Popover button "Delete annotation"
225 t00m 758
            button = get_popover_button("Delete annotation", 'basico-delete')
759
            button.show_all()
760
            button.connect('clicked', self.cb.action_annotation_delete)
761
            box.pack_start(button, False, False, 0)
226 t00m 762
 
763
            # Popover button "Duplicate annotation"
764
            button = get_popover_button("Duplicate annotation", 'basico-duplicate')
765
            button.show_all()
766
            button.connect('clicked', self.cb.action_annotation_duplicate)
767
            box.pack_start(button, False, False, 0)
768
 
225 t00m 769
        else:
770
            # Popover button "Add an annotation"
771
            button = get_popover_button("Add an annotation", 'basico-annotation')
772
            button.show_all()
773
            button.connect('clicked', self.cb.gui_annotation_widget_show, sid, 'create')
774
            box.pack_start(button, False, False, 0)
178 t00m 775
 
225 t00m 776
            # Popover button "Open SAP Note"
777
            button = get_popover_button("See SAP Note", 'basico-browse')
778
            button.connect('clicked', self.cb.sapnote_browse, sid)
779
            box.pack_start(button, False, False, 0)
178 t00m 780
 
225 t00m 781
            # Popover button "Bookmark"
782
            button = get_popover_button("(Un)bookmark SAP Note", 'basico-bookmarks')
783
            button.connect('clicked', self.cb.switch_bookmark, [sid], popover)
784
            box.pack_start(button, False, False, 0)
198 t00m 785
 
225 t00m 786
            # Separator
787
            separator = Gtk.Separator(orientation = Gtk.Orientation.HORIZONTAL)
788
            box.pack_start(separator, True, True, 0)
162 t00m 789
 
229 t00m 790
            # Popover button Collection Management
791
            button = get_popover_button("Manage collections", 'basico-collection')
225 t00m 792
            box.pack_start(button, False, False, 0)
229 t00m 793
            self.popcollections = self.gui.add_widget('gtk_popover_button_manage_collections_single_note', Gtk.Popover.new(button))
794
            self.popcollections.set_position(Gtk.PositionType.RIGHT)
795
            button.connect('clicked', self.cb.gui_show_popover, self.popcollections)
796
            self.popcollections.add(CollectionsMgtView(self.app, sid, self.popcollections))
197 t00m 797
 
225 t00m 798
            # Separator
799
            separator = Gtk.Separator(orientation = Gtk.Orientation.HORIZONTAL)
800
            box.pack_start(separator, True, True, 0)
197 t00m 801
 
802
 
225 t00m 803
            # Popover button "Delete SAP Note"
804
            button = get_popover_button("Delete SAP Note", 'basico-delete')
805
            button.connect('clicked', self.cb.sapnote_delete, sid)
806
            box.pack_start(button, False, False, 0)
197 t00m 807
 
808
        return box