Subversion Repositories basico

Rev

Rev 4 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
4 t00mlabs 1
#!/usr/bin/python
2
# -*- coding: utf-8 -*-
3
# File: sapnoteview.py
4
# Author: Tomás Vírseda
5
# License: GPL v3
6
# Description: TreeView for SAP Notes
7
 
8
from cgi import escape
9
from enum import IntEnum
10
from gi.repository import Gtk
11
from gi.repository.GdkPixbuf import Pixbuf
12
from gi.repository import Pango
13
from datetime import datetime
14
from dateutil import parser as dateparser
74 t00mlabs 15
#~ from bs4 import BeautifulSoup as BSHTML
4 t00mlabs 16
from .log import get_logger
17
 
18
#~ Enum(value='Column', names=<...>, *, module='...', qualname='...', type=<mixed-in class>, start=1)
19
#~ Column = Enum('Column', 'rowtype checkbox icon id title component category type priority language released', start=0)
20
 
21
class Column(IntEnum):
22
    rowtype = 0
23
    checkbox = 1
24
    icon = 2
74 t00mlabs 25
    component = 3
26
    category = 4
27
    type = 5
28
    id = 6
29
    title = 7
4 t00mlabs 30
    priority = 8
31
    language = 9
32
    released = 10
33
 
34
 
35
class SAPNoteView(Gtk.TreeView):
36
    def __init__(self, app):
37
        self.app = app
38
        LOG_FILE = self.app.get_file('LOG')
39
        LOG_NAME = self.__class__.__name__
40
        self.log = get_logger(LOG_NAME, LOG_FILE)
41
        self.get_services()
42
        self.toggled = 0
43
        self.selected = set()
44
        self.count = 0
45
 
46
 
47
        # Setup treeview and model
48
        Gtk.TreeView.__init__(self)
49
        self.model = Gtk.TreeStore(
74 t00mlabs 50
            str,            # RowType@RowId
4 t00mlabs 51
            bool,           # CheckBox
52
            Pixbuf,         # Icon
53
            str,            # Component key
54
            str,            # Category
55
            str,            # Type
56
            str,            # SAP Note Id
57
            str,            # Title
58
            str,            # Priority
59
            str,            # Language
60
            str             # Release date
61
        )
62
        self.set_model(self.model)
63
 
64
        # Setup columns
65
        # RowType
66
        renderer = Gtk.CellRendererText()
67
        column = Gtk.TreeViewColumn('', renderer, text=Column.rowtype.value)
68
        column.set_visible(False)
69
        column.set_expand(False)
70
        column.set_clickable(False)
71
        column.set_sort_indicator(False)
72
        self.append_column(column)
73
 
74
        # Checkbox
75
        renderer = Gtk.CellRendererToggle()
76
        renderer.connect("toggled", self.on_cell_toggled)
74 t00mlabs 77
        self.column_checkbox = Gtk.TreeViewColumn('', renderer, active=1)
78
        self.column_checkbox.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE)
79
        self.column_checkbox.set_visible(True)
80
        self.column_checkbox.set_expand(False)
81
        self.column_checkbox.set_clickable(False)
82
        self.column_checkbox.set_sort_indicator(False)
83
        self.append_column(self.column_checkbox)
84
        self.column_checkbox.set_cell_data_func(renderer, self.cell_data_func)
4 t00mlabs 85
 
86
        # Icon
87
        renderer = Gtk.CellRendererPixbuf()
88
        renderer.set_alignment(0.0, 0.5)
89
        self.column_icon = Gtk.TreeViewColumn('', renderer, pixbuf=2)
90
        self.column_icon.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE)
91
        self.column_icon.set_visible(True)
92
        self.column_icon.set_expand(False)
93
        self.column_icon.set_clickable(False)
94
        self.column_icon.set_sort_indicator(False)
95
        self.append_column(self.column_icon)
96
 
97
        # Component key
98
        renderer = Gtk.CellRendererText()
99
        #~ renderer.set_property('ellipsize', Pango.EllipsizeMode.MIDDLE)
100
        self.column_component = Gtk.TreeViewColumn('SAP Notes', renderer, markup=3)
101
        self.column_component.set_visible(True)
102
        #~ self.column_component.set_expand(True)
103
        self.column_component.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE)
104
        self.column_component.set_clickable(True)
105
        self.column_component.set_sort_indicator(True)
106
        self.column_component.set_sort_column_id(3)
107
        self.column_component.set_sort_order(Gtk.SortType.ASCENDING)
74 t00mlabs 108
        self.column_component.set_expand(True)
4 t00mlabs 109
        self.append_column(self.column_component)
110
        expander_column = self.column_component
111
 
112
 
113
        # Category
114
        renderer = Gtk.CellRendererText()
115
        self.column_cat = Gtk.TreeViewColumn('Category', renderer, markup=4)
116
        self.column_cat.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE)
117
        self.column_cat.set_visible(False)
118
        self.column_cat.set_expand(False)
119
        self.column_cat.set_clickable(True)
120
        self.column_cat.set_sort_indicator(True)
121
        self.column_cat.set_sort_column_id(4)
122
        self.column_cat.set_sort_order(Gtk.SortType.ASCENDING)
123
        self.append_column(self.column_cat)
124
 
125
        # Type
126
        renderer = Gtk.CellRendererText()
127
        column = Gtk.TreeViewColumn('Type', renderer, markup=5)
128
        column.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE)
129
        column.set_visible(False)
130
        column.set_expand(False)
131
        column.set_clickable(True)
132
        column.set_sort_indicator(True)
133
        column.set_sort_column_id(5)
134
        column.set_sort_order(Gtk.SortType.ASCENDING)
135
        self.append_column(column)
136
 
137
        # SAP Note Id
138
        renderer = Gtk.CellRendererText()
74 t00mlabs 139
        renderer.set_alignment(1.0, 0.5)
4 t00mlabs 140
        self.column_sid = Gtk.TreeViewColumn('SAP Note', renderer, markup=6)
141
        self.column_sid.set_visible(False)
142
        self.column_sid.set_expand(False)
143
        self.column_sid.set_clickable(True)
144
        self.column_sid.set_sort_indicator(True)
145
        self.column_sid.set_sort_column_id(6)
146
        self.column_sid.set_sort_order(Gtk.SortType.ASCENDING)
147
        self.append_column(self.column_sid)
148
 
149
        # Title
150
        renderer = Gtk.CellRendererText()
151
        renderer.set_property('ellipsize', Pango.EllipsizeMode.MIDDLE)
152
        self.column_title = Gtk.TreeViewColumn('Title', renderer, markup=7)
153
        self.column_title.set_visible(False)
154
        self.column_title.set_expand(True)
155
        self.column_title.set_clickable(True)
156
        self.column_title.set_sort_indicator(True)
157
        self.column_title.set_sort_column_id(7)
158
        self.column_title.set_sort_order(Gtk.SortType.ASCENDING)
159
        self.append_column(self.column_title)
160
 
161
        # Priority
162
        renderer = Gtk.CellRendererText()
163
        self.column_priority = Gtk.TreeViewColumn('Priority', renderer, markup=8)
164
        self.column_priority.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE)
165
        self.column_priority.set_visible(True)
166
        self.column_priority.set_expand(False)
167
        self.column_priority.set_clickable(True)
168
        self.column_priority.set_sort_indicator(True)
169
        self.column_priority.set_sort_column_id(8)
170
        self.column_priority.set_sort_order(Gtk.SortType.ASCENDING)
171
        self.append_column(self.column_priority)
172
 
173
        # Language
174
        renderer = Gtk.CellRendererText()
175
        column = Gtk.TreeViewColumn('Language', renderer, markup=9)
176
        column.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE)
177
        column.set_visible(False)
178
        column.set_expand(False)
179
        column.set_clickable(True)
180
        column.set_sort_indicator(True)
181
        column.set_sort_column_id(9)
182
        column.set_sort_order(Gtk.SortType.ASCENDING)
183
        self.append_column(column)
184
 
185
        # Release date
186
        renderer = Gtk.CellRendererText()
187
        self.column_rel = Gtk.TreeViewColumn('Released on', renderer, markup=10)
188
        self.column_rel.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE)
189
        self.column_rel.set_visible(False)
190
        self.column_rel.set_expand(False)
191
        self.column_rel.set_clickable(True)
192
        self.column_rel.set_sort_indicator(True)
193
        self.column_rel.set_sort_column_id(10)
194
        self.column_rel.set_sort_order(Gtk.SortType.ASCENDING)
195
        self.append_column(self.column_rel)
196
 
197
        # TreeView common
74 t00mlabs 198
        #~ self.set_level_indentation(6)
4 t00mlabs 199
        self.set_can_focus(True)
200
        self.set_headers_visible(False)
201
        self.set_enable_search(True)
202
        #~ self.set_rules_hint(True)
203
        #~ self.set_expander_column(expander_column)
74 t00mlabs 204
        self.set_hover_selection(False)
4 t00mlabs 205
        self.set_grid_lines(Gtk.TreeViewGridLines.NONE)
206
        self.set_search_entry(self.gui.get_widget('stySearchInfo'))
207
        self.set_search_column(3)
208
        #~ self.set_row_separator_func(self.row_separator_func)
209
 
210
        # Selection
211
        self.selection = self.get_selection()
212
        self.selection.set_select_function(self.select_function)
74 t00mlabs 213
        #~ self.selection.set_mode(Gtk.SelectionMode.BROWSE)
214
        self.selection.set_mode(Gtk.SelectionMode.SINGLE)
4 t00mlabs 215
 
216
        # Go live
217
        self.connect('button_press_event', self.cb_button_press)
218
        self.connect('row-activated', self.double_click)
219
        self.connect('cursor-changed', self.row_changed)
220
        self.show_all()
221
 
222
 
223
    def cell_data_func(self, column, cell, store, iter, data=None):
74 t00mlabs 224
        """Do not show checkbox when row type is distinct of sapnote"""
225
        row = store[iter][0]
226
        row_type, key = row.split('@')
227
 
228
        if row_type != 'sapnote':
4 t00mlabs 229
            cell.set_visible(False)
230
        else:
231
            cell.set_visible(True)
232
 
233
 
234
    def select_function(self, selection, store, path, current):
235
        return True
236
 
237
        #~ This code works: only allow select rows of type 'sapnote'
238
        #~ rowtype = store[path][0]
239
        #~ if rowtype == 'sapnote':
240
            #~ return True
241
        #~ else:
242
            #~ return False
243
 
244
 
245
    #~ def row_separator_func(self, model, iter):
246
        #~ """ Call user function to determine if this node is separator """
247
        #~ if iter and model.iter_is_valid(iter):
248
            #~ rowtype = model.get_value(iter, 0)
249
            #~ if row<type == 'sapnote':
250
                #~ return True
251
            #~ else:
252
                #~ return False
253
            #~ self.log.debug("Row type: %s" % rowtype)
254
            #~ return False
255
        #~ return False
256
 
257
 
258
    def get_services(self):
259
        self.gui = self.app.get_service("GUI")
260
        self.cb = self.app.get_service('Callbacks')
261
        self.menu = self.app.get_service("Menus")
262
        self.sap = self.app.get_service('SAP')
263
        self.im = self.app.get_service('IM')
264
        self.settings = self.app.get_service('Settings')
265
        self.plugins = self.app.get_service('Plugins')
74 t00mlabs 266
        self.db = self.app.get_service('DB')
4 t00mlabs 267
 
268
 
269
    def row_changed(self, treeview):
270
        #~ button = self.gui.get_widget('mnuBtnActions')
271
        selected = set()
272
        selection = treeview.get_selection()
273
        model, treeiters = selection.get_selected_rows()
74 t00mlabs 274
        try:
275
            row = model[treeiters[0]][0]
276
            row_type, sid = row.split('@')
277
            self.log.debug("Row Type: %s - Id: %s" % (row_type, sid))
278
        except Exception as error:
279
            return
280
            #~ self.log.error(error)
281
            #~ raise
282
            #~ return
4 t00mlabs 283
 
74 t00mlabs 284
        if row_type == 'sapnote':
285
            trvprops = self.gui.get_widget('trvprops')
286
            modelprops = trvprops.get_model()
287
            #~ tid = model[treeiters[0]][Column.id.value]
288
            #~ tid = BSHTML(tid, "lxml").text # clean Id by removing all tags.
289
            #~ sid = "0"*(10 - len(tid)) + tid
290
            sapnote = self.db.get_sapnote_metadata(sid)
4 t00mlabs 291
 
74 t00mlabs 292
            modelprops.clear()
293
            modelprops.append(None, ["<big><b>SAP Note Id</b></big>", "<big>%s</big>" % sid])
294
            modelprops.append(None, ["<big><b>Title</b></big>", "<big>%s</big>" %  sapnote['title']])
295
            modelprops.append(None, ["<big><b>Version</b></big>", "<big>%s</big>" %  sapnote['version']])
296
            modelprops.append(None, ["<big><b>Component Key</b></big>", "<big>%s</big>" %  sapnote['componentkey']])
297
            modelprops.append(None, ["<big><b>Component Text</b></big>", "<big>%s</big>" %  sapnote['componenttxt']])
298
            modelprops.append(None, ["<big><b>Category</b></big>", "<big>%s</big>" %  sapnote['category']])
299
            modelprops.append(None, ["<big><b>Type</b></big>", "<big>%s</big>" %  sapnote['type']])
300
            modelprops.append(None, ["<big><b>Priority</b></big>", "<big>%s</big>" %  sapnote['priority']])
301
            modelprops.append(None, ["<big><b>Language</b></big>", "<big>%s</big>" %  sapnote['language']])
302
            modelprops.append(None, ["<big><b>Released</b></big>", "<big>%s</big>" %  sapnote['releaseon']])
303
            modelprops.append(None, ["<big><b>Downloaded</b></big>", "<big>%s</big>" %  str(sapnote['feedupdate'])])
304
            modelprops.append(None, ["<big><b>Bookmarked</b></big>", "<big>%s</big>" %  str(sapnote['bookmark'])])
305
            try:
306
                # Not all sapnotes are linked to a task. Skip this field
307
                tasks = self.app.get_service('Tasks')
308
                ltasks = sapnote['tasks']
309
                tasks.select(ltasks)
310
                modelprops.append(None, ["<b>Tasks</b>", ', '.join(ltasks)])
311
                self.log.debug("SAP Note %s activated" % sid)
312
            except Exception as error:
313
                pass
314
        else:
315
            tasks = self.app.get_service('Tasks')
316
            tasks.clear()
317
            tasks.show_window()
318
 
319
 
4 t00mlabs 320
    def double_click(self, treeview, row, col):
321
        model = treeview.get_model()
74 t00mlabs 322
        row = model[row][0]
323
        row_type, sid = row.split('@')
324
        self.set_select_notes([sid])
4 t00mlabs 325
        #~ self.log.debug("Launching SAP Note %s in browser" % noteid)
326
        self.cb.actions_browse()
327
 
328
 
329
    def cb_button_press(self, treeview, event, data=None):
330
        if event.button == 3:
331
            x = int(event.x)
332
            y = int(event.y)
333
            time = event.time
334
            pthinfo = self.get_path_at_pos(x,y)
335
            if pthinfo is not None:
336
                path,col,cellx,celly = pthinfo
337
                self.grab_focus()
338
                self.set_cursor(path,col,0)
339
 
340
                model = treeview.get_model()
341
                treeiter = model.get_iter(path)
74 t00mlabs 342
                #~ for n in range(9):
343
                    #~ self.log.debug("%d -> %s" % (n, model.get_value(treeiter, n)))
4 t00mlabs 344
                rowtype = model.get_value(treeiter, 0)
74 t00mlabs 345
                self.log.debug("Row type: %s" % rowtype)
4 t00mlabs 346
                if rowtype == 'task':
347
                    task = model.get_value(treeiter, 6)
348
                    self.popup_menu = self.menu.create_popup_menu_by_task(task)
349
                elif rowtype == 'component':
74 t00mlabs 350
                    comptitle = model.get_value(treeiter, 3)
351
                    self.log.debug(comptitle)
352
                    token = "</b></big>"
353
                    pos = comptitle.find(token)
354
                    component = comptitle[8:pos]
4 t00mlabs 355
                    self.popup_menu = self.menu.create_popup_menu_by_component(component)
356
                elif rowtype == 'sapnote':
357
                    sid = model.get_value(treeiter, 6)
358
                    self.popup_menu = self.menu.create_popup_menu_by_sapnote(sid)
359
                else:
360
                    return False
361
 
362
 
363
                #~ noteid = model.get_value(treeiter, 6)
364
                #~ sapnote = self.sap.get_node(noteid)
365
                #~ self.log.debug("Selected SAP Note: %s" % sapnote)
74 t00mlabs 366
                if self.popup_menu is not None:
367
                    self.popup_menu.show_all()
368
                    self.popup_menu.popup(None, None, None, None, event.button, event.time)
369
                    return True # event has been handled
370
                else:
371
                    return False
4 t00mlabs 372
 
373
 
374
    def populate(self, sapnotes):
375
        #~ self.column_icon.set_visible(True)
376
        #~ self.column_component.set_visible(True)
377
        #~ self.column_title.set_visible(False)
378
        #~ self.column_cat.set_visible(False)
379
 
380
        self.set_headers_visible(False)
381
        self.column_sid.set_visible(False)
382
        self.column_rel.set_visible(False)
383
        self.column_priority.set_visible(False)
384
        self.column_icon.set_visible(True)
74 t00mlabs 385
        self.column_checkbox.set_visible(True)
4 t00mlabs 386
 
387
        if self.view == 'components':
388
            self.populate_by_components(sapnotes)
74 t00mlabs 389
        elif self.view == 'description':
390
            self.populate_by_component_descriptions(sapnotes)
4 t00mlabs 391
        elif self.view == 'projects':
392
            self.populate_by_projects(sapnotes)
393
        elif self.view == 'tasks':
394
            self.populate_by_tasks(sapnotes)
395
        elif self.view == 'bookmarks':
396
            self.populate_by_bookmarks(sapnotes)
74 t00mlabs 397
        elif self.view == 'tags':
398
            self.populate_by_tags(sapnotes)
399
        elif self.view == 'category':
400
            self.populate_by_category(sapnotes)
401
        elif self.view == 'chronologic':
402
            self.populate_by_chronologic(sapnotes)
403
        elif self.view == 'priority':
404
            self.populate_by_priority(sapnotes)
405
        elif self.view == 'type':
406
            self.populate_by_type(sapnotes)
4 t00mlabs 407
        else:
408
            self.populate_by_components(sapnotes)
409
        # Save last populated list of sap notes
74 t00mlabs 410
        total = self.db.get_total()
4 t00mlabs 411
        notesid = set()
412
        for sapnote in sapnotes:
413
            notesid.add(sapnote)
414
 
415
        if len(notesid) < total:
416
            self.settings.set_config_value('Notes', ','.join(notesid))
417
 
74 t00mlabs 418
        self.log.debug("View '%s' populated with %d SAP Notes" % (self.view, len(sapnotes)))
4 t00mlabs 419
 
420
 
421
    def populate_by_bookmarks(self, sapnotes):
422
        #~ self.log.debug('Populating bookmarks')
423
        self.model.clear()
424
        self.set_headers_visible(True)
425
        self.column_sid.set_visible(True)
426
        self.column_icon.set_visible(False)
427
        self.column_component.set_visible(True)
428
        self.column_component.set_expand(False)
429
        self.column_title.set_visible(True)
74 t00mlabs 430
        self.column_title.set_expand(True)
4 t00mlabs 431
        self.column_priority.set_expand(False)
432
        self.column_cat.set_visible(False)
74 t00mlabs 433
        self.column_sid.set_expand(False)
4 t00mlabs 434
        self.column_component.set_title('Component')
435
        icon_bookmark = self.im.get_icon('bookmark')
436
 
437
        for sid in sapnotes:
438
            try:
439
                bookmark = sapnotes[sid]['bookmark'] # True or False
440
            except:
441
                bookmark = False
442
 
443
            if bookmark:
74 t00mlabs 444
                sapnote = self.get_node_sapnote_bookmark(sapnotes[sid], sid)
4 t00mlabs 445
                self.model.append(None, sapnote)
446
 
447
 
448
    def get_node_project(self, project, icon):
449
        if project == '':
450
            title = "<span size='18000'><b>No project assigned</b></span>"
451
        else:
452
            title = "<span size='18000'><b>%s</b></span>" % project
453
 
454
        node = []
74 t00mlabs 455
        node.append('project@%s' % project)
4 t00mlabs 456
        node.append(0)
457
        node.append(icon)
458
        node.append(title) # Component
459
        node.append("") # Category
460
        node.append("") # Type
461
        node.append("") # Id
462
        node.append("") # Title
463
        node.append("") # Priority
464
        node.append("") # Lang
465
        node.append("") # Release on
466
        return node
467
 
468
 
469
    def get_node_task(self, task, icon):
470
        if task == '':
74 t00mlabs 471
            title = "<big><b>No task assigned</b></big>"
4 t00mlabs 472
        else:
74 t00mlabs 473
            title = "<big><b>%s</b></big>" % task
4 t00mlabs 474
 
475
        node = []
74 t00mlabs 476
        node.append('task@%s' % task)
4 t00mlabs 477
        node.append(0)
478
        node.append(icon)
479
        node.append(title) # Component
480
        node.append("") # Category
481
        node.append("") # Type
74 t00mlabs 482
        node.append("") # Id
4 t00mlabs 483
        node.append("") # Title
484
        node.append("") # Priority
485
        node.append("") # Lang
486
        node.append("") # Release on
487
        return node
488
 
489
 
490
    def populate_by_projects(self, sapnotes):
491
        self.model.clear()
492
        treepids = {}
493
        icon_noproject = self.im.get_icon('noproject')
494
        icon_project = self.im.get_icon('project')
74 t00mlabs 495
        icon_sapnote = self.im.get_icon('fingerprint')
4 t00mlabs 496
        icon_bookmark = self.im.get_icon('bookmark')
497
        self.column_component.set_title('Projects')
498
 
499
        if len(sapnotes) == 0:
500
            return
501
 
502
        node = self.get_node_project('', icon_noproject)
503
        pid = self.model.append(None, node)
504
        treepids['None'] = pid
505
 
506
        notlinked = 0
507
        for sid in sapnotes:
508
            try:
509
                projects = sapnotes[sid]['projects']
510
            except:
511
                projects = []
512
 
513
 
514
            if len(projects) == 0:
515
                #~ SAP Note not linked to any project
516
                sapnote = self.get_node_sapnote(sapnotes[sid], sid)
517
                self.model.append(treepids['None'], sapnote)
518
                notlinked += 1
519
            else:
520
                #~ SAP Note linked to projects
521
                for project in projects:
522
                    try:
523
                        pid = treepids[project]
524
                    except:
525
                        node = self.get_node_project(project, icon_project)
526
                        pid = self.model.append(None, node)
527
                        treepids[project] = pid
528
 
529
                    sapnote = self.get_node_sapnote(sapnotes[sid], sid)
530
                    self.model.append(pid, sapnote)
531
 
532
        if notlinked == 0:
533
            self.model.remove(treepids['None'])
534
 
535
 
74 t00mlabs 536
    def populate_by_tags(self, sapnotes):
537
        pass
538
        #~ for sid in sapnotes:
539
            #~ tags = sapnotes[sid]['']
540
 
4 t00mlabs 541
    def populate_by_tasks(self, sapnotes):
542
        self.model.clear()
543
        treepids = {}
74 t00mlabs 544
        icon_notask = self.im.get_icon('notask', 32, 32)
545
        icon_task = self.im.get_icon('task', 32, 32)
546
        icon_sapnote = self.im.get_icon('fingerprint', 32, 32)
547
        icon_bookmark = self.im.get_icon('bookmark', 32, 32)
4 t00mlabs 548
        self.column_component.set_title('Tasks')
74 t00mlabs 549
        #~ self.column_icon.set_visible(False)
550
        #~ self.column_sid.set_visible(True)
551
        self.set_headers_visible(True)
552
        self.column_sid.set_visible(True)
553
        self.column_icon.set_visible(True)
554
        self.column_component.set_visible(True)
555
        self.column_component.set_expand(True)
556
        self.column_title.set_visible(False)
557
        self.column_title.set_expand(True)
558
        self.column_priority.set_expand(False)
559
        self.column_cat.set_visible(False)
560
        self.column_sid.set_expand(False)
4 t00mlabs 561
 
562
        if len(sapnotes) == 0:
563
            return
564
 
565
        #~ "No task assigned" node creation
566
        node = self.get_node_task('', icon_notask)
567
        pid = self.model.append(None, node)
568
        treepids['None'] = pid
569
 
570
        scomp = set()
571
        dcomp = {}
572
        taskset = set()
573
        for sid in sapnotes:
574
            try:
575
                # setup components
576
                compkey = escape(sapnotes[sid]['componentkey'])
577
                comptxt = escape(sapnotes[sid]['componenttxt'])
578
                scomp.add(compkey)
579
                dcomp[compkey] = comptxt
580
 
581
                # setup tasks
582
                for task in sapnotes[sid]['tasks']:
583
                    taskset.add(task)
584
            except: pass
585
 
586
        lcomp = list(scomp)
587
        lcomp.sort()
588
 
589
        tasklist = []
590
        tasklist.extend(taskset)
591
        tasklist.sort()
592
 
593
        for task in tasklist:
594
            node = self.get_node_task(task, icon_task)
595
            pid = self.model.append(None, node)
596
            treepids[task] = pid
597
 
598
        notask = 0
599
        for sid in sapnotes:
600
            #~ Get category
601
            compkey = escape(sapnotes[sid]['componentkey'])
602
            catname = escape(sapnotes[sid]['category'])
603
 
604
 
605
            #~ Get tasks for this sapnote
606
            try:
607
                tasks = sapnotes[sid]['tasks']
608
            except:
609
                sapnotes[sid]['tasks'] = tasks = []
610
 
611
 
612
            if len(tasks) == 0:
613
                # Components in no-task node
614
                cmpkey = "notask" + '-' + compkey
615
                comptxt = dcomp[compkey]
616
                try:
617
                    pid = treepids[cmpkey]
618
                except:
619
                    node = self.get_node_component(compkey, comptxt)
620
                    pid = self.model.append(treepids['None'], node)
621
                    treepids[cmpkey] = pid
622
 
623
                # Categories in no-task node
624
                catkey = "notask" + '-' + compkey + '-' + catname
625
                try:
626
                    cid = treepids[catkey]
627
                except:
628
                    node = self.get_node_category(sapnotes[sid])
629
                    cid = self.model.append(pid, node)
630
                    treepids[catkey] = cid
631
 
632
                #~ SAP Note not linked to any task
74 t00mlabs 633
                sapnote = self.get_node_sapnote_task(sapnotes[sid], sid)
4 t00mlabs 634
                self.model.append(cid, sapnote)
635
                notask += 1
636
            else:
637
                #~ SAP Note linked to tasks
638
                for task in sapnotes[sid]['tasks']:
639
                    # Components in task node
640
                    cmpkey = task + '-' + compkey
641
                    comptxt = dcomp[compkey]
642
                    pid = treepids[task]
74 t00mlabs 643
                    sapnote = self.get_node_sapnote_task(sapnotes[sid], sid)
644
                    self.model.append(treepids[task], sapnote)
4 t00mlabs 645
 
646
        #~ "No task assigned" node deletion if no tasks at all
647
        if notask == 0:
648
            self.model.remove(treepids['None'])
649
 
650
 
74 t00mlabs 651
    def populate_by_priority(self, sapnotes):
652
        self.model.clear()
653
        treepids = {}
654
 
655
        self.set_headers_visible(True)
656
        self.column_sid.set_visible(True)
657
        self.column_icon.set_visible(True)
658
        self.column_component.set_visible(True)
659
        self.column_component.set_expand(False)
660
        self.column_title.set_visible(True)
661
        self.column_title.set_expand(True)
662
        self.column_priority.set_expand(False)
663
        self.column_cat.set_visible(False)
664
        self.column_sid.set_expand(False)
665
 
666
        if len(sapnotes) == 0:
667
            return
668
 
669
        scomp = set()
670
        dcomp = {}
671
        pset = set()
672
 
673
        for sid in sapnotes:
674
            try:
675
                priority = sapnotes[sid]['priority']
676
                pset.add(priority)
677
            except: pass
678
 
679
        plist = []
680
        plist.extend(pset)
681
        plist.sort()
682
 
683
        for priority in plist:
684
            node = self.get_node_priority(priority)
685
            pid = self.model.append(None, node)
686
            treepids[priority] = pid
687
 
688
        for sid in sapnotes:
689
            priority = sapnotes[sid]['priority']
690
            pid = treepids[priority]
691
            sapnote = self.get_node_sapnote(sapnotes[sid], sid)
692
            self.model.append(pid, sapnote)
693
 
694
 
695
    def populate_by_type(self, sapnotes):
696
        self.model.clear()
697
        treepids = {}
698
 
699
        self.set_headers_visible(True)
700
        self.column_sid.set_visible(True)
701
        self.column_icon.set_visible(True)
702
        self.column_component.set_visible(True)
703
        self.column_component.set_expand(False)
704
        self.column_title.set_visible(True)
705
        self.column_title.set_expand(True)
706
        self.column_priority.set_expand(False)
707
        self.column_cat.set_visible(False)
708
        self.column_sid.set_expand(False)
709
 
710
        if len(sapnotes) == 0:
711
            return
712
 
713
        scomp = set()
714
        dcomp = {}
715
        pset = set()
716
 
717
        for sid in sapnotes:
718
            try:
719
                sntype = sapnotes[sid]['type']
720
                pset.add(sntype)
721
            except: pass
722
 
723
        plist = []
724
        plist.extend(pset)
725
        plist.sort()
726
 
727
        for sntype in plist:
728
            node = self.get_node_type(sntype)
729
            pid = self.model.append(None, node)
730
            treepids[sntype] = pid
731
 
732
        for sid in sapnotes:
733
            sntype = sapnotes[sid]['type']
734
            pid = treepids[sntype]
735
            sapnote = self.get_node_sapnote_type(sapnotes[sid], sid)
736
            self.model.append(pid, sapnote)
737
 
738
 
739
 
740
    def populate_by_component_descriptions(self, sapnotes):
741
        self.model.clear()
742
        treepids = {}
743
 
744
        self.set_headers_visible(True)
745
        self.column_sid.set_visible(True)
746
        self.column_icon.set_visible(True)
747
        self.column_component.set_visible(True)
748
        self.column_component.set_expand(True)
749
        self.column_title.set_visible(False)
750
        self.column_title.set_expand(True)
751
        self.column_priority.set_expand(False)
752
        self.column_cat.set_visible(False)
753
        self.column_sid.set_expand(False)
754
 
755
        if len(sapnotes) == 0:
756
            return
757
 
758
        scomp = set()
759
        dcomp = {}
760
        pset = set()
761
 
762
        for sid in sapnotes:
763
            try:
764
                comptxt = escape(sapnotes[sid]['componenttxt'])
765
                pset.add(comptxt)
766
            except: pass
767
 
768
        plist = []
769
        plist.extend(pset)
770
        plist.sort()
771
 
772
        for comptxt in plist:
773
            node = self.get_node_component_desc(comptxt)
774
            pid = self.model.append(None, node)
775
            treepids[comptxt] = pid
776
 
777
        for sid in sapnotes:
778
            comptxt = escape(sapnotes[sid]['componenttxt'])
779
            pid = treepids[comptxt]
780
            sapnote = self.get_node_sapnote_component_desc(sapnotes[sid], sid)
781
            self.model.append(pid, sapnote)
782
 
783
 
784
    def populate_by_category(self, sapnotes):
785
        self.model.clear()
786
        treepids = {}
787
        icon_nocat = self.im.get_icon('notask')
788
        icon_cat = self.im.get_icon('category')
789
        icon_sapnote = self.im.get_icon('fingerprint')
790
        icon_bookmark = self.im.get_icon('bookmark')
791
        self.column_component.set_title('Categories')
792
        #~ self.column_icon.set_visible(False)
793
        #~ self.column_sid.set_visible(True)
794
        self.set_headers_visible(True)
795
        self.column_sid.set_visible(True)
796
        self.column_icon.set_visible(True)
797
        self.column_component.set_visible(True)
798
        self.column_component.set_expand(True)
799
        self.column_title.set_visible(False)
800
        self.column_title.set_expand(True)
801
        self.column_priority.set_expand(False)
802
        self.column_cat.set_visible(False)
803
        self.column_sid.set_expand(False)
804
 
805
        if len(sapnotes) == 0:
806
            return
807
 
808
        scomp = set()
809
        dcomp = {}
810
        catset = set()
811
 
812
        for sid in sapnotes:
813
            try:
814
                cat = sapnotes[sid]['category']
815
                catset.add(cat)
816
            except: pass
817
 
818
        catlist = []
819
        catlist.extend(catset)
820
        catlist.sort()
821
 
822
        for cat in catlist:
823
            node = self.get_node_category_view(cat)
824
            pid = self.model.append(None, node)
825
            treepids[cat] = pid
826
 
827
        for sid in sapnotes:
828
            category = sapnotes[sid]['category']
829
            pid = treepids[category]
830
            sapnote = self.get_node_sapnote_category(sapnotes[sid], sid)
831
            self.model.append(pid, sapnote)
832
 
833
 
834
    def populate_by_chronologic(self, sapnotes):
835
        self.model.clear()
836
        treepids = {}
837
 
838
        self.column_component.set_title('Download date')
839
        self.set_headers_visible(True)
840
        self.column_sid.set_visible(True)
841
        self.column_icon.set_visible(True)
842
        self.column_component.set_visible(True)
843
        self.column_component.set_expand(True)
844
        self.column_title.set_visible(False)
845
        self.column_title.set_expand(True)
846
        self.column_priority.set_expand(False)
847
        self.column_cat.set_visible(False)
848
        self.column_sid.set_expand(False)
849
 
850
        if len(sapnotes) == 0:
851
            return
852
 
853
        years = set()
854
        months = set()
855
        days = set()
856
        for sid in sapnotes:
857
            try:
858
                downloaded = dateparser.parse(sapnotes[sid]['feedupdate'])
859
                year = "%d" % downloaded.year
860
                month = "%02d" % downloaded.month
861
                day = "%02d" % downloaded.day
862
                key_year    = year
863
                key_month   = year + month
864
                key_day     = year + month + day
865
                years.add(key_year)
866
                months.add(key_month)
867
                days.add(key_day)
868
            except:
869
                pass
870
        years = list(years)
871
        years.sort(reverse=True)
872
        months = list(months)
873
        months.sort(reverse=True)
874
        days = list(days)
875
        days.sort(reverse=True)
876
 
877
        for key_year in years:
878
            try:
879
                treepids[key_year]
880
            except:
881
                adate = key_year + '0101'
882
                downloaded = dateparser.parse(adate)
883
                node = self.get_node_date_year(downloaded, key_year)
884
                treepids[key_year] = self.model.append(None, node)
885
 
886
        for key_month in months:
887
            try:
888
                treepids[key_month]
889
            except:
890
                adate = key_month + '01'
891
                downloaded = dateparser.parse(adate)
892
                node = self.get_node_date_month(downloaded, key_month)
893
                key_year = key_month[0:4]
894
                treepids[key_month] = self.model.append(treepids[key_year], node)
895
 
896
        for key_day in days:
897
            try:
898
                treepids[key_day]
899
            except:
900
                downloaded = dateparser.parse(key_day)
901
                key_month = key_day[0:6]
902
                node = self.get_node_date_day(downloaded, key_day)
903
                treepids[key_day] = self.model.append(treepids[key_month], node)
904
 
905
        for sid in sapnotes:
906
            downloaded = dateparser.parse(sapnotes[sid]['feedupdate'])
907
            year = "%d" % downloaded.year
908
            month = "%02d" % downloaded.month
909
            day = "%02d" % downloaded.day
910
            key_year    = year
911
            key_month   = year + month
912
            key_day     = year + month + day
913
            node = self.get_node_sapnote_chronologic(sapnotes[sid], sid)
914
            #~ self.log.debug("KeyDay %s for SAP Note %s" % (treepids[key_day], sid))
915
            self.model.append(treepids[key_day], node)
916
 
917
        self.collapse_all()
918
        self.expand_all()
919
 
920
 
921
 
922
 
4 t00mlabs 923
    def get_node_component(self, compkey, comptxt):
924
        #~ compkey = escape(sapnote['componentkey'])
925
        #~ comptxt = escape(sapnote['componenttxt'])
74 t00mlabs 926
        icon = self.im.get_icon('component', 32, 32)
4 t00mlabs 927
        node = []
74 t00mlabs 928
        if len(comptxt) > 0:
929
            component = "<big><b>%s</b></big> (<i>%s</i>)" % (compkey, comptxt) # component
930
        else:
931
            component = "<big><b>%s</b></big>" % compkey
932
 
4 t00mlabs 933
        #~ component = "<big><b>%s</b></big>" % (compkey)
934
        #~ component = "<span size='18000'><b>%s</b></span> <span size='12000'>(<i>%s</i>)</span>" % (compkey, comptxt)
74 t00mlabs 935
        node.append('component@%s' % compkey)
4 t00mlabs 936
        node.append(0)
937
        node.append(icon)
938
        node.append(component) # Component
939
        node.append("") # Category
940
        node.append("") # Type
74 t00mlabs 941
        node.append("") # Id
4 t00mlabs 942
        node.append("") # Title
943
        node.append("") # Priority
944
        node.append("") # Lang
945
        #~ node.append("") # Version
946
        node.append("") # Release on
947
        return node
948
 
949
 
950
    def get_node_category(self, sapnote):
951
        compkey = escape(sapnote['componentkey'])
952
        catname = escape(sapnote['category'])
953
        catkey = compkey + '-' + catname
74 t00mlabs 954
        icon = self.im.get_icon('category', 32, 32)
4 t00mlabs 955
 
956
        if len(catname) == 0:
957
            #~ catname = "<span size='12000'><b>No category assigned</b></span>"
74 t00mlabs 958
            catname = "\t<b>No category assigned</b>"
4 t00mlabs 959
        else:
960
            #~ category = "<span size='15000'><b>%s</b></span>" % catname
74 t00mlabs 961
            category = "\t<b>%s</b>" % catname
4 t00mlabs 962
 
963
        node = []
74 t00mlabs 964
        node.append('category@%s' % catname)
4 t00mlabs 965
        node.append(0)
966
        node.append(icon)
967
        node.append(category) # Component
968
        node.append("") # Category
969
        node.append("") # Type
970
        node.append("") # Id
971
        node.append("") # Title
972
        node.append("") # Priority
973
        node.append("") # Lang
974
        #~ node.append("") # Version
975
        node.append("") # Release on
976
        return node
977
 
978
 
74 t00mlabs 979
    def get_node_date_year(self, date, token_date):
980
        title = "<span size='12000'><b>%s</b></span>" % token_date
981
 
982
        node = []
983
        node.append('date-year@%s' % token_date)
984
        node.append(0)
985
        node.append(None)
986
        node.append(title) # Component
987
        node.append("") # Category
988
        node.append("") # Type
989
        node.append("") # Id
990
        node.append("") # Title
991
        node.append("") # Priority
992
        node.append("") # Lang
993
        #~ node.append("") # Version
994
        node.append("") # Release on
995
        return node
996
 
997
 
998
    def get_node_date_month(self, date, token_date):
999
        title = "<span size='12000'><b>%s</b></span>" % date.strftime("%B")
1000
 
1001
        node = []
1002
        node.append('date-month@%s' % token_date)
1003
        node.append(0)
1004
        node.append(None)
1005
        node.append(title) # Component
1006
        node.append("") # Category
1007
        node.append("") # Type
1008
        node.append("") # Id
1009
        node.append("") # Title
1010
        node.append("") # Priority
1011
        node.append("") # Lang
1012
        #~ node.append("") # Version
1013
        node.append("") # Release on
1014
        return node
1015
 
1016
 
1017
    def get_node_date_day(self, date, token_date):
1018
        title = "<span size='12000'><b>%s</b></span>" % date.strftime("%d - %A")
1019
 
1020
        node = []
1021
        node.append('date-day@%s' % token_date)
1022
        node.append(0)
1023
        node.append(None)
1024
        node.append(title) # Component
1025
        node.append("") # Category
1026
        node.append("") # Type
1027
        node.append("") # Id
1028
        node.append("") # Title
1029
        node.append("") # Priority
1030
        node.append("") # Lang
1031
        #~ node.append("") # Version
1032
        node.append("") # Release on
1033
        return node
1034
 
1035
 
1036
    def get_node_priority(self, priority):
1037
        icon = None # self.im.get_icon('category', 32, 32)
1038
 
1039
        if len(priority) == 0:
1040
            title = "<big><b>No priority assigned</b></big>"
1041
        else:
1042
            title = "<big><b>%s</b></big>" % priority
1043
 
1044
        node = []
1045
        node.append('priority@%s' % priority)
1046
        node.append(0)
1047
        node.append(icon)
1048
        node.append(title) # Component # Category title
1049
        node.append("") # Category
1050
        node.append("") # Type
1051
        node.append("") # Id
1052
        node.append("") # Title
1053
        node.append("") # Priority
1054
        node.append("") # Lang
1055
        #~ node.append("") # Version
1056
        node.append("") # Release on
1057
        return node
1058
 
1059
 
1060
    def get_node_type(self, sntype):
1061
        icon = self.im.get_icon('type', 32, 32)
1062
 
1063
        if len(sntype) == 0:
1064
            title = "<big><b>SAP Note type not found</b></big>"
1065
        else:
1066
            title = "<big><b>%s</b></big>" % sntype
1067
 
1068
        node = []
1069
        node.append('sntype@%s' % sntype)
1070
        node.append(0)
1071
        node.append(icon)
1072
        node.append(title) # Component # Category title
1073
        node.append("") # Category
1074
        node.append("") # Type
1075
        node.append("") # Id
1076
        node.append("") # Title
1077
        node.append("") # Priority
1078
        node.append("") # Lang
1079
        #~ node.append("") # Version
1080
        node.append("") # Release on
1081
        return node
1082
 
1083
 
1084
 
1085
    def get_node_component_desc(self, comptxt):
1086
        icon = self.im.get_icon('component', 32, 32)
1087
 
1088
        if len(comptxt) == 0:
1089
            title = "<big><b>No component assigned</b></big>"
1090
        else:
1091
            title = "<big><b>%s</b></big>" % comptxt
1092
 
1093
        node = []
1094
        node.append('component-desc@%s' % comptxt)
1095
        node.append(0)
1096
        node.append(icon)
1097
        node.append(title) # Component # Category title
1098
        node.append("") # Category
1099
        node.append("") # Type
1100
        node.append("") # Id
1101
        node.append("") # Title
1102
        node.append("") # Priority
1103
        node.append("") # Lang
1104
        #~ node.append("") # Version
1105
        node.append("") # Release on
1106
        return node
1107
 
1108
 
1109
    def get_node_category_view(self, category=''):
1110
        #~ compkey = escape(sapnote['componentkey'])
1111
        #~ catname = escape(sapnote['category'])
1112
        #~ catkey = compkey + '-' + catname
1113
        icon = None # self.im.get_icon('category', 32, 32)
1114
 
1115
        if len(category) == 0:
1116
            #~ catname = "<span size='12000'><b>No category assigned</b></span>"
1117
            catname = "<big><b>No category assigned</b></big>"
1118
        else:
1119
            #~ category = "<span size='15000'><b>%s</b></span>" % catname
1120
            catname = "<big><b>%s</b></big>" % category
1121
 
1122
        node = []
1123
        node.append('category@%s' % category)
1124
        node.append(0)
1125
        node.append(icon)
1126
        node.append(catname) # Component # Category title
1127
        node.append("") # Category
1128
        node.append("") # Type
1129
        node.append("") # Id
1130
        node.append("") # Title
1131
        node.append("") # Priority
1132
        node.append("") # Lang
1133
        #~ node.append("") # Version
1134
        node.append("") # Release on
1135
        return node
1136
 
1137
 
1138
    def get_node_sapnote_bookmark(self, sapnote, sid):
4 t00mlabs 1139
        compkey = escape(sapnote['componentkey'])
74 t00mlabs 1140
        icon_note = self.im.get_pixbuf_icon('fingerprint')
4 t00mlabs 1141
        icon_fav = self.im.get_icon('bookmark')
1142
        compkey = escape(sapnote['componentkey'])
1143
        compkey = escape(sapnote['componentkey'])
1144
        catname = escape(sapnote['category'])
74 t00mlabs 1145
        priority = "%s" % escape(sapnote['priority'])
1146
        released = dateparser.parse(sapnote['releaseon'])
1147
        released = released.strftime("%Y.%m.%d")
1148
        sid = "0"*(10 - len(sid)) + sid
1149
        title = "<big>%s</big>" % (escape(sapnote['title']))
4 t00mlabs 1150
 
74 t00mlabs 1151
        # Create row-node
1152
        node = []
1153
        node.append('sapnote@%s' % sid)     # 0. # RowType
1154
        node.append(0)                      # 1. # CheckBox
1155
        node.append(icon_fav)               # 2. # Icon
1156
        node.append("%s" % compkey)         # 3. # Component
1157
        node.append("%s" % catname)         # 4. # Category
1158
        node.append(sapnote['type'])        # 5. # Type
1159
        node.append("<b>%s</b>" %sid)       # 6. # Sap Note ID
1160
        node.append(title)                  # 7. # Title
1161
        node.append(priority)               # 8. # Priority
1162
        node.append(sapnote['language'])    # 9. # Lang
1163
        node.append(released)               # 10. # Release date
1164
 
1165
        return node
1166
 
1167
 
1168
    def get_node_sapnote_task(self, sapnote, sid):
1169
        compkey = escape(sapnote['componentkey'])
1170
        compkey = escape(sapnote['componentkey'])
1171
        catname = escape(sapnote['category'])
1172
        priority = "%s" % escape(sapnote['priority'])
1173
        released = dateparser.parse(sapnote['releaseon'])
1174
        released = released.strftime("%Y.%m.%d")
1175
        sid = "0"*(10 - len(sid)) + sid
1176
        title = "<big>%s</big>" % (escape(sapnote['title']))
1177
        bookmarked = sapnote['bookmark']
1178
 
1179
        if bookmarked:
1180
            icon = self.im.get_icon('bookmark', 32, 32)
1181
        else:
1182
            icon = self.im.get_icon('fingerprint', 32, 32)
1183
 
1184
        # Create row-node
1185
        node = []
1186
        node.append('sapnote@%s' % sid)     # 0. # RowType
1187
        node.append(0)                      # 1. # CheckBox
1188
        node.append(icon)                   # 2. # Icon
1189
        node.append(title)                  # 3. # Component
1190
        node.append("")                     # 4. # Category
1191
        node.append(sapnote['type'])        # 5. # Type
1192
        node.append("<b>%s</b>" %sid)       # 6. # Sap Note ID
1193
        node.append("")                     # 7. # Title
1194
        node.append(priority)               # 8. # Priority
1195
        node.append(sapnote['language'])    # 9. # Lang
1196
        node.append(released)               # 10. # Release date
1197
 
1198
        return node
1199
 
1200
 
1201
    def get_node_sapnote_type(self, sapnote, sid):
1202
        #~ compkey = escape(sapnote['componentkey'])
1203
        #~ compkey = escape(sapnote['componentkey'])
1204
        #~ catname = escape(sapnote['category'])
1205
        sntype = "%s" % escape(sapnote['type'])
1206
        #~ released = dateparser.parse(sapnote['releaseon'])
1207
        #~ released = released.strftime("%Y.%m.%d")
1208
        sid = "0"*(10 - len(sid)) + sid
1209
        title = "<big>%s</big>" % (escape(sapnote['title']))
1210
        bookmarked = sapnote['bookmark']
1211
 
1212
        if bookmarked:
1213
            icon = self.im.get_icon('bookmark', 32, 32)
1214
        else:
1215
            icon = self.im.get_icon('fingerprint', 32, 32)
1216
 
1217
        # Create row-node
1218
        node = []
1219
        node.append('sapnote@%s' % sid)     # 0. # RowType
1220
        node.append(0)                      # 1. # CheckBox
1221
        node.append(icon)                   # 2. # Icon
1222
        node.append(title)                  # 3. # Component
1223
        node.append("")                     # 4. # Category
1224
        node.append(sapnote['type'])        # 5. # Type
1225
        node.append("<b>%s</b>" %sid)       # 6. # Sap Note ID
1226
        node.append("")                     # 7. # Title
1227
        node.append("")                     # 8. # Priority
1228
        node.append(sapnote['language'])    # 9. # Lang
1229
        node.append("")                     # 10. # Release date
1230
 
1231
        return node
1232
 
1233
 
1234
    def get_node_sapnote_component_desc(self, sapnote, sid):
1235
        compkey = escape(sapnote['componentkey'])
1236
        compkey = escape(sapnote['componentkey'])
1237
        catname = escape(sapnote['category'])
1238
        priority = "%s" % escape(sapnote['priority'])
1239
        released = dateparser.parse(sapnote['releaseon'])
1240
        released = released.strftime("%Y.%m.%d")
1241
        sid = "0"*(10 - len(sid)) + sid
1242
        title = "<big>%s</big>" % (escape(sapnote['title']))
1243
        bookmarked = sapnote['bookmark']
1244
 
1245
        if bookmarked:
1246
            icon = self.im.get_icon('bookmark', 32, 32)
1247
        else:
1248
            icon = self.im.get_icon('fingerprint', 32, 32)
1249
 
1250
        # Create row-node
1251
        node = []
1252
        node.append('sapnote@%s' % sid)     # 0. # RowType
1253
        node.append(0)                      # 1. # CheckBox
1254
        node.append(icon)                   # 2. # Icon
1255
        node.append(title)                  # 3. # Component
1256
        node.append("")                     # 4. # Category
1257
        node.append(sapnote['type'])        # 5. # Type
1258
        node.append("<b>%s</b>" %sid)       # 6. # Sap Note ID
1259
        node.append("")                     # 7. # Title
1260
        node.append(priority)               # 8. # Priority
1261
        node.append(sapnote['language'])    # 9. # Lang
1262
        node.append(released)               # 10. # Release date
1263
 
1264
        return node
1265
 
1266
 
1267
    def get_node_sapnote_category(self, sapnote, sid):
1268
        compkey = escape(sapnote['componentkey'])
1269
        compkey = escape(sapnote['componentkey'])
1270
        catname = escape(sapnote['category'])
1271
        priority = "%s" % escape(sapnote['priority'])
1272
        released = dateparser.parse(sapnote['releaseon'])
1273
        released = released.strftime("%Y.%m.%d")
1274
        sid = "0"*(10 - len(sid)) + sid
1275
        title = "<big>%s</big>" % (escape(sapnote['title']))
1276
        bookmarked = sapnote['bookmark']
1277
 
1278
        if bookmarked:
1279
            icon = self.im.get_icon('bookmark', 32, 32)
1280
        else:
1281
            icon = self.im.get_icon('fingerprint', 32, 32)
1282
 
1283
        # Create row-node
1284
        node = []
1285
        node.append('sapnote@%s' % sid)     # 0. # RowType
1286
        node.append(0)                      # 1. # CheckBox
1287
        node.append(icon)                   # 2. # Icon
1288
        node.append(title)                  # 3. # Component
1289
        node.append("")                     # 4. # Category
1290
        node.append(sapnote['type'])        # 5. # Type
1291
        node.append("<b>%s</b>" %sid)       # 6. # Sap Note ID
1292
        node.append("")                     # 7. # Title
1293
        node.append(priority)               # 8. # Priority
1294
        node.append(sapnote['language'])    # 9. # Lang
1295
        node.append(released)               # 10. # Release date
1296
 
1297
        return node
1298
 
1299
 
1300
    def get_node_sapnote_chronologic(self, sapnote, sid):
1301
        compkey = escape(sapnote['componentkey'])
1302
        compkey = escape(sapnote['componentkey'])
1303
        catname = escape(sapnote['category'])
1304
        priority = "%s" % escape(sapnote['priority'])
1305
        released = dateparser.parse(sapnote['releaseon'])
1306
        released = released.strftime("%Y.%m.%d")
1307
        sid = "0"*(10 - len(sid)) + sid
1308
        title = "<big>%s</big>" % (escape(sapnote['title']))
1309
        bookmarked = sapnote['bookmark']
1310
 
1311
        if bookmarked:
1312
            icon = self.im.get_icon('bookmark', 32, 32)
1313
        else:
1314
            icon = self.im.get_icon('fingerprint', 32, 32)
1315
 
1316
        # Create row-node
1317
        node = []
1318
        node.append('sapnote@%s' % sid)     # 0. # RowType
1319
        node.append(0)                      # 1. # CheckBox
1320
        node.append(icon)                   # 2. # Icon
1321
        node.append(title)                  # 3. # Component
1322
        node.append("")                     # 4. # Category
1323
        node.append(sapnote['type'])        # 5. # Type
1324
        node.append("<b>%s</b>" %sid)       # 6. # Sap Note ID
1325
        node.append("")                     # 7. # Title
1326
        node.append(priority)               # 8. # Priority
1327
        node.append(sapnote['language'])    # 9. # Lang
1328
        node.append(released)               # 10. # Release date
1329
 
1330
        return node
1331
 
1332
 
1333
 
1334
    def get_node_sapnote(self, sapnote, sid):
1335
        compkey = escape(sapnote['componentkey'])
1336
        icon_note = self.im.get_icon('fingerprint', 32, 32)
1337
        icon_fav = self.im.get_icon('bookmark', 32, 32)
1338
        compkey = escape(sapnote['componentkey'])
1339
        compkey = escape(sapnote['componentkey'])
1340
        catname = escape(sapnote['category'])
1341
        sid = "0"*(10 - len(sid)) + sid
1342
 
4 t00mlabs 1343
        # Get bookmark
1344
        try:
1345
            bookmark = sapnote['bookmark']
1346
        except Exception as error:
1347
            bookmark = False
1348
 
1349
        # Get correct title
74 t00mlabs 1350
        title = "%s" % (escape(sapnote['title']))
4 t00mlabs 1351
 
74 t00mlabs 1352
        # Create row-node
4 t00mlabs 1353
        node = []
74 t00mlabs 1354
        node.append('sapnote@%s' % sid) # 0. # RowType
1355
        node.append(0) # 1. # CheckBox
4 t00mlabs 1356
 
1357
        # 2. # Icon
1358
        if bookmark:
1359
            node.append(icon_fav)
1360
        else:
1361
            node.append(icon_note)
1362
 
1363
        # 3. # Component
1364
        if self.view == 'components':
1365
            node.append(title)
1366
            # 4. # Category
1367
            node.append("")
1368
        elif self.view == 'bookmarks':
74 t00mlabs 1369
            node.append("%s" % compkey)
4 t00mlabs 1370
            # 4. # Category
1371
            node.append("%s" % catname)
1372
            #~ node.append(catname)
74 t00mlabs 1373
        elif self.view == 'tasks':
1374
            node.append("%s" % compkey)
1375
            # 4. # Category
1376
            node.append("%s" % catname)
1377
            #~ node.append(catname)
1378
        elif self.view == 'chronologic':
1379
            node.append("")
1380
            # 4. # Category
1381
            node.append("")
1382
            #~ node.append(catname)
1383
        elif self.view == 'category':
1384
            node.append("")
1385
            # 4. # Category
1386
            node.append("")
1387
            #~ node.append(catname)
1388
        elif self.view == 'description':
1389
            node.append("")
1390
            # 4. # Category
1391
            node.append("")
1392
            #~ node.append(catname)
4 t00mlabs 1393
        else:
1394
            node.append(title)
1395
            # 4. # Category
1396
            node.append("")
1397
 
74 t00mlabs 1398
        node.append(sapnote['type'])  # 5. # Type
1399
        node.append("<b>%s</b>" %sid) # 6. # Sap Note ID
4 t00mlabs 1400
 
1401
        # 7. # Title
1402
        if self.view == 'bookmarks':
1403
            node.append(title)
74 t00mlabs 1404
        elif self.view == 'tasks':
1405
            node.append(title)
1406
        elif self.view == 'chronologic':
1407
            node.append(title)
1408
        elif self.view == 'category':
1409
            node.append(title)
1410
        elif self.view == 'description':
1411
            node.append(title)
4 t00mlabs 1412
        else:
1413
            node.append("")
1414
 
1415
        # 8. # Priority
1416
        priority = "%s" % escape(sapnote['priority'])
1417
        node.append(priority)
1418
 
1419
        # 9. # Lang
1420
        node.append(sapnote['language'])
1421
 
1422
        # 10. # Release date
1423
        released = dateparser.parse(sapnote['releaseon'])
1424
        node.append(released.strftime("%Y.%m.%d"))
1425
 
1426
        return node
1427
 
1428
 
1429
    def populate_by_components(self, sapnotes, only_bookmarks=False):
74 t00mlabs 1430
        self.log.debug('Populating by components')
4 t00mlabs 1431
        self.model.clear()
1432
        self.treepids = {}
1433
        self.column_component.set_title('Components')
74 t00mlabs 1434
        self.column_icon.set_visible(True)
1435
        self.column_component.set_visible(True)
1436
        self.column_component.set_expand(True)
4 t00mlabs 1437
        self.column_title.set_visible(False)
74 t00mlabs 1438
        self.column_sid.set_visible(True)
1439
        #~ self.column_title.set_visible(True)
1440
        self.set_headers_visible(True)
1441
        #~ self.set_grid_lines(Gtk.TreeViewGridLines.VERTICAL)
4 t00mlabs 1442
 
74 t00mlabs 1443
        #~ self.column_title
4 t00mlabs 1444
 
1445
        if len(sapnotes) == 0:
1446
            return
1447
 
1448
        scomp = set()
1449
        dcomp = {}
1450
 
1451
        for sid in sapnotes:
1452
            compkey = escape(sapnotes[sid]['componentkey'])
1453
            comptxt = escape(sapnotes[sid]['componenttxt'])
1454
            scomp.add(compkey)
1455
            dcomp[compkey] = comptxt
1456
        lcomp = list(scomp)
1457
        lcomp.sort()
1458
 
1459
        for compkey in lcomp:
74 t00mlabs 1460
            #~ print (compkey)
1461
            subkeys = compkey.split('-')
1462
            ppid = None
1463
            for i in range(1, len(subkeys)+1):
1464
                key = ('-').join(subkeys[0:i])
1465
                try:
1466
                    ppid = self.treepids[key]
1467
                    #~ print ("\tSubkey found: %s" % key)
1468
                except:
1469
                    if i == len(subkeys):
1470
                        title = dcomp[compkey]
1471
                    else:
1472
                        title = ""
1473
                        #~ title = key[key.rfind('-')+1:]
1474
                    node = self.get_node_component(key, title)
1475
                    ppid = self.model.append(ppid, node)
1476
                    self.treepids[key] = ppid
1477
                    #~ print ("\tSubkey added: %s" % key)
4 t00mlabs 1478
 
74 t00mlabs 1479
 
4 t00mlabs 1480
        for sid in sapnotes:
1481
            #~ Gety component
1482
            compkey = escape(sapnotes[sid]['componentkey'])
1483
            pid = self.treepids[compkey]
1484
 
1485
            #~ Get category
1486
            catname = escape(sapnotes[sid]['category'])
1487
            catkey = compkey + '-' + catname
1488
            try:
1489
                cid = self.treepids[catkey]
1490
            except:
1491
                node = self.get_node_category(sapnotes[sid])
1492
                cid = self.model.append(pid, node)
1493
                self.treepids[catkey] = cid
1494
 
1495
            #~ Get SAP Note
1496
            if only_bookmarks:
1497
                try:
1498
                    bookmark = sapnotes[sid]['bookmark'] # True or False
1499
                except:
1500
                    bookmark = False
74 t00mlabs 1501
 
4 t00mlabs 1502
                if bookmark:
1503
                    node = self.get_node_sapnote(sapnotes[sid], sid)
1504
                    self.model.append(cid, node)
1505
            else:
1506
                node = self.get_node_sapnote(sapnotes[sid], sid)
1507
                self.model.append(cid, node)
1508
 
1509
 
1510
    def changed(self, *args):
1511
        try:
1512
            model, treeiters = self.selection.get_selected_rows()
1513
            selected = set()
1514
            if len(treeiters) > 0:
1515
                for treeiter in treeiters:
1516
                    if treeiter != None:
1517
                        selected.add(model[treeiter][0])
1518
        except Exception as error:
1519
            self.log.error (self.get_traceback())
1520
 
1521
 
1522
    def on_cell_toggled(self, widget, path):
1523
        model = self.get_model()
1524
        rtype = model[path][0]
74 t00mlabs 1525
 
4 t00mlabs 1526
        if rtype != 'component' and rtype != 'category':
1527
            model[path][1] = not model[path][1]
1528
            self.count = 0
1529
            self.check_states()
1530
 
74 t00mlabs 1531
        self.cb.check_task_link_button_status()
1532
        #FIXME:
1533
        #(basico:10248): Gtk-WARNING **: Failed to set text from markup
1534
        # due to error parsing markup: Error en la lÝnea 1: La entidad
1535
        # no termina con un punto y coma; probablemente utiliz¾ el
1536
        # carßcter "&" sin la intenci¾n de indicar una entidad, escape
1537
        #el signo "&" como &amp;
4 t00mlabs 1538
 
74 t00mlabs 1539
 
4 t00mlabs 1540
    def check_states(self):
1541
        lblSelectedNotes = self.gui.get_widget('lblSelectedNotes')
1542
        self.selected = set()
1543
 
1544
        def traverse_treeview(model, path, iter, user_data=None):
74 t00mlabs 1545
            row = model.get_value(iter, 0)
1546
            row_type, key = row.split('@')
1547
            if row_type == 'component':
4 t00mlabs 1548
                # select everything (categories and notes)
74 t00mlabs 1549
                #~ component = rtype = model.get_value(iter, 3)
1550
                #~ ce = component.find('</b></big>')
1551
                compkey = key #component[8:ce]
1552
            elif row_type == 'category':
4 t00mlabs 1553
                # select all notes under that category
74 t00mlabs 1554
                #~ category = rtype = model.get_value(iter, 3)
1555
                #~ ce = category.find("</b></big>")
1556
                catkey = key # category[9:ce]
4 t00mlabs 1557
 
1558
            toggled = model.get_value(iter, 1)
1559
            if toggled:
1560
                self.count += 1
74 t00mlabs 1561
                #~ title = model.get_value(iter, 3)
1562
                #~ tid = model.get_value(iter, 6)
1563
                #~ sid = BSHTML(tid, "lxml").text
1564
                self.selected.add(key)
4 t00mlabs 1565
            return False
1566
 
1567
        model = self.get_model()
1568
        model.foreach(traverse_treeview)
74 t00mlabs 1569
        lblSelectedNotes.set_markup('<big>%d of %d\nSAP Notes selected</big>' % (len(self.selected), self.db.get_total()))
4 t00mlabs 1570
        actions = self.gui.get_widget('mnuBtnActions')
1571
        if (len(self.selected)) > 0:
1572
            actions.set_sensitive(True)
1573
            self.cb.setup_menu_actions()
1574
        else:
1575
            actions.set_sensitive(False)
1576
 
74 t00mlabs 1577
        self.cb.setup_menu_import()
4 t00mlabs 1578
 
74 t00mlabs 1579
 
4 t00mlabs 1580
    def set_select_notes(self, sapnotes):
1581
        self.selected = set()
1582
        for sapnote in sapnotes:
1583
            self.selected.add(sapnote)
1584
 
1585
 
1586
    def get_selected_notes(self):
74 t00mlabs 1587
        bag = list(self.selected)
1588
        bag.sort()
1589
        self.log.debug("Selected SAP Notes: %s" % ', '.join(bag))
1590
        return bag
4 t00mlabs 1591
 
1592
 
1593
    def get_view(self):
1594
        if self.view is None:
1595
            return 'components'
1596
 
1597
        return self.view
1598
 
1599
 
1600
    def set_view(self, view):
1601
        settings = self.app.get_service('Settings')
1602
 
1603
        if view is None:
1604
            view = settings.get_config_value('View')
1605
 
1606
        # Save view to settings
1607
        if view not in ['settings', 'download']:
1608
            self.view = view
1609
            settings = self.app.get_service('Settings')
1610
            settings.set_config_value('View', view)
1611
 
1612
        # Change icon
1613
        iconview = self.gui.get_widget('imgViewCurrent')
1614
        if view == 'settings':
1615
            iconname = 'gtk-preferences'
1616
        elif view == 'download':
1617
            iconname = 'download'
1618
        else:
1619
            iconname = view
1620
 
1621
        icon = self.im.get_pixbuf_icon(iconname, 48, 48)
1622
        iconview.set_from_pixbuf(icon)
1623
 
1624
        # Change label
1625
        viewlabel = self.gui.get_widget('lblViewCurrent')
1626
        name = "<span size='20000'><b>%-10s</b></span>" % view.capitalize()
1627
        viewlabel.set_markup(name)
1628
 
1629
 
1630
 
1631
    def expand(self):
1632
        switch = self.gui.get_widget('schExpandCollapse')
1633
        switch.set_active(True)
1634
 
1635
    def collapse(self):
1636
        switch = self.gui.get_widget('schExpandCollapse')
1637
        switch.set_active(False)
1638
 
1639
    def expand_collapse(self, switch, active):
1640
        if active:
1641
            self.expand_all()
1642
        else:
1643
            self.collapse_all()
1644
 
1645
 
1646
    def select_all_none(self, switch, active):
1647
        model = self.get_model()
1648
 
1649
        def traverse_treeview(model, path, iter, user_data=None):
74 t00mlabs 1650
            row = model.get_value(iter, 0)
1651
            row_type, sid = row.split('@')
1652
            if row_type == 'sapnote':
4 t00mlabs 1653
                model.set_value(iter, 1, active)
1654
 
1655
            return False
1656
 
1657
        model.foreach(traverse_treeview, active)
1658
        self.check_states()
1659
 
1660
 
1661
    def select_by_component(self, component_target, active):
1662
        model = self.get_model()
74 t00mlabs 1663
        #~ self.log.debug("Component target: %s" % component_target)
4 t00mlabs 1664
 
1665
        def traverse_treeview(model, path, iter, user_data=None):
74 t00mlabs 1666
            row = model.get_value(iter, 0)
1667
            row_type, sid = row.split('@')
1668
            if row_type == 'sapnote':
1669
                tid = model.get_value(iter, 6)
1670
                sid = "0"*(10 - len(tid)) + tid
1671
                self.log.debug(sid)
1672
                sapnote = self.db.get_sapnote_metadata(sid)
4 t00mlabs 1673
                component_source = sapnote['componentkey']
74 t00mlabs 1674
                #~ self.log.debug("Component source: %s - Component target: %s" % (component_source, component_target))
4 t00mlabs 1675
                if component_source == component_target:
1676
                    model.set_value(iter, 1, active)
1677
 
1678
            return False
1679
 
1680
        model.foreach(traverse_treeview, True)
1681
        self.check_states()
1682
 
1683
 
1684
    def select_by_task(self, task_target, active):
1685
        model = self.get_model()
1686
 
1687
        def traverse_treeview(model, path, iter, user_data=None):
74 t00mlabs 1688
            row = model.get_value(iter, 0)
1689
            row_type, sid = row.split('@')
1690
            if row_type == 'sapnote':
4 t00mlabs 1691
                sid = model.get_value(iter, 6)
74 t00mlabs 1692
                sapnote = self.db.get_sapnote_metadata(sid)
4 t00mlabs 1693
                tasks_source = sapnote['tasks']
1694
 
1695
                if task_target in tasks_source:
1696
                    model.set_value(iter, 1, active)
1697
                else:
1698
                    if len(task_target) == 0 and len(tasks_source) == 0:
1699
                        model.set_value(iter, 1, active)
1700
 
1701
            return False
1702
 
1703
        model.foreach(traverse_treeview, True)
1704
        self.check_states()