Subversion Repositories basico

Rev

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

Rev Author Line No. Line
113 t00mlabs 1
#!/usr/bin/python
2
# -*- coding: utf-8 -*-
3
# File: sapnoteviewvisor.py
4
# Author: Tomás Vírseda
5
# License: GPL v3
133 t00mlabs 6
# Description: SAPNoteViewVisor widget
113 t00mlabs 7
 
217 t00m 8
import os
207 t00m 9
from os.path import sep as SEP
113 t00mlabs 10
from cgi import escape
207 t00m 11
import glob
12
import json
113 t00mlabs 13
 
14
import gi
15
gi.require_version('Gdk', '3.0')
16
gi.require_version('Gtk', '3.0')
17
from gi.repository import Gdk
18
from gi.repository import Gio
19
from gi.repository import Gtk
197 t00m 20
from gi.repository.GdkPixbuf import Pixbuf
113 t00mlabs 21
from gi.repository import Pango
22
 
207 t00m 23
from .env import LPATH
141 t00mlabs 24
from .service import Service
232 t00m 25
from .widgets.collections import CollectionsMgtView
26
from .widgets.annotation import AnnotationWidget
27
from .widgets.importwdg import ImportWidget
113 t00mlabs 28
 
156 t00m 29
class SAPNoteViewVisorToolbar(Gtk.HBox, Service):
30
    def __init__(self, app):
31
        Gtk.Box.__init__(self, app)
32
        self.app = app
33
        self.get_services()
34
        self.set_homogeneous(False)
35
        self.tool_bar = Gtk.Toolbar()
36
        self.pack_start(self.tool_bar, False, True, 0)
37
        self.tool_bar.get_style_context().add_class(Gtk.STYLE_CLASS_PRIMARY_TOOLBAR)
203 t00m 38
        self.tool_bar.set_property('margin-bottom', 0)
113 t00mlabs 39
 
203 t00m 40
        # Toggle Views button
213 t00m 41
        tool = self.gui.add_widget('gtk_toogletoolbutton_menu_view', Gtk.ToggleToolButton.new())
203 t00m 42
        tool.set_icon_name('gtk-select-color')
43
        tool.connect('toggled', self.cb.gui_toggle_menu_view)
44
        tool.set_active(False)
45
        tool.set_hexpand(False)
46
        self.tool_bar.insert(tool, -1)
47
 
48
        # View combobox button/popover
49
        tool = Gtk.ToolItem.new()
50
        lhbox = Gtk.HBox()
213 t00m 51
        menuviews = self.gui.add_widget('gtk_button_menu_views', Gtk.Button())
203 t00m 52
        hbox = Gtk.HBox()
213 t00m 53
        label = self.gui.add_widget('gtk_label_current_view', Gtk.Label())
203 t00m 54
        label.set_xalign(0.0)
213 t00m 55
        image = self.gui.add_widget('gtk_image_current_view', Gtk.Image())
203 t00m 56
        hbox.pack_start(image, False, False, 3)
57
        hbox.pack_start(label, True, True, 3)
58
        menuviews.add(hbox)
59
        lhbox.pack_start(menuviews, True, True, 3)
60
        lhbox.show_all()
61
        tool.add(lhbox)
62
        tool.set_expand(False)
63
        self.tool_bar.insert(tool, -1)
64
 
65
        ### Popover menuviews
213 t00m 66
        popover = self.gui.add_widget('gtk_popover_button_menu_views', Gtk.Popover.new(menuviews))
203 t00m 67
        menuviews.connect('clicked', self.cb.gui_show_popover, popover)
68
        box = Gtk.Box(spacing = 0, orientation="vertical")
69
        popover.add(box)
70
 
71
 
217 t00m 72
        box.pack_start(self.uif.create_menuview_button('annotation'), False, False, 0)
203 t00m 73
        separator = Gtk.Separator(orientation = Gtk.Orientation.HORIZONTAL)
74
        box.pack_start(separator, False, False, 0)
229 t00m 75
        box.pack_start(self.uif.create_menuview_button('collection'), False, False, 0)
203 t00m 76
        box.pack_start(self.uif.create_menuview_button('component'), False, False, 0)
77
        box.pack_start(self.uif.create_menuview_button('description'), False, False, 0)
78
        box.pack_start(self.uif.create_menuview_button('bookmarks'), False, False, 0)
79
        box.pack_start(self.uif.create_menuview_button('category'), False, False, 0)
80
        box.pack_start(self.uif.create_menuview_button('chronologic'), False, False, 0)
81
        box.pack_start(self.uif.create_menuview_button('priority'), False, False, 0)
82
        box.pack_start(self.uif.create_menuview_button('type'), False, False, 0)
83
 
201 t00m 84
        # Import button
85
        tool = Gtk.ToolButton()
86
        tool.set_icon_name('basico-add')
213 t00m 87
        popover = self.gui.add_widget('gtk_popover_toolbutton_import', Gtk.Popover.new(tool))
201 t00m 88
        tool.connect('clicked', self.cb.gui_show_popover, popover)
89
        self.tool_bar.insert(tool, -1)
90
 
91
        ## Popover body
92
        box = Gtk.VBox(spacing = 0, orientation="vertical")
93
        box.set_property('margin', 3)
94
        widget_import = self.gui.add_widget('widget_import', ImportWidget(self.app))
95
        box.pack_start(widget_import, True, True, 6)
96
        popover.add(box)
97
 
98
        # Annotation button
99
        tool = Gtk.ToolButton()
100
        tool.set_icon_name('basico-annotation')
213 t00m 101
        popover = self.gui.add_widget('gtk_popover_annotation', Gtk.Popover.new(tool))
207 t00m 102
        # ~ tool.connect('clicked', self.cb.gui_show_popover, popover)
222 t00m 103
        tool.connect('clicked', self.cb.gui_annotation_widget_show)
201 t00m 104
        self.tool_bar.insert(tool, -1)
105
 
106
        ## Popover body
107
        box = Gtk.VBox(spacing = 0, orientation="vertical")
108
        box.set_property('margin', 3)
109
        widget_import = self.gui.add_widget('widget_annotation', AnnotationWidget(self.app))
110
        box.pack_start(widget_import, True, True, 6)
111
        popover.add(box)
112
 
113
 
164 t00m 114
        # Filter entry
115
        tool = Gtk.ToolItem.new()
116
 
117
        hbox = Gtk.HBox()
118
        entry = Gtk.Entry()
188 t00m 119
        entry.connect('activate', self.cb.gui_filter_visor)
213 t00m 120
        self.gui.add_widget('gtk_entry_filter_visor', entry)
164 t00m 121
 
201 t00m 122
        icon = self.im.get_pixbuf_icon('basico-find')
123
        entry.set_icon_from_pixbuf(Gtk.EntryIconPosition.PRIMARY, icon)
124
        entry.set_icon_sensitive(Gtk.EntryIconPosition.PRIMARY, True)
125
        entry.set_icon_tooltip_markup (Gtk.EntryIconPosition.PRIMARY, "Search in the whole database")
126
 
175 t00m 127
        icon = self.im.get_pixbuf_icon('basico-filter')
128
        entry.set_icon_from_pixbuf(Gtk.EntryIconPosition.SECONDARY, icon)
129
        entry.set_icon_sensitive(Gtk.EntryIconPosition.SECONDARY, True)
130
        entry.set_icon_tooltip_markup (Gtk.EntryIconPosition.SECONDARY, "Click here to filter results")
131
        entry.set_placeholder_text("Filter results...")
132
 
133
        def on_icon_pressed(entry, icon_pos, event):
134
            if icon_pos == Gtk.EntryIconPosition.PRIMARY:
201 t00m 135
                self.cb.action_search(entry)
175 t00m 136
            elif icon_pos == Gtk.EntryIconPosition.SECONDARY:
188 t00m 137
                self.cb.gui_filter_visor(entry)
175 t00m 138
 
199 t00m 139
        entry.connect('changed', self.cb.gui_filter_visor)
175 t00m 140
        entry.connect("icon-press", on_icon_pressed)
184 t00m 141
        hbox.pack_start(entry, True, True, 0)
164 t00m 142
        tool.add(hbox)
184 t00m 143
        tool.set_expand(True)
164 t00m 144
        self.tool_bar.insert(tool, -1)
145
 
175 t00m 146
        # ~ Separator
147
        tool = Gtk.SeparatorToolItem.new()
148
        tool.set_draw(False)
149
        tool.set_expand(True)
150
        self.tool_bar.insert(tool, -1)
151
 
203 t00m 152
        # Button Total SAP Notes
153
        tool = Gtk.ToolItem()
154
        tool.set_expand(False)
213 t00m 155
        button = self.gui.add_widget('gtk_button_total_notes', Gtk.Button())
203 t00m 156
        button.set_relief(Gtk.ReliefStyle.NONE)
157
 
213 t00m 158
        popover = self.gui.add_widget('gtk_popover_button_total_notes', Gtk.Popover.new(button))
159
        label = self.gui.add_widget('gtk_label_total_notes', Gtk.Label())
178 t00m 160
        hbox = Gtk.HBox()
161
        hbox.pack_start(label, False, False, 0)
203 t00m 162
        button.add(hbox)
163
        button.connect('clicked', self.cb.gui_show_popover, popover)
164
        tool.add(button)
165
        self.tool_bar.insert(tool, -1)
166
 
167
        ## Popover body
212 t00m 168
        box = self.build_popover(popover)
203 t00m 169
        popover.add(box)
170
 
171
        # Fullscreen toggle button
172
        tool = Gtk.ToolItem()
178 t00m 173
        tool.set_expand(False)
203 t00m 174
        icon = self.im.get_new_image_icon('basico-fullscreen', 24, 24)
213 t00m 175
        box = self.gui.add_widget('gtk_box_container_icon_fullscreen', Gtk.Box())
203 t00m 176
        box.pack_start(icon, False, False, 0)
177
        button = Gtk.ToggleButton()
178
        button.set_relief(Gtk.ReliefStyle.NONE)
179
        button.connect('toggled', self.cb.gui_toggle_fullscreen)
180
        button.add(box)
181
        tool.add(button)
156 t00m 182
        self.tool_bar.insert(tool, -1)
183
 
184
        # Toolbar initial settings
201 t00m 185
        self.set_visible(True)
186
        self.set_no_show_all(False)
156 t00m 187
        self.tool_bar.set_hexpand(True)
188
 
189
 
190
    def get_services(self):
191
        self.gui = self.app.get_service("GUI")
192
        self.cb = self.app.get_service('Callbacks')
193
        self.sap = self.app.get_service('SAP')
194
        self.im = self.app.get_service('IM')
195
        self.settings = self.app.get_service('Settings')
196
        self.db = self.app.get_service('DB')
197
        self.uif = self.app.get_service("UIF")
198
 
164 t00m 199
 
212 t00m 200
    def build_popover(self, popover):
201
        box = Gtk.Box(spacing = 3, orientation="vertical")
202
        sid = '0000000000'
203
 
204
        def get_popover_button(text, icon_name):
205
            button = Gtk.Button()
206
            button.set_relief(Gtk.ReliefStyle.NONE)
207
            hbox = Gtk.HBox()
208
            icon = self.im.get_new_image_icon(icon_name, 24, 24)
209
            lbltext = Gtk.Label()
210
            lbltext.set_xalign(0.0)
211
            lbltext.set_markup('%s' % text)
212
            hbox.pack_start(icon, False, False, 3)
213
            hbox.pack_start(lbltext, True, True, 3)
214
            button.add(hbox)
215
            return button
216
 
217
        # Popover button "Bookmark"
218
        button = get_popover_button("(Un)bookmark SAP Notes", 'basico-bookmarks')
219
        button.connect('clicked', self.cb.switch_bookmark_current_set, popover)
220
        box.pack_start(button, False, False, 0)
221
 
222
        # Separator
223
        separator = Gtk.Separator(orientation = Gtk.Orientation.HORIZONTAL)
224
        box.pack_start(separator, True, True, 0)
225
 
229 t00m 226
        # Popover button Collection Management
227
        button = get_popover_button("Manage collections", 'basico-collection')
212 t00m 228
        box.pack_start(button, False, False, 0)
229 t00m 229
        self.popcollections = self.gui.add_widget('gtk_popover_button_manage_collections_selected_notes', Gtk.Popover.new(button))
230
        self.popcollections.set_position(Gtk.PositionType.RIGHT)
231
        button.connect('clicked', self.cb.gui_show_popover, self.popcollections)
232
        self.popcollections.add(CollectionsMgtView(self.app, sid, self.popcollections))
212 t00m 233
 
234
        # Separator
235
        separator = Gtk.Separator(orientation = Gtk.Orientation.HORIZONTAL)
236
        box.pack_start(separator, True, True, 0)
237
 
238
 
239
        # Popover button "Delete SAP Notes"
240
        button = get_popover_button("Delete SAP Notes", 'basico-delete')
241
        button.connect('clicked', self.cb.sapnote_delete, sid)
242
        box.pack_start(button, False, False, 0)
243
 
244
        return box
245
 
141 t00mlabs 246
class SAPNoteViewVisor(Gtk.Box, Service):
113 t00mlabs 247
    def __init__(self, app):
141 t00mlabs 248
        Gtk.Box.__init__(self, app)
113 t00mlabs 249
        self.app = app
198 t00m 250
        self.bag = []
113 t00mlabs 251
        self.get_services()
197 t00m 252
        self.setup()
113 t00mlabs 253
 
254
 
255
    def get_services(self):
256
        self.gui = self.app.get_service("GUI")
257
        self.cb = self.app.get_service('Callbacks')
258
        self.sap = self.app.get_service('SAP')
259
        self.im = self.app.get_service('IM')
260
        self.settings = self.app.get_service('Settings')
261
        self.db = self.app.get_service('DB')
262
        self.uif = self.app.get_service("UIF")
207 t00m 263
        self.utils = self.app.get_service("Utils")
217 t00m 264
        self.annot = self.app.get_service('Annotation')
113 t00mlabs 265
 
199 t00m 266
    def get_treeview(self):
267
        return self.treeview
113 t00mlabs 268
 
178 t00m 269
 
197 t00m 270
    def setup(self):
271
        scr = Gtk.ScrolledWindow()
272
        scr.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
273
        scr.set_shadow_type(Gtk.ShadowType.IN)
274
        viewport = Gtk.Viewport()
275
        self.treeview = Gtk.TreeView()
276
        viewport.add(self.treeview)
277
        scr.add(viewport)
278
        self.pack_start(scr, True, True, 6)
178 t00m 279
 
197 t00m 280
        # Setup model
199 t00m 281
        self.model = Gtk.TreeStore(
201 t00m 282
            int,        # key
197 t00m 283
            Pixbuf,     # Icon
284
            int,        # checkbox
201 t00m 285
            str,        # sid
197 t00m 286
            str,        # title
287
            str,        # component
288
            str,        # category
289
            str,        # type
290
            str,        # priority
226 t00m 291
            str,        # last update
217 t00m 292
            str,        # Annotation Id (extra key)
226 t00m 293
            str,        # Timestamp
197 t00m 294
        )
178 t00m 295
 
197 t00m 296
        # Setup columns
228 t00m 297
        def get_column_header_widget(title, icon_name=None, width=24, height=24):
201 t00m 298
            hbox = Gtk.HBox()
299
            icon = self.im.get_new_image_icon(icon_name, width, height)
300
            label = Gtk.Label()
301
            label.set_markup("<b>%s</b>" % title)
228 t00m 302
            label.modify_font(Pango.FontDescription('Monospace 10'))
201 t00m 303
            hbox.pack_start(icon, False, False, 3)
304
            hbox.pack_start(label, True, True, 3)
305
            hbox.show_all()
306
            return hbox
307
 
197 t00m 308
        # SAP Note key
309
        self.renderer_key = Gtk.CellRendererText()
310
        self.renderer_key.set_property('height', 32)
311
        self.column_key = Gtk.TreeViewColumn('Key', self.renderer_key, text=0)
312
        self.column_key.set_visible(False)
313
        self.column_key.set_expand(False)
314
        self.column_key.set_clickable(False)
315
        self.column_key.set_sort_indicator(False)
316
        self.treeview.append_column(self.column_key)
178 t00m 317
 
197 t00m 318
        # Icon
319
        self.renderer_icon = Gtk.CellRendererPixbuf()
320
        self.renderer_icon.set_alignment(0.0, 0.5)
200 t00m 321
        self.column_icon = Gtk.TreeViewColumn('Bookmark', self.renderer_icon, pixbuf=1)
201 t00m 322
        widget = get_column_header_widget('', 'basico-bookmarks')
323
        self.column_icon.set_widget(widget)
197 t00m 324
        self.column_icon.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE)
207 t00m 325
        self.column_icon.set_visible(True)
197 t00m 326
        self.column_icon.set_expand(False)
327
        self.column_icon.set_clickable(False)
328
        self.column_icon.set_sort_indicator(False)
329
        self.treeview.append_column(self.column_icon)
117 t00mlabs 330
 
197 t00m 331
        # SAP Note Checkbox
332
        self.renderer_checkbox = Gtk.CellRendererToggle()
333
        self.renderer_checkbox.connect("toggled", self.toggle_checkbox)
334
        self.column_checkbox = Gtk.TreeViewColumn('', self.renderer_checkbox, active=2)
335
        self.column_checkbox.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE)
198 t00m 336
        self.column_checkbox.set_visible(False)
197 t00m 337
        self.column_checkbox.set_expand(False)
338
        self.column_checkbox.set_clickable(False)
339
        self.column_checkbox.set_sort_indicator(False)
340
        self.column_checkbox.set_property('spacing', 50)
341
        self.treeview.append_column(self.column_checkbox)
117 t00mlabs 342
 
197 t00m 343
        # SAP Note Id
344
        self.renderer_sid = Gtk.CellRendererText()
345
        self.renderer_sid.set_property('xalign', 1.0)
346
        self.renderer_sid.set_property('height', 36)
200 t00m 347
        self.renderer_sid.set_property('background', '#F0E3E3')
199 t00m 348
        self.column_sid = Gtk.TreeViewColumn('SAP Note Id', self.renderer_sid, markup=3)
201 t00m 349
        widget = get_column_header_widget('SAP Note Id', 'basico-sid')
350
        self.column_sid.set_widget(widget)
197 t00m 351
        self.column_sid.set_visible(True)
198 t00m 352
        self.column_sid.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE)
197 t00m 353
        self.column_sid.set_expand(False)
354
        self.column_sid.set_clickable(True)
355
        self.column_sid.set_sort_indicator(True)
201 t00m 356
        self.column_sid.set_sort_column_id(0)
199 t00m 357
        self.column_sid.set_sort_order(Gtk.SortType.ASCENDING)
201 t00m 358
        self.model.set_sort_column_id(0, Gtk.SortType.ASCENDING)
197 t00m 359
        self.treeview.append_column(self.column_sid)
130 t00mlabs 360
 
197 t00m 361
        # SAP Note title
362
        self.renderer_title = Gtk.CellRendererText()
200 t00m 363
        self.renderer_title.set_property('background', '#FFFEEA')
199 t00m 364
        self.renderer_title.set_property('ellipsize', Pango.EllipsizeMode.MIDDLE)
197 t00m 365
        self.column_title = Gtk.TreeViewColumn('Title', self.renderer_title, markup=4)
201 t00m 366
        widget = get_column_header_widget('Title', 'basico-tag')
367
        self.column_title.set_widget(widget)
197 t00m 368
        self.column_title.set_visible(True)
198 t00m 369
        self.column_title.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE)
197 t00m 370
        self.column_title.set_expand(True)
371
        self.column_title.set_clickable(True)
372
        self.column_title.set_sort_indicator(True)
199 t00m 373
        self.column_title.set_sort_column_id(4)
197 t00m 374
        self.treeview.append_column(self.column_title)
117 t00mlabs 375
 
197 t00m 376
        # SAP Note Component
377
        self.renderer_component = Gtk.CellRendererText()
200 t00m 378
        self.renderer_component.set_property('background', '#E3E3F0')
197 t00m 379
        self.column_component = Gtk.TreeViewColumn('Component', self.renderer_component, markup=5)
201 t00m 380
        widget = get_column_header_widget('Component', 'basico-component')
381
        self.column_component.set_widget(widget)
199 t00m 382
        self.column_component.set_visible(True)
383
        self.column_component.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE)
384
        self.column_component.set_expand(False)
197 t00m 385
        self.column_component.set_clickable(True)
386
        self.column_component.set_sort_indicator(True)
199 t00m 387
        self.column_component.set_sort_column_id(5)
197 t00m 388
        self.treeview.append_column(self.column_component)
117 t00mlabs 389
 
197 t00m 390
        # SAP Note Category
391
        self.renderer_category = Gtk.CellRendererText()
200 t00m 392
        self.renderer_category.set_property('background', '#E3F1E3')
197 t00m 393
        self.column_category = Gtk.TreeViewColumn('Category', self.renderer_category, markup=6)
201 t00m 394
        widget = get_column_header_widget('Category', 'basico-category')
395
        self.column_category.set_widget(widget)
223 t00m 396
        self.column_category.set_visible(False)
198 t00m 397
        self.column_category.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE)
197 t00m 398
        self.column_category.set_expand(False)
399
        self.column_category.set_clickable(True)
400
        self.column_category.set_sort_indicator(True)
199 t00m 401
        self.column_category.set_sort_column_id(6)
197 t00m 402
        self.treeview.append_column(self.column_category)
117 t00mlabs 403
 
197 t00m 404
        # SAP Note Type
405
        self.renderer_type = Gtk.CellRendererText()
212 t00m 406
        self.renderer_type.set_property('background', '#e4f1f1')
197 t00m 407
        self.column_type = Gtk.TreeViewColumn('Type', self.renderer_type, markup=7)
207 t00m 408
        self.column_type.set_visible(True)
409
        self.column_type.set_expand(False)
410
        self.column_type.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE)
197 t00m 411
        self.column_type.set_clickable(True)
412
        self.column_type.set_sort_indicator(True)
213 t00m 413
        self.column_type.set_sort_column_id(7)
197 t00m 414
        self.treeview.append_column(self.column_type)
117 t00mlabs 415
 
197 t00m 416
        # SAP Note Priority
417
        self.renderer_priority = Gtk.CellRendererText()
418
        self.column_priority = Gtk.TreeViewColumn('Priority', self.renderer_priority, markup=8)
419
        self.column_priority.set_visible(False)
420
        self.column_priority.set_expand(True)
421
        self.column_priority.set_clickable(True)
422
        self.column_priority.set_sort_indicator(True)
226 t00m 423
        self.column_priority.set_sort_column_id(8)
197 t00m 424
        self.treeview.append_column(self.column_priority)
117 t00mlabs 425
 
226 t00m 426
        # SAP Note UpdatedOn
427
        self.renderer_updated = Gtk.CellRendererText()
428
        self.renderer_updated.set_property('background', '#FFE6D1')
429
        self.column_updated = Gtk.TreeViewColumn('Updated On', self.renderer_updated, markup=9)
430
        self.column_updated.set_visible(True)
431
        self.column_updated.set_expand(False)
432
        self.column_updated.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE)
433
        self.column_updated.set_clickable(True)
434
        self.column_updated.set_sort_indicator(True)
435
        self.column_updated.set_sort_column_id(11)
436
        self.treeview.append_column(self.column_updated)
437
 
217 t00m 438
        # Annotation Id
439
        self.renderer_annotation = Gtk.CellRendererText()
226 t00m 440
        self.column_annotation = Gtk.TreeViewColumn('Annotation Id', self.renderer_annotation, markup=10)
217 t00m 441
        self.column_annotation.set_visible(False)
442
        self.column_annotation.set_expand(False)
443
        self.column_annotation.set_clickable(False)
444
        self.column_annotation.set_sort_indicator(False)
445
        self.treeview.append_column(self.column_annotation)
446
 
226 t00m 447
        # Timestamp
448
        self.renderer_timestamp = Gtk.CellRendererText()
449
        self.column_timestamp = Gtk.TreeViewColumn('Annotation Id', self.renderer_timestamp, text=11)
450
        self.column_timestamp.set_visible(False)
451
        self.column_timestamp.set_expand(False)
452
        self.column_timestamp.set_clickable(False)
453
        self.column_timestamp.set_sort_indicator(False)
454
        self.treeview.append_column(self.column_timestamp)
455
 
199 t00m 456
        # Treeview properties
197 t00m 457
        self.treeview.set_can_focus(False)
458
        self.treeview.set_enable_tree_lines(True)
198 t00m 459
        self.treeview.set_headers_visible(True)
197 t00m 460
        self.treeview.set_enable_search(True)
461
        self.treeview.set_hover_selection(False)
207 t00m 462
        self.treeview.set_grid_lines(Gtk.TreeViewGridLines.NONE)
463
        self.treeview.set_enable_tree_lines(True)
464
        self.treeview.set_level_indentation(10)
228 t00m 465
        self.treeview.modify_font(Pango.FontDescription('Monospace 10'))
197 t00m 466
        self.treeview.connect('button_press_event', self.right_click)
162 t00m 467
 
199 t00m 468
        # DOC: In order to have a Gtk.Widged with sorting and filtering
469
        # capabilities, you have to filter the model first, and use this
470
        # new model to create the sorted model. Then, attach the sorted
471
        # model to the treeview...
472
 
473
        # Treeview filtering:
474
        self.visible_filter = self.model.filter_new()
200 t00m 475
        self.visible_filter.set_visible_func(self.visible_function)
230 t00m 476
        # ~ treeview.set_search_equal_func(self.search_function)
477
        # https://stackoverflow.com/questions/23355866/user-search-collapsed-rows-in-a-gtk-treeview
199 t00m 478
 
479
        # TreeView sorting
480
        self.sorted_model = Gtk.TreeModelSort(model=self.visible_filter)
481
        self.sorted_model.set_sort_func(0, self.sort_function, None)
482
 
197 t00m 483
        # Selection
484
        self.selection = self.treeview.get_selection()
217 t00m 485
        self.selection.set_mode(Gtk.SelectionMode.SINGLE)
197 t00m 486
        self.selection.connect('changed', self.row_changed)
162 t00m 487
 
199 t00m 488
        # Set model (filtered and sorted)
197 t00m 489
        self.treeview.set_model(self.sorted_model)
162 t00m 490
 
197 t00m 491
        self.show_all()
492
 
199 t00m 493
 
197 t00m 494
    def sort_function(self, model, row1, row2, user_data):
199 t00m 495
        sort_column = 0
197 t00m 496
 
497
        value1 = model.get_value(row1, sort_column)
498
        value2 = model.get_value(row2, sort_column)
225 t00m 499
 
197 t00m 500
        if value1 < value2:
501
            return -1
502
        elif value1 == value2:
503
            return 0
504
        else:
505
            return 1
506
 
198 t00m 507
 
200 t00m 508
    def visible_function(self, model, itr, data):
213 t00m 509
        entry = self.gui.get_widget('gtk_entry_filter_visor')
199 t00m 510
        text = entry.get_text()
511
        sid = str(model.get(itr, 3)[0])
230 t00m 512
        if sid.startswith('<'):
513
            sid = sid[3:-4]
199 t00m 514
        title = model.get(itr, 4)[0]
200 t00m 515
        component = str(model.get(itr, 5)[0])
516
        category = model.get(itr, 6)[0]
230 t00m 517
        rtype = model.get(itr, 7)[0]
518
        string = ' '.join(['SAP Note %s' % sid, title, component, category, rtype])
519
        match = text.upper() in string.upper()
520
        # ~ self.debug("%s in %s? %s" % (text, string, match))
199 t00m 521
 
230 t00m 522
        return match
199 t00m 523
 
230 t00m 524
 
202 t00m 525
    def update_total_sapnotes_count(self, count=0):
213 t00m 526
        statusbar = self.gui.get_widget('widget_statusbar')
225 t00m 527
        lblnotescount = self.gui.get_widget('gtk_label_total_notes')
202 t00m 528
        total = self.db.get_total()
225 t00m 529
 
202 t00m 530
        lblnotescount.set_markup("<b>%d/<big>%d</big></b>" % (count, total))
203 t00m 531
        statusbar.message("<b>View populated with %d SAP Notes</b>" % count)
202 t00m 532
 
533
 
199 t00m 534
    def get_visible_filter(self):
535
        return self.visible_filter
536
 
537
 
197 t00m 538
    def row_changed(self, selection):
217 t00m 539
        try:
226 t00m 540
            model, treeiter = selection.get_selected()
541
            if treeiter is not None:
542
                component = model[treeiter][5]
543
                if component == 'Annotation':
544
                    aid = model[treeiter][10]
545
                    is_valid = self.annot.is_valid(aid)
546
                    if is_valid:
547
                        self.cb.action_annotation_edit(aid)
548
                else:
549
                    aid = None
550
                    self.uif.set_widget_visibility('gtk_vbox_container_annotations', False)
217 t00m 551
        except Exception as error:
552
            self.debug(error)
553
            self.print_traceback()
197 t00m 554
 
198 t00m 555
 
197 t00m 556
    def toggle_checkbox(self, cell, path):
557
        self.model[path][2] = not self.model[path][2]
558
 
559
 
226 t00m 560
    def get_node(self, key, icon, checkbox, sid, title, component, category='', sntype='', priority='', updated='', aid='', timestamp=''):
197 t00m 561
        node = []
562
        node.append(key)
563
        node.append(icon)
564
        node.append(checkbox)
565
        node.append(sid)
566
        node.append(title)
567
        node.append(component)
568
        node.append(category)
569
        node.append(sntype)
570
        node.append(priority)
226 t00m 571
        node.append(updated)
217 t00m 572
        node.append(aid) # Extra key for annotations id (aid)
226 t00m 573
        node.append(timestamp)
197 t00m 574
        return node
575
 
576
 
207 t00m 577
    def refresh(self):
578
        self.populate()
579
 
580
 
212 t00m 581
    def get_bag(self):
582
        return self.bag
583
 
584
 
198 t00m 585
    def populate(self, bag=None, cid=None):
209 t00m 586
        icon_annotation = self.im.get_pixbuf_icon('basico-annotation', 32, 32)
587
        icon_content = self.im.get_pixbuf_icon('basico-logviewer', 32, 32)
210 t00m 588
        icon_link = self.im.get_pixbuf_icon('basico-browser', 32, 32)
228 t00m 589
        icon_empty = self.im.get_pixbuf_icon('basico-empty', 32, 32)
590
        icon_sapnote = self.im.get_pixbuf_icon('basico-sapnote', 32, 32)
591
        icon_bookmark = self.im.get_pixbuf_icon('basico-bookmarks', 32, 32)
230 t00m 592
        self.column_sid.set_visible(True)
210 t00m 593
 
198 t00m 594
        if bag is None:
213 t00m 595
            bag = self.bag
198 t00m 596
        else:
597
            self.bag = bag
212 t00m 598
 
228 t00m 599
 
197 t00m 600
        self.model.clear()
212 t00m 601
 
213 t00m 602
        for sid in self.bag:
197 t00m 603
            metadata = self.db.get_sapnote_metadata(sid)
218 t00m 604
            if metadata is not None:
605
                bookmark = metadata['bookmark']
606
                title = escape(metadata['title'])
607
                sid = str(int(metadata['id']))
608
                if bookmark:
609
                    icon = icon_bookmark
610
                    title = "<b>%s</b>" % title
611
                    sid = "<b>%s</b>" % sid
612
                else:
228 t00m 613
                    icon = icon_sapnote
198 t00m 614
 
226 t00m 615
                timestamp = metadata['releaseon']
616
                timestamp = timestamp.replace('-', '')
617
                timestamp = timestamp.replace(':', '')
618
                timestamp = timestamp.replace('T', '_')
201 t00m 619
 
218 t00m 620
                node = self.get_node(   int(metadata['id']),
621
                                        icon,
622
                                        bookmark,
623
                                        '<b>%s</b>' % sid,
624
                                        title,
625
                                        escape(metadata['componentkey']),
626
                                        escape(metadata['category']),
627
                                        escape(metadata['type']),
628
                                        escape(metadata['priority']),
226 t00m 629
                                        self.utils.fuzzy_date_from_timestamp(timestamp),
630
                                        '',
631
                                        timestamp
218 t00m 632
                                    )
633
                pid = self.model.append(None, node)
179 t00m 634
 
218 t00m 635
                # Load annotations
224 t00m 636
                files = self.annot.get_by_sid(metadata['id'])
218 t00m 637
                for fname in files:
638
                    with open(fname, 'r') as fa:
639
                        annotation = json.load(fa)
225 t00m 640
                        self.debug("Populating annotation: %s" % annotation['aid'])
218 t00m 641
                        node = self.get_node(   0,
642
                                                icon_annotation,
643
                                                False,
226 t00m 644
                                                '',
218 t00m 645
                                                annotation['title'],
646
                                                annotation['component'],
647
                                                '',
225 t00m 648
                                                annotation['type'],
224 t00m 649
                                                '',
226 t00m 650
                                                self.utils.fuzzy_date_from_timestamp(annotation['timestamp']),
651
                                                annotation['aid'],
652
                                                annotation['timestamp']
218 t00m 653
                                            )
225 t00m 654
                        self.model.append(pid, node)
228 t00m 655
        self.treeview.set_model(self.sorted_model)
225 t00m 656
        self.update_total_sapnotes_count(len(self.model))
657
        self.show_widgets()
658
        stack = self.gui.get_widget('gtk_stack_main')
659
        stack.set_visible_child_name('visor')
660
        # ~ self.annot.get_all()
217 t00m 661
 
662
 
226 t00m 663
    def populate_annotations(self, annotations=None):
225 t00m 664
        icon_annotation = self.im.get_pixbuf_icon('basico-annotation', 32, 32)
665
        icon_content = self.im.get_pixbuf_icon('basico-logviewer', 32, 32)
666
        icon_link = self.im.get_pixbuf_icon('basico-browser', 32, 32)
667
        icon_empty = self.im.get_pixbuf_icon('basico-empty', 32, 32)
668
        icon_bookmark = self.im.get_pixbuf_icon('basico-bookmarks', 32, 32)
228 t00m 669
        icon_sapnote = self.im.get_pixbuf_icon('basico-sapnote', 32, 32)
230 t00m 670
        self.column_sid.set_visible(False)
225 t00m 671
 
672
        self.model.clear()
226 t00m 673
 
674
        if annotations is None:
675
            annotations = self.annot.get_all()
676
 
230 t00m 677
        snpids = {}
678
 
225 t00m 679
        for fname in annotations:
680
            with open(fname, 'r') as fa:
681
                annotation = json.load(fa)
682
                sid = self.annot.get_sid(annotation['aid'])
230 t00m 683
                # ~ if sid != '0000000000':
684
                    # ~ try:
685
                        # ~ pid = snpids[self.db.normalize_sid(sid)]
686
                    # ~ except:
687
                        # ~ metadata = self.db.get_sapnote_metadata(sid)
688
                        # ~ if metadata is not None:
689
                            # ~ bookmark = metadata['bookmark']
690
                            # ~ title = escape(metadata['title'])
691
                            # ~ sid = str(int(metadata['id']))
692
                            # ~ if bookmark:
693
                                # ~ icon = icon_bookmark
694
                                # ~ title = "<b>%s</b>" % title
695
                                # ~ sid = "<b>%s</b>" % sid
696
                            # ~ else:
697
                                # ~ icon = icon_sapnote
226 t00m 698
 
230 t00m 699
                            # ~ timestamp = metadata['releaseon']
700
                            # ~ timestamp = timestamp.replace('-', '')
701
                            # ~ timestamp = timestamp.replace(':', '')
702
                            # ~ timestamp = timestamp.replace('T', '_')
703
                            # ~ node = self.get_node(   int(metadata['id']),
704
                                                # ~ icon,
705
                                                # ~ bookmark,
706
                                                # ~ '<b>%s</b>' % sid,
707
                                                # ~ title,
708
                                                # ~ escape(metadata['componentkey']),
709
                                                # ~ escape(metadata['category']),
710
                                                # ~ escape(metadata['type']),
711
                                                # ~ escape(metadata['priority']),
712
                                                # ~ self.utils.fuzzy_date_from_timestamp(timestamp),
713
                                                # ~ '',
714
                                                # ~ timestamp
715
                                                # ~ )
716
                            # ~ pid = self.model.append(None, node)
717
                            # ~ snpids[self.db.normalize_sid(sid)] = pid
718
                # ~ else:
719
                    # ~ pid = None
225 t00m 720
                node = self.get_node(   0,
721
                                        icon_annotation,
722
                                        False,
230 t00m 723
                                        str(int(sid)),
225 t00m 724
                                        annotation['title'],
725
                                        annotation['component'],
726
                                        '',
727
                                        annotation['type'],
728
                                        '',
226 t00m 729
                                        self.utils.fuzzy_date_from_timestamp(annotation['timestamp']),
730
                                        annotation['aid'],
731
                                        annotation['timestamp']
225 t00m 732
                                    )
230 t00m 733
                self.model.append(None, node)
228 t00m 734
        self.treeview.set_model(self.sorted_model)
225 t00m 735
        self.treeview.expand_all()
213 t00m 736
        self.update_total_sapnotes_count(len(self.model))
212 t00m 737
        self.show_widgets()
215 t00m 738
        stack = self.gui.get_widget('gtk_stack_main')
739
        stack.set_visible_child_name('visor')
179 t00m 740
 
213 t00m 741
 
212 t00m 742
    def show_widgets(self):
213 t00m 743
        button = self.gui.get_widget('gtk_button_total_notes')
212 t00m 744
        button.set_no_show_all(False)
745
        button.show_all()
202 t00m 746
 
222 t00m 747
 
197 t00m 748
    def right_click(self, treeview, event, data=None):
749
        if event.button == 3:
750
            rect = Gdk.Rectangle()
751
            rect.x = x = int(event.x)
752
            rect.y = y = int(event.y)
753
            pthinfo = self.treeview.get_path_at_pos(x,y)
754
            if pthinfo is not None:
755
                path,col,cellx,celly = pthinfo
756
                model = treeview.get_model()
757
                treeiter = model.get_iter(path)
222 t00m 758
                component = model[treeiter][5]
759
                sid = model[treeiter][0]
201 t00m 760
                sid = "0"*(10 - len(str(sid))) + str(sid)
197 t00m 761
                toolbar = self.gui.get_widget('visortoolbar')
225 t00m 762
                popover = self.gui.add_widget('gtk_popover_visor_row', Gtk.Popover.new(treeview))
203 t00m 763
                popover.set_position(Gtk.PositionType.TOP)
197 t00m 764
                popover.set_pointing_to(rect)
225 t00m 765
                box = self.build_popover(sid, popover, component)
197 t00m 766
                popover.add(box)
225 t00m 767
                self.cb.gui_show_popover(None, popover)
179 t00m 768
 
769
 
225 t00m 770
    def build_popover(self, sid, popover, component):
197 t00m 771
        box = Gtk.Box(spacing = 3, orientation="vertical")
162 t00m 772
 
197 t00m 773
        def get_popover_button(text, icon_name):
774
            button = Gtk.Button()
775
            button.set_relief(Gtk.ReliefStyle.NONE)
776
            hbox = Gtk.HBox()
777
            icon = self.im.get_new_image_icon(icon_name, 24, 24)
778
            lbltext = Gtk.Label()
779
            lbltext.set_xalign(0.0)
780
            lbltext.set_markup('%s' % text)
781
            hbox.pack_start(icon, False, False, 3)
782
            hbox.pack_start(lbltext, True, True, 3)
783
            button.add(hbox)
784
            return button
162 t00m 785
 
225 t00m 786
        if component == 'Annotation':
226 t00m 787
            # Popover button "Delete annotation"
225 t00m 788
            button = get_popover_button("Delete annotation", 'basico-delete')
789
            button.show_all()
790
            button.connect('clicked', self.cb.action_annotation_delete)
791
            box.pack_start(button, False, False, 0)
226 t00m 792
 
793
            # Popover button "Duplicate annotation"
794
            button = get_popover_button("Duplicate annotation", 'basico-duplicate')
795
            button.show_all()
796
            button.connect('clicked', self.cb.action_annotation_duplicate)
797
            box.pack_start(button, False, False, 0)
798
 
225 t00m 799
        else:
800
            # Popover button "Add an annotation"
801
            button = get_popover_button("Add an annotation", 'basico-annotation')
802
            button.show_all()
803
            button.connect('clicked', self.cb.gui_annotation_widget_show, sid, 'create')
804
            box.pack_start(button, False, False, 0)
178 t00m 805
 
225 t00m 806
            # Popover button "Open SAP Note"
807
            button = get_popover_button("See SAP Note", 'basico-browse')
808
            button.connect('clicked', self.cb.sapnote_browse, sid)
809
            box.pack_start(button, False, False, 0)
178 t00m 810
 
225 t00m 811
            # Popover button "Bookmark"
812
            button = get_popover_button("(Un)bookmark SAP Note", 'basico-bookmarks')
813
            button.connect('clicked', self.cb.switch_bookmark, [sid], popover)
814
            box.pack_start(button, False, False, 0)
198 t00m 815
 
225 t00m 816
            # Separator
817
            separator = Gtk.Separator(orientation = Gtk.Orientation.HORIZONTAL)
818
            box.pack_start(separator, True, True, 0)
162 t00m 819
 
229 t00m 820
            # Popover button Collection Management
821
            button = get_popover_button("Manage collections", 'basico-collection')
225 t00m 822
            box.pack_start(button, False, False, 0)
229 t00m 823
            self.popcollections = self.gui.add_widget('gtk_popover_button_manage_collections_single_note', Gtk.Popover.new(button))
824
            self.popcollections.set_position(Gtk.PositionType.RIGHT)
825
            button.connect('clicked', self.cb.gui_show_popover, self.popcollections)
826
            self.popcollections.add(CollectionsMgtView(self.app, sid, self.popcollections))
197 t00m 827
 
225 t00m 828
            # Separator
829
            separator = Gtk.Separator(orientation = Gtk.Orientation.HORIZONTAL)
830
            box.pack_start(separator, True, True, 0)
197 t00m 831
 
832
 
225 t00m 833
            # Popover button "Delete SAP Note"
834
            button = get_popover_button("Delete SAP Note", 'basico-delete')
835
            button.connect('clicked', self.cb.sapnote_delete, sid)
836
            box.pack_start(button, False, False, 0)
197 t00m 837
 
838
        return box