Subversion Repositories basico

Rev

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