Subversion Repositories basico

Rev

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