Subversion Repositories basico

Rev

Rev 341 | Rev 349 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
340 t00mlabs 1
#!/usr/bin/python
2
# -*- coding: utf-8 -*-
3
"""
4
# File: srv_cb.py
5
# Author: Tomás Vírseda
6
# License: GPL v3
7
# Description: UI and related callbacks service
8
"""
9
 
10
import os
11
import json
12
import time
13
from concurrent.futures import ThreadPoolExecutor as Executor
14
 
15
import gi
16
gi.require_version('Gtk', '3.0')
17
from gi.repository import Gtk
18
from gi.repository import Gdk
19
 
20
from basico.core.mod_srv import Service
21
from basico.core.mod_env import FILE, LPATH, ATYPES, APP
22
from basico.widgets.wdg_visor_sapnotes import SAPNotesVisor
23
from basico.widgets.wdg_visor_toolbar import VisorToolbar
24
from basico.widgets.wdg_cols import CollectionsMgtView
25
from basico.widgets.wdg_settingsview import SettingsView
26
 
27
# PROPKEYS = CSV headers. SAP Note metadata
28
PROPKEYS = ['id', 'title', 'type', 'componentkey',
29
            'componenttxt', 'category', 'priority', 'releasedon',
30
            'language', 'version']
31
 
32
# Extend PROPKEYS with custom basico metadata
33
PROPKEYS.extend (['Bookmark'])
34
 
35
class Callback(Service):
36
    def initialize(self):
37
        self.get_services()
38
 
39
    def get_services(self):
40
        self.srvstg = self.get_service('Settings')
41
        self.srvdtb = self.get_service('DB')
42
        self.srvgui = self.get_service('GUI')
43
        self.srvuif = self.get_service("UIF")
44
        self.srvsap = self.get_service('SAP')
45
        self.srvicm = self.get_service('IM')
46
        self.srvutl = self.get_service('Utils')
47
        self.srvant = self.get_service('Annotation')
48
        self.srvbnr = self.get_service('BNR')
49
        self.srvclt = self.get_service('Collections')
50
 
51
 
52
    def gui_visor_switch_page(self, notebook, page, page_num):
53
        # 0|1|(2) -> SAP Notes Visor | Annotations Visor | (Help)
54
        self.srvgui.set_key_value('current_visor_tab', page_num)
55
        notebook_viewmenu = self.srvgui.get_widget('gtk_notebook_menuview')
56
        paned = self.srvgui.get_widget('gtk_hpaned')
57
 
58
        if page_num == 0:
59
            self.srvuif.set_widget_visibility('gtk_button_menu_views', True)
60
            self.srvuif.set_widget_visibility('gtk_label_total_notes', True)
61
            visor = self.srvgui.get_widget('visor_sapnotes')
62
            visible_filter = visor.get_visible_filter()
63
            visor.update_total_sapnotes_count()
64
            paned.set_position(400)
65
            notebook_viewmenu.set_current_page(0)
66
        elif page_num == 1:
67
            self.srvuif.set_widget_visibility('gtk_button_menu_views', False)
68
            self.srvuif.set_widget_visibility('gtk_label_total_notes', True)
69
            visor = self.srvgui.get_widget('visor_annotations')
70
            visor.populate_annotations()
71
            paned.set_position(200)
72
            notebook_viewmenu.set_current_page(1)
73
 
74
 
75
    def gui_show_visor_sapnotes(self):
76
        notebook = self.srvgui.get_widget('gtk_notebook_visor')
77
        notebook.set_current_page(0)
78
 
79
 
80
    def gui_show_visor_annotations(self):
81
        notebook = self.srvgui.get_widget('gtk_notebook_visor')
82
        notebook.set_current_page(1)
83
 
84
 
85
    def action_search(self, entry):
86
        visor_sapnotes = self.srvgui.get_widget('visor_sapnotes')
87
        visor_annotations = self.srvgui.get_widget('visor_annotations')
88
        term = entry.get_text()
89
        page = self.srvgui.get_key_value('current_visor_tab')
90
        completion = self.srvgui.get_widget('gtk_entrycompletion_visor')
91
        completion_model = completion.get_model()
92
        completion_model.clear()
93
 
94
        if page == 0:
95
            bag = self.srvdtb.search(term)
96
            visor_sapnotes.populate_sapnotes(bag)
97
            ebuffer = entry.get_buffer()
98
            ebuffer.delete_text(0, -1)
99
            msg = "Found %d SAP Notes for term '%s'" % (len(bag), term)
100
            self.log.info(msg)
101
            self.srvuif.statusbar_msg(msg)
102
        elif page == 1:
103
            annotations = self.srvant.search_term(term)
104
            visor_annotations.populate_annotations(annotations)
105
            msg = "Found %d annotations for term '%s'" % (len(annotations), term)
106
            self.log.info(msg)
107
            self.srvuif.statusbar_msg(msg)
108
 
109
 
110
 
111
    def sapnote_browse(self, button, sid):
112
        self.log.info("Browsing SAP Note %d" % int(sid))
113
        SAP_NOTE_URL = self.srvstg.get('SAP', 'SAP_NOTE_URL')
114
        url = SAP_NOTE_URL % sid
115
        self.srvutl.browse(url)
116
 
117
 
118
    def sapnote_download_pdf(self, button, sid):
119
        self.log.info("Browsing PDF for SAP Note %d" % int(sid))
120
        SAP_NOTE_URL_PDF = self.srvstg.get('SAP', 'SAP_NOTE_URL_PDF')
121
        url = SAP_NOTE_URL_PDF % sid
122
        self.srvutl.browse(url)
123
 
124
 
125
    def sapnote_delete(self, button, sid):
126
        visor = self.srvgui.get_widget('visor_sapnotes')
127
        viewmenu = self.srvgui.get_widget('viewmenu')
128
 
129
        answer = self.srvuif.warning_message_delete_sapnotes(button, 'Deleting SAP Notes', 'Are you sure?', [sid])
130
        if answer is True:
131
            self.srvdtb.delete(sid)
132
            self.srvuif.statusbar_msg("SAP Note %s deleted" % sid, True)
133
            visor.reload()
134
        else:
135
            self.log.info("SAP Note %s not deletd", sid)
136
 
137
 
138
    def sapnote_delete_view(self, button):
139
        visor = self.srvgui.get_widget('visor_sapnotes')
140
        viewmenu = self.srvgui.get_widget('viewmenu')
141
 
142
        bag = visor.get_filtered_bag()
143
        answer = self.srvuif.warning_message_delete_sapnotes(button, 'Deleting SAP Notes', 'Are you sure?', bag)
144
        if answer is True:
145
            for sid in bag:
146
                self.srvdtb.delete(sid)
147
            visor.reload()
148
            msg = "Deleted %d SAP Notes" % len(bag)
149
            self.log.info(msg)
150
            self.srvuif.statusbar_msg(msg, True)
151
        else:
152
            msg = "None of the %d SAP Notes has been deleted" % len(bag)
153
            self.log.info(msg)
154
            self.srvuif.statusbar_msg(msg, True)
155
        visor.reload()
156
        viewmenu.populate()
157
 
158
    def gui_hide_popover(self, popover):
159
        popover.hide()
160
 
161
 
162
    def gui_database_backup(self, *args):
163
        window = self.srvgui.get_window()
164
        question = "Backup database"
165
        message = "\nShould this backup include all your annotations?"
166
        wdialog = self.srvuif.message_dialog_question(question, message)
167
        res_bck_annot = wdialog.run()
168
        wdialog.destroy()
169
 
170
        dialog = Gtk.FileChooserDialog("Please choose target folder and backup name (without extension)", window,
171
            Gtk.FileChooserAction.SAVE,
172
            ("Cancel", Gtk.ResponseType.CANCEL,
173
            "Select", Gtk.ResponseType.OK))
174
        TIMESTAMP = self.srvutl.timestamp()
175
        TARGET_FILE = 'basico-%s' % TIMESTAMP
176
        dialog.set_filename(LPATH['BACKUP'])
177
        dialog.set_current_folder_uri(LPATH['BACKUP'])
178
        dialog.set_current_name(TARGET_FILE)
179
        dialog.set_default_size(800, 400)
180
        res_bck_file = dialog.run()
181
        self.log.debug("Backup file: %s", dialog.get_filename())
182
 
183
        if res_bck_file == Gtk.ResponseType.OK:
184
            backup_filename = dialog.get_filename()
185
            if res_bck_annot == Gtk.ResponseType.YES:
186
                bckname = self.srvbnr.backup(backup_filename, backup_annotations=True)
187
                msg = "Database with annotations backed up successfully to: %s" % bckname
188
                dialog.destroy()
189
            else:
190
                bckname = self.srvbnr.backup(backup_filename, backup_annotations=False)
191
                msg = "Database without annotations backed up successfully to: %s" % bckname
192
            self.log.info(msg)
193
            self.srvuif.statusbar_msg(msg, True)
194
            self.srvuif.copy_text_to_clipboard(bckname)
195
 
196
        else:
197
            self.srvuif.statusbar_msg("Backup aborted by user", True)
198
            self.log.info("Backup aborted")
199
        self.srvuif.grab_focus()
200
 
201
 
202
    def gui_database_restore(self, *args):
203
        visor_annotations = self.srvgui.get_widget('visor_annotations')
204
        window = self.srvgui.get_window()
205
        dialog = Gtk.FileChooserDialog("Please choose a backup file", window,
206
            Gtk.FileChooserAction.OPEN,
207
            (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
208
            Gtk.STOCK_OPEN, Gtk.ResponseType.OK))
209
        dialog.set_current_folder(LPATH['BACKUP'])
210
        filter_zip = Gtk.FileFilter()
211
        filter_zip.set_name("Basico backup files")
212
        filter_zip.add_pattern("*.bco")
213
        dialog.add_filter(filter_zip)
214
        response = dialog.run()
215
        backup = dialog.get_filename()
216
        self.log.info("You are about to restore this file: %s" % backup)
217
        dialog.destroy()
218
 
219
        if response == Gtk.ResponseType.OK:
220
            res = self.srvbnr.test(backup)
221
            if res is None:
222
                dialog = self.srvuif.message_dialog_info("Backup file corrupted?", "It wasn't possible to read all data from this file")
223
                dialog.run()
224
                self.srvuif.statusbar_msg("Backup file corrupted. It wasn't possible to read all data from this file", True)
225
                self.log.info("Backup file corrupted?")
226
            else:
227
                # Ask if the process should force an overwrite in target database
228
                question = "Should the import process overwrite data?"
229
                message = "All metadata for SAP Notes will be overwrited and annotations with the same identifier will be overwriten"
230
                wdialog = self.srvuif.message_dialog_question(question, message)
231
                response = wdialog.run()
232
                wdialog.destroy()
233
                if response == Gtk.ResponseType.YES:
234
                    overwrite = True
235
                else:
236
                    overwrite = False
237
 
238
 
239
                # Ask for final confirmation
240
                sncount, ancount, clcount = res
241
                question = "Restoring backup %s" % os.path.basename(backup)
242
                message = "\n%s contains:\n\n<b>%6d SAP Notes</b>\n<b>%6d collections</b>\n<b>%6d annotations</b>\n\n" % (os.path.basename(backup), sncount, clcount, ancount)
243
                message += "Do you still want to restore this backup?\n"
244
                wdialog = self.srvuif.message_dialog_question(question, message)
245
                response = wdialog.run()
246
                wdialog.destroy()
247
                if response == Gtk.ResponseType.YES:
248
                    self.srvbnr.restore_from_backup(backup, overwrite)
249
                    self.srvdtb.load_notes()
250
                    self.srvclt.load_collections()
251
                    visor_annotations.populate_annotations()
252
                    self.gui_refresh_view()
253
                    self.gui_show_visor_sapnotes()
254
                    self.srvuif.statusbar_msg("Backup restored successfully", True)
255
                    self.log.info("Backup restored successfully")
256
                elif response == Gtk.ResponseType.NO:
257
                    self.srvuif.statusbar_msg("Restore aborted by user", True)
258
                    self.log.info("Restore aborted")
259
        elif response == Gtk.ResponseType.CANCEL:
260
            self.srvuif.statusbar_msg("Restore aborted by user", True)
261
            self.log.info("Restore aborted")
262
 
263
        dialog.destroy()
264
        self.srvuif.grab_focus()
265
 
266
 
267
    def gui_show_about(self, *args):
268
        notebook_menuview = self.srvgui.get_widget('gtk_notebook_menuview')
269
        about = self.srvgui.get_widget('widget_about')
270
        stack = self.srvgui.get_widget('gtk_stack_main')
271
 
272
        stack.set_visible_child_name('about')
273
        self.gui_hide_popover(self.srvgui.get_widget('gtk_popover_button_menu_system'))
274
        self.srvuif.set_widget_visibility('gtk_label_total_notes', False)
275
        self.srvuif.set_widget_visibility('gtk_button_dashboard', True)
276
 
277
        notebook_menuview.hide()
278
        self.gui_annotation_widget_hide()
279
        about.grab_focus()
280
 
281
 
282
    def gui_show_log(self, *args):
283
        notebook_menuview = self.srvgui.get_widget('gtk_notebook_menuview')
284
        logviewer = self.srvgui.get_widget('widget_logviewer')
285
        stack = self.srvgui.get_widget('gtk_stack_main')
286
 
287
        logviewer.update()
288
        self.gui_hide_popover(self.srvgui.get_widget('gtk_popover_button_menu_system'))
289
        stack.set_visible_child_name('log')
290
        self.srvuif.set_widget_visibility('gtk_button_dashboard', True)
291
 
292
        notebook_menuview.hide()
293
        self.gui_annotation_widget_hide()
294
        logviewer.grab_focus()
295
        self.srvuif.statusbar_msg("Displaying application log")
296
 
297
 
298
    def gui_show_settings(self, button):
299
        notebook_menuview = self.srvgui.get_widget('gtk_notebook_menuview')
300
        stack = self.srvgui.get_widget('gtk_stack_main')
301
        view_settings = self.srvgui.get_widget('widget_settings')
302
 
303
        stack.set_visible_child_name('settings')
304
        view_settings.update()
305
        self.gui_hide_popover(self.srvgui.get_widget('gtk_popover_button_menu_system'))
306
        self.srvuif.set_widget_visibility('gtk_label_total_notes', False)
307
        self.srvuif.set_widget_visibility('gtk_button_dashboard', True)
308
 
309
        notebook_menuview.hide()
310
        self.gui_annotation_widget_hide()
311
        view_settings.grab_focus()
312
        self.srvuif.statusbar_msg("Displaying application settings")
313
 
314
 
315
    def gui_show_dashboard(self, *args):
316
        stack = self.srvgui.get_widget('gtk_stack_main')
317
        notebook_menuview = self.srvgui.get_widget('gtk_notebook_menuview')
318
        viewmenu = self.srvgui.get_widget('viewmenu')
319
        current_view = viewmenu.get_view()
320
 
321
        notebook_menuview.show_all()
322
        stack.set_visible_child_name('visor')
323
        self.gui_hide_popover(self.srvgui.get_widget('gtk_popover_button_menu_system'))
324
        self.srvuif.set_widget_visibility('gtk_button_dashboard', False)
325
 
326
        if current_view == 'annotation':
327
            self.srvuif.set_widget_visibility('gtk_label_total_notes', True)
328
        else:
329
            self.srvuif.set_widget_visibility('gtk_label_total_notes', True)
330
        self.srvuif.statusbar_msg("Displaying application dashboard")
331
 
332
 
333
    def gui_toggle_help_visor(self, *args):
334
        button = self.srvgui.get_widget('gtk_togglebutton_help')
335
        notebook = self.srvgui.get_widget('gtk_notebook_visor')
336
 
337
        if button.get_active():
338
            self.srvuif.set_widget_visibility('gtk_notebook_help_page', True)
339
            notebook.set_current_page(2)
340
        else:
341
            self.srvuif.set_widget_visibility('gtk_notebook_help_page', False)
342
            notebook.set_current_page(0)
343
        self.srvuif.statusbar_msg("Displaying application help")
344
 
345
 
346
    def gui_lauch_help_visor(self, *args):
347
        self.srvutl.browse("file://%s" % FILE['HELP_INDEX'])
348
 
349
 
350
    def gui_annotation_widget_show(self, widget, sid='0000000000', action='create'):
351
        widget_annotation = self.srvgui.get_widget('widget_annotation')
352
        widget = self.srvgui.get_widget('gtk_entry_annotation_title')
353
 
354
        if action == 'create':
355
            self.gui_annotation_widget_clear()
356
            aid = self.srvant.gen_aid(sid)
357
        elif action == 'edit':
358
            aid = sid
359
 
360
        widget_annotation.set_metadata_to_widget(aid, action)
361
 
362
        self.srvuif.set_widget_visibility('gtk_vbox_container_annotations', True)
363
        widget.grab_focus()
364
 
365
 
366
    def gui_show_popover(self, button, popover):
367
        if popover.get_visible():
368
            popover.hide()
369
        else:
370
            popover.show_all()
371
 
372
 
373
    def switch_bookmark_current_view(self, *args):
374
        visor = self.srvgui.get_widget('visor_sapnotes')
375
        bag = visor.get_filtered_bag()
376
        try:
377
            for sid in bag:
378
                metadata = self.srvdtb.get_sapnote_metadata(sid)
379
                bookmark = metadata['bookmark']
380
                if bookmark:
381
                    self.sapnote_unbookmark([sid])
382
                else:
383
                    self.sapnote_bookmark([sid])
384
        except:
385
            self.log.error("Could not bookmark SAP Note %s" % sid)
386
            self.log.error(self.get_traceback())
387
        visor.populate_sapnotes(bag)
388
        msg = "%d SAP Notes (un)bookmarked" % len(bag)
389
        self.log.info(msg)
390
        self.srvuif.statusbar_msg(msg, True)
391
 
392
 
393
    def switch_bookmark(self, button, lsid, popover):
394
        visor = self.srvgui.get_widget('visor_sapnotes')
395
        try:
396
            for sid in lsid:
397
                metadata = self.srvdtb.get_sapnote_metadata(sid)
398
                bookmark = metadata['bookmark']
399
                if bookmark:
400
                    self.sapnote_unbookmark([sid])
401
                    self.srvuif.statusbar_msg("SAP Notes unbookmarked")
402
                else:
403
                    self.sapnote_bookmark([sid])
404
                    self.srvuif.statusbar_msg("SAP Notes bookmarked")
405
            popover.hide()
406
        except:
407
            self.log.error("Could not bookmark SAP Note %s" % sid)
408
            self.log.error(self.get_traceback())
409
        visor.populate_sapnotes()
410
 
411
 
412
    def sapnote_bookmark(self, lsid):
413
        self.srvdtb.set_bookmark(lsid)
414
 
415
 
416
    def sapnote_unbookmark(self, lsid):
417
        self.srvdtb.set_no_bookmark(lsid)
418
 
419
 
420
    def sapnote_import_from_launchpad(self, *args):
421
        db = self.get_service('DB')
422
        webdriver = self.get_service('Driver')
423
        textview = self.srvgui.get_widget('gtk_textview_download_launchpad')
424
        visor = self.srvgui.get_widget('visor_sapnotes')
425
 
426
        bag = []
427
        all_notes = []
428
        sapnotes = []
429
 
430
        dlbuffer = textview.get_buffer()
431
        istart, iend = dlbuffer.get_bounds()
432
        text = dlbuffer.get_text(istart, iend, False)
433
        lines = text.replace(' ', ',')
434
        lines = lines.replace('\n', ',')
435
        for sid in lines.split(','):
436
            sid = sid.strip()
437
            if len(sid) > 0:
438
                sapnotes.append(sid)
439
        for sid in sapnotes:
440
            is_valid = self.srvdtb.is_valid(sid)
441
            is_saved = self.srvdtb.get_sapnote_metadata(sid)
442
            if is_valid and not is_saved:
443
                bag.append(sid)
444
            if is_valid:
445
                all_notes.append(sid)
446
        lbag = list(bag)
447
        lbag.sort()
448
 
449
        if len(bag)> 0:
450
            driver = webdriver.open()
451
 
452
        winroot = self.srvgui.get_widget('gtk_app_window_main')
453
        msg = "%d SAP Notes to be downloaded: %s" % (len(bag), ', '.join(list(bag)))
454
        self.log.info(msg)
455
 
456
        result = {}
457
 
458
        self.srvsap.start_fetching(len(bag))
459
        dlbag = []
460
 
461
        # FIXME: max_workers = 1 = Threads disabled
462
        # Indeed, I think this is the best option right now.
463
        with Executor(max_workers=1) as exe:
464
            jobs = []
465
            for sapnote in lbag:
466
                job = exe.submit(self.srvsap.fetch, driver, sapnote)
467
                jobs.append(job)
468
 
469
            for job in jobs:
470
                rc, sapnote = job.result()
471
                msg = "\tRC SAP Note %s: %s" % (sapnote, rc)
472
                self.log.info(msg)
473
                result[sapnote] = rc
474
                if rc:
475
                    sid = "0"*(10 - len(sapnote)) + sapnote
476
                    dlbag.append(sid)
477
                time.sleep(0.2)
478
 
479
        dlbuffer.set_text('')
480
        popover = self.srvgui.get_widget('gtk_popover_toolbutton_import')
481
        self.gui_hide_popover(popover)
482
        if len(bag) > 0:
483
            webdriver.close(driver)
484
 
485
        self.srvsap.stop_fetching()
486
        db.save_notes()
487
        db.build_stats()
488
        self.log.info("Download completed.")
489
        self.srvuif.statusbar_msg("Download completed", True)
490
        visor.populate_sapnotes(all_notes)
491
        self.gui_show_visor_sapnotes()
492
        return result
493
 
494
 
495
    def expand_menuview(self):
496
        viewmenu = self.srvgui.get_widget('viewmenu')
497
        viewmenu.expand_all()
498
 
499
 
500
    def gui_viewmenu_filter(self, *args):
501
        entry = self.srvgui.get_widget('gtk_entry_filter_view')
502
        filter = entry.get_text()
503
        viewmenu = self.srvgui.get_widget('viewmenu')
504
        selection = viewmenu.get_selection()
505
 
506
        def gui_iterate_over_data(model, path, itr):
507
            rowkey = model.get(itr, 0)[0]
508
            rowtype, rowval = rowkey.split('@')
509
            dsc = model.get(itr, 1)[0]
510
            contents = model.get(itr, 1)[0]
511
            cleanstr = contents.replace('<b>', '')
512
            cleanstr = cleanstr.replace('</b>', '')
513
            model.set(itr, 1, '%s' % cleanstr)
514
            viewmenu.collapse_row(path)
515
 
516
            if len(filter) > 0:
517
                if filter.upper() in rowval.upper() or filter.upper() in dsc.upper():
518
                    viewmenu.expand_to_path (path)
519
                    selection.select_path(path)
520
                    model.set(itr, 1, '<b>%s</b>' % contents)
521
            else:
522
                return
523
 
524
        model = viewmenu.get_model()
525
        model.foreach(gui_iterate_over_data)
526
 
527
 
528
    def gui_viewmenu_select_first_entry(self):
529
        viewmenu = self.srvgui.get_widget('viewmenu')
530
        selection = viewmenu.get_selection()
531
        selection.select_path("0")
532
 
533
 
534
    def gui_filter_visor(self, entry):
535
        page = self.srvgui.get_key_value('current_visor_tab')
536
        if page == 0:
537
            visor = self.srvgui.get_widget('visor_sapnotes')
538
            visible_filter = visor.get_visible_filter()
539
            visible_filter.refilter()
540
            visor.update_total_sapnotes_count()
541
        elif page == 1:
542
            visor = self.srvgui.get_widget('visor_annotations')
543
            visor.populate_annotations()
544
            visible_filter = visor.get_visible_filter()
545
            visible_filter.refilter()
546
            visor.update_total_annotations_count()
547
 
548
 
549
    def gui_refresh_view(self, button=None, view=None):
550
        window = self.srvgui.get_widget('gtk_app_window_main')
551
        viewmenu = self.srvgui.get_widget('viewmenu')
552
        if view is None:
553
            view = viewmenu.get_view()
554
 
555
        if view is not None:
556
            viewlabel = self.srvgui.get_widget('gtk_label_current_view')
557
            name = "<b>%-10s</b>" % view.capitalize()
558
            viewlabel.set_markup(name)
559
        viewmenu.set_view(view)
560
        popover = self.srvgui.get_widget('gtk_popover_button_menu_views')
561
        popover.hide()
562
        self.gui_show_visor_sapnotes()
563
 
564
 
565
    def gui_toggle_menu_view(self, obj):
566
        paned = self.srvgui.get_widget('gtk_vbox_container_menu_view')
567
        button = self.srvgui.get_widget('gtk_toogletoolbutton_menu_view')
568
        if isinstance(obj, Gtk.ToggleToolButton):
569
            if button.get_active():
570
                paned.show_all()
571
            else:
572
                paned.hide()
573
        elif isinstance(obj, bool):
574
            if obj == True:
575
                button.set_active(True)
576
            else:
577
                button.set_active(False)
578
 
579
 
580
    def gui_toggle_fullscreen(self, button):
581
        icon_container = self.srvgui.get_widget('gtk_box_container_icon_fullscreen')
582
        icon_fullscreen = self.srvicm.get_new_image_icon('basico-fullscreen', 24, 24)
583
        icon_unfullscreen = self.srvicm.get_new_image_icon('basico-unfullscreen', 24, 24)
584
        active = button.get_active()
585
        window = self.srvgui.get_window()
586
        if active:
587
            self.srvgui.swap_widget(icon_container, icon_unfullscreen)
588
            window.fullscreen()
589
        else:
590
            self.srvgui.swap_widget(icon_container, icon_fullscreen)
591
            window.unfullscreen()
592
 
593
 
594
    def action_annotation_edit(self, aid):
595
        self.gui_annotation_widget_show(None, aid, 'edit')
596
 
597
 
598
    def action_annotation_duplicate(self, *args):
599
        self.log.debug("ACTION-DUPLICATE: %s" % args)
600
 
601
 
602
    def action_annotation_delete(self, *args):
603
        visor = self.srvgui.get_widget('visor_annotations')
604
        widget_annotation = self.srvgui.get_widget('widget_annotation')
605
        aid = widget_annotation.get_aid_from_widget()
606
 
607
        answer = self.srvuif.warning_message_delete_annotations(None, 'Deleting annotations', 'Are you sure?', [aid])
608
        if answer is True:
609
            title = self.srvant.get_title(aid)
610
            self.srvant.delete(aid)
611
            self.gui_annotation_widget_clear()
612
            self.srvuif.set_widget_visibility('gtk_vbox_container_annotations', False)
613
            visor.populate_annotations()
614
            self.srvuif.statusbar_msg("Annotation <i>'%s'</i> deleted" % title, True)
615
        else:
616
            self.log.info("Annotation %s hasn't been deleted" % title)
617
            self.srvuif.statusbar_msg("Action canceled. Nothing deleted.", True)
618
 
619
        self.srvuif.grab_focus()
620
 
621
 
622
    def action_annotation_accept(self, button, sid):
623
        widget_annotation = self.srvgui.get_widget('widget_annotation')
624
        visor_annotations = self.srvgui.get_widget('visor_annotations')
625
        visor_sapnotes = self.srvgui.get_widget('visor_sapnotes')
626
        viewmenu = self.srvgui.get_widget('viewmenu')
627
 
628
        aid = widget_annotation.get_aid_from_widget()
629
        annotation = widget_annotation.get_metadata_from_widget()
630
 
631
        if self.srvant.is_valid(aid):
632
            self.srvant.update(annotation)
633
            title = self.srvant.get_title(aid)
634
            self.srvuif.statusbar_msg("Updated annotation: %s" % title, True)
635
        else:
636
            self.srvant.create(annotation)
637
            title = self.srvant.get_title(aid)
638
            self.srvuif.statusbar_msg('New annotation created: %s' % title, True)
639
        visor_annotations.populate_annotations()
640
        visor_sapnotes.populate_sapnotes()
641
        self.gui_annotation_widget_clear()
642
        self.srvuif.set_widget_visibility('gtk_vbox_container_annotations', False)
643
        self.srvuif.grab_focus()
644
 
645
 
646
    def action_annotation_cancel(self, *args):
647
        statusbar = self.srvgui.get_widget('widget_statusbar')
648
        self.gui_annotation_widget_clear()
649
        self.srvuif.set_widget_visibility('gtk_vbox_container_annotations', False)
650
        self.log.debug('Annotation canceled')
651
        self.srvuif.statusbar_msg("Annotation canceled")
652
        self.srvuif.grab_focus()
653
 
654
 
655
    def get_sapnotes_from_current_view(self, colname=None):
656
        viewmenu = self.srvgui.get_widget('viewmenu')
657
        view = viewmenu.get_view()
658
        rowtype = viewmenu.get_row_type()
659
        rowid = viewmenu.get_row_id()
660
 
661
        if view == 'collection':
662
            cols = self.srvclt.get_collections_by_row_title(colname)
663
            bag = []
664
            for colid in cols:
665
                bag.extend(self.srvdtb.get_notes_by_node('collection', colid))
666
        else:
667
            bag = self.srvdtb.get_notes_by_node(rowtype, rowid)
668
 
669
        return bag
670
 
671
 
672
    def action_collection_export_text_csv(self, *args):
673
        rootwin = self.srvgui.get_window()
674
        timestamp = self.srvutl.timestamp()
675
        filename = "%s%s.csv" % (LPATH['EXPORT'], timestamp)
676
        visor_sapnotes = self.srvgui.get_widget('visor_sapnotes')
677
 
678
        bag = visor_sapnotes.get_filtered_bag()
679
 
680
        dialog = Gtk.FileChooserDialog("Save file", rootwin,
681
            Gtk.FileChooserAction.SAVE,
682
                (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
683
                 Gtk.STOCK_SAVE, Gtk.ResponseType.OK))
684
        dialog.set_filename(filename)
685
        dialog.set_current_name(os.path.basename(filename))
686
        response = dialog.run()
687
 
688
        if response == Gtk.ResponseType.OK:
689
            export_path = dialog.get_filename()
690
            res = self.srvbnr.export_to_text_csv(bag, export_path)
691
            self.log.info("%d SAP Notes exported to CSV format: %s", len(bag), export_path)
692
            self.srvuif.statusbar_msg("%d SAP Notes exported to CSV format: %s" % (len(bag), export_path), True)
693
            self.srvuif.copy_text_to_clipboard(export_path)
694
        else:
695
            self.log.info("Export canceled by user")
696
            self.srvuif.statusbar_msg("Export canceled by user", True)
697
        dialog.destroy()
698
 
699
 
700
    def action_collection_export_excel(self, *args):
701
        rootwin = self.srvgui.get_window()
702
        timestamp = self.srvutl.timestamp()
703
        filename = "%s%s.xlsx" % (LPATH['EXPORT'], timestamp)
704
        visor_sapnotes = self.srvgui.get_widget('visor_sapnotes')
705
 
706
        bag = visor_sapnotes.get_filtered_bag()
707
 
708
        dialog = Gtk.FileChooserDialog("Save file", rootwin,
709
            Gtk.FileChooserAction.SAVE,
710
                (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
711
                 Gtk.STOCK_SAVE, Gtk.ResponseType.OK))
712
        dialog.set_filename(filename)
713
        dialog.set_current_name(os.path.basename(filename))
714
        response = dialog.run()
715
 
716
        if response == Gtk.ResponseType.OK:
717
            export_path = dialog.get_filename()
718
            res = self.srvbnr.export_to_excel(bag, export_path)
719
            if res:
720
                self.log.info("Selected SAP Notes exported to MS Excel format (xlsx): %s" % export_path)
721
                self.srvuif.statusbar_msg("%d SAP Notes exported to MS Excel format: %s" % (len(bag), export_path), True)
722
                self.srvuif.copy_text_to_clipboard(export_path)
723
            else:
724
                self.log.error(self.get_traceback())
725
        else:
726
            self.log.info("Export canceled by user")
727
            self.srvuif.statusbar_msg("Export canceled by user", True)
728
        dialog.destroy()
729
 
730
 
731
    def action_collection_export_basico(self, *args):
732
        rootwin = self.srvgui.get_window()
733
        timestamp = self.srvutl.timestamp()
734
        filename = "%s%s.bco" % (LPATH['EXPORT'], timestamp)
735
        visor_sapnotes = self.srvgui.get_widget('visor_sapnotes')
736
 
737
        bag = visor_sapnotes.get_filtered_bag()
738
 
739
        dialog = Gtk.FileChooserDialog("Save file", rootwin,
740
            Gtk.FileChooserAction.SAVE,
741
                (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
742
                 Gtk.STOCK_SAVE, Gtk.ResponseType.OK))
743
        dialog.set_filename(filename)
744
        dialog.set_current_name(os.path.basename(filename))
745
        response = dialog.run()
746
 
747
        if response == Gtk.ResponseType.OK:
748
            export_path = dialog.get_filename()
749
            target = self.srvbnr.export_to_basico(bag, export_path)
750
            self.log.info("%d SAP Notes exported to Basico %s format: %s", len(bag), APP['version'], target)
751
            self.srvuif.statusbar_msg("%d SAP Notes exported to Basico %s format: %s" % (len(bag), APP['version'], target), True)
752
            self.srvuif.copy_text_to_clipboard(export_path)
753
        else:
754
            self.log.info("Export canceled by user")
755
            self.srvuif.statusbar_msg("Export canceled by user", True)
756
        dialog.destroy()
757
 
758
 
759
    def action_collection_copy_to_clipboard(self, button):
760
        clipboard = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD)
761
        visor_sapnotes = self.srvgui.get_widget('visor_sapnotes')
762
 
763
        bag = visor_sapnotes.get_filtered_bag()
764
        text = ''
765
        for sid in bag:
766
            metadata = self.srvdtb.get_sapnote_metadata(sid)
767
            text += "SAP Note %s: %s - Component: %s\n" % (str(int(sid)), metadata['title'], metadata['componentkey'])
768
        clipboard.set_text(text, -1)
769
 
770
        msg = "%d SAP Notes copied to the clipboard: %s" % (len(bag), ', '.join(list(bag)))
771
        self.log.info(msg)
772
        msg = "%d SAP Notes copied to the clipboard" % len(bag)
773
        self.srvuif.statusbar_msg(msg, True)
774
 
775
 
776
    def gui_annotation_widget_clear(self):
777
        a_wdg_timestamp = self.srvgui.get_widget('gtk_label_human_timestamp')
778
        a_wdg_title = self.srvgui.get_widget('gtk_entry_annotation_title')
779
        a_wdg_type = self.srvgui.get_widget('gtk_combobox_annotation_type')
780
        a_wdg_text = self.srvgui.get_widget('gtk_textview_annotation_text')
781
        a_wdg_link = self.srvgui.get_widget('gtk_entry_annotation_link')
782
        a_wdg_link_button = self.srvgui.get_widget('gtk_link_button_annotation_link')
783
        a_wdg_link_type = self.srvgui.get_widget('gtk_combobox_annotation_link_type')
784
 
785
        a_wdg_timestamp.set_text('')
786
        a_wdg_title.set_text('')
787
        textbuffer = a_wdg_text.get_buffer()
788
        textbuffer.set_text('')
789
        a_wdg_link.set_text('')
790
        a_wdg_link_button.set_uri('')
791
        self.gui_annotation_widget_hide()
792
 
793
 
794
    def gui_annotation_widget_hide(self):
795
        self.srvuif.set_widget_visibility('gtk_vbox_container_annotations', False)
796
 
797
 
798
    def gui_copy_to_clipboard_sapnote(self, widget, lsid, popover):
799
        visor_sapnotes = self.srvgui.get_widget('visor_sapnotes')
800
        clipboard = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD)
801
        text = ''
802
        for sid in lsid:
803
            metadata = self.srvdtb.get_sapnote_metadata(sid)
804
            text += "SAP Note %10s: %s - Component: %s\n" % (sid, metadata['title'], metadata['componentkey'])
805
        clipboard.set_text(text, -1)
806
        if popover is not None:
807
            popover.hide()
808
            self.srvuif.grab_focus()
809
 
810
 
811
    def gui_jump_to_sapnote(self, widget, sid):
812
        visor_sapnotes = self.srvgui.get_widget('visor_sapnotes')
813
        visor_sapnotes.populate_sapnotes([sid])
814
        self.gui_show_visor_sapnotes()
815
        self.srvuif.grab_focus()
816
        msg = "Jumping to SAP Note %s" % sid
817
        self.log.info(msg)
818
        self.srvuif.statusbar_msg(msg)
819
 
820
 
821
    def gui_link_to_sapnote(self, *args):
822
        pass
823
 
824
    def gui_switch_selection_atypes(self, switch, state):
825
        label = self.srvgui.get_widget('gtk_label_switch_select_atypes')
826
        switched = switch.get_active()
827
        switch.set_state(switched)
828
        if switched is True:
829
            label.set_text ("All selected")
830
 
831
        else:
832
            label.set_text("None selected")
833
 
834
        for name in ATYPES:
835
            button = self.srvgui.get_widget('gtk_button_type_%s' % name.lower())
836
            button.set_state(switched)
837
            button.set_active(switched)
838
 
839
 
840
    def gui_sapnotes_select_all_none(self, witch, state):
841
        visor = self.srvgui.get_widget('visor_sapnotes')
842
        model = visor.get_model()
843
 
844
        def get_selected_sapnotes(model, path, itr):
845
            component = model.get(itr, 5)
846
            if component != 'Annotation':
847
                model.set(itr, 2, state)
848
 
849
        model.foreach(get_selected_sapnotes)
348 t00mlabs 850
 
851
 
852
    def gui_maximize_annotation_window(self, *args):
853
        stack_main = self.srvgui.get_widget('gtk_stack_main')
854
        toggle_button = self.srvgui.get_widget('gtk_togglebutton_maximize_annotation_widget')
855
        if toggle_button.get_active():
856
            stack_main.hide()
857
        else:
858
            stack_main.show_all()