Subversion Repositories basico

Rev

Rev 402 | Rev 406 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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