Subversion Repositories basico

Rev

Rev 403 | Rev 405 | 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_annotations.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 html import escape
13
import glob
14
import json
15
import html
402 t00mlabs 16
from enum import IntEnum
340 t00mlabs 17
 
18
import gi
19
gi.require_version('Gdk', '3.0')
20
gi.require_version('Gtk', '3.0')
21
from gi.repository import Gdk
22
from gi.repository import Gio
23
from gi.repository import Gtk
24
from gi.repository.GdkPixbuf import Pixbuf
25
from gi.repository import Pango
393 t00mlabs 26
from gi.repository import GObject
340 t00mlabs 27
 
28
from basico.core.mod_env import LPATH, ATYPES
29
from basico.core.mod_wdg import BasicoWidget
30
from basico.widgets.wdg_cols import CollectionsMgtView
31
from basico.widgets.wdg_import import ImportWidget
32
 
402 t00mlabs 33
class COLUMN(IntEnum):
34
    AID = 0
35
    ICON = 1
36
    CHECKBOX = 2
37
    SID = 3
38
    TITLE = 4
39
    COMPONENT = 5
403 t00mlabs 40
    TYPE = 6
41
    SCOPE = 7
42
    PRODUCT = 8
43
    PRIORITY = 9
44
    UPDATED = 10
45
    TS_UPDATED = 11
46
    CREATED = 12
47
    TS_CREATED = 13
340 t00mlabs 48
 
402 t00mlabs 49
 
340 t00mlabs 50
class AnnotationsVisor(BasicoWidget, Gtk.HBox):
51
    def __init__(self, app):
52
        super().__init__(app, __class__.__name__)
53
        Gtk.HBox.__init__(self, app)
54
        self.set_homogeneous(False)
55
        self.bag = []
400 t00mlabs 56
        self.__get_services()
57
        self.__setup_panel()
58
        self.__set_initial_panel_button_status()
59
        self.__setup_visor()
340 t00mlabs 60
        self.icons = {}
61
        self.icons['type'] = {}
62
        for atype in ATYPES:
384 t00mlabs 63
            self.icons['type'][atype.lower()] = self.srvicm.get_pixbuf_icon('basico-annotation-type-%s' % atype.lower(), 32)
340 t00mlabs 64
        self.log.debug("Annotation Visor initialized")
65
 
66
 
400 t00mlabs 67
    def __get_services(self):
340 t00mlabs 68
        self.srvgui = self.get_service("GUI")
69
        self.srvclb = self.get_service('Callbacks')
70
        self.srvsap = self.get_service('SAP')
71
        self.srvicm = self.get_service('IM')
72
        self.srvstg = self.get_service('Settings')
73
        self.srvdtb = self.get_service('DB')
74
        self.srvuif = self.get_service("UIF")
75
        self.srvutl = self.get_service("Utils")
76
        self.srvant = self.get_service('Annotation')
77
 
78
 
400 t00mlabs 79
    def __set_initial_panel_button_status(self):
340 t00mlabs 80
        # Categories
81
        self.srvgui.set_key_value('ANNOTATIONS_CATEGORY_INBOX_VISIBLE', True)
82
        self.srvgui.set_key_value('ANNOTATIONS_CATEGORY_DRAFTS_VISIBLE', False)
83
        self.srvgui.set_key_value('ANNOTATIONS_CATEGORY_ARCHIVED_VISIBLE', False)
84
 
85
        # Types
86
        for atype in ATYPES:
87
            self.srvgui.set_key_value('ANNOTATIONS_TYPE_%s_VISIBLE' % atype.upper(), True)
88
 
89
        # Priorty
90
        for priority in ['High', 'Normal', 'Low']:
91
            self.srvgui.set_key_value('ANNOTATIONS_PRIORITY_%s_VISIBLE' % priority.upper(), True)
92
 
369 t00mlabs 93
 
400 t00mlabs 94
    def __sort_by_timestamp(self):
399 t00mlabs 95
        sorted_model = self.srvgui.get_widget('visor_annotation_sorted_model')
402 t00mlabs 96
        sorted_model.set_sort_column_id(COLUMN.TS_UPDATED, Gtk.SortType.DESCENDING)
340 t00mlabs 97
 
98
 
400 t00mlabs 99
    def __setup_panel(self):
389 t00mlabs 100
        vbox_main = Gtk.VBox()
101
        self.pack_start(vbox_main, False, False, 3)
390 t00mlabs 102
        # ~ separator = Gtk.Separator(orientation = Gtk.Orientation.VERTICAL)
103
        # ~ self.pack_start(separator, False, False, 3)
389 t00mlabs 104
        vbox_main.set_hexpand(False)
393 t00mlabs 105
        # ~ vbox_main.set_property('margin-top', 6)
389 t00mlabs 106
        vbox_main.set_property('margin-left', 6)
107
        vbox_main.set_property('margin-right', 6)
108
        vbox_main.set_property('margin-bottom', 3)
340 t00mlabs 109
 
389 t00mlabs 110
        def create_panel_elem_button(icon, title):
111
            button = self.srvgui.add_widget('gtk_togglebutton_%s' % title, Gtk.ToggleButton())
112
            button.set_relief(Gtk.ReliefStyle.NONE)
113
            icon = self.srvicm.get_image_icon(icon, 36, 36)
114
            label = Gtk.Label('')
115
            label.set_markup('%s' % title.capitalize())
116
            hbox_cat_elem = Gtk.HBox()
117
            hbox_cat_elem.set_hexpand(False)
118
            hbox_cat_elem.pack_start(icon, False, False, 3)
119
            hbox_cat_elem.pack_start(label, False, False, 3)
120
            button.add(hbox_cat_elem)
121
 
122
            return button
123
 
393 t00mlabs 124
        # Separator
394 t00mlabs 125
        # ~ separator = Gtk.Separator()
126
        # ~ vbox_main.pack_start(separator, False, False, 6)
393 t00mlabs 127
 
128
        # Scope filter
394 t00mlabs 129
        hbox_scope = Gtk.VBox()
393 t00mlabs 130
        label = Gtk.Label()
131
        label.set_markup("<big><b>Scope </b></big>")
132
        label.set_xalign(0.0)
133
        model = Gtk.ListStore(str)
134
        scope = Gtk.ComboBox.new_with_model(model)
400 t00mlabs 135
        signal = scope.connect('changed', self.__clb_scope_changed)
393 t00mlabs 136
        self.srvgui.add_signal('gtk_combobox_filter_scope', 'changed', signal)
137
        self.srvgui.add_widget('gtk_combobox_filter_scope', scope)
138
        renderer = Gtk.CellRendererText()
139
        scope.pack_start(renderer, True)
140
        scope.add_attribute(renderer, "markup", 0)
394 t00mlabs 141
        # ~ hbox_scope.pack_start(label, False, False, 0)
393 t00mlabs 142
        hbox_scope.pack_start(scope, True, True, 0)
143
        vbox_main.pack_start(hbox_scope, False, False, 6)
144
 
394 t00mlabs 145
        # Product filter
146
        hbox_product = Gtk.VBox()
147
        label = Gtk.Label()
148
        label.set_markup("<big><b>Product </b></big>")
149
        label.set_xalign(0.0)
393 t00mlabs 150
        model = Gtk.ListStore(str)
151
        product = Gtk.ComboBox.new_with_model(model)
400 t00mlabs 152
        signal = product.connect('changed', self.__clb_product_changed)
394 t00mlabs 153
        self.srvgui.add_signal('gtk_combobox_filter_product', 'changed', signal)
393 t00mlabs 154
        self.srvgui.add_widget('gtk_combobox_filter_product', product)
155
        renderer = Gtk.CellRendererText()
156
        product.pack_start(renderer, True)
157
        product.add_attribute(renderer, "markup", 0)
394 t00mlabs 158
        # ~ hbox_product.pack_start(label, False, False, 0)
159
        hbox_product.pack_start(product, True, True, 0)
160
        vbox_main.pack_start(hbox_product, False, False, 6)
393 t00mlabs 161
 
389 t00mlabs 162
        hbox_main = Gtk.HBox()
163
        hbox_main.set_homogeneous(True)
164
        vbox_main.pack_start(hbox_main, False, False, 0)
165
 
393 t00mlabs 166
        # Separator
394 t00mlabs 167
        # ~ separator = Gtk.Separator()
168
        # ~ vbox_main.pack_start(separator, False, False, 6)
389 t00mlabs 169
 
170
        # Categories
171
        button = self.srvgui.add_widget('gtk_togglebutton_categories', Gtk.ToggleButton())
394 t00mlabs 172
        button.set_relief(Gtk.ReliefStyle.NORMAL)
173
        icon = self.srvicm.get_image_icon('basico-category', 24, 24)
389 t00mlabs 174
        label = Gtk.Label('')
175
        label.set_markup('<big><b>Categories</b></big>')
176
        hbox_cat = Gtk.HBox()
394 t00mlabs 177
        hbox_cat.set_hexpand(False)
178
        # ~ hbox_cat.pack_start(icon, False, False, 3)
389 t00mlabs 179
        hbox_cat.pack_start(label, False, False, 3)
180
        button.add(hbox_cat)
394 t00mlabs 181
        vbox_main.pack_start(button, False, False, 6)
389 t00mlabs 182
 
183
        revealer = self.srvgui.add_widget('gtk_revealer_annotations_categories', Gtk.Revealer())
184
        vbox_revealer = Gtk.VBox()
185
        vbox_revealer.set_hexpand(False)
186
 
187
        for name in ['inbox', 'drafts', 'archived']:
188
            button = create_panel_elem_button('basico-%s' % name.lower(), name)
189
            self.srvgui.add_widget('gtk_button_category_%s' % name, button)
190
            vbox_revealer.pack_start(button, False, False, 2)
191
 
192
        revealer.add(vbox_revealer)
394 t00mlabs 193
        vbox_main.pack_start(revealer, False, False, 3)
389 t00mlabs 194
 
195
        # Types
196
        button = self.srvgui.add_widget('gtk_togglebutton_types', Gtk.ToggleButton())
394 t00mlabs 197
        button.set_relief(Gtk.ReliefStyle.NORMAL)
198
        icon = self.srvicm.get_image_icon('basico-type', 24, 24)
389 t00mlabs 199
        label = Gtk.Label('')
200
        label.set_markup('<big><b>Types</b></big>')
201
        hbox_type = Gtk.HBox()
394 t00mlabs 202
        hbox_type.set_hexpand(False)
389 t00mlabs 203
 
395 t00mlabs 204
        # ~ hbox_type.pack_start(icon, False, False, 3)
389 t00mlabs 205
        hbox_type.pack_start(label, False, False, 3)
206
        button.add(hbox_type)
394 t00mlabs 207
        vbox_main.pack_start(button, False, False, 0)
389 t00mlabs 208
 
209
        revealer = self.srvgui.add_widget('gtk_revealer_annotations_types', Gtk.Revealer())
210
        vbox_revealer = Gtk.VBox()
211
        vbox_revealer.set_hexpand(False)
212
 
213
        hbox_sel = Gtk.HBox()
214
        switch = Gtk.Switch()
215
        switch.set_active(True)
216
        switch.set_state(True)
400 t00mlabs 217
        switch.connect('state-set', self.__clb_switch_selection_atypes)
389 t00mlabs 218
        label_select = Gtk.Label()
219
        label_select.set_markup("<b>All selected</b>")
220
        label = self.srvgui.add_widget('gtk_label_switch_select_atypes', label_select)
221
        hbox_sel.pack_start(label, False, False, 6)
222
        hbox_sel.pack_start(switch, False, False, 6)
223
        vbox_revealer.pack_start(hbox_sel, False, False, 6)
224
 
225
        for name in ATYPES:
226
            button = create_panel_elem_button('basico-annotation-type-%s' % name.lower(), name.lower())
227
            self.srvgui.add_widget('gtk_button_type_%s' % name.lower(), button)
228
            button.set_active(True)
229
            vbox_revealer.pack_start(button, False, False, 2)
230
 
231
        revealer.add(vbox_revealer)
232
        vbox_main.pack_start(revealer, False, False, 6)
233
 
234
        # ~ separator = Gtk.Separator()
235
        # ~ vbox_main.pack_start(separator, False, False, 6)
236
 
393 t00mlabs 237
 
389 t00mlabs 238
        return vbox_main
239
 
393 t00mlabs 240
 
400 t00mlabs 241
    def __clb_set_visible_categories(self, togglebutton):
340 t00mlabs 242
        types = self.srvgui.get_widget('gtk_togglebutton_types')
243
        revealer = self.srvgui.get_widget('gtk_revealer_annotations_categories')
244
 
245
        active = togglebutton.get_active()
246
        if active:
247
            types.set_active(False)
248
        revealer.set_reveal_child(active)
249
 
250
 
400 t00mlabs 251
    def __clb_set_visible_types(self, togglebutton):
340 t00mlabs 252
        categories = self.srvgui.get_widget('gtk_togglebutton_categories')
253
        revealer = self.srvgui.get_widget('gtk_revealer_annotations_types')
254
 
255
        active = togglebutton.get_active()
256
        if active:
257
            categories.set_active(False)
258
        revealer.set_reveal_child(active)
259
 
260
 
400 t00mlabs 261
    def __clb_set_visible_priority(self, togglebutton):
340 t00mlabs 262
        categories = self.srvgui.get_widget('gtk_togglebutton_categories')
263
        revealer = self.srvgui.get_widget('gtk_revealer_annotations_priority')
264
 
265
        active = togglebutton.get_active()
266
        if active:
267
            priority.set_active(False)
268
        revealer.set_reveal_child(active)
269
 
270
 
400 t00mlabs 271
    def __clb_set_visible_category(self, togglebutton, title):
340 t00mlabs 272
        active = togglebutton.get_active()
273
        self.srvgui.set_key_value('ANNOTATIONS_CATEGORY_%s_VISIBLE' % title.upper(), active)
400 t00mlabs 274
        self.__set_bag()
362 t00mlabs 275
        self.populate()
340 t00mlabs 276
 
277
 
400 t00mlabs 278
    def __clb_set_visible_annotation_type(self, togglebutton, atype):
340 t00mlabs 279
        active = togglebutton.get_active()
280
        self.srvgui.set_key_value('ANNOTATIONS_TYPE_%s_VISIBLE' % atype.upper(), active)
400 t00mlabs 281
        self.__set_bag()
362 t00mlabs 282
        self.populate()
340 t00mlabs 283
 
284
 
400 t00mlabs 285
    def __clb_set_visible_priority(self, togglebutton, title):
340 t00mlabs 286
        active = togglebutton.get_active()
287
        self.srvgui.set_key_value('ANNOTATIONS_PRIORITY_%s_VISIBLE' % title.upper(), active)
400 t00mlabs 288
        self.__set_bag()
362 t00mlabs 289
        self.populate()
340 t00mlabs 290
 
291
 
400 t00mlabs 292
    def __setup_visor(self):
340 t00mlabs 293
        scr = Gtk.ScrolledWindow()
294
        scr.set_hexpand(True)
295
        scr.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
389 t00mlabs 296
        scr.set_shadow_type(Gtk.ShadowType.IN)
399 t00mlabs 297
        treeview = self.srvgui.add_widget('visor_annotation_treeview', Gtk.TreeView())
298
        scr.add(treeview)
340 t00mlabs 299
        scr.set_hexpand(True)
300
        self.pack_start(scr, True, True, 0)
301
 
302
        # Setup model
399 t00mlabs 303
        model = Gtk.TreeStore(
393 t00mlabs 304
            str,        # Annotation Id
351 t00mlabs 305
            Pixbuf,     # Icon
340 t00mlabs 306
            int,        # checkbox
307
            str,        # sid
308
            str,        # title
309
            str,        # component
403 t00mlabs 310
            str,        # type
393 t00mlabs 311
            str,        # Scope
312
            str,        # Product
340 t00mlabs 313
            str,        # priority
314
            str,        # last update
351 t00mlabs 315
            str,        # Timestamp updated
316
            str,        # Annotation created
317
            str,        # Timestamp created
340 t00mlabs 318
        )
399 t00mlabs 319
        self.srvgui.add_widget('gtk_model_annotation', model)
340 t00mlabs 320
 
321
        # Setup columns
389 t00mlabs 322
        def get_column_header_widget(title, icon_name=None, width=28, height=28):
340 t00mlabs 323
            hbox = Gtk.HBox()
324
            icon = self.srvicm.get_new_image_icon(icon_name, width, height)
325
            label = Gtk.Label()
326
            label.set_markup("<b>%s</b>" % title)
327
            # ~ label.modify_font(Pango.FontDescription('Monospace 10'))
328
            hbox.pack_start(icon, False, False, 3)
329
            hbox.pack_start(label, True, True, 3)
330
            hbox.show_all()
331
            return hbox
332
 
394 t00mlabs 333
        # Annotation key
340 t00mlabs 334
        self.renderer_key = Gtk.CellRendererText()
402 t00mlabs 335
        self.column_key = Gtk.TreeViewColumn('Key', self.renderer_key, text=COLUMN.AID)
340 t00mlabs 336
        self.column_key.set_visible(False)
337
        self.column_key.set_expand(False)
338
        self.column_key.set_clickable(False)
339
        self.column_key.set_sort_indicator(True)
399 t00mlabs 340
        treeview.append_column(self.column_key)
340 t00mlabs 341
 
394 t00mlabs 342
        # Annotation Icon
340 t00mlabs 343
        self.renderer_icon = Gtk.CellRendererPixbuf()
344
        self.renderer_icon.set_alignment(0.0, 0.5)
402 t00mlabs 345
        self.column_icon = Gtk.TreeViewColumn('', self.renderer_icon, pixbuf=COLUMN.ICON)
346
        # ~ widget = get_column_header_widget('', 'basico-type')
347
        # ~ self.column_icon.set_widget(widget)
340 t00mlabs 348
        self.column_icon.set_visible(True)
349
        self.column_icon.set_expand(False)
389 t00mlabs 350
        self.column_icon.set_clickable(True)
340 t00mlabs 351
        self.column_icon.set_sort_indicator(True)
403 t00mlabs 352
        self.column_icon.set_sort_column_id(COLUMN.TYPE)
399 t00mlabs 353
        treeview.append_column(self.column_icon)
340 t00mlabs 354
 
394 t00mlabs 355
        # Annotation Checkbox
340 t00mlabs 356
        self.renderer_checkbox = Gtk.CellRendererToggle()
402 t00mlabs 357
        self.renderer_checkbox.connect("toggled", self.__clb_row_toggled)
358
        self.column_checkbox = Gtk.TreeViewColumn('', self.renderer_checkbox, active=COLUMN.CHECKBOX)
389 t00mlabs 359
        widget = get_column_header_widget('', 'basico-check-accept')
360
        self.column_checkbox.set_widget(widget)
340 t00mlabs 361
        self.column_checkbox.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE)
377 t00mlabs 362
        self.column_checkbox.set_visible(True)
340 t00mlabs 363
        self.column_checkbox.set_expand(False)
389 t00mlabs 364
        # ~ self.column_checkbox.set_clickable(True)
365
        # ~ self.column_checkbox.set_sort_indicator(True)
366
        # ~ self.column_checkbox.set_sort_column_id(2)
340 t00mlabs 367
        self.column_checkbox.set_property('spacing', 50)
399 t00mlabs 368
        treeview.append_column(self.column_checkbox)
340 t00mlabs 369
 
394 t00mlabs 370
        # Annotation Id
340 t00mlabs 371
        self.renderer_sid = Gtk.CellRendererText()
372
        self.renderer_sid.set_property('xalign', 1.0)
373
        self.renderer_sid.set_property('height', 36)
374
        self.renderer_sid.set_property('background', '#F0E3E3')
402 t00mlabs 375
        self.column_sid = Gtk.TreeViewColumn('SAP Note Id', self.renderer_sid, markup=COLUMN.SID)
340 t00mlabs 376
        widget = get_column_header_widget('SAP Note Id', 'basico-sid')
377
        self.column_sid.set_widget(widget)
378
        self.column_sid.set_visible(True)
379
        self.column_sid.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE)
380
        self.column_sid.set_expand(False)
381
        self.column_sid.set_clickable(True)
382
        self.column_sid.set_sort_indicator(True)
402 t00mlabs 383
        # ~ self.column_sid.set_sort_column_id(0)
399 t00mlabs 384
        treeview.append_column(self.column_sid)
340 t00mlabs 385
 
394 t00mlabs 386
        # Annotation title
340 t00mlabs 387
        self.renderer_title = Gtk.CellRendererText()
388
        self.renderer_title.set_property('background', '#FFFEEA')
389
        self.renderer_title.set_property('ellipsize', Pango.EllipsizeMode.MIDDLE)
402 t00mlabs 390
        self.column_title = Gtk.TreeViewColumn('Title', self.renderer_title, markup=COLUMN.TITLE)
340 t00mlabs 391
        widget = get_column_header_widget('Title', 'basico-tag')
392
        self.column_title.set_widget(widget)
393
        self.column_title.set_visible(True)
394
        self.column_title.set_sizing(Gtk.TreeViewColumnSizing.FIXED)
395
        self.column_title.set_expand(True)
396
        self.column_title.set_clickable(True)
397
        self.column_title.set_sort_indicator(True)
402 t00mlabs 398
        self.column_title.set_sort_column_id(COLUMN.TITLE)
399 t00mlabs 399
        treeview.append_column(self.column_title)
340 t00mlabs 400
 
394 t00mlabs 401
        # Annotation Component
340 t00mlabs 402
        self.renderer_component = Gtk.CellRendererText()
403
        self.renderer_component.set_property('background', '#E3E3F0')
402 t00mlabs 404
        self.column_component = Gtk.TreeViewColumn('Component', self.renderer_component, markup=COLUMN.COMPONENT)
340 t00mlabs 405
        widget = get_column_header_widget('Component', 'basico-component')
406
        self.column_component.set_widget(widget)
393 t00mlabs 407
        self.column_component.set_visible(False)
340 t00mlabs 408
        self.column_component.set_sizing(Gtk.TreeViewColumnSizing.FIXED)
409
        self.column_component.set_expand(False)
410
        self.column_component.set_clickable(True)
411
        self.column_component.set_sort_indicator(True)
402 t00mlabs 412
        self.column_component.set_sort_column_id(COLUMN.COMPONENT)
399 t00mlabs 413
        treeview.append_column(self.column_component)
340 t00mlabs 414
 
403 t00mlabs 415
        # Annotation Type
416
        self.renderer_component = Gtk.CellRendererText()
417
        self.renderer_component.set_property('background', '#E3E3F0')
418
        self.column_component = Gtk.TreeViewColumn('Type', self.renderer_component, markup=COLUMN.TYPE)
419
        # ~ widget = get_column_header_widget('Type', 'basico-type')
420
        # ~ self.column_component.set_widget(widget)
404 t00mlabs 421
        self.column_component.set_visible(False)
403 t00mlabs 422
        self.column_component.set_sizing(Gtk.TreeViewColumnSizing.FIXED)
423
        self.column_component.set_expand(False)
424
        self.column_component.set_clickable(True)
425
        self.column_component.set_sort_indicator(True)
426
        self.column_component.set_sort_column_id(COLUMN.TYPE)
427
        treeview.append_column(self.column_component)
428
 
393 t00mlabs 429
        # Annotation Scope
430
        self.renderer_scope = Gtk.CellRendererText()
431
        self.renderer_scope.set_property('background', '#E3F1E3')
402 t00mlabs 432
        self.column_scope = Gtk.TreeViewColumn('Scope', self.renderer_scope, markup=COLUMN.SCOPE)
395 t00mlabs 433
        widget = get_column_header_widget('Scope', 'basico-scope')
393 t00mlabs 434
        self.column_scope.set_widget(widget)
435
        self.column_scope.set_visible(True)
436
        self.column_scope.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE)
437
        self.column_scope.set_expand(False)
438
        self.column_scope.set_clickable(True)
439
        self.column_scope.set_sort_indicator(True)
402 t00mlabs 440
        self.column_scope.set_sort_column_id(COLUMN.SCOPE)
399 t00mlabs 441
        treeview.append_column(self.column_scope)
340 t00mlabs 442
 
394 t00mlabs 443
        # Annotation Product
340 t00mlabs 444
        self.renderer_type = Gtk.CellRendererText()
445
        self.renderer_type.set_property('background', '#DADAFF')
398 t00mlabs 446
        # ~ self.renderer_type.set_property('ellipsize', Pango.EllipsizeMode.MIDDLE)
402 t00mlabs 447
        self.column_type = Gtk.TreeViewColumn('Type', self.renderer_type, markup=COLUMN.PRODUCT)
394 t00mlabs 448
        widget = get_column_header_widget('Product', 'basico-type')
389 t00mlabs 449
        self.column_type.set_widget(widget)
340 t00mlabs 450
        self.column_type.set_visible(True)
451
        self.column_type.set_expand(False)
452
        self.column_type.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE)
453
        self.column_type.set_clickable(True)
454
        self.column_type.set_sort_indicator(True)
402 t00mlabs 455
        self.column_type.set_sort_column_id(COLUMN.PRODUCT)
399 t00mlabs 456
        treeview.append_column(self.column_type)
340 t00mlabs 457
 
394 t00mlabs 458
        # Annotation Priority
340 t00mlabs 459
        self.renderer_priority = Gtk.CellRendererText()
460
        self.renderer_priority.set_property('background', '#e4f1f1')
402 t00mlabs 461
        self.column_priority = Gtk.TreeViewColumn('Priority', self.renderer_priority, markup=COLUMN.PRIORITY)
400 t00mlabs 462
        widget = get_column_header_widget('Priority', 'basico-priority')
389 t00mlabs 463
        self.column_priority.set_widget(widget)
340 t00mlabs 464
        self.column_priority.set_visible(True)
465
        self.column_priority.set_expand(False)
466
        self.column_priority.set_clickable(True)
467
        self.column_priority.set_sort_indicator(True)
402 t00mlabs 468
        self.column_priority.set_sort_column_id(COLUMN.PRIORITY)
399 t00mlabs 469
        treeview.append_column(self.column_priority)
340 t00mlabs 470
 
351 t00mlabs 471
        # Annotation Updated On
340 t00mlabs 472
        self.renderer_updated = Gtk.CellRendererText()
473
        self.renderer_updated.set_property('background', '#FFE6D1')
402 t00mlabs 474
        self.column_updated = Gtk.TreeViewColumn('Updated', self.renderer_updated, markup=COLUMN.UPDATED)
390 t00mlabs 475
        widget = get_column_header_widget('Updated', 'basico-chronologic')
389 t00mlabs 476
        self.column_updated.set_widget(widget)
340 t00mlabs 477
        self.column_updated.set_visible(True)
478
        self.column_updated.set_expand(False)
479
        self.column_updated.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE)
480
        self.column_updated.set_clickable(True)
481
        self.column_updated.set_sort_indicator(True)
402 t00mlabs 482
        self.column_updated.set_sort_column_id(COLUMN.TS_UPDATED)
340 t00mlabs 483
        self.column_updated.set_sort_order(Gtk.SortType.DESCENDING)
402 t00mlabs 484
        model.set_sort_column_id(COLUMN.TS_UPDATED, Gtk.SortType.DESCENDING)
399 t00mlabs 485
        treeview.append_column(self.column_updated)
340 t00mlabs 486
 
351 t00mlabs 487
        # Timestamp updated
389 t00mlabs 488
        self.renderer_timestamp_updated = Gtk.CellRendererText()
402 t00mlabs 489
        self.column_timestamp_updated = Gtk.TreeViewColumn('Timestamp updated', self.renderer_timestamp_updated, text=COLUMN.TS_UPDATED)
389 t00mlabs 490
        self.column_timestamp_updated.set_visible(False)
491
        self.column_timestamp_updated.set_expand(False)
492
        self.column_timestamp_updated.set_clickable(False)
493
        self.column_timestamp_updated.set_sort_indicator(True)
402 t00mlabs 494
        self.column_timestamp_updated.set_sort_column_id(COLUMN.TS_UPDATED)
389 t00mlabs 495
        self.column_timestamp_updated.set_sort_order(Gtk.SortType.ASCENDING)
399 t00mlabs 496
        treeview.append_column(self.column_timestamp_updated)
351 t00mlabs 497
 
498
        # Annotation Created On
389 t00mlabs 499
        self.renderer_created = Gtk.CellRendererText()
500
        self.renderer_created.set_property('background', '#FFE6D1')
402 t00mlabs 501
        self.column_created = Gtk.TreeViewColumn('Created', self.renderer_created, markup=COLUMN.CREATED)
390 t00mlabs 502
        widget = get_column_header_widget('Created', 'basico-chronologic')
389 t00mlabs 503
        self.column_created.set_widget(widget)
398 t00mlabs 504
        self.column_created.set_visible(False)
389 t00mlabs 505
        self.column_created.set_expand(False)
506
        self.column_created.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE)
507
        self.column_created.set_clickable(True)
508
        self.column_created.set_sort_indicator(True)
402 t00mlabs 509
        self.column_created.set_sort_column_id(COLUMN.TS_CREATED)
389 t00mlabs 510
        self.column_created.set_sort_order(Gtk.SortType.DESCENDING)
402 t00mlabs 511
        model.set_sort_column_id(COLUMN.TS_CREATED, Gtk.SortType.DESCENDING)
399 t00mlabs 512
        treeview.append_column(self.column_created)
351 t00mlabs 513
 
340 t00mlabs 514
        # Timestamp
389 t00mlabs 515
        self.renderer_timestamp_created = Gtk.CellRendererText()
402 t00mlabs 516
        self.column_timestamp_created = Gtk.TreeViewColumn('Timestamp created', self.renderer_timestamp_created, text=COLUMN.TS_CREATED)
389 t00mlabs 517
        self.column_timestamp_created.set_visible(False)
518
        self.column_timestamp_created.set_expand(False)
519
        self.column_timestamp_created.set_clickable(False)
520
        self.column_timestamp_created.set_sort_indicator(True)
402 t00mlabs 521
        self.column_timestamp_created.set_sort_column_id(COLUMN.TS_CREATED)
389 t00mlabs 522
        self.column_timestamp_created.set_sort_order(Gtk.SortType.ASCENDING)
399 t00mlabs 523
        treeview.append_column(self.column_timestamp_created)
377 t00mlabs 524
 
340 t00mlabs 525
        # Treeview properties
399 t00mlabs 526
        treeview.set_can_focus(False)
527
        treeview.set_enable_tree_lines(True)
528
        treeview.set_headers_visible(True)
529
        treeview.set_enable_search(True)
530
        treeview.set_hover_selection(False)
531
        treeview.set_grid_lines(Gtk.TreeViewGridLines.HORIZONTAL)
532
        treeview.set_enable_tree_lines(True)
533
        treeview.set_level_indentation(10)
400 t00mlabs 534
        treeview.connect('button_press_event', self.__clb_row_right_click)
340 t00mlabs 535
 
399 t00mlabs 536
        treeview.modify_font(Pango.FontDescription('Monospace 9'))
377 t00mlabs 537
 
340 t00mlabs 538
        # DOC: In order to have a Gtk.Widged with sorting and filtering
539
        # capabilities, you have to filter the model first, and use this
540
        # new model to create the sorted model. Then, attach the sorted
541
        # model to the treeview...
542
 
543
        # Treeview filtering:
400 t00mlabs 544
        visible_filter = self.srvgui.add_widget('visor_annotation_visible_filter', model.filter_new())
545
        visible_filter.set_visible_func(self.__visible_function)
340 t00mlabs 546
 
547
        # TreeView sorting
399 t00mlabs 548
        sorted_model = Gtk.TreeModelSort(model=visible_filter)
549
        self.srvgui.add_widget('visor_annotation_sorted_model', sorted_model)
402 t00mlabs 550
        sorted_model.set_sort_func(COLUMN.AID, self.__sort_function, None)
340 t00mlabs 551
 
552
        # Selection
399 t00mlabs 553
        selection = treeview.get_selection()
554
        selection.set_mode(Gtk.SelectionMode.SINGLE)
400 t00mlabs 555
        selection.connect('changed', self.__clb_row_changed)
340 t00mlabs 556
 
557
        # Set model (filtered and sorted)
402 t00mlabs 558
        sorted_model.set_sort_column_id(COLUMN.TS_UPDATED, Gtk.SortType.ASCENDING)
399 t00mlabs 559
        treeview.set_model(sorted_model)
340 t00mlabs 560
 
361 t00mlabs 561
        # Other signals
400 t00mlabs 562
        treeview.connect('row-activated', self.__clb_row_double_click)
361 t00mlabs 563
 
340 t00mlabs 564
        self.show_all()
565
 
566
 
400 t00mlabs 567
    def __sort_function(self, model, row1, row2, user_data):
340 t00mlabs 568
        sort_column = 0
569
 
570
        value1 = model.get_value(row1, sort_column)
571
        value2 = model.get_value(row2, sort_column)
572
 
573
        if value1 < value2:
574
            return -1
575
        elif value1 == value2:
576
            return 0
577
        else:
578
            return 1
579
 
580
 
400 t00mlabs 581
    def __visible_function(self, model, itr, data):
340 t00mlabs 582
        entry = self.srvgui.get_widget('gtk_entry_filter_visor')
583
        text = self.srvutl.clean_html(entry.get_text())
402 t00mlabs 584
        title = model.get(itr, COLUMN.TITLE)[0]
585
        scope = model.get(itr, COLUMN.SCOPE)[0]
586
        product = model.get(itr, COLUMN.PRODUCT)[0]
340 t00mlabs 587
        match = text.upper() in title.upper()
588
 
393 t00mlabs 589
        cmb_scope = self.srvgui.get_widget('gtk_combobox_filter_scope')
394 t00mlabs 590
        scope_filter = self.srvutl.clean_html(self.srvuif.get_combobox_text(cmb_scope, 0))
591
        cmb_product = self.srvgui.get_widget('gtk_combobox_filter_product')
592
        product_filter = self.srvutl.clean_html(self.srvuif.get_combobox_text(cmb_product, 0))
593
 
594
 
595
        if scope_filter in [scope, 'All', '', 'Scope']:
393 t00mlabs 596
            match = match and True
394 t00mlabs 597
        elif scope_filter == 'None' and scope == '':
598
            match = True
393 t00mlabs 599
        else:
600
            match = match and False
601
 
394 t00mlabs 602
        if product_filter in [product, 'All', '', 'Product']:
603
            match = match and True
604
        elif product_filter == 'None' and product == '':
605
            match = True
606
        else:
607
            match = match and False
608
 
340 t00mlabs 609
        return match
610
 
611
 
612
    def update_total_annotations_count(self):
400 t00mlabs 613
        visible_filter = self.srvgui.get_widget('visor_annotation_visible_filter')
340 t00mlabs 614
        statusbar = self.srvgui.get_widget('widget_statusbar')
615
        lblnotescount = self.srvgui.get_widget('gtk_label_total_notes')
616
        total = self.srvant.get_total()
399 t00mlabs 617
        count = len(visible_filter)
340 t00mlabs 618
        lblnotescount.set_markup("<b>%d/<big>%d annotations</big></b>" % (count, total))
619
        msg = 'View populated with %d annotations' % count
620
        self.srvuif.statusbar_msg(msg)
621
 
622
 
623
    def get_visible_filter(self):
624
        return self.visible_filter
625
 
626
 
367 t00mlabs 627
    def row_current(self, *args):
399 t00mlabs 628
        treeview = self.srvgui.get_widget('visor_annotation_treeview')
629
        selection = treeview.get_selection()
367 t00mlabs 630
        model, treeiter = selection.get_selected()
631
        return treeiter
632
 
377 t00mlabs 633
 
367 t00mlabs 634
    def row_previous(self, *args):
399 t00mlabs 635
        treeview = self.srvgui.get_widget('visor_annotation_treeview')
636
        selection = treeview.get_selection()
367 t00mlabs 637
        model, iter_current = selection.get_selected()
638
        if iter_current is not None:
639
            iter_previous = model.iter_previous(iter_current)
640
            if iter_previous:
641
                selection.select_iter(iter_previous)
395 t00mlabs 642
                widget_annotation = self.srvgui.get_widget('widget_annotation')
643
                widget_annotation.preview()
367 t00mlabs 644
 
377 t00mlabs 645
 
367 t00mlabs 646
    def row_next(self, *args):
399 t00mlabs 647
        treeview = self.srvgui.get_widget('visor_annotation_treeview')
648
        selection = treeview.get_selection()
367 t00mlabs 649
        model, iter_current = selection.get_selected()
650
        if iter_current is not None:
651
            iter_next = model.iter_next(iter_current)
652
            if iter_next:
653
                selection.select_iter(iter_next)
399 t00mlabs 654
                path, col = treeview.get_cursor()
367 t00mlabs 655
                row = self.srvuif.tree_path_to_row(path)
399 t00mlabs 656
                treeview.scroll_to_cell(row, column=None, use_align=False, row_align=0.5, col_align=0)
395 t00mlabs 657
                widget_annotation = self.srvgui.get_widget('widget_annotation')
658
                widget_annotation.preview()
367 t00mlabs 659
 
660
 
377 t00mlabs 661
    def rows_toggled(self):
399 t00mlabs 662
        sorted_model = self.srvgui.get_widget('visor_annotation_sorted_model')
377 t00mlabs 663
        selected = []
664
 
400 t00mlabs 665
        def get_toggled_rows(model, path, itr):
402 t00mlabs 666
            aid = sorted_model.get(itr, COLUMN.AID)[0]
667
            checked = sorted_model.get(itr, COLUMN.CHECKBOX)[0]
377 t00mlabs 668
            if checked:
669
                selected.append(str(aid))
400 t00mlabs 670
        sorted_model.foreach(get_toggled_rows)
377 t00mlabs 671
 
672
        return selected
673
 
674
 
400 t00mlabs 675
    def __clb_row_changed(self, selection):
340 t00mlabs 676
        try:
677
            model, treeiter = selection.get_selected()
678
            if treeiter is not None:
402 t00mlabs 679
                component = model[treeiter][COLUMN.COMPONENT]
340 t00mlabs 680
                if component == 'Annotation':
402 t00mlabs 681
                    aid = model[treeiter][COLUMN.AID]
340 t00mlabs 682
                    is_valid = self.srvant.is_valid(aid)
683
                    if is_valid:
361 t00mlabs 684
                        widget_annotation = self.srvgui.get_widget('widget_annotation')
685
                        widget_annotation.set_metadata_to_widget(aid)
394 t00mlabs 686
                        # ~ widget_annotation.preview()
340 t00mlabs 687
                else:
688
                    aid = None
389 t00mlabs 689
                    # ~ self.srvuif.set_widget_visibility('gtk_vbox_container_annotations', False)
340 t00mlabs 690
        except Exception as error:
361 t00mlabs 691
            pass
692
            # ~ head = "Error reading annotation's contents"
693
            # ~ body = "<i>%s</i>\n\n" % error
694
            # ~ body += "As a workaround, a new file will be created"
695
            # ~ dialog = self.srvuif.message_dialog_error(head, body)
696
            # ~ self.log.debug(error)
697
            # ~ self.log.debug(self.get_traceback())
698
            # ~ dialog.run()
699
            # ~ dialog.destroy()
340 t00mlabs 700
            #FIXME: create an empty file for contents
701
 
702
 
402 t00mlabs 703
    def __clb_row_toggled(self, cell, path):
399 t00mlabs 704
        sorted_model = self.srvgui.get_widget('visor_annotation_sorted_model')
705
        model = sorted_model.get_model()
706
        rpath = sorted_model.convert_path_to_child_path(Gtk.TreePath(path))
402 t00mlabs 707
        model[rpath][COLUMN.CHECKBOX] = not model[rpath][COLUMN.CHECKBOX]
340 t00mlabs 708
 
709
 
403 t00mlabs 710
    def __get_node(self, key, icon, checkbox, sid, title, component, atype, scope='', sntype='', priority='', updated='', ts_updated='', created='', ts_created=''):
340 t00mlabs 711
        # Add completion entries
712
        completion = self.srvgui.get_widget('gtk_entrycompletion_visor')
713
        completion_model = completion.get_model()
714
        title = self.srvutl.clean_html(title)
715
        completion_model.append([title])
716
 
717
        node = []
718
        node.append(key)
719
        node.append(icon)
720
        node.append(checkbox)
721
        node.append(sid)
722
        node.append(title)
723
        node.append(component)
403 t00mlabs 724
        node.append(atype)
393 t00mlabs 725
        node.append(scope)
340 t00mlabs 726
        node.append(sntype)
727
        node.append(priority)
728
        node.append(updated)
351 t00mlabs 729
        node.append(ts_updated)
730
        node.append(created)
731
        node.append(ts_created)
340 t00mlabs 732
        return node
733
 
734
 
400 t00mlabs 735
    def __set_bag(self, annotations=None):
340 t00mlabs 736
        self.bag = annotations
737
 
738
 
739
    def get_bag(self):
740
        return self.bag
741
 
742
 
362 t00mlabs 743
    def populate(self, annotations=None):
399 t00mlabs 744
        treeview = self.srvgui.get_widget('visor_annotation_treeview')
745
        sorted_model = self.srvgui.get_widget('visor_annotation_sorted_model')
746
        model = self.srvgui.get_widget('gtk_model_annotation')
340 t00mlabs 747
        self.column_sid.set_visible(False)
748
        completion = self.srvgui.get_widget('gtk_entrycompletion_visor')
749
        completion_model = completion.get_model()
750
        completion_model.clear()
751
 
399 t00mlabs 752
        treeview.set_model(None)
753
        model.clear()
340 t00mlabs 754
 
755
        if annotations is None:
369 t00mlabs 756
            annotations = self.get_bag()
757
            if annotations is None:
758
                annotations = self.srvant.get_all()
759
            else:
760
                self.log.debug("Displaying last query")
340 t00mlabs 761
        else:
369 t00mlabs 762
            self.log.debug("Displaying following annotations: %s", annotations)
400 t00mlabs 763
            self.__set_bag(annotations)
340 t00mlabs 764
 
765
        dcats = {}
766
        snpids = {}
767
        nodes = []
393 t00mlabs 768
        bag = set()
769
 
340 t00mlabs 770
        for fname in annotations:
771
            try:
772
                with open(fname, 'r') as fa:
773
                    try:
395 t00mlabs 774
                        try:
775
                            annotation = json.load(fa)
776
                        except Exception as error:
777
                            self.log.error("Annotation: %s", fname)
778
                            self.log.error(error)
394 t00mlabs 779
                        # Get Scope
393 t00mlabs 780
                        try:
781
                            scope = annotation['Scope']
782
                        except:
783
                            scope = ''
394 t00mlabs 784
 
785
                        # Get Product
786
                        try:
787
                            product = annotation['Product']
788
                        except:
789
                            product = ''
790
 
369 t00mlabs 791
                        # ~ self.log.debug("Annotation: %s", annotation['Title'])
340 t00mlabs 792
                        category = annotation['Category']
793
                        atype = annotation['Type']
794
                        cat_key = 'ANNOTATIONS_CATEGORY_%s_VISIBLE' % category.upper()
795
                        type_key = 'ANNOTATIONS_TYPE_%s_VISIBLE' % atype.upper()
796
                        category_active = self.srvgui.get_key_value(cat_key)
797
                        try:
798
                            type_active = self.srvgui.get_key_value(type_key)
799
                        except Exception as error:
800
                            self.log.error(error)
801
                            type_active = True
802
                        if category_active:
803
                            if type_active:
804
                                ppid = None
805
                                sid = self.srvant.get_sid(annotation['AID'])
806
                                try:
807
                                    icon = self.icons['type']['%s' % atype.lower()]
808
                                except:
809
                                    icon = None
810
                                if sid != '0000000000':
811
                                    title = "<b>[SAP Note %d]</b> %s" % (int(sid), annotation['Title'])
812
                                else:
813
                                    title = annotation['Title']
814
 
815
                                try:
816
                                    annotation['Priority']
817
                                except:
818
                                    annotation['Priority'] = 'Normal'
819
 
400 t00mlabs 820
                                node = self.__get_node(   annotation['AID'],
340 t00mlabs 821
                                                        icon,
822
                                                        False,
823
                                                        str(int(sid)),
824
                                                        title,
825
                                                        annotation['Component'],
403 t00mlabs 826
                                                        annotation['Type'],
393 t00mlabs 827
                                                        scope,
394 t00mlabs 828
                                                        product,
340 t00mlabs 829
                                                        annotation['Priority'],
830
                                                        self.srvutl.fuzzy_date_from_timestamp(annotation['Timestamp']),
351 t00mlabs 831
                                                        annotation['Timestamp'],
832
                                                        self.srvutl.fuzzy_date_from_timestamp(annotation['Created']),
833
                                                        annotation['Created']
340 t00mlabs 834
                                                    )
835
                                nodes.append(node)
836
                    except Exception as error:
837
                        self.log.error(error)
351 t00mlabs 838
                        self.log.error(self.get_traceback())
340 t00mlabs 839
            except Exception as error:
840
                # Whenever an annotation is deleted, after reloading
841
                # the view, it fails. Then, skip it
399 t00mlabs 842
                pass
340 t00mlabs 843
 
844
        for node in nodes:
399 t00mlabs 845
            model.append(None, node)
340 t00mlabs 846
 
399 t00mlabs 847
        treeview.set_model(sorted_model)
400 t00mlabs 848
        self.__sort_by_timestamp()
849
        self.__update_panel_values()
340 t00mlabs 850
        self.update_total_annotations_count()
851
 
369 t00mlabs 852
 
400 t00mlabs 853
    def __clb_preview(self, button, aid):
380 t00mlabs 854
        self.srvclb.action_annotation_preview(aid)
855
 
856
 
400 t00mlabs 857
    def __clb_edit(self, button, aid):
380 t00mlabs 858
        self.srvclb.action_annotation_edit(aid)
859
 
860
 
400 t00mlabs 861
    def __clb_row_double_click(self, treeview, row, col):
361 t00mlabs 862
        try:
863
            selection = treeview.get_selection()
864
            model, treeiter = selection.get_selected()
865
            if treeiter is not None:
402 t00mlabs 866
                component = model[treeiter][COLUMN.COMPONENT]
361 t00mlabs 867
                if component == 'Annotation':
402 t00mlabs 868
                    aid = model[treeiter][COLUMN.AID]
361 t00mlabs 869
                    is_valid = self.srvant.is_valid(aid)
870
                    if is_valid:
380 t00mlabs 871
                        self.srvclb.action_annotation_preview(aid)
361 t00mlabs 872
        except Exception as error:
389 t00mlabs 873
            self.log.error(error)
361 t00mlabs 874
 
399 t00mlabs 875
 
400 t00mlabs 876
    def __clb_row_right_click(self, treeview, event, data=None):
399 t00mlabs 877
        treeview = self.srvgui.get_widget('visor_annotation_treeview')
340 t00mlabs 878
        if event.button == 3:
879
            rect = Gdk.Rectangle()
880
            rect.x = x = int(event.x)
881
            rect.y = y = int(event.y)
399 t00mlabs 882
            pthinfo = treeview.get_path_at_pos(x,y)
340 t00mlabs 883
            if pthinfo is not None:
884
                path,col,cellx,celly = pthinfo
885
                model = treeview.get_model()
886
                treeiter = model.get_iter(path)
402 t00mlabs 887
                component = model[treeiter][COLUMN.COMPONENT]
888
                aid = model[treeiter][COLUMN.AID]
340 t00mlabs 889
                popover = self.srvgui.add_widget('gtk_popover_visor_row', Gtk.Popover.new(treeview))
890
                popover.set_pointing_to(rect)
400 t00mlabs 891
                box = self.__build_popover(aid, popover, component)
340 t00mlabs 892
                if box is not None:
361 t00mlabs 893
                    visor_annotations = self.srvgui.get_widget('visor_annotations')
894
                    width, height = visor_annotations.get_size_request()
340 t00mlabs 895
                    popover.add(box)
896
                    self.srvclb.gui_show_popover(None, popover)
897
 
898
 
377 t00mlabs 899
 
400 t00mlabs 900
    def __build_popover(self, aid, popover, component):
340 t00mlabs 901
        sid = self.srvant.get_sid(aid)
902
 
903
        def get_popover_button(text, icon_name):
904
            button = Gtk.Button()
905
            button.set_relief(Gtk.ReliefStyle.NONE)
906
            hbox = Gtk.HBox()
907
            icon = self.srvicm.get_new_image_icon(icon_name, 24, 24)
908
            hbox.pack_start(icon, False, False, 3)
380 t00mlabs 909
            if len(text) > 0:
910
                lbltext = Gtk.Label()
911
                lbltext.set_xalign(0.0)
912
                lbltext.set_markup('%s' % text)
913
                hbox.pack_start(lbltext, True, True, 3)
340 t00mlabs 914
            button.add(hbox)
915
            return button
916
 
917
        if component == 'Annotation':
918
            box = Gtk.Box(spacing = 3, orientation="vertical")
919
 
380 t00mlabs 920
            hbox_sel = Gtk.HBox()
921
            button = get_popover_button("", 'basico-check-all')
922
            button.set_tooltip_markup("Select all")
400 t00mlabs 923
            button.connect('clicked', self.__clb_select_all, True)
380 t00mlabs 924
            hbox_sel.pack_start(button, True, False, 0)
340 t00mlabs 925
 
380 t00mlabs 926
            button = get_popover_button("", 'basico-check-none')
927
            button.set_tooltip_markup("Select none")
400 t00mlabs 928
            button.connect('clicked', self.__clb_select_all, False)
380 t00mlabs 929
            hbox_sel.pack_start(button, True, False, 0)
377 t00mlabs 930
 
380 t00mlabs 931
            button = get_popover_button("", 'basico-check-invert')
932
            button.set_tooltip_markup("Invert selection")
400 t00mlabs 933
            button.connect('clicked', self.__clb_select_all, None)
380 t00mlabs 934
            hbox_sel.pack_start(button, True, False, 0)
378 t00mlabs 935
 
380 t00mlabs 936
            box.pack_start(hbox_sel, False, False, 0)
937
            box.show_all()
938
 
377 t00mlabs 939
            if len(self.rows_toggled()) > 0:
378 t00mlabs 940
                separator = Gtk.Separator(orientation = Gtk.Orientation.HORIZONTAL)
941
                box.pack_start(separator, False, False, 0)
942
 
377 t00mlabs 943
                button = get_popover_button("<b>Delete</b> annotations", 'basico-delete')
944
                button.show_all()
945
                button.connect('clicked', self.srvclb.action_annotation_delete)
946
                box.pack_start(button, False, False, 0)
947
 
378 t00mlabs 948
                button = get_popover_button("<b>Backup</b> annotations", 'basico-backup')
949
                button.show_all()
950
                # ~ button.connect('clicked', self.srvclb.action_annotation_backup)
951
                box.pack_start(button, False, False, 0)
952
 
379 t00mlabs 953
            else:
954
                separator = Gtk.Separator(orientation = Gtk.Orientation.HORIZONTAL)
955
                box.pack_start(separator, False, False, 0)
956
 
957
                # Popover button "Jump to SAP Note"
958
                if sid != '0000000000':
959
                    # Jump to SAP Note
380 t00mlabs 960
                    button = get_popover_button("<b>Jump</b> to SAP Note %d" % int(sid), 'basico-jump-sapnote')
379 t00mlabs 961
                    button.show_all()
962
                    button.connect('clicked', self.srvclb.gui_jump_to_sapnote, sid)
963
                    box.pack_start(button, False, False, 0)
964
 
380 t00mlabs 965
                button = get_popover_button("<b>Preview</b> annotation", 'basico-preview')
340 t00mlabs 966
                button.show_all()
400 t00mlabs 967
                button.connect('clicked', self.__clb_preview, aid)
340 t00mlabs 968
                box.pack_start(button, False, False, 0)
379 t00mlabs 969
 
380 t00mlabs 970
                button = get_popover_button("<b>Edit</b> annotation", 'basico-edit')
379 t00mlabs 971
                button.show_all()
400 t00mlabs 972
                button.connect('clicked', self.__clb_edit, aid)
379 t00mlabs 973
                box.pack_start(button, False, False, 0)
974
 
380 t00mlabs 975
                button = get_popover_button("<b>Duplicate</b> annotation", 'basico-copy-paste')
379 t00mlabs 976
                button.show_all()
977
                # ~ button.connect('clicked', self.srvclb.duplicate_sapnote, aid)
978
                box.pack_start(button, False, False, 0)
979
 
340 t00mlabs 980
            return box
981
 
982
 
400 t00mlabs 983
    def __clb_select_all(self, button, checked):
399 t00mlabs 984
        sorted_model = self.srvgui.get_widget('visor_annotation_sorted_model')
377 t00mlabs 985
        def check_row(model, path, itr):
378 t00mlabs 986
            if checked is not None:
402 t00mlabs 987
                model[path][COLUMN.CHECKBOX] = checked
378 t00mlabs 988
            else:
402 t00mlabs 989
                state = model[path][COLUMN.CHECKBOX]
990
                model[path][COLUMN.CHECKBOX] = not state
377 t00mlabs 991
 
399 t00mlabs 992
        model = sorted_model.get_model()
377 t00mlabs 993
        model.foreach(check_row)
379 t00mlabs 994
        self.srvuif.grab_focus()
377 t00mlabs 995
 
996
 
400 t00mlabs 997
    def set_menuview_signals(self):
340 t00mlabs 998
        # Categories
999
        button = self.srvgui.get_widget('gtk_togglebutton_categories')
400 t00mlabs 1000
        button.connect('toggled', self.__clb_set_visible_categories)
340 t00mlabs 1001
 
1002
        for name in ['inbox', 'drafts', 'archived']:
1003
            button = self.srvgui.get_widget('gtk_button_category_%s' % name)
400 t00mlabs 1004
            button.connect('toggled', self.__clb_set_visible_category, name)
340 t00mlabs 1005
 
1006
        # Types
1007
        button = self.srvgui.get_widget('gtk_togglebutton_types')
400 t00mlabs 1008
        button.connect('toggled', self.__clb_set_visible_types)
340 t00mlabs 1009
 
1010
        for name in ATYPES:
1011
            button = self.srvgui.get_widget('gtk_button_type_%s' % name.lower())
400 t00mlabs 1012
            button.connect('toggled', self.__clb_set_visible_annotation_type, name)
340 t00mlabs 1013
 
1014
 
1015
    def set_active_categories(self):
1016
        category = self.srvgui.get_widget('gtk_togglebutton_inbox')
1017
        category.set_active(True)
1018
 
393 t00mlabs 1019
 
400 t00mlabs 1020
    def __update_panel_values(self):
1021
        self.__update_scopes()
1022
        self.__update_products()
394 t00mlabs 1023
 
400 t00mlabs 1024
    def __update_scopes(self):
399 t00mlabs 1025
        sorted_model = self.srvgui.get_widget('visor_annotation_sorted_model')
393 t00mlabs 1026
        scopes = set()
394 t00mlabs 1027
 
393 t00mlabs 1028
        def get_values(model, path, itr):
402 t00mlabs 1029
            scope = sorted_model.get(itr, COLUMN.SCOPE)[0]
393 t00mlabs 1030
            scopes.add(scope)
399 t00mlabs 1031
        sorted_model.foreach(get_values)
393 t00mlabs 1032
 
394 t00mlabs 1033
        # Update scope combo
393 t00mlabs 1034
        cmb_scope = self.srvgui.get_widget('gtk_combobox_filter_scope')
1035
        signal = self.srvgui.get_signal('gtk_combobox_filter_scope', 'changed')
1036
        GObject.signal_handler_block(cmb_scope, signal)
1037
        model = cmb_scope.get_model()
1038
        model.clear()
394 t00mlabs 1039
        first = model.append(['<big><b>Scope</b></big>'])
1040
        model.append(['All'])
1041
        model.append(['None'])
1042
        cmb_scope.set_active_iter(first)
393 t00mlabs 1043
        lscopes = list(scopes)
1044
        lscopes.sort()
1045
        for item in lscopes:
1046
            if len(item) > 0:
1047
                model.append([item])
1048
        GObject.signal_handler_unblock(cmb_scope, signal)
1049
 
1050
 
400 t00mlabs 1051
    def __update_products(self):
399 t00mlabs 1052
        sorted_model = self.srvgui.get_widget('visor_annotation_sorted_model')
394 t00mlabs 1053
        products = set()
1054
 
1055
        def get_values(model, path, itr):
402 t00mlabs 1056
            product = sorted_model.get(itr, COLUMN.PRODUCT)[0]
394 t00mlabs 1057
            products.add(product)
399 t00mlabs 1058
        sorted_model.foreach(get_values)
394 t00mlabs 1059
 
1060
        # Update product combo
1061
        cmb_product = self.srvgui.get_widget('gtk_combobox_filter_product')
1062
        signal = self.srvgui.get_signal('gtk_combobox_filter_product', 'changed')
1063
        GObject.signal_handler_block(cmb_product, signal)
1064
        model = cmb_product.get_model()
1065
        model.clear()
1066
        first = model.append(['<big><b>Product</b></big>'])
1067
        model.append(['All'])
1068
        model.append(['None'])
1069
        cmb_product.set_active_iter(first)
1070
        lproducts = list(products)
1071
        lproducts.sort()
1072
        for item in lproducts:
1073
            if len(item) > 0:
1074
                model.append([item])
1075
        GObject.signal_handler_unblock(cmb_product, signal)
1076
 
1077
 
400 t00mlabs 1078
    def __clb_scope_changed(self, *args):
1079
        visible_filter = self.srvgui.get_widget('visor_annotation_visible_filter')
393 t00mlabs 1080
        visible_filter.refilter()
1081
        self.update_total_annotations_count()
394 t00mlabs 1082
        self.update_products()
1083
 
1084
 
400 t00mlabs 1085
    def __clb_product_changed(self, *args):
1086
        visible_filter = self.srvgui.get_widget('visor_annotation_visible_filter')
394 t00mlabs 1087
        visible_filter.refilter()
1088
        self.update_total_annotations_count()
1089
        self.update_scopes()
1090
 
1091
 
400 t00mlabs 1092
    def __clb_switch_selection_atypes(self, switch, state):
1093
        label = self.srvgui.get_widget('gtk_label_switch_select_atypes')
1094
        switched = switch.get_active()
1095
        switch.set_state(switched)
1096
        if switched is True:
1097
            label.set_text ("All selected")
1098
 
1099
        else:
1100
            label.set_text("None selected")
1101
 
1102
        for name in ATYPES:
1103
            button = self.srvgui.get_widget('gtk_button_type_%s' % name.lower())
1104
            button.set_state(switched)
1105
            button.set_active(switched)