Subversion Repositories basico

Rev

Rev 400 | 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_menuview.py
5
# Author: Tomás Vírseda
6
# License: GPL v3
7
# Description: MenuView Widget
8
"""
9
 
10
from enum import IntEnum
11
from html import escape
12
from collections import OrderedDict
13
import gi
14
gi.require_version('Gdk', '3.0')
15
gi.require_version('Gtk', '3.0')
16
from gi.repository import Gdk
17
from gi.repository import Gtk
18
from gi.repository import Pango
19
from gi.repository import GObject
20
from gi.repository.GdkPixbuf import Pixbuf
21
from dateutil import parser as dateparser
22
from basico.widgets.wdg_cols import CollectionsMgtView
23
from basico.core.mod_wdg import BasicoWidget
363 t00mlabs 24
from basico.services.srv_collections import COL_DOWNLOADED
340 t00mlabs 25
 
26
class Row(IntEnum):
27
    ROWID = 0
28
    ROWNAME = 1
29
    ROWCOUNT = 2
30
 
31
 
32
class MenuView(BasicoWidget, Gtk.TreeView):
33
    view = 'component'
34
    current_status = None
35
    current_collection = None
36
 
37
    def __init__(self, app):
38
        super().__init__(app, __class__.__name__)
39
        Gtk.TreeView.__init__(self)
40
        self.row_type = None
41
        self.get_services()
42
        self.toggled = 0
43
        self.selected = set()
44
        self.count = 0
45
        self.completion = self.srvgui.add_widget('gtk_entrycompletion_viewmenu', Gtk.EntryCompletion())
46
        self.completion.set_match_func(self.completion_match_func)
47
        self.completion_model = Gtk.ListStore(str)
48
        self.completion.set_model(self.completion_model)
49
        self.completion.set_text_column(0)
50
 
51
        # Setup treeview and model
52
        Gtk.TreeView.__init__(self)
53
        self.model = Gtk.TreeStore(
54
            str,            # RowType@RowId
55
            str,            # RowName
56
            str,            # RowCount
57
        )
58
        self.set_model(self.model)
59
 
60
        # Setup columns
61
        # Row Id
62
        self.renderer_rowid = Gtk.CellRendererText()
63
        self.column_rowid = Gtk.TreeViewColumn('', self.renderer_rowid, text=Row.ROWID.value)
64
        self.column_rowid.set_visible(False)
65
        self.column_rowid.set_expand(False)
66
        self.column_rowid.set_clickable(False)
67
        self.column_rowid.set_sort_indicator(False)
68
        self.append_column(self.column_rowid)
69
 
70
        # Row Name
71
        self.renderer_rowname = Gtk.CellRendererText()
72
        self.column_rowname = Gtk.TreeViewColumn('', self.renderer_rowname, markup=Row.ROWNAME.value)
73
        self.column_rowname.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE)
74
        self.column_rowname.set_visible(True)
75
        self.column_rowname.set_expand(True)
76
        self.column_rowname.set_clickable(True)
77
        self.column_rowname.set_sort_indicator(True)
78
        self.column_rowname.set_sort_column_id(1)
79
        self.column_rowname.set_sort_order(Gtk.SortType.ASCENDING)
80
        self.append_column(self.column_rowname)
81
 
82
        # Row Count
83
        self.renderer_rowcount = Gtk.CellRendererText()
84
        self.renderer_rowcount.set_property('xalign', 0.5)
85
        self.renderer_rowcount.set_property('background', '#F0E3E3')
86
        self.column_rowcount = Gtk.TreeViewColumn('', self.renderer_rowcount, markup=Row.ROWCOUNT.value)
87
        self.column_rowcount.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE)
88
        self.column_rowcount.set_visible(True)
89
        self.column_rowcount.set_expand(False)
90
        self.column_rowcount.set_clickable(False)
91
        self.column_rowcount.set_sort_indicator(False)
92
        self.column_rowcount.set_sort_column_id(2)
93
        self.column_rowcount.set_sort_order(Gtk.SortType.ASCENDING)
94
        self.append_column(self.column_rowcount)
95
 
96
        # TreeView common
97
        #~ self.set_level_indentation(6)
98
        self.set_can_focus(True)
99
        self.set_headers_visible(False)
100
        self.set_enable_search(True)
101
        self.set_hover_selection(False)
102
        self.set_grid_lines(Gtk.TreeViewGridLines.NONE)
405 t00mlabs 103
        # ~ self.set_search_entry(self.srvgui.get_widget('stySearchInfo'))
340 t00mlabs 104
        self.set_search_column(1)
105
        #~ self.set_row_separator_func(self.row_separator_func)
106
 
107
        # Selection
108
        self.selection = self.get_selection()
109
        self.selection.set_mode(Gtk.SelectionMode.SINGLE)
110
 
111
        font_desc = Pango.FontDescription('Monospace 10')
112
        if font_desc:
113
            self.modify_font(font_desc)
114
 
115
        self.prepare()
116
        self.show_all()
117
 
118
 
119
    def get_services(self):
120
        self.srvgui = self.get_service("GUI")
121
        self.srvclb = self.get_service('Callbacks')
122
        self.srvsap = self.get_service('SAP')
123
        self.srvicm = self.get_service('IM')
124
        self.srvstg = self.get_service('Settings')
125
        self.srvdtb = self.get_service('DB')
126
        self.srvant = self.get_service('Annotation')
127
        self.srvuif = self.get_service('UIF')
128
        self.srvclt = self.get_service('Collections')
129
        self.srvutl = self.get_service('Utils')
130
 
131
 
132
    def get_node(self, rowid, rowname, rowcount='0'):
133
        completion = self.srvgui.get_widget('gtk_entrycompletion_viewmenu')
134
        completion_model = completion.get_model()
135
        title = self.srvutl.clean_html(rowname)
136
        completion_model.append([title])
137
        node = []
138
        node.append(rowid)
139
        node.append(rowname)
140
        node.append("%5s" % rowcount)
141
 
142
        return node
143
 
144
 
145
    def get_node_date_year(self, date, token_date, count='0'):
146
        title = "%s" % token_date
147
        return self.get_node('date-year@%s' % token_date, title, count)
148
 
149
 
150
    def get_node_date_month(self, date, token_date, count='0'):
151
        title = "%s" % date.strftime("%B")
152
        return self.get_node('date-month@%s' % token_date, title, count)
153
 
154
 
155
    def get_node_date_day(self, date, token_date, count='0'):
156
        title = "%s" % date.strftime("%d - %A")
157
        return self.get_node('date-day@%s' % token_date, title, count)
158
 
159
 
160
    def get_node_priority(self, priority, count='0'):
161
        if len(priority) == 0:
162
            title = "No priority assigned"
163
        else:
164
            title = "%s" % priority
165
 
166
        return self.get_node('priority@%s' % priority, title, count)
167
 
168
 
169
    def get_node_collection(self, collection_id, collection_name, count='0'):
170
        return self.get_node('collection@%s' % collection_id, collection_name, count)
171
 
172
 
173
    def get_node_type(self, sntype, count='0'):
174
        if len(sntype) == 0:
175
            title = "SAP Note type not found"
176
        else:
177
            title = "%s" % sntype
178
        return self.get_node('type@%s' % sntype, title, count)
179
 
180
 
181
    def get_row_id(self):
182
        return self.cid
183
 
184
 
185
    def get_row_type(self):
186
        return self.row_type
187
 
188
 
189
    def get_node_category(self, category='', count='0'):
190
        if len(category) == 0:
191
            catname = "No category assigned"
192
        else:
193
            catname = "%s" % category
194
        return self.get_node('category@%s' % catname, catname, count)
195
 
196
 
197
    def get_node_component(self, compkey, comptxt, count='0'):
198
        return self.get_node('componentkey@%s' % compkey, compkey, count)
199
 
200
 
201
    def get_node_component_desc(self, compkey, comptxt, count='0'):
202
        icon = self.srvicm.get_icon('basico-description', 32, 32)
203
        node = []
204
        count = len(self.srvdtb.get_notes_by_node("componentkey", compkey))
205
        if len(comptxt) == 0:
206
            component = "%s" % (compkey)
207
        else:
208
            component = "%s" % (comptxt)
209
        return self.get_node('componentkey@%s' % compkey, component, count)
210
 
211
 
212
    def completion_match_func(self, completion, key, treeiter):
213
        model = completion.get_model()
214
        text = model.get_value(treeiter, 0)
215
        if key.upper() in text.upper():
216
            return True
217
        return False
218
 
219
 
220
    def prepare(self):
221
        self.column_rowid.set_visible(False)
222
        self.column_rowname.set_visible(True)
223
        self.column_rowcount.set_visible(True)
224
 
225
        # TreeView common
226
        self.set_can_focus(True)
227
        self.set_headers_visible(False)
228
        self.set_enable_search(True)
229
        self.set_hover_selection(False)
230
        self.set_grid_lines(Gtk.TreeViewGridLines.NONE)
231
        self.set_level_indentation(0)
232
        signal = self.selection.connect('changed', self.row_changed)
233
        self.srvgui.set_key_value('menuview-selection', self.selection)
234
        self.srvgui.set_key_value('menuview-row-changed', signal)
235
        self.connect('button_press_event', self.right_click)
236
 
237
 
238
    def refresh(self):
362 t00mlabs 239
        visor_sapnotes = self.srvgui.get_widget('visor_sapnotes')
340 t00mlabs 240
        try:
241
            if self.row_type is not None:
242
                matches = self.srvdtb.get_notes_by_node(self.row_type, self.cid)
362 t00mlabs 243
                visor_sapnotes.populate(matches)
340 t00mlabs 244
        except Exception as error:
245
            pass
246
 
247
 
248
    def row_changed(self, selection):
249
        if self.current_status is None:
362 t00mlabs 250
            visor_sapnotes = self.srvgui.get_widget('visor_sapnotes')
400 t00mlabs 251
            # ~ self.log.warning("gui_show_visor_sapnotes!!!")
340 t00mlabs 252
 
253
            try:
254
                model, treeiter = selection.get_selected()
255
                row = model[treeiter][0]
256
                row_title = self.srvutl.clean_html(model[treeiter][1])
257
                self.row_type, self.cid = row.split('@')
258
                iter_has_child = model.iter_has_child(treeiter)
259
                if self.row_type == 'collection':
260
                    colname = self.srvclt.get_name_by_cid(self.cid)
261
                    self.set_current_collection(self.cid)
262
                    if not iter_has_child:
263
                        matches = self.srvdtb.get_notes_by_node(self.row_type, self.cid)
362 t00mlabs 264
                        visor_sapnotes.populate(matches, self.cid)
340 t00mlabs 265
                    else:
266
                        matches = set()
267
                        cols = self.srvclt.get_collections_by_row_title(row_title)
268
                        for col in cols:
269
                            for sid in self.srvdtb.get_notes_by_node(self.row_type, col):
270
                                matches.add(sid)
362 t00mlabs 271
                        visor_sapnotes.populate(list(matches))
340 t00mlabs 272
                else:
273
                    self.set_current_collection(None)
274
                    matches = self.srvdtb.get_notes_by_node(self.row_type, self.cid)
362 t00mlabs 275
                    visor_sapnotes.populate(matches, self.cid)
400 t00mlabs 276
                # ~ self.srvuif.statusbar_msg("View populated with %d SAP Notes" % (len(matches)))
340 t00mlabs 277
            except Exception as error:
278
                pass
279
 
280
 
281
    def set_current_collection(self, cid=None):
282
        self.current_collection = cid
283
 
284
 
285
    def get_current_collection(self):
286
        return self.current_collection
287
 
288
 
289
    def show_popover_manage_collections(self, *args):
290
        button = self.srvgui.get_widget('gtk_button_popover_manage_collections')
291
        popcollections = self.srvgui.add_widget('gtk_popover_button_manage_collections_single_note', Gtk.Popover.new(button))
292
        popcollections.set_position(Gtk.PositionType.RIGHT)
293
        popcollections.add(CollectionsMgtView(self.app, '0000000000'))
294
        self.srvclb.gui_show_popover(None, popcollections)
295
 
296
 
297
    def show_popover_export_collections(self, *args):
298
        popexport = self.srvgui.get_widget('gtk_popover_menuview_export')
299
        self.srvclb.gui_show_popover(None, popexport)
300
 
301
 
302
    def build_popover_export(self, colname):
303
        box = Gtk.Box(spacing = 3, orientation="vertical")
304
        sid = '0000000000'
305
 
306
        def get_popover_button(text, icon_name):
307
            button = Gtk.Button()
308
            button.set_relief(Gtk.ReliefStyle.NONE)
309
            hbox = Gtk.HBox()
310
            icon = self.srvicm.get_new_image_icon(icon_name, 24, 24)
311
            lbltext = Gtk.Label()
312
            lbltext.set_xalign(0.0)
313
            lbltext.set_markup('%s' % text)
314
            hbox.pack_start(icon, False, False, 3)
315
            hbox.pack_start(lbltext, True, True, 3)
316
            button.add(hbox)
317
            return button
318
 
319
        # Popover button "export to CSV"
320
        button = get_popover_button("Export to <b>csv</b>", 'basico-backup-text-csv')
321
        self.srvgui.add_widget("gtk_button_popover_manage_collections", button)
322
        button.connect('clicked', self.srvclb.action_collection_export_text_csv)
323
        box.pack_start(button, False, False, 0)
324
 
325
        # Popover button "export to Excel"
326
        button = get_popover_button("Export to <b>Excel</b>", 'basico-backup-ms-excel')
327
        self.srvgui.add_widget("gtk_button_popover_manage_collections", button)
328
        button.connect('clicked', self.srvclb.action_collection_export_excel)
329
        box.pack_start(button, False, False, 0)
330
 
331
        # Popover button "export to Basico format"
332
        button = get_popover_button("Export to <b>Basico format</b>", 'basico-component')
333
        self.srvgui.add_widget("gtk_button_popover_manage_collections", button)
334
        button.connect('clicked', self.srvclb.action_collection_export_basico)
335
        box.pack_start(button, False, False, 0)
336
 
337
        return box
338
 
339
 
340
    def build_popover(self, colid, colname):
341
        box = Gtk.Box(spacing = 3, orientation="vertical")
342
        sid = '0000000000'
343
 
344
        visor_sapnotes = self.srvgui.get_widget('visor_sapnotes')
345
        count = len(visor_sapnotes.get_filtered_bag())
346
        if count == 0:
347
            count = len(visor_sapnotes.get_filtered_bag())
348
 
349
        def get_popover_button(text, icon_name):
350
            button = Gtk.Button()
351
            button.set_relief(Gtk.ReliefStyle.NONE)
352
            hbox = Gtk.HBox()
353
            icon = self.srvicm.get_new_image_icon(icon_name, 24, 24)
354
            lbltext = Gtk.Label()
355
            lbltext.set_xalign(0.0)
356
            lbltext.set_markup('%s' % text)
357
            hbox.pack_start(icon, False, False, 3)
358
            hbox.pack_start(lbltext, True, True, 3)
359
            button.add(hbox)
360
            return button
361
 
362
        # Popover button Manage collections
363
        button = get_popover_button("<b>Manage collections</b>", 'basico-category')
364
        self.srvgui.add_widget("gtk_button_popover_manage_collections", button)
365
        button.connect('clicked', self.show_popover_manage_collections)
366
        box.pack_start(button, False, False, 0)
367
 
368
        # Separator
369
        separator = Gtk.Separator(orientation = Gtk.Orientation.HORIZONTAL)
370
        box.pack_start(separator, True, True, 0)
371
 
372
        # Popover button copy to clipboard
373
        button = get_popover_button("<b>Copy to clipboard</b> %d SAP Notes" % count, 'basico-clipboard')
374
        button.connect('clicked', self.srvclb.action_collection_copy_to_clipboard)
375
        box.pack_start(button, False, False, 0)
376
 
377
        # Popover button "Export collection"
378
        button = get_popover_button("<b>Export</b> %d SAP Notes" % count, 'basico-backup')
379
        self.srvgui.add_widget("gtk_button_popover_export_collections", button)
380
        button.connect('clicked', self.show_popover_export_collections)
381
        box.pack_start(button, False, False, 0)
382
 
383
        popover = self.srvgui.add_widget('gtk_popover_menuview_export', Gtk.Popover.new(button))
384
        popover.set_position(Gtk.PositionType.RIGHT)
385
        popover.add(self.build_popover_export(colname))
386
 
387
        # Popover button "Link SAP Notes  in view to collection(s)"
388
        button = get_popover_button("<b>Link to collection(s)</b> %d SAP Notes" % count, 'basico-collection')
389
        box.pack_start(button, False, False, 0)
390
        self.popviewtocat = self.srvgui.add_widget('gtk_popover_button_assign_view_to_category', Gtk.Popover.new(button))
391
        self.popviewtocat.set_position(Gtk.PositionType.RIGHT)
392
        button.connect('clicked', self.srvclb.gui_show_popover, self.popviewtocat)
393
        colmgt = CollectionsMgtView(self.app, 'view', overwrite=False)
394
        self.popviewtocat.add(colmgt)
395
 
396
        # Popover button "Bookmark all SAP Notes in this view"
397
        button = get_popover_button("<b>(Un)Bookmark</b> %d SAP Notes in this view" % count, 'basico-bookmarks')
398
        button.connect('clicked', self.srvclb.switch_bookmark_current_view)
399
        box.pack_start(button, False, False, 0)
400
 
401
        # Popover button "Delete all SAP Notes in this view"
402
        button = get_popover_button("<b>Delete</b> %d SAP Notes in this view" % count, 'basico-delete')
403
        button.connect('clicked', self.srvclb.sapnote_delete_view)
404
        box.pack_start(button, False, False, 0)
405
 
406
        return box
407
 
408
 
409
    def right_click(self, treeview, event, data=None):
410
        selection = treeview.get_selection()
411
        if event.button == 3:
412
            rect = Gdk.Rectangle()
413
            rect.x = x = int(event.x)
414
            rect.y = y = int(event.y)
415
            pthinfo = treeview.get_path_at_pos(x, y)
416
            if pthinfo is not None:
417
                path, col, cellx, celly = pthinfo
418
                selection.select_path(path) # -> Force select current path
419
                model = treeview.get_model()
420
                treeiter = model.get_iter(path)
421
                rid = model[treeiter][0]
422
                coltitle = model[treeiter][1]
423
                colid = model[treeiter][0]
424
                rtype = rid[:rid.find('@')]
425
                try:
426
                    colid = rid[rid.find('@')+1:]
427
                except:
428
                    colid = None
429
                popover = self.srvgui.add_widget('gtk_popover_menuview', Gtk.Popover.new(treeview))
430
                popover.set_position(Gtk.PositionType.RIGHT)
431
                popover.set_pointing_to(rect)
432
                popover.add(self.build_popover(colid, coltitle))
433
                self.srvclb.gui_show_popover(None, popover)
434
 
435
 
436
    def set_view(self, view=None):
437
        # FIXME: Get last view visited from config
438
        if view is None:
439
            view = 'chronologic'
440
 
441
        iconview = self.srvgui.get_widget('gtk_image_current_view')
442
        icon = self.srvicm.get_pixbuf_icon('basico-%s' % view, 24, 24)
443
        iconview.set_from_pixbuf(icon)
444
        iconview.show_all()
445
        self.view = view
446
 
447
        # Change label
448
        viewlabel = self.srvgui.get_widget('gtk_label_current_view')
449
        name = "<b>%s</b>" % view.capitalize()
450
        viewlabel.set_markup(name)
451
        viewlabel.set_xalign(0.0)
452
        viewlabel.set_justify(Gtk.Justification.LEFT)
453
        viewlabel.show_all()
454
        self.populate([])
455
        self.srvuif.statusbar_msg("Switching to <i>%s</i> view" % name)
456
 
457
 
458
    def get_view(self):
459
        return self.view
460
 
461
 
462
    def populate(self, sapnotes=[]):
463
        self.current_status = "working"
464
        self.set_headers_visible(False) # Set
465
        completion = self.srvgui.get_widget('gtk_entrycompletion_viewmenu')
466
        completion_model = completion.get_model()
467
        completion_model.clear()
468
 
469
        if len(sapnotes) == 0:
470
            sapnotes = self.srvdtb.get_notes()
471
 
472
        if self.view == 'component':
473
            self.populate_by_components(sapnotes)
474
        elif self.view == 'description':
475
            self.populate_by_component_descriptions(sapnotes)
476
        elif self.view == 'bookmarks':
477
            self.populate_by_bookmarks()
478
        elif self.view == 'projects':
479
            self.populate_by_projects(sapnotes)
480
        elif self.view == 'collections':
481
            self.populate_by_collections(sapnotes)
482
        elif self.view == 'tags':
483
            self.populate_by_tags(sapnotes)
484
        elif self.view == 'category':
485
            self.populate_by_category(sapnotes)
486
        elif self.view == 'chronologic':
487
            self.populate_by_chronologic(sapnotes)
488
        elif self.view == 'priority':
489
            self.populate_by_priority(sapnotes)
490
        elif self.view == 'type':
491
            self.populate_by_type(sapnotes)
492
        elif self.view == 'collection':
493
            self.populate_by_collection(sapnotes)
494
        elif self.view == 'annotation':
362 t00mlabs 495
            self.populate()
340 t00mlabs 496
        else:
497
            self.populate_by_components(sapnotes)
498
 
499
        viewfilter = self.srvgui.get_widget('gtk_entry_filter_view')
500
        completion = self.srvgui.get_widget('gtk_entrycompletion_viewmenu')
501
        completion.set_model(completion_model)
502
        viewfilter.set_completion(completion)
503
        self.srvclb.gui_show_dashboard()
504
        self.current_status = None
505
 
506
 
507
    def populate_by_bookmarks(self):
508
        matches = []
509
        sapnotes = self.srvdtb.get_notes()
510
        for sid in sapnotes:
511
            if sapnotes[sid]['bookmark']:
512
                matches.append(sid)
513
        matches.sort()
514
 
362 t00mlabs 515
        visor_sapnotes = self.srvgui.get_widget('visor_sapnotes')
516
        visor_sapnotes.populate(matches)
340 t00mlabs 517
        self.srvuif.statusbar_msg("View <i>%s</i> populated with %d SAP Notes" % (self.row_type, len(matches)))
518
 
519
 
520
    def populate_by_components(self, sapnotes, only_bookmarks=False):
521
        self.model.clear()
522
        self.treepids = {}
523
 
524
        if len(sapnotes) == 0:
525
            return
526
 
527
        scomp = set()
528
        dcomp = {}
529
 
530
        for sid in sapnotes:
531
            compkey = escape(sapnotes[sid]['componentkey'])
532
            comptxt = escape(sapnotes[sid]['componenttxt'])
533
            scomp.add(compkey)
534
            dcomp[compkey] = comptxt
535
        lcomp = list(scomp)
536
        lcomp.sort()
537
 
538
        for compkey in lcomp:
539
            subkeys = compkey.split('-')
540
            ppid = None
541
            for i in range(1, len(subkeys)+1):
542
                key = ('-').join(subkeys[0:i])
543
                try:
544
                    ppid = self.treepids[key]
545
                except:
546
                    if i == len(subkeys):
547
                        title = dcomp[compkey]
548
                    else:
549
                        title = ""
550
                    count = len(self.srvdtb.get_notes_by_node('componentkey', key))
551
                    node = self.get_node_component(key, title, str(count))
552
                    ppid = self.model.append(ppid, node)
553
                    self.treepids[key] = ppid
554
 
555
 
556
    def populate_by_priority(self, sapnotes):
557
        self.model.clear()
558
        treepids = {}
559
 
560
        if len(sapnotes) == 0:
561
            return
562
 
563
        scomp = set()
564
        dcomp = {}
565
        pset = set()
566
 
567
        for sid in sapnotes:
568
            try:
569
                priority = sapnotes[sid]['priority']
570
                pset.add(priority)
571
            except: pass
572
 
573
        plist = []
574
        plist.extend(pset)
575
        plist.sort()
576
 
577
        for priority in plist:
578
            count = len(self.srvdtb.get_notes_by_node('priority', priority))
579
            node = self.get_node_priority(priority, count)
580
            pid = self.model.append(None, node)
581
            treepids[priority] = pid
582
 
583
 
584
    def populate_by_type(self, sapnotes):
585
        self.model.clear()
586
        treepids = {}
587
 
588
        if len(sapnotes) == 0:
589
            return
590
 
591
        scomp = set()
592
        dcomp = {}
593
        pset = set()
594
 
595
        for sid in sapnotes:
596
            try:
597
                sntype = sapnotes[sid]['type']
598
                pset.add(sntype)
599
            except: pass
600
 
601
        plist = []
602
        plist.extend(pset)
603
        plist.sort()
604
 
605
        for sntype in plist:
606
            count = len(self.srvdtb.get_notes_by_node('type', sntype))
607
            node = self.get_node_type(sntype, count)
608
            pid = self.model.append(None, node)
609
            treepids[sntype] = pid
610
 
611
 
612
    def populate_by_component_descriptions(self, sapnotes, only_bookmarks=False):
613
        self.model.clear()
614
        self.treepids = {}
615
 
616
        if len(sapnotes) == 0:
617
            return
618
 
619
        scomp = set()
620
        dcomp = {}
621
 
622
        for sid in sapnotes:
623
            compkey = escape(sapnotes[sid]['componentkey'])
624
            comptxt = escape(sapnotes[sid]['componenttxt'])
625
            scomp.add(compkey)
626
            dcomp[compkey] = comptxt
627
        lcomp = list(scomp)
628
        lcomp.sort()
629
 
630
        for compkey in lcomp:
631
            subkeys = compkey.split('-')
632
            ppid = None
633
            for i in range(1, len(subkeys)+1):
634
                key = ('-').join(subkeys[0:i])
635
                try:
636
                    ppid = self.treepids[key]
637
                except:
638
                    if i == len(subkeys):
639
                        title = dcomp[compkey]
640
                    else:
641
                        title = ""
642
                    count = len(self.srvdtb.get_notes_by_node('componentkey', key))
643
                    node = self.get_node_component_desc(key, title, str(count))
644
                    ppid = self.model.append(ppid, node)
645
                    self.treepids[key] = ppid
646
 
647
 
648
    def populate_by_category(self, sapnotes):
649
        self.model.clear()
650
        treepids = {}
651
 
652
        if len(sapnotes) == 0:
653
            return
654
 
655
        scomp = set()
656
        dcomp = {}
657
        catset = set()
658
 
659
        for sid in sapnotes:
660
            try:
661
                cat = sapnotes[sid]['category']
662
                catset.add(cat)
663
            except: pass
664
 
665
        catlist = []
666
        catlist.extend(catset)
667
        catlist.sort()
668
 
669
        for cat in catlist:
670
            count = len(self.srvdtb.get_notes_by_node('category', cat))
671
            node = self.get_node_category(cat, str(count))
672
            pid = self.model.append(None, node)
673
            treepids[cat] = pid
674
 
675
 
676
    def populate_by_collection(self, sapnotes):
677
        treepids = {}
678
        scomp = set()
679
        dcomp = {}
680
        self.model.clear()
374 t00mlabs 681
 
340 t00mlabs 682
        # Add Downloaded collection
683
        cid = self.srvclt.get_cid_by_name('Downloaded')
684
        count = len(self.srvdtb.get_notes_by_node('collection', cid))
685
        node = self.get_node_collection(cid, "<span color='black'><b>Downloaded</b></span>", str(count))
686
        treepids['Downloaded'] = self.model.append(None, node)
687
 
688
        collections = self.srvclt.get_all()
689
        od = OrderedDict(sorted(collections.items(), key=lambda t: t[1]))
690
        if len(od) > 0:
691
            for cid in od:
692
                colname = self.srvclt.get_name_by_cid(cid)
693
                if cid == COL_DOWNLOADED:
694
                    continue
695
 
696
                compkey = od[cid]
697
                subkeys = compkey.split(' ')
698
                ppid = None
699
                for i in range(1, len(subkeys)+1):
700
                    key = (' ').join(subkeys[0:i])
701
                    try:
702
                        ppid = treepids[key]
703
                    except:
704
                        title = key
705
                        if title == compkey:
706
                            matches = set()
707
                            cols = self.srvclt.get_collections_by_row_title(title)
708
                            for col in cols:
709
                                for sid in self.srvdtb.get_notes_by_node('collection', col):
710
                                    matches.add(sid)
711
                            node = self.get_node_collection(cid, title, str(len(matches)))
712
                        else:
713
 
714
                            matches = set()
715
                            cols = self.srvclt.get_collections_by_row_title(title)
716
                            for col in cols:
717
                                for sid in self.srvdtb.get_notes_by_node('collection', col):
718
                                    matches.add(sid)
719
                            node = self.get_node_collection('', title, str(len(matches)))
720
                        ppid = self.model.append(ppid, node)
721
                        treepids[key] = ppid
722
        else:
723
            node = self.get_node_collection('', 'No collections available yet')
724
            self.model.append(None, node)
725
 
726
 
727
    def populate_annotations(self, annotations=None):
362 t00mlabs 728
        visor_annotations = self.srvgui.get_widget('visor_annotations')
729
        visor_annotations.populate(annotations)
340 t00mlabs 730
 
731
 
732
    def populate_by_chronologic(self, sapnotes):
733
        self.model.clear()
734
        treepids = {}
735
 
736
        if len(sapnotes) == 0:
737
            return
738
 
739
        years = set()
740
        months = set()
741
        days = set()
742
        for sid in sapnotes:
743
            try:
744
                downloaded = dateparser.parse(sapnotes[sid]['feedupdate'])
745
                year = "%d" % downloaded.year
746
                month = "%02d" % downloaded.month
747
                day = "%02d" % downloaded.day
748
                key_year = year
749
                key_month = year + month
750
                key_day = year + month + day
751
                years.add(key_year)
752
                months.add(key_month)
753
                days.add(key_day)
754
            except:
755
                pass
756
        years = list(years)
757
        years.sort(reverse=True)
758
        months = list(months)
759
        months.sort(reverse=True)
760
        days = list(days)
761
        days.sort(reverse=True)
762
 
763
        for key_year in years:
764
            try:
765
                treepids[key_year]
766
            except:
767
                adate = key_year + '0101'
768
                downloaded = dateparser.parse(adate)
769
                count = len(self.srvdtb.get_notes_by_node('date-year', key_year))
770
                node = self.get_node_date_year(downloaded, key_year, str(count))
771
                treepids[key_year] = self.model.append(None, node)
772
 
773
        for key_month in months:
774
            try:
775
                treepids[key_month]
776
            except:
777
                adate = key_month + '01'
778
                downloaded = dateparser.parse(adate)
779
                count = len(self.srvdtb.get_notes_by_node('date-month', key_month))
780
                node = self.get_node_date_month(downloaded, key_month, str(count))
781
                key_year = key_month[0:4]
782
                treepids[key_month] = self.model.append(treepids[key_year], node)
783
 
784
        for key_day in days:
785
            try:
786
                treepids[key_day]
787
            except:
788
                downloaded = dateparser.parse(key_day)
789
                count = len(self.srvdtb.get_notes_by_node('date-day', key_day))
790
                key_month = key_day[0:6]
791
                node = self.get_node_date_day(downloaded, key_day, str(count))
792
                treepids[key_day] = self.model.append(treepids[key_month], node)
793