Subversion Repositories basico

Rev

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

Rev Author Line No. Line
340 t00mlabs 1
#!/usr/bin/python
2
# -*- coding: utf-8 -*-
3
"""
4
# File: wdg_visor_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')
405 t00mlabs 616
        lblnotescount.modify_font(Pango.FontDescription('Monospace 12'))
340 t00mlabs 617
        total = self.srvant.get_total()
399 t00mlabs 618
        count = len(visible_filter)
405 t00mlabs 619
        selected = len(self.rows_toggled())
620
        lblnotescount.set_markup("<b><small>%d</small>/%d/<big>%d</big></b>" % (selected, count, total))
340 t00mlabs 621
        msg = 'View populated with %d annotations' % count
622
        self.srvuif.statusbar_msg(msg)
623
 
624
 
625
    def get_visible_filter(self):
626
        return self.visible_filter
627
 
628
 
367 t00mlabs 629
    def row_current(self, *args):
399 t00mlabs 630
        treeview = self.srvgui.get_widget('visor_annotation_treeview')
631
        selection = treeview.get_selection()
367 t00mlabs 632
        model, treeiter = selection.get_selected()
633
        return treeiter
634
 
377 t00mlabs 635
 
367 t00mlabs 636
    def row_previous(self, *args):
399 t00mlabs 637
        treeview = self.srvgui.get_widget('visor_annotation_treeview')
638
        selection = treeview.get_selection()
367 t00mlabs 639
        model, iter_current = selection.get_selected()
640
        if iter_current is not None:
641
            iter_previous = model.iter_previous(iter_current)
642
            if iter_previous:
643
                selection.select_iter(iter_previous)
395 t00mlabs 644
                widget_annotation = self.srvgui.get_widget('widget_annotation')
645
                widget_annotation.preview()
367 t00mlabs 646
 
377 t00mlabs 647
 
367 t00mlabs 648
    def row_next(self, *args):
399 t00mlabs 649
        treeview = self.srvgui.get_widget('visor_annotation_treeview')
650
        selection = treeview.get_selection()
367 t00mlabs 651
        model, iter_current = selection.get_selected()
652
        if iter_current is not None:
653
            iter_next = model.iter_next(iter_current)
654
            if iter_next:
655
                selection.select_iter(iter_next)
399 t00mlabs 656
                path, col = treeview.get_cursor()
367 t00mlabs 657
                row = self.srvuif.tree_path_to_row(path)
399 t00mlabs 658
                treeview.scroll_to_cell(row, column=None, use_align=False, row_align=0.5, col_align=0)
395 t00mlabs 659
                widget_annotation = self.srvgui.get_widget('widget_annotation')
660
                widget_annotation.preview()
367 t00mlabs 661
 
662
 
377 t00mlabs 663
    def rows_toggled(self):
399 t00mlabs 664
        sorted_model = self.srvgui.get_widget('visor_annotation_sorted_model')
377 t00mlabs 665
        selected = []
666
 
400 t00mlabs 667
        def get_toggled_rows(model, path, itr):
402 t00mlabs 668
            aid = sorted_model.get(itr, COLUMN.AID)[0]
669
            checked = sorted_model.get(itr, COLUMN.CHECKBOX)[0]
377 t00mlabs 670
            if checked:
671
                selected.append(str(aid))
400 t00mlabs 672
        sorted_model.foreach(get_toggled_rows)
377 t00mlabs 673
 
674
        return selected
675
 
676
 
400 t00mlabs 677
    def __clb_row_changed(self, selection):
340 t00mlabs 678
        try:
679
            model, treeiter = selection.get_selected()
680
            if treeiter is not None:
402 t00mlabs 681
                component = model[treeiter][COLUMN.COMPONENT]
340 t00mlabs 682
                if component == 'Annotation':
402 t00mlabs 683
                    aid = model[treeiter][COLUMN.AID]
340 t00mlabs 684
                    is_valid = self.srvant.is_valid(aid)
685
                    if is_valid:
361 t00mlabs 686
                        widget_annotation = self.srvgui.get_widget('widget_annotation')
687
                        widget_annotation.set_metadata_to_widget(aid)
394 t00mlabs 688
                        # ~ widget_annotation.preview()
340 t00mlabs 689
                else:
690
                    aid = None
389 t00mlabs 691
                    # ~ self.srvuif.set_widget_visibility('gtk_vbox_container_annotations', False)
340 t00mlabs 692
        except Exception as error:
361 t00mlabs 693
            pass
694
            # ~ head = "Error reading annotation's contents"
695
            # ~ body = "<i>%s</i>\n\n" % error
696
            # ~ body += "As a workaround, a new file will be created"
697
            # ~ dialog = self.srvuif.message_dialog_error(head, body)
698
            # ~ self.log.debug(error)
699
            # ~ self.log.debug(self.get_traceback())
700
            # ~ dialog.run()
701
            # ~ dialog.destroy()
340 t00mlabs 702
            #FIXME: create an empty file for contents
703
 
704
 
402 t00mlabs 705
    def __clb_row_toggled(self, cell, path):
399 t00mlabs 706
        sorted_model = self.srvgui.get_widget('visor_annotation_sorted_model')
707
        model = sorted_model.get_model()
708
        rpath = sorted_model.convert_path_to_child_path(Gtk.TreePath(path))
402 t00mlabs 709
        model[rpath][COLUMN.CHECKBOX] = not model[rpath][COLUMN.CHECKBOX]
405 t00mlabs 710
        self.update_total_annotations_count()
340 t00mlabs 711
 
712
 
403 t00mlabs 713
    def __get_node(self, key, icon, checkbox, sid, title, component, atype, scope='', sntype='', priority='', updated='', ts_updated='', created='', ts_created=''):
340 t00mlabs 714
        # Add completion entries
715
        completion = self.srvgui.get_widget('gtk_entrycompletion_visor')
716
        completion_model = completion.get_model()
717
        title = self.srvutl.clean_html(title)
718
        completion_model.append([title])
719
 
720
        node = []
721
        node.append(key)
722
        node.append(icon)
723
        node.append(checkbox)
724
        node.append(sid)
725
        node.append(title)
726
        node.append(component)
403 t00mlabs 727
        node.append(atype)
393 t00mlabs 728
        node.append(scope)
340 t00mlabs 729
        node.append(sntype)
730
        node.append(priority)
731
        node.append(updated)
351 t00mlabs 732
        node.append(ts_updated)
733
        node.append(created)
734
        node.append(ts_created)
340 t00mlabs 735
        return node
736
 
737
 
400 t00mlabs 738
    def __set_bag(self, annotations=None):
340 t00mlabs 739
        self.bag = annotations
740
 
741
 
742
    def get_bag(self):
743
        return self.bag
744
 
745
 
362 t00mlabs 746
    def populate(self, annotations=None):
399 t00mlabs 747
        treeview = self.srvgui.get_widget('visor_annotation_treeview')
748
        sorted_model = self.srvgui.get_widget('visor_annotation_sorted_model')
749
        model = self.srvgui.get_widget('gtk_model_annotation')
340 t00mlabs 750
        self.column_sid.set_visible(False)
751
        completion = self.srvgui.get_widget('gtk_entrycompletion_visor')
752
        completion_model = completion.get_model()
753
        completion_model.clear()
754
 
399 t00mlabs 755
        treeview.set_model(None)
756
        model.clear()
340 t00mlabs 757
 
758
        if annotations is None:
369 t00mlabs 759
            annotations = self.get_bag()
760
            if annotations is None:
761
                annotations = self.srvant.get_all()
762
            else:
763
                self.log.debug("Displaying last query")
340 t00mlabs 764
        else:
369 t00mlabs 765
            self.log.debug("Displaying following annotations: %s", annotations)
400 t00mlabs 766
            self.__set_bag(annotations)
340 t00mlabs 767
 
768
        dcats = {}
769
        snpids = {}
770
        nodes = []
393 t00mlabs 771
        bag = set()
772
 
340 t00mlabs 773
        for fname in annotations:
774
            try:
775
                with open(fname, 'r') as fa:
776
                    try:
395 t00mlabs 777
                        try:
778
                            annotation = json.load(fa)
779
                        except Exception as error:
780
                            self.log.error("Annotation: %s", fname)
781
                            self.log.error(error)
394 t00mlabs 782
                        # Get Scope
393 t00mlabs 783
                        try:
784
                            scope = annotation['Scope']
785
                        except:
786
                            scope = ''
394 t00mlabs 787
 
788
                        # Get Product
789
                        try:
790
                            product = annotation['Product']
791
                        except:
792
                            product = ''
793
 
369 t00mlabs 794
                        # ~ self.log.debug("Annotation: %s", annotation['Title'])
340 t00mlabs 795
                        category = annotation['Category']
796
                        atype = annotation['Type']
797
                        cat_key = 'ANNOTATIONS_CATEGORY_%s_VISIBLE' % category.upper()
798
                        type_key = 'ANNOTATIONS_TYPE_%s_VISIBLE' % atype.upper()
799
                        category_active = self.srvgui.get_key_value(cat_key)
800
                        try:
801
                            type_active = self.srvgui.get_key_value(type_key)
802
                        except Exception as error:
803
                            self.log.error(error)
804
                            type_active = True
805
                        if category_active:
806
                            if type_active:
807
                                ppid = None
808
                                sid = self.srvant.get_sid(annotation['AID'])
809
                                try:
810
                                    icon = self.icons['type']['%s' % atype.lower()]
811
                                except:
812
                                    icon = None
813
                                if sid != '0000000000':
814
                                    title = "<b>[SAP Note %d]</b> %s" % (int(sid), annotation['Title'])
815
                                else:
816
                                    title = annotation['Title']
817
 
818
                                try:
819
                                    annotation['Priority']
820
                                except:
821
                                    annotation['Priority'] = 'Normal'
822
 
400 t00mlabs 823
                                node = self.__get_node(   annotation['AID'],
340 t00mlabs 824
                                                        icon,
825
                                                        False,
826
                                                        str(int(sid)),
827
                                                        title,
828
                                                        annotation['Component'],
403 t00mlabs 829
                                                        annotation['Type'],
393 t00mlabs 830
                                                        scope,
394 t00mlabs 831
                                                        product,
340 t00mlabs 832
                                                        annotation['Priority'],
833
                                                        self.srvutl.fuzzy_date_from_timestamp(annotation['Timestamp']),
351 t00mlabs 834
                                                        annotation['Timestamp'],
835
                                                        self.srvutl.fuzzy_date_from_timestamp(annotation['Created']),
836
                                                        annotation['Created']
340 t00mlabs 837
                                                    )
838
                                nodes.append(node)
839
                    except Exception as error:
840
                        self.log.error(error)
351 t00mlabs 841
                        self.log.error(self.get_traceback())
340 t00mlabs 842
            except Exception as error:
843
                # Whenever an annotation is deleted, after reloading
844
                # the view, it fails. Then, skip it
399 t00mlabs 845
                pass
340 t00mlabs 846
 
847
        for node in nodes:
399 t00mlabs 848
            model.append(None, node)
340 t00mlabs 849
 
399 t00mlabs 850
        treeview.set_model(sorted_model)
400 t00mlabs 851
        self.__sort_by_timestamp()
852
        self.__update_panel_values()
340 t00mlabs 853
        self.update_total_annotations_count()
854
 
369 t00mlabs 855
 
400 t00mlabs 856
    def __clb_preview(self, button, aid):
380 t00mlabs 857
        self.srvclb.action_annotation_preview(aid)
858
 
859
 
400 t00mlabs 860
    def __clb_edit(self, button, aid):
380 t00mlabs 861
        self.srvclb.action_annotation_edit(aid)
862
 
863
 
400 t00mlabs 864
    def __clb_row_double_click(self, treeview, row, col):
361 t00mlabs 865
        try:
866
            selection = treeview.get_selection()
867
            model, treeiter = selection.get_selected()
868
            if treeiter is not None:
402 t00mlabs 869
                component = model[treeiter][COLUMN.COMPONENT]
361 t00mlabs 870
                if component == 'Annotation':
402 t00mlabs 871
                    aid = model[treeiter][COLUMN.AID]
361 t00mlabs 872
                    is_valid = self.srvant.is_valid(aid)
873
                    if is_valid:
380 t00mlabs 874
                        self.srvclb.action_annotation_preview(aid)
361 t00mlabs 875
        except Exception as error:
389 t00mlabs 876
            self.log.error(error)
361 t00mlabs 877
 
399 t00mlabs 878
 
400 t00mlabs 879
    def __clb_row_right_click(self, treeview, event, data=None):
399 t00mlabs 880
        treeview = self.srvgui.get_widget('visor_annotation_treeview')
340 t00mlabs 881
        if event.button == 3:
882
            rect = Gdk.Rectangle()
883
            rect.x = x = int(event.x)
884
            rect.y = y = int(event.y)
399 t00mlabs 885
            pthinfo = treeview.get_path_at_pos(x,y)
340 t00mlabs 886
            if pthinfo is not None:
887
                path,col,cellx,celly = pthinfo
888
                model = treeview.get_model()
889
                treeiter = model.get_iter(path)
402 t00mlabs 890
                component = model[treeiter][COLUMN.COMPONENT]
891
                aid = model[treeiter][COLUMN.AID]
340 t00mlabs 892
                popover = self.srvgui.add_widget('gtk_popover_visor_row', Gtk.Popover.new(treeview))
893
                popover.set_pointing_to(rect)
400 t00mlabs 894
                box = self.__build_popover(aid, popover, component)
340 t00mlabs 895
                if box is not None:
361 t00mlabs 896
                    visor_annotations = self.srvgui.get_widget('visor_annotations')
897
                    width, height = visor_annotations.get_size_request()
340 t00mlabs 898
                    popover.add(box)
899
                    self.srvclb.gui_show_popover(None, popover)
900
 
901
 
377 t00mlabs 902
 
400 t00mlabs 903
    def __build_popover(self, aid, popover, component):
340 t00mlabs 904
        sid = self.srvant.get_sid(aid)
905
 
906
        def get_popover_button(text, icon_name):
907
            button = Gtk.Button()
908
            button.set_relief(Gtk.ReliefStyle.NONE)
909
            hbox = Gtk.HBox()
910
            icon = self.srvicm.get_new_image_icon(icon_name, 24, 24)
911
            hbox.pack_start(icon, False, False, 3)
380 t00mlabs 912
            if len(text) > 0:
913
                lbltext = Gtk.Label()
914
                lbltext.set_xalign(0.0)
915
                lbltext.set_markup('%s' % text)
916
                hbox.pack_start(lbltext, True, True, 3)
340 t00mlabs 917
            button.add(hbox)
918
            return button
919
 
920
        if component == 'Annotation':
921
            box = Gtk.Box(spacing = 3, orientation="vertical")
922
 
380 t00mlabs 923
            hbox_sel = Gtk.HBox()
924
            button = get_popover_button("", 'basico-check-all')
925
            button.set_tooltip_markup("Select all")
400 t00mlabs 926
            button.connect('clicked', self.__clb_select_all, True)
380 t00mlabs 927
            hbox_sel.pack_start(button, True, False, 0)
340 t00mlabs 928
 
380 t00mlabs 929
            button = get_popover_button("", 'basico-check-none')
930
            button.set_tooltip_markup("Select none")
400 t00mlabs 931
            button.connect('clicked', self.__clb_select_all, False)
380 t00mlabs 932
            hbox_sel.pack_start(button, True, False, 0)
377 t00mlabs 933
 
380 t00mlabs 934
            button = get_popover_button("", 'basico-check-invert')
935
            button.set_tooltip_markup("Invert selection")
400 t00mlabs 936
            button.connect('clicked', self.__clb_select_all, None)
380 t00mlabs 937
            hbox_sel.pack_start(button, True, False, 0)
378 t00mlabs 938
 
380 t00mlabs 939
            box.pack_start(hbox_sel, False, False, 0)
940
            box.show_all()
941
 
377 t00mlabs 942
            if len(self.rows_toggled()) > 0:
378 t00mlabs 943
                separator = Gtk.Separator(orientation = Gtk.Orientation.HORIZONTAL)
944
                box.pack_start(separator, False, False, 0)
945
 
377 t00mlabs 946
                button = get_popover_button("<b>Delete</b> annotations", 'basico-delete')
947
                button.show_all()
948
                button.connect('clicked', self.srvclb.action_annotation_delete)
949
                box.pack_start(button, False, False, 0)
950
 
378 t00mlabs 951
                button = get_popover_button("<b>Backup</b> annotations", 'basico-backup')
952
                button.show_all()
953
                # ~ button.connect('clicked', self.srvclb.action_annotation_backup)
954
                box.pack_start(button, False, False, 0)
955
 
379 t00mlabs 956
            else:
957
                separator = Gtk.Separator(orientation = Gtk.Orientation.HORIZONTAL)
958
                box.pack_start(separator, False, False, 0)
959
 
960
                # Popover button "Jump to SAP Note"
961
                if sid != '0000000000':
962
                    # Jump to SAP Note
380 t00mlabs 963
                    button = get_popover_button("<b>Jump</b> to SAP Note %d" % int(sid), 'basico-jump-sapnote')
379 t00mlabs 964
                    button.show_all()
965
                    button.connect('clicked', self.srvclb.gui_jump_to_sapnote, sid)
966
                    box.pack_start(button, False, False, 0)
967
 
380 t00mlabs 968
                button = get_popover_button("<b>Preview</b> annotation", 'basico-preview')
340 t00mlabs 969
                button.show_all()
400 t00mlabs 970
                button.connect('clicked', self.__clb_preview, aid)
340 t00mlabs 971
                box.pack_start(button, False, False, 0)
379 t00mlabs 972
 
380 t00mlabs 973
                button = get_popover_button("<b>Edit</b> annotation", 'basico-edit')
379 t00mlabs 974
                button.show_all()
400 t00mlabs 975
                button.connect('clicked', self.__clb_edit, aid)
379 t00mlabs 976
                box.pack_start(button, False, False, 0)
977
 
380 t00mlabs 978
                button = get_popover_button("<b>Duplicate</b> annotation", 'basico-copy-paste')
379 t00mlabs 979
                button.show_all()
980
                # ~ button.connect('clicked', self.srvclb.duplicate_sapnote, aid)
981
                box.pack_start(button, False, False, 0)
982
 
340 t00mlabs 983
            return box
984
 
985
 
400 t00mlabs 986
    def __clb_select_all(self, button, checked):
399 t00mlabs 987
        sorted_model = self.srvgui.get_widget('visor_annotation_sorted_model')
377 t00mlabs 988
        def check_row(model, path, itr):
378 t00mlabs 989
            if checked is not None:
402 t00mlabs 990
                model[path][COLUMN.CHECKBOX] = checked
378 t00mlabs 991
            else:
402 t00mlabs 992
                state = model[path][COLUMN.CHECKBOX]
993
                model[path][COLUMN.CHECKBOX] = not state
377 t00mlabs 994
 
399 t00mlabs 995
        model = sorted_model.get_model()
377 t00mlabs 996
        model.foreach(check_row)
405 t00mlabs 997
        self.update_total_annotations_count()
379 t00mlabs 998
        self.srvuif.grab_focus()
377 t00mlabs 999
 
1000
 
400 t00mlabs 1001
    def set_menuview_signals(self):
340 t00mlabs 1002
        # Categories
1003
        button = self.srvgui.get_widget('gtk_togglebutton_categories')
400 t00mlabs 1004
        button.connect('toggled', self.__clb_set_visible_categories)
340 t00mlabs 1005
 
1006
        for name in ['inbox', 'drafts', 'archived']:
1007
            button = self.srvgui.get_widget('gtk_button_category_%s' % name)
400 t00mlabs 1008
            button.connect('toggled', self.__clb_set_visible_category, name)
340 t00mlabs 1009
 
1010
        # Types
1011
        button = self.srvgui.get_widget('gtk_togglebutton_types')
400 t00mlabs 1012
        button.connect('toggled', self.__clb_set_visible_types)
340 t00mlabs 1013
 
1014
        for name in ATYPES:
1015
            button = self.srvgui.get_widget('gtk_button_type_%s' % name.lower())
400 t00mlabs 1016
            button.connect('toggled', self.__clb_set_visible_annotation_type, name)
340 t00mlabs 1017
 
1018
 
1019
    def set_active_categories(self):
1020
        category = self.srvgui.get_widget('gtk_togglebutton_inbox')
1021
        category.set_active(True)
1022
 
393 t00mlabs 1023
 
400 t00mlabs 1024
    def __update_panel_values(self):
1025
        self.__update_scopes()
1026
        self.__update_products()
394 t00mlabs 1027
 
400 t00mlabs 1028
    def __update_scopes(self):
399 t00mlabs 1029
        sorted_model = self.srvgui.get_widget('visor_annotation_sorted_model')
393 t00mlabs 1030
        scopes = set()
394 t00mlabs 1031
 
393 t00mlabs 1032
        def get_values(model, path, itr):
402 t00mlabs 1033
            scope = sorted_model.get(itr, COLUMN.SCOPE)[0]
393 t00mlabs 1034
            scopes.add(scope)
399 t00mlabs 1035
        sorted_model.foreach(get_values)
393 t00mlabs 1036
 
394 t00mlabs 1037
        # Update scope combo
393 t00mlabs 1038
        cmb_scope = self.srvgui.get_widget('gtk_combobox_filter_scope')
1039
        signal = self.srvgui.get_signal('gtk_combobox_filter_scope', 'changed')
1040
        GObject.signal_handler_block(cmb_scope, signal)
1041
        model = cmb_scope.get_model()
1042
        model.clear()
394 t00mlabs 1043
        first = model.append(['<big><b>Scope</b></big>'])
1044
        model.append(['All'])
1045
        model.append(['None'])
1046
        cmb_scope.set_active_iter(first)
393 t00mlabs 1047
        lscopes = list(scopes)
1048
        lscopes.sort()
1049
        for item in lscopes:
1050
            if len(item) > 0:
1051
                model.append([item])
1052
        GObject.signal_handler_unblock(cmb_scope, signal)
1053
 
1054
 
400 t00mlabs 1055
    def __update_products(self):
399 t00mlabs 1056
        sorted_model = self.srvgui.get_widget('visor_annotation_sorted_model')
394 t00mlabs 1057
        products = set()
1058
 
1059
        def get_values(model, path, itr):
402 t00mlabs 1060
            product = sorted_model.get(itr, COLUMN.PRODUCT)[0]
394 t00mlabs 1061
            products.add(product)
399 t00mlabs 1062
        sorted_model.foreach(get_values)
394 t00mlabs 1063
 
1064
        # Update product combo
1065
        cmb_product = self.srvgui.get_widget('gtk_combobox_filter_product')
1066
        signal = self.srvgui.get_signal('gtk_combobox_filter_product', 'changed')
1067
        GObject.signal_handler_block(cmb_product, signal)
1068
        model = cmb_product.get_model()
1069
        model.clear()
1070
        first = model.append(['<big><b>Product</b></big>'])
1071
        model.append(['All'])
1072
        model.append(['None'])
1073
        cmb_product.set_active_iter(first)
1074
        lproducts = list(products)
1075
        lproducts.sort()
1076
        for item in lproducts:
1077
            if len(item) > 0:
1078
                model.append([item])
1079
        GObject.signal_handler_unblock(cmb_product, signal)
1080
 
1081
 
400 t00mlabs 1082
    def __clb_scope_changed(self, *args):
1083
        visible_filter = self.srvgui.get_widget('visor_annotation_visible_filter')
393 t00mlabs 1084
        visible_filter.refilter()
1085
        self.update_total_annotations_count()
394 t00mlabs 1086
        self.update_products()
1087
 
1088
 
400 t00mlabs 1089
    def __clb_product_changed(self, *args):
1090
        visible_filter = self.srvgui.get_widget('visor_annotation_visible_filter')
394 t00mlabs 1091
        visible_filter.refilter()
1092
        self.update_total_annotations_count()
1093
        self.update_scopes()
1094
 
1095
 
400 t00mlabs 1096
    def __clb_switch_selection_atypes(self, switch, state):
1097
        label = self.srvgui.get_widget('gtk_label_switch_select_atypes')
1098
        switched = switch.get_active()
1099
        switch.set_state(switched)
1100
        if switched is True:
1101
            label.set_text ("All selected")
1102
 
1103
        else:
1104
            label.set_text("None selected")
1105
 
1106
        for name in ATYPES:
1107
            button = self.srvgui.get_widget('gtk_button_type_%s' % name.lower())
1108
            button.set_state(switched)
1109
            button.set_active(switched)