Subversion Repositories basico

Rev

Rev 407 | 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
407 t00mlabs 12
from html import escape
340 t00mlabs 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
406 t00mlabs 47
    UPDATED_TIMESTAMP = 10
405 t00mlabs 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')
406 t00mlabs 84
        sorted_model.set_sort_column_id(COLUMN.UPDATED_TIMESTAMP, Gtk.SortType.ASCENDING)
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
406 t00mlabs 206
        model = Gtk.TreeStore(
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
406 t00mlabs 234
        renderer = self.srvgui.add_widget('visor_sapnotes_renderer_key', Gtk.CellRendererText())
235
        column = self.srvgui.add_widget('visor_sapnotes_column_key', Gtk.TreeViewColumn('Key', renderer, text=COLUMN.KEY))
236
        renderer.set_property('height', 32)
237
        column.set_visible(False)
238
        column.set_expand(False)
239
        column.set_clickable(False)
240
        column.set_sort_indicator(False)
241
        treeview.append_column(column)
340 t00mlabs 242
 
243
        # Icon
406 t00mlabs 244
        renderer = self.srvgui.add_widget('visor_sapnotes_renderer_icon', Gtk.CellRendererPixbuf())
245
        column = self.srvgui.add_widget('visor_sapnotes_column_icon', Gtk.TreeViewColumn('', renderer, pixbuf=COLUMN.ICON))
246
        renderer.set_alignment(0.0, 0.5)
247
        column.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE)
248
        column.set_visible(True)
249
        column.set_expand(False)
250
        column.set_clickable(True)
251
        column.set_sort_indicator(True)
252
        column.set_sort_column_id(COLUMN.TYPE)
253
        column.set_sort_order(Gtk.SortType.ASCENDING)
254
        treeview.append_column(column)
340 t00mlabs 255
 
256
        # SAP Note Checkbox
406 t00mlabs 257
        renderer = self.srvgui.add_widget('visor_sapnotes_renderer_checkbox', Gtk.CellRendererToggle())
258
        column = self.srvgui.add_widget('visor_sapnotes_column_checkbox', Gtk.TreeViewColumn('', renderer, active=COLUMN.CHECKBOX))
259
        renderer.connect("toggled", self.__clb_row_toggled)
260
        column = Gtk.TreeViewColumn('', renderer, active=COLUMN.CHECKBOX)
402 t00mlabs 261
        widget = get_column_header_widget('', 'basico-check-accept')
406 t00mlabs 262
        column.set_widget(widget)
263
        column.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE)
264
        column.set_visible(True)
265
        column.set_expand(False)
266
        column.set_clickable(True)
267
        column.set_sort_indicator(False)
268
        column.set_property('spacing', 50)
269
        treeview.append_column(column)
340 t00mlabs 270
 
271
        # SAP Note Id
406 t00mlabs 272
        renderer = self.srvgui.add_widget('visor_sapnotes_renderer_sid', Gtk.CellRendererText())
273
        column = self.srvgui.add_widget('visor_sapnotes_column_sid', Gtk.TreeViewColumn('SAP Note', renderer, markup=COLUMN.SID))
274
        renderer.set_property('xalign', 1.0)
275
        renderer.set_property('height', 36)
276
        renderer.set_property('background', '#F0E3E3')
277
        column.set_visible(True)
278
        column.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE)
279
        column.set_expand(False)
280
        column.set_clickable(True)
281
        column.set_sort_indicator(True)
282
        column.set_sort_column_id(COLUMN.KEY)
283
        column.set_sort_order(Gtk.SortType.ASCENDING)
284
        treeview.append_column(column)
340 t00mlabs 285
 
286
        # SAP Note title
406 t00mlabs 287
        renderer = self.srvgui.add_widget('visor_sapnotes_renderer_title', Gtk.CellRendererText())
288
        column = self.srvgui.add_widget('visor_sapnotes_column_title', Gtk.TreeViewColumn('Title', renderer, markup=COLUMN.TITLE))
289
        renderer.set_property('background', '#FFFEEA')
290
        renderer.set_property('ellipsize', Pango.EllipsizeMode.MIDDLE)
291
        column = Gtk.TreeViewColumn('Title', renderer, markup=COLUMN.TITLE)
340 t00mlabs 292
        widget = get_column_header_widget('Title', 'basico-tag')
406 t00mlabs 293
        column.set_widget(widget)
294
        column.set_visible(True)
295
        column.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE)
296
        column.set_expand(True)
297
        column.set_clickable(True)
298
        column.set_sort_indicator(True)
299
        column.set_sort_column_id(COLUMN.TITLE)
300
        treeview.append_column(column)
340 t00mlabs 301
 
302
        # SAP Note Component
406 t00mlabs 303
        renderer = self.srvgui.add_widget('visor_sapnotes_renderer_component', Gtk.CellRendererText())
304
        column = self.srvgui.add_widget('visor_sapnotes_column_component', Gtk.TreeViewColumn('Component', renderer, markup=COLUMN.COMPONENT))
305
        renderer.set_property('background', '#E3E3F0')
340 t00mlabs 306
        widget = get_column_header_widget('Component', 'basico-component')
406 t00mlabs 307
        column.set_widget(widget)
308
        column.set_visible(True)
309
        column.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE)
310
        column.set_expand(False)
311
        column.set_clickable(True)
312
        column.set_sort_indicator(True)
313
        column.set_sort_column_id(COLUMN.COMPONENT)
314
        treeview.append_column(column)
340 t00mlabs 315
 
316
        # SAP Note Category
406 t00mlabs 317
        renderer = self.srvgui.add_widget('visor_sapnotes_renderer_category', Gtk.CellRendererText())
318
        column = self.srvgui.add_widget('visor_sapnotes_column_category', Gtk.TreeViewColumn('Category', renderer, markup=COLUMN.CATEGORY))
319
        renderer.set_property('background', '#E3F1E3')
340 t00mlabs 320
        widget = get_column_header_widget('Category', 'basico-category')
406 t00mlabs 321
        column.set_widget(widget)
322
        column.set_visible(False)
323
        column.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE)
324
        column.set_expand(False)
325
        column.set_clickable(True)
326
        column.set_sort_indicator(True)
327
        column.set_sort_column_id(COLUMN.CATEGORY)
328
        treeview.append_column(column)
340 t00mlabs 329
 
330
        # SAP Note Type
406 t00mlabs 331
        renderer = self.srvgui.add_widget('visor_sapnotes_renderer_type', Gtk.CellRendererText())
332
        column = self.srvgui.add_widget('visor_sapnotes_column_type', Gtk.TreeViewColumn('Type', renderer, markup=COLUMN.TYPE))
333
        renderer.set_property('background', '#e4f1f1')
389 t00mlabs 334
        widget = get_column_header_widget('Type', 'basico-type')
406 t00mlabs 335
        column.set_widget(widget)
336
        column.set_visible(True)
337
        column.set_expand(False)
338
        column.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE)
339
        column.set_clickable(True)
340
        column.set_sort_indicator(True)
341
        column.set_sort_column_id(COLUMN.TYPE)
342
        treeview.append_column(column)
340 t00mlabs 343
 
344
        # SAP Note Priority
406 t00mlabs 345
        renderer = self.srvgui.add_widget('visor_sapnotes_renderer_priority', Gtk.CellRendererText())
346
        column = self.srvgui.add_widget('visor_sapnotes_column_priority', Gtk.TreeViewColumn('Priority', renderer, markup=COLUMN.PRIORITY))
347
        renderer.set_property('background', '#f1e4f1')
348
        widget = get_column_header_widget('Priority', 'basico-priority')
349
        column.set_widget(widget)
350
        column.set_visible(True)
351
        column.set_expand(False)
352
        column.set_clickable(True)
353
        column.set_sort_indicator(True)
354
        column.set_sort_column_id(COLUMN.PRIORITY)
355
        treeview.append_column(column)
340 t00mlabs 356
 
406 t00mlabs 357
        # SAP Note Updated
358
        renderer = self.srvgui.add_widget('visor_sapnotes_renderer_updated', Gtk.CellRendererText())
359
        column = self.srvgui.add_widget('visor_sapnotes_column_updated', Gtk.TreeViewColumn('Updated', renderer, markup=COLUMN.UPDATED))
360
        renderer.set_property('background', '#FFE6D1')
390 t00mlabs 361
        widget = get_column_header_widget('Updated', 'basico-chronologic')
406 t00mlabs 362
        column.set_widget(widget)
363
        column.set_visible(True)
364
        column.set_expand(False)
365
        column.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE)
366
        column.set_clickable(True)
367
        column.set_sort_indicator(True)
368
        column.set_sort_column_id(COLUMN.UPDATED_TIMESTAMP)
369
        column.set_sort_order(Gtk.SortType.DESCENDING)
370
        model.set_sort_column_id(COLUMN.UPDATED_TIMESTAMP, Gtk.SortType.DESCENDING)
371
        treeview.append_column(column)
340 t00mlabs 372
 
406 t00mlabs 373
        # Timestamp updated
374
        renderer = self.srvgui.add_widget('visor_sapnotes_renderer_updated_timestamp', Gtk.CellRendererText())
375
        column = self.srvgui.add_widget('visor_sapnotes_column_updated_timestamp', Gtk.TreeViewColumn('Updated', renderer, markup=COLUMN.UPDATED_TIMESTAMP))
376
        column.set_visible(False)
377
        column.set_expand(False)
378
        column.set_clickable(False)
379
        column.set_sort_indicator(True)
380
        column.set_sort_column_id(COLUMN.UPDATED_TIMESTAMP)
381
        column.set_sort_order(Gtk.SortType.ASCENDING)
382
        treeview.append_column(column)
340 t00mlabs 383
 
384
        # Treeview properties
405 t00mlabs 385
        treeview.set_can_focus(False)
386
        treeview.set_enable_tree_lines(True)
387
        treeview.set_headers_visible(True)
388
        treeview.set_enable_search(True)
389
        treeview.set_hover_selection(False)
390
        treeview.set_grid_lines(Gtk.TreeViewGridLines.HORIZONTAL)
391
        treeview.set_enable_tree_lines(True)
392
        treeview.set_level_indentation(10)
393
        # ~ treeview.modify_font(Pango.FontDescription('Monospace 10'))
394
        treeview.connect('button_press_event', self.right_click)
340 t00mlabs 395
 
396
        # DOC: In order to have a Gtk.Widged with sorting and filtering
397
        # capabilities, you have to filter the model first, and use this
398
        # new model to create the sorted model. Then, attach the sorted
399
        # model to the treeview...
400
 
406 t00mlabs 401
        # Treeview filtering
402
        visible_filter = self.srvgui.add_widget('visor_sapnotes_visible_filter', model.filter_new())
403
        visible_filter.set_visible_func(self.__clb_visible_function)
340 t00mlabs 404
        # https://stackoverflow.com/questions/23355866/user-search-collapsed-rows-in-a-gtk-treeview
405
 
406
        # TreeView sorting
406 t00mlabs 407
        sorted_model = Gtk.TreeModelSort(model=visible_filter)
402 t00mlabs 408
        self.srvgui.add_widget('visor_sapnotes_sorted_model', sorted_model)
409
        sorted_model.set_sort_func(0, self.sort_function, None)
340 t00mlabs 410
 
411
        # Selection
406 t00mlabs 412
        selection = treeview.get_selection()
413
        selection.set_mode(Gtk.SelectionMode.SINGLE)
414
        selection.connect('changed', self.row_changed)
340 t00mlabs 415
 
416
        # Set model (filtered and sorted)
405 t00mlabs 417
        treeview.set_model(sorted_model)
340 t00mlabs 418
 
419
        self.show_all()
389 t00mlabs 420
        return visor
340 t00mlabs 421
 
422
 
423
    def sort_function(self, model, row1, row2, user_data):
424
        sort_column = 0
425
 
426
        value1 = model.get_value(row1, sort_column)
427
        value2 = model.get_value(row2, sort_column)
428
 
429
        if value1 < value2:
430
            return -1
431
        elif value1 == value2:
432
            return 0
433
        else:
434
            return 1
435
 
436
 
437
    def always_visible(self, model, itr, data):
438
        return False
439
 
440
 
406 t00mlabs 441
    def __clb_visible_function(self, model, itr, data):
340 t00mlabs 442
        entry = self.srvgui.get_widget('gtk_entry_filter_visor')
443
        text = self.srvutl.clean_html(entry.get_text())
405 t00mlabs 444
        title = model.get(itr, COLUMN.TITLE)[0]
445
        component = model.get(itr, COLUMN.COMPONENT)[0]
343 t00mlabs 446
        fields = title + ' ' + component
447
        match = text.upper() in fields.upper()
340 t00mlabs 448
 
449
        return match
450
 
451
 
452
    def update_total_sapnotes_count(self):
406 t00mlabs 453
        visible_filter = self.srvgui.get_widget('visor_sapnotes_visible_filter')
340 t00mlabs 454
        statusbar = self.srvgui.get_widget('widget_statusbar')
455
        lblnotescount = self.srvgui.get_widget('gtk_label_total_notes')
456
        total = self.srvdtb.get_total()
406 t00mlabs 457
        count = len(visible_filter)
405 t00mlabs 458
        lblnotescount.set_markup("<b>%d/<big>%d</big></b>" % (count, total))
340 t00mlabs 459
        msg = 'View populated with %d SAP Notes' % count
460
        self.srvuif.statusbar_msg(msg)
461
 
462
 
463
    def row_changed(self, selection):
405 t00mlabs 464
        pass
465
        # ~ try:
466
            # ~ model, treeiter = selection.get_selected()
467
            # ~ if treeiter is not None:
468
                # ~ component = model[treeiter][5]
469
                # ~ if component == 'Annotation':
470
                    # ~ aid = model[treeiter][10]
471
                    # ~ is_valid = self.srvant.is_valid(aid)
472
                    # ~ if is_valid:
473
                        # ~ self.srvclb.action_annotation_edit(aid)
474
                # ~ else:
475
                    # ~ aid = None
476
        # ~ except Exception as error:
477
            # ~ self.log.debug(error)
340 t00mlabs 478
 
479
 
402 t00mlabs 480
    def __clb_row_toggled(self, cell, path):
481
        sorted_model = self.srvgui.get_widget('visor_sapnotes_sorted_model')
482
        model = sorted_model.get_model()
483
        rpath = sorted_model.convert_path_to_child_path(Gtk.TreePath(path))
405 t00mlabs 484
        model[rpath][COLUMN.CHECKBOX] = not model[rpath][COLUMN.CHECKBOX]
340 t00mlabs 485
 
486
 
406 t00mlabs 487
    def get_node(self, key, icon, checkbox, sid, title, component, category='', sntype='', priority='', updated='', timestamp=''):
340 t00mlabs 488
        # Add completion entries
489
        completion = self.srvgui.get_widget('gtk_entrycompletion_visor')
490
        completion_model = completion.get_model()
491
        title = self.srvutl.clean_html(title)
492
        completion_model.append([title])
493
 
494
        node = []
495
        node.append(key)
496
        node.append(icon)
497
        node.append(checkbox)
498
        node.append(sid)
499
        node.append(title)
500
        node.append(component)
501
        node.append(category)
502
        node.append(sntype)
503
        node.append(priority)
504
        node.append(updated)
505
        node.append(timestamp)
506
        return node
507
 
508
 
509
    def get_bag(self):
510
        return self.bag
511
 
512
 
513
    def reload(self):
362 t00mlabs 514
        self.populate(self.bag)
340 t00mlabs 515
 
516
 
362 t00mlabs 517
    def populate(self, bag=None, cid=None):
405 t00mlabs 518
        model = self.srvgui.get_widget('gtk_model_sapnotes')
402 t00mlabs 519
        sorted_model = self.srvgui.get_widget('visor_sapnotes_sorted_model')
340 t00mlabs 520
        icon_sapnote = self.srvicm.get_pixbuf_icon('basico-sapnote', 32, 32)
521
        icon_bookmark = self.srvicm.get_pixbuf_icon('basico-bookmarks', 32, 32)
522
        for atype in ATYPES:
523
            self.icons['type'][atype.lower()] = self.srvicm.get_pixbuf_icon('basico-annotation-type-%s' % atype.lower())
524
        completion = self.srvgui.get_widget('gtk_entrycompletion_visor')
525
        completion_model = completion.get_model()
526
        completion_model.clear()
405 t00mlabs 527
        model.clear()
340 t00mlabs 528
        if bag is None:
529
            bag = self.bag
530
        else:
531
            self.bag = bag
532
 
533
        for sid in self.bag:
534
            metadata = self.srvdtb.get_sapnote_metadata(sid)
535
            if metadata is not None:
536
                bookmark = metadata['bookmark']
537
                title = escape(metadata['title'])
538
                sid = str(int(metadata['id']))
384 t00mlabs 539
 
540
                has_annotations = self.srvant.get_by_sid(sid)
541
                has_attachments = self.srvatc.get_by_sid(sid)
340 t00mlabs 542
                if bookmark:
543
                    icon = icon_bookmark
544
                    title = "<b>%s</b>" % title
545
                    sid = "<b>%s</b>" % sid
546
                else:
384 t00mlabs 547
                    if len(has_annotations) > 0 and len(has_attachments) > 0:
548
                        icon = self.srvicm.get_pixbuf_icon('basico-annotation-attachment', 32, 32)
549
                    elif len(has_annotations) > 0 and len(has_attachments) == 0:
550
                        icon = self.srvicm.get_pixbuf_icon('basico-annotation', 32, 32)
551
                    elif len(has_annotations) == 0 and len(has_attachments) > 0:
552
                        icon = self.srvicm.get_pixbuf_icon('basico-attachment', 32, 32)
553
                    else:
554
                        icon = icon_sapnote
340 t00mlabs 555
 
556
                timestamp = metadata['releasedon']
557
                timestamp = timestamp.replace('-', '')
558
                timestamp = timestamp.replace(':', '')
559
                timestamp = timestamp.replace('T', '_')
401 t00mlabs 560
                stype = escape(metadata['type'].lower())
561
                icon_name = 'basico-%s' % stype.replace(' ', '-')
562
                icon = self.srvicm.get_pixbuf_icon(icon_name, 36, 36)
340 t00mlabs 563
                node = self.get_node(   int(metadata['id']),
564
                                        icon,
565
                                        False,
566
                                        '<b>%s</b>' % sid,
567
                                        title,
568
                                        escape(metadata['componentkey']),
569
                                        escape(metadata['category']),
570
                                        escape(metadata['type']),
571
                                        escape(metadata['priority']),
572
                                        self.srvutl.fuzzy_date_from_timestamp(timestamp),
573
                                        timestamp
574
                                    )
406 t00mlabs 575
                pid = model.append(None, node)
340 t00mlabs 576
 
577
                # Load annotations
406 t00mlabs 578
                files = self.srvant.get_by_sid(metadata['id'])
579
                for fname in files:
580
                    with open(fname, 'r') as fa:
581
                        annotation = json.load(fa)
582
                        atype = annotation['Type']
583
                        try:
584
                            icon = self.icons['type']['%s' % atype.lower()]
585
                        except:
586
                            icon = None
587
                        node = self.get_node(   0,
588
                                                icon,
589
                                                False,
590
                                                '',
591
                                                annotation['Title'],
592
                                                annotation['Component'],
593
                                                '',
594
                                                annotation['Type'],
595
                                                '',
596
                                                self.srvutl.fuzzy_date_from_timestamp(annotation['Timestamp']),
383 t00mlabs 597
                                                # ~ annotation['AID'],
406 t00mlabs 598
                                                annotation['Timestamp']
599
                                            )
600
                        model.append(pid, node)
361 t00mlabs 601
 
602
                # Load attachments
383 t00mlabs 603
                # ~ files = self.srvatc.get_by_sid(metadata['id'])
604
                # ~ for fname in files:
605
                    # ~ with open(fname, 'r') as ft:
606
                        # ~ attachment = json.load(ft)
607
                        # ~ icon = self.srvicm.get_pixbuf_icon('basico-attachment')
608
                        # ~ node = self.get_node(   0,
609
                                                # ~ icon,
610
                                                # ~ False,
611
                                                # ~ '',
612
                                                # ~ attachment['Title'],
613
                                                # ~ 'Attachment',
614
                                                # ~ '',
615
                                                # ~ attachment['Description'],
616
                                                # ~ '',
617
                                                # ~ self.srvutl.fuzzy_date_from_timestamp(attachment['Created']),
618
                                                # ~ attachment['TID'],
619
                                                # ~ attachment['Created']
620
                                            # ~ )
405 t00mlabs 621
                        # ~ model.append(pid, node)
622
        treeview = self.srvgui.get_widget('visor_sapnotes_treeview')
623
        treeview.set_model(sorted_model)
340 t00mlabs 624
        self.update_total_sapnotes_count()
625
        self.show_widgets()
389 t00mlabs 626
        self.srvclb.gui_show_dashboard()
340 t00mlabs 627
 
406 t00mlabs 628
 
340 t00mlabs 629
    def show_widgets(self):
630
        self.srvuif.set_widget_visibility('gtk_label_total_notes', True)
631
 
632
 
633
    def right_click(self, treeview, event, data=None):
405 t00mlabs 634
        treeview = self.srvgui.get_widget('visor_sapnotes_treeview')
340 t00mlabs 635
        if event.button == 3:
636
            rect = Gdk.Rectangle()
637
            rect.x = x = int(event.x)
638
            rect.y = y = int(event.y)
405 t00mlabs 639
            pthinfo = treeview.get_path_at_pos(x,y)
340 t00mlabs 640
            if pthinfo is not None:
641
                path,col,cellx,celly = pthinfo
642
                model = treeview.get_model()
643
                treeiter = model.get_iter(path)
405 t00mlabs 644
                component = model[treeiter][COLUMN.COMPONENT]
645
                sid = model[treeiter][COLUMN.KEY]
361 t00mlabs 646
                if sid == 0:
647
                    return
340 t00mlabs 648
                sid = "0"*(10 - len(str(sid))) + str(sid)
389 t00mlabs 649
                # ~ toolbar = self.srvgui.get_widget('visortoolbar')
340 t00mlabs 650
                popover = self.srvgui.add_widget('gtk_popover_visor_row', Gtk.Popover.new(treeview))
651
                popover.set_position(Gtk.PositionType.TOP)
652
                popover.set_pointing_to(rect)
653
                box = self.build_popover(sid, popover, component)
654
                popover.add(box)
655
                self.srvclb.gui_show_popover(None, popover)
656
 
657
 
380 t00mlabs 658
    def clb_create_annotation(self, button, sid):
659
        self.srvclb.action_annotation_create_for_sapnote(sid)
660
 
661
 
340 t00mlabs 662
    def build_popover(self, sid, popover, component):
663
        box = Gtk.Box(spacing = 3, orientation="vertical")
664
        isid = int(sid)
665
 
666
        def get_popover_button(text, icon_name):
667
            button = Gtk.Button()
668
            button.set_relief(Gtk.ReliefStyle.NONE)
669
            hbox = Gtk.HBox()
670
            icon = self.srvicm.get_new_image_icon(icon_name, 24, 24)
671
            lbltext = Gtk.Label()
672
            lbltext.set_xalign(0.0)
673
            lbltext.set_markup('%s' % text)
674
            hbox.pack_start(icon, False, False, 3)
675
            hbox.pack_start(lbltext, True, True, 3)
676
            button.add(hbox)
677
            return button
678
 
679
        if component == 'Annotation':
680
            # Popover button "Delete annotation"
681
            button = get_popover_button("<b>Delete annotation</b>", 'basico-delete')
682
            button.show_all()
683
            button.connect('clicked', self.srvclb.action_annotation_delete)
684
            box.pack_start(button, False, False, 0)
685
 
686
            # Popover button "Duplicate annotation"
687
            button = get_popover_button("<b>Duplicate annotation</b>", 'basico-duplicate')
688
            button.show_all()
689
            button.connect('clicked', self.srvclb.action_annotation_duplicate)
690
            box.pack_start(button, False, False, 0)
691
 
692
        else:
693
            # Popover button "Add an annotation"
694
            button = get_popover_button("<b>Add an annotation</b> to SAP Note %d" % isid, 'basico-annotation')
695
            button.show_all()
380 t00mlabs 696
            button.connect('clicked', self.clb_create_annotation, sid)
340 t00mlabs 697
            box.pack_start(button, False, False, 0)
698
 
383 t00mlabs 699
            fbox = Gtk.VBox()
700
            frame = Gtk.Frame()
701
            frame.set_border_width(3)
702
            label = Gtk.Label()
703
            label.set_markup(' <b>Attachments</b> ')
704
            frame.set_label_widget(label)
360 t00mlabs 705
            # Popover button "Add attachments"
383 t00mlabs 706
            button = get_popover_button("<b>Add</b> new to SAP Note %d" % isid, 'basico-attachment')
707
            button.set_property('margin', 3)
360 t00mlabs 708
            button.show_all()
709
            button.connect('clicked', self.srvclb.gui_attachment_add_to_sapnote, sid)
383 t00mlabs 710
            fbox.pack_start(button, False, False, 0)
380 t00mlabs 711
 
383 t00mlabs 712
            # Popover button "Show attachments"
713
            if len(self.srvatc.get_by_sid(sid)) > 0:
714
                button = get_popover_button("<b>Show</b> linked to SAP Note %d" % isid, 'basico-attachment')
715
                button.set_property('margin', 3)
716
                button.show_all()
717
                # ~ button.connect('clicked', self.srvclb.gui_attachment_show_, sid)
718
                fbox.pack_start(button, False, False, 0)
719
            frame.add(fbox)
720
            box.pack_start(frame, False, False, 0)
721
 
340 t00mlabs 722
            # Popover button "Open SAP Note"
383 t00mlabs 723
            button = get_popover_button("<b>Browse</b> SAP Note %d" % isid, 'basico-preview')
340 t00mlabs 724
            button.connect('clicked', self.srvclb.sapnote_browse, sid)
725
            box.pack_start(button, False, False, 0)
726
 
727
            # Popover button "Download SAP Note in PDF"
728
            button = get_popover_button("See SAP Note %d in <b>PDF</b>" % isid, 'basico-browse')
729
            button.connect('clicked', self.srvclb.sapnote_download_pdf, sid)
730
            box.pack_start(button, False, False, 0)
731
 
732
            # Popover button "Bookmark"
733
            button = get_popover_button("<b>(Un)bookmark</b> SAP Note %d" % isid, 'basico-bookmarks')
734
            button.connect('clicked', self.srvclb.switch_bookmark, [sid], popover)
735
            box.pack_start(button, False, False, 0)
736
 
737
            # Popover button "Copy to clipboard"
738
            button = get_popover_button("<b>Copy</b> SAP Note %d details <b>to clipboard</b>" % isid, 'basico-clipboard')
739
            button.connect('clicked', self.srvclb.gui_copy_to_clipboard_sapnote, [sid], popover)
740
            box.pack_start(button, False, False, 0)
741
 
742
            # Separator
743
            separator = Gtk.Separator(orientation = Gtk.Orientation.HORIZONTAL)
744
            box.pack_start(separator, True, True, 0)
745
 
746
            # Assing SAP Notes in current view to a category
747
            # Only available in Donwloaded category
748
            viewmenu = self.srvgui.get_widget('viewmenu')
749
            current_viewmenu = viewmenu.get_view()
750
            current_collection = viewmenu.get_current_collection()
751
            view_is_collection = current_viewmenu == 'collection'
752
            collection_is_downloaded = current_collection == COL_DOWNLOADED
753
 
754
            # Popover button Collection Management
755
            button = get_popover_button("<b>Manage collections</b> for SAP Note %d" % isid, 'basico-collection')
756
            box.pack_start(button, False, False, 0)
757
            self.popcollections = self.srvgui.add_widget('gtk_popover_button_manage_collections_single_note', Gtk.Popover.new(button))
758
            self.popcollections.set_position(Gtk.PositionType.RIGHT)
759
            button.connect('clicked', self.srvclb.gui_show_popover, self.popcollections)
760
            colmgt = CollectionsMgtView(self.app, sid, overwrite=True)
761
            self.popcollections.add(colmgt)
762
 
763
            # Separator
764
            separator = Gtk.Separator(orientation = Gtk.Orientation.HORIZONTAL)
765
            box.pack_start(separator, True, True, 0)
766
 
767
 
768
            # Popover button "Delete SAP Note"
769
            button = get_popover_button("<b>Delete</b> SAP Note %d" % isid, 'basico-delete')
770
            button.connect('clicked', self.srvclb.sapnote_delete, sid)
771
            button.set_tooltip_text("Checkbox must be activated in order to trigger the deletion")
772
            box.pack_start(button, False, False, 0)
773
 
774
        return box
775
 
776
 
777
    def get_filtered_bag(self):
408 t00mlabs 778
        clean_html = self.srvutl.clean_html
402 t00mlabs 779
        sorted_model = self.srvgui.get_widget('visor_sapnotes_sorted_model')
362 t00mlabs 780
        visor_sapnotes = self.srvgui.get_widget('visor_sapnotes')
340 t00mlabs 781
        selected = []
782
 
783
        def get_selected_sapnotes(model, path, itr):
408 t00mlabs 784
            sid = clean_html(model.get(itr, COLUMN.SID)[0])
407 t00mlabs 785
            if len(escape(sid)) > 0:
340 t00mlabs 786
                selected.append(str(sid))
787
 
402 t00mlabs 788
        sorted_model.foreach(get_selected_sapnotes)
340 t00mlabs 789
        return selected