Subversion Repositories basico

Rev

Rev 407 | 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
369 t00mlabs 19
from gi.repository import GObject
340 t00mlabs 20
 
21
from basico.core.mod_srv import Service
22
from basico.core.mod_env import FILE, LPATH, ATYPES, APP
23
from basico.widgets.wdg_cols import CollectionsMgtView
24
from basico.widgets.wdg_settingsview import SettingsView
25
 
26
 
27
class Callback(Service):
28
    def initialize(self):
29
        self.get_services()
30
 
31
    def get_services(self):
32
        self.srvstg = self.get_service('Settings')
33
        self.srvdtb = self.get_service('DB')
34
        self.srvgui = self.get_service('GUI')
35
        self.srvuif = self.get_service("UIF")
36
        self.srvsap = self.get_service('SAP')
37
        self.srvicm = self.get_service('IM')
38
        self.srvutl = self.get_service('Utils')
39
        self.srvant = self.get_service('Annotation')
40
        self.srvbnr = self.get_service('BNR')
41
        self.srvclt = self.get_service('Collections')
356 t00mlabs 42
        self.srvatc = self.get_service('Attachment')
340 t00mlabs 43
 
44
 
390 t00mlabs 45
    def stack_visor_changed(self, stack, gparam):
46
        visible_stack_name = stack.get_visible_child_name()
47
        if visible_stack_name is None:
48
            return
49
 
50
        if visible_stack_name == 'visor-sapnotes':
340 t00mlabs 51
            self.srvuif.set_widget_visibility('gtk_label_total_notes', True)
362 t00mlabs 52
            visor_sapnotes = self.srvgui.get_widget('visor_sapnotes')
53
            visor_sapnotes.update_total_sapnotes_count()
390 t00mlabs 54
        elif visible_stack_name == 'visor-annotations':
340 t00mlabs 55
            self.srvuif.set_widget_visibility('gtk_label_total_notes', True)
362 t00mlabs 56
            visor_annotations = self.srvgui.get_widget('visor_annotations')
57
            visor_annotations.populate()
367 t00mlabs 58
        else:
362 t00mlabs 59
            self.srvuif.set_widget_visibility('gtk_label_total_notes', True)
60
            visor_attachments = self.srvgui.get_widget('visor_attachments')
61
            visor_attachments.populate()
340 t00mlabs 62
 
393 t00mlabs 63
 
340 t00mlabs 64
    def gui_show_visor_sapnotes(self):
393 t00mlabs 65
        stack_main = self.srvgui.get_widget('gtk_stack_main')
66
        stack_main.set_visible_child_name('dashboard')
67
        stack_visors = self.srvgui.get_widget('gtk_stack_visors')
68
        stack_visors.set_visible_child_name('visor-sapnotes')
340 t00mlabs 69
 
70
 
71
    def gui_show_visor_annotations(self):
393 t00mlabs 72
        stack_main = self.srvgui.get_widget('gtk_stack_main')
73
        stack_main.set_visible_child_name('dashboard')
74
        stack_visors = self.srvgui.get_widget('gtk_stack_visors')
75
        stack_visors.set_visible_child_name('visor-annotations')
340 t00mlabs 76
 
77
 
393 t00mlabs 78
    def gui_show_visor_attachments(self):
79
        stack_main = self.srvgui.get_widget('gtk_stack_main')
80
        stack_main.set_visible_child_name('dashboard')
81
        stack_visors = self.srvgui.get_widget('gtk_stack_visors')
82
        stack_visors.set_visible_child_name('visor-attachments')
83
 
84
 
340 t00mlabs 85
    def action_search(self, entry):
390 t00mlabs 86
        stack_visors = self.srvgui.get_widget('gtk_stack_visors')
340 t00mlabs 87
        visor_sapnotes = self.srvgui.get_widget('visor_sapnotes')
88
        visor_annotations = self.srvgui.get_widget('visor_annotations')
89
        term = entry.get_text()
390 t00mlabs 90
 
91
        stack_visor = stack_visors.get_visible_child_name()
340 t00mlabs 92
        completion = self.srvgui.get_widget('gtk_entrycompletion_visor')
93
        completion_model = completion.get_model()
94
        completion_model.clear()
95
 
390 t00mlabs 96
        if stack_visor == 'visor-sapnotes':
340 t00mlabs 97
            bag = self.srvdtb.search(term)
362 t00mlabs 98
            visor_sapnotes.populate(bag)
340 t00mlabs 99
            ebuffer = entry.get_buffer()
100
            ebuffer.delete_text(0, -1)
101
            msg = "Found %d SAP Notes for term '%s'" % (len(bag), term)
102
            self.log.info(msg)
103
            self.srvuif.statusbar_msg(msg)
390 t00mlabs 104
        elif stack_visor == 'visor-annotations':
340 t00mlabs 105
            annotations = self.srvant.search_term(term)
362 t00mlabs 106
            visor_annotations.populate(annotations)
340 t00mlabs 107
            msg = "Found %d annotations for term '%s'" % (len(annotations), term)
108
            self.log.info(msg)
109
            self.srvuif.statusbar_msg(msg)
110
 
111
 
112
 
113
    def sapnote_browse(self, button, sid):
114
        self.log.info("Browsing SAP Note %d" % int(sid))
115
        SAP_NOTE_URL = self.srvstg.get('SAP', 'SAP_NOTE_URL')
116
        url = SAP_NOTE_URL % sid
383 t00mlabs 117
        self.srvuif.grab_focus()
340 t00mlabs 118
        self.srvutl.browse(url)
119
 
120
 
121
    def sapnote_download_pdf(self, button, sid):
122
        self.log.info("Browsing PDF for SAP Note %d" % int(sid))
123
        SAP_NOTE_URL_PDF = self.srvstg.get('SAP', 'SAP_NOTE_URL_PDF')
124
        url = SAP_NOTE_URL_PDF % sid
125
        self.srvutl.browse(url)
126
 
127
 
128
    def sapnote_delete(self, button, sid):
362 t00mlabs 129
        visor_sapnotes = self.srvgui.get_widget('visor_sapnotes')
340 t00mlabs 130
        viewmenu = self.srvgui.get_widget('viewmenu')
131
 
132
        answer = self.srvuif.warning_message_delete_sapnotes(button, 'Deleting SAP Notes', 'Are you sure?', [sid])
133
        if answer is True:
134
            self.srvdtb.delete(sid)
135
            self.srvuif.statusbar_msg("SAP Note %s deleted" % sid, True)
362 t00mlabs 136
            visor_sapnotes.reload()
340 t00mlabs 137
        else:
138
            self.log.info("SAP Note %s not deletd", sid)
139
 
140
 
141
    def sapnote_delete_view(self, button):
362 t00mlabs 142
        visor_sapnotes = self.srvgui.get_widget('visor_sapnotes')
340 t00mlabs 143
        viewmenu = self.srvgui.get_widget('viewmenu')
144
 
362 t00mlabs 145
        bag = visor_sapnotes.get_filtered_bag()
340 t00mlabs 146
        answer = self.srvuif.warning_message_delete_sapnotes(button, 'Deleting SAP Notes', 'Are you sure?', bag)
147
        if answer is True:
148
            for sid in bag:
149
                self.srvdtb.delete(sid)
362 t00mlabs 150
            visor_sapnotes.reload()
340 t00mlabs 151
            msg = "Deleted %d SAP Notes" % len(bag)
152
            self.log.info(msg)
153
            self.srvuif.statusbar_msg(msg, True)
154
        else:
155
            msg = "None of the %d SAP Notes has been deleted" % len(bag)
156
            self.log.info(msg)
157
            self.srvuif.statusbar_msg(msg, True)
362 t00mlabs 158
        visor_sapnotes.reload()
340 t00mlabs 159
        viewmenu.populate()
160
 
362 t00mlabs 161
 
340 t00mlabs 162
    def gui_hide_popover(self, popover):
163
        popover.hide()
164
 
165
 
166
    def gui_database_backup(self, *args):
167
        window = self.srvgui.get_window()
168
        question = "Backup database"
169
        message = "\nShould this backup include all your annotations?"
170
        wdialog = self.srvuif.message_dialog_question(question, message)
171
        res_bck_annot = wdialog.run()
172
        wdialog.destroy()
173
 
174
        dialog = Gtk.FileChooserDialog("Please choose target folder and backup name (without extension)", window,
175
            Gtk.FileChooserAction.SAVE,
176
            ("Cancel", Gtk.ResponseType.CANCEL,
177
            "Select", Gtk.ResponseType.OK))
178
        TIMESTAMP = self.srvutl.timestamp()
179
        TARGET_FILE = 'basico-%s' % TIMESTAMP
180
        dialog.set_filename(LPATH['BACKUP'])
181
        dialog.set_current_folder_uri(LPATH['BACKUP'])
182
        dialog.set_current_name(TARGET_FILE)
183
        dialog.set_default_size(800, 400)
184
        res_bck_file = dialog.run()
185
        self.log.debug("Backup file: %s", dialog.get_filename())
377 t00mlabs 186
 
340 t00mlabs 187
        if res_bck_file == Gtk.ResponseType.OK:
188
            backup_filename = dialog.get_filename()
189
            if res_bck_annot == Gtk.ResponseType.YES:
190
                bckname = self.srvbnr.backup(backup_filename, backup_annotations=True)
191
                msg = "Database with annotations backed up successfully to: %s" % bckname
192
                dialog.destroy()
193
            else:
194
                bckname = self.srvbnr.backup(backup_filename, backup_annotations=False)
195
                msg = "Database without annotations backed up successfully to: %s" % bckname
196
            self.log.info(msg)
197
            self.srvuif.statusbar_msg(msg, True)
198
            self.srvuif.copy_text_to_clipboard(bckname)
377 t00mlabs 199
 
340 t00mlabs 200
        else:
201
            self.srvuif.statusbar_msg("Backup aborted by user", True)
202
            self.log.info("Backup aborted")
203
        self.srvuif.grab_focus()
204
 
205
 
206
    def gui_database_restore(self, *args):
207
        visor_annotations = self.srvgui.get_widget('visor_annotations')
208
        window = self.srvgui.get_window()
209
        dialog = Gtk.FileChooserDialog("Please choose a backup file", window,
210
            Gtk.FileChooserAction.OPEN,
211
            (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
212
            Gtk.STOCK_OPEN, Gtk.ResponseType.OK))
213
        dialog.set_current_folder(LPATH['BACKUP'])
214
        filter_zip = Gtk.FileFilter()
215
        filter_zip.set_name("Basico backup files")
216
        filter_zip.add_pattern("*.bco")
217
        dialog.add_filter(filter_zip)
218
        response = dialog.run()
219
        backup = dialog.get_filename()
220
        self.log.info("You are about to restore this file: %s" % backup)
221
        dialog.destroy()
222
 
223
        if response == Gtk.ResponseType.OK:
224
            res = self.srvbnr.test(backup)
225
            if res is None:
226
                dialog = self.srvuif.message_dialog_info("Backup file corrupted?", "It wasn't possible to read all data from this file")
227
                dialog.run()
228
                self.srvuif.statusbar_msg("Backup file corrupted. It wasn't possible to read all data from this file", True)
229
                self.log.info("Backup file corrupted?")
230
            else:
231
                # Ask if the process should force an overwrite in target database
232
                question = "Should the import process overwrite data?"
233
                message = "All metadata for SAP Notes will be overwrited and annotations with the same identifier will be overwriten"
234
                wdialog = self.srvuif.message_dialog_question(question, message)
235
                response = wdialog.run()
236
                wdialog.destroy()
237
                if response == Gtk.ResponseType.YES:
238
                    overwrite = True
239
                else:
240
                    overwrite = False
241
 
242
 
243
                # Ask for final confirmation
244
                sncount, ancount, clcount = res
245
                question = "Restoring backup %s" % os.path.basename(backup)
246
                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)
247
                message += "Do you still want to restore this backup?\n"
248
                wdialog = self.srvuif.message_dialog_question(question, message)
249
                response = wdialog.run()
250
                wdialog.destroy()
251
                if response == Gtk.ResponseType.YES:
252
                    self.srvbnr.restore_from_backup(backup, overwrite)
253
                    self.srvdtb.load_notes()
254
                    self.srvclt.load_collections()
362 t00mlabs 255
                    visor_annotations.populate()
340 t00mlabs 256
                    self.gui_refresh_view()
257
                    self.gui_show_visor_sapnotes()
258
                    self.srvuif.statusbar_msg("Backup restored successfully", True)
259
                    self.log.info("Backup restored successfully")
260
                elif response == Gtk.ResponseType.NO:
261
                    self.srvuif.statusbar_msg("Restore aborted by user", True)
262
                    self.log.info("Restore aborted")
263
        elif response == Gtk.ResponseType.CANCEL:
264
            self.srvuif.statusbar_msg("Restore aborted by user", True)
265
            self.log.info("Restore aborted")
266
 
267
        dialog.destroy()
268
        self.srvuif.grab_focus()
269
 
270
 
271
    def gui_show_about(self, *args):
272
        about = self.srvgui.get_widget('widget_about')
273
        stack = self.srvgui.get_widget('gtk_stack_main')
274
        stack.set_visible_child_name('about')
275
        self.gui_hide_popover(self.srvgui.get_widget('gtk_popover_button_menu_system'))
276
        self.srvuif.set_widget_visibility('gtk_label_total_notes', False)
389 t00mlabs 277
        # ~ self.srvuif.set_widget_visibility('gtk_button_dashboard', True)
278
        self.srvuif.grab_focus()
340 t00mlabs 279
 
280
 
281
    def gui_show_log(self, *args):
282
        logviewer = self.srvgui.get_widget('widget_logviewer')
283
        stack = self.srvgui.get_widget('gtk_stack_main')
284
        logviewer.update()
285
        self.gui_hide_popover(self.srvgui.get_widget('gtk_popover_button_menu_system'))
286
        stack.set_visible_child_name('log')
389 t00mlabs 287
        # ~ self.srvuif.set_widget_visibility('gtk_button_dashboard', True)
340 t00mlabs 288
        self.srvuif.statusbar_msg("Displaying application log")
389 t00mlabs 289
        self.srvuif.grab_focus()
340 t00mlabs 290
 
291
 
292
    def gui_show_settings(self, button):
293
        notebook_menuview = self.srvgui.get_widget('gtk_notebook_menuview')
294
        stack = self.srvgui.get_widget('gtk_stack_main')
295
        view_settings = self.srvgui.get_widget('widget_settings')
296
        stack.set_visible_child_name('settings')
297
        view_settings.update()
298
        self.gui_hide_popover(self.srvgui.get_widget('gtk_popover_button_menu_system'))
299
        self.srvuif.set_widget_visibility('gtk_label_total_notes', False)
389 t00mlabs 300
        # ~ self.srvuif.set_widget_visibility('gtk_button_dashboard', True)
340 t00mlabs 301
 
302
        notebook_menuview.hide()
303
        view_settings.grab_focus()
304
        self.srvuif.statusbar_msg("Displaying application settings")
305
 
306
 
307
    def gui_show_dashboard(self, *args):
308
        stack = self.srvgui.get_widget('gtk_stack_main')
389 t00mlabs 309
        # ~ notebook_menuview = self.srvgui.get_widget('gtk_notebook_menuview')
340 t00mlabs 310
        viewmenu = self.srvgui.get_widget('viewmenu')
311
        current_view = viewmenu.get_view()
312
 
389 t00mlabs 313
        # ~ notebook_menuview.show_all()
314
        stack.set_visible_child_name('dashboard')
340 t00mlabs 315
        self.gui_hide_popover(self.srvgui.get_widget('gtk_popover_button_menu_system'))
389 t00mlabs 316
        # ~ self.srvuif.set_widget_visibility('gtk_button_dashboard', False)
340 t00mlabs 317
 
318
        if current_view == 'annotation':
319
            self.srvuif.set_widget_visibility('gtk_label_total_notes', True)
320
        else:
321
            self.srvuif.set_widget_visibility('gtk_label_total_notes', True)
322
        self.srvuif.statusbar_msg("Displaying application dashboard")
323
 
324
 
325
    def gui_toggle_help_visor(self, *args):
326
        button = self.srvgui.get_widget('gtk_togglebutton_help')
327
        notebook = self.srvgui.get_widget('gtk_notebook_visor')
328
 
329
        if button.get_active():
330
            self.srvuif.set_widget_visibility('gtk_notebook_help_page', True)
331
            notebook.set_current_page(2)
332
        else:
333
            self.srvuif.set_widget_visibility('gtk_notebook_help_page', False)
334
            notebook.set_current_page(0)
335
        self.srvuif.statusbar_msg("Displaying application help")
336
 
337
 
338
    def gui_lauch_help_visor(self, *args):
339
        self.srvutl.browse("file://%s" % FILE['HELP_INDEX'])
340
 
341
 
380 t00mlabs 342
    def gui_annotation_widget_show(self, aid, action='create'):
389 t00mlabs 343
        notebook = self.srvgui.get_widget('gtk_notebook_annotations_visor')
340 t00mlabs 344
        widget_annotation = self.srvgui.get_widget('widget_annotation')
385 t00mlabs 345
        stack_main = self.srvgui.get_widget('gtk_stack_main')
377 t00mlabs 346
        widget = self.srvgui.get_widget('gtk_label_timestamp_created')
389 t00mlabs 347
        stack_visors = self.srvgui.get_widget('gtk_stack_visors')
380 t00mlabs 348
 
389 t00mlabs 349
        stack_visors.set_visible_child_name("visor-annotations")
350
        notebook.set_current_page(1)
351
        self.srvuif.set_widget_visibility('visortoolbar', False)
352
 
340 t00mlabs 353
        if action == 'create':
389 t00mlabs 354
            widget_annotation.clear()
380 t00mlabs 355
            if aid == '':
356
                aid = self.srvant.gen_aid()
357
            else:
358
                sid = aid
359
                aid = self.srvant.gen_aid(sid)
360
            widget_annotation.set_visible_stack('editor')
340 t00mlabs 361
        elif action == 'edit':
380 t00mlabs 362
            widget_annotation.set_visible_stack('editor')
363
        elif action == 'preview':
364
            widget_annotation.set_visible_stack('preview')
340 t00mlabs 365
 
383 t00mlabs 366
        self.log.debug("Action: %s annotation with Id: %s", action, aid)
367
 
340 t00mlabs 368
        widget_annotation.set_metadata_to_widget(aid, action)
389 t00mlabs 369
        # ~ stack_main.set_visible_child_name('annotations')
385 t00mlabs 370
 
380 t00mlabs 371
        self.srvuif.grab_focus()
340 t00mlabs 372
 
373
 
374
    def gui_show_popover(self, button, popover):
379 t00mlabs 375
        self.srvgui.set_key_value('LAST_POPOVER', popover)
340 t00mlabs 376
        if popover.get_visible():
383 t00mlabs 377
            popover.popdown()
340 t00mlabs 378
            popover.hide()
379
        else:
380
            popover.show_all()
383 t00mlabs 381
            popover.popup()
340 t00mlabs 382
 
383
 
384
    def switch_bookmark_current_view(self, *args):
362 t00mlabs 385
        visor_sapnotes = self.srvgui.get_widget('visor_sapnotes')
386
        bag = visor_sapnotes.get_filtered_bag()
340 t00mlabs 387
        try:
388
            for sid in bag:
389
                metadata = self.srvdtb.get_sapnote_metadata(sid)
390
                bookmark = metadata['bookmark']
391
                if bookmark:
392
                    self.sapnote_unbookmark([sid])
393
                else:
394
                    self.sapnote_bookmark([sid])
395
        except:
396
            self.log.error("Could not bookmark SAP Note %s" % sid)
397
            self.log.error(self.get_traceback())
362 t00mlabs 398
        visor_sapnotes.populate(bag)
340 t00mlabs 399
        msg = "%d SAP Notes (un)bookmarked" % len(bag)
400
        self.log.info(msg)
401
        self.srvuif.statusbar_msg(msg, True)
402
 
403
 
404
    def switch_bookmark(self, button, lsid, popover):
362 t00mlabs 405
        visor_sapnotes = self.srvgui.get_widget('visor_sapnotes')
340 t00mlabs 406
        try:
407
            for sid in lsid:
408
                metadata = self.srvdtb.get_sapnote_metadata(sid)
409
                bookmark = metadata['bookmark']
410
                if bookmark:
411
                    self.sapnote_unbookmark([sid])
412
                    self.srvuif.statusbar_msg("SAP Notes unbookmarked")
413
                else:
414
                    self.sapnote_bookmark([sid])
415
                    self.srvuif.statusbar_msg("SAP Notes bookmarked")
416
            popover.hide()
417
        except:
418
            self.log.error("Could not bookmark SAP Note %s" % sid)
419
            self.log.error(self.get_traceback())
362 t00mlabs 420
        visor_sapnotes.populate()
340 t00mlabs 421
 
422
 
423
    def sapnote_bookmark(self, lsid):
424
        self.srvdtb.set_bookmark(lsid)
425
 
426
 
427
    def sapnote_unbookmark(self, lsid):
428
        self.srvdtb.set_no_bookmark(lsid)
429
 
430
 
431
    def sapnote_import_from_launchpad(self, *args):
432
        db = self.get_service('DB')
433
        webdriver = self.get_service('Driver')
434
        textview = self.srvgui.get_widget('gtk_textview_download_launchpad')
362 t00mlabs 435
        visor_sapnotes = self.srvgui.get_widget('visor_sapnotes')
340 t00mlabs 436
 
437
        bag = []
438
        all_notes = []
439
        sapnotes = []
440
        dlbuffer = textview.get_buffer()
441
        istart, iend = dlbuffer.get_bounds()
442
        text = dlbuffer.get_text(istart, iend, False)
396 t00mlabs 443
        self.log.debug(text)
340 t00mlabs 444
        lines = text.replace(' ', ',')
445
        lines = lines.replace('\n', ',')
396 t00mlabs 446
        self.log.debug(lines)
340 t00mlabs 447
        for sid in lines.split(','):
448
            sid = sid.strip()
449
            if len(sid) > 0:
450
                sapnotes.append(sid)
451
        for sid in sapnotes:
452
            is_valid = self.srvdtb.is_valid(sid)
453
            is_saved = self.srvdtb.get_sapnote_metadata(sid)
454
            if is_valid and not is_saved:
455
                bag.append(sid)
456
            if is_valid:
457
                all_notes.append(sid)
458
        lbag = list(bag)
459
        lbag.sort()
460
 
461
        if len(bag)> 0:
462
            driver = webdriver.open()
463
 
464
        winroot = self.srvgui.get_widget('gtk_app_window_main')
465
        msg = "%d SAP Notes to be downloaded: %s" % (len(bag), ', '.join(list(bag)))
466
        self.log.info(msg)
467
 
468
        result = {}
469
 
470
        self.srvsap.start_fetching(len(bag))
471
        dlbag = []
472
 
473
        # FIXME: max_workers = 1 = Threads disabled
474
        # Indeed, I think this is the best option right now.
475
        with Executor(max_workers=1) as exe:
476
            jobs = []
477
            for sapnote in lbag:
478
                job = exe.submit(self.srvsap.fetch, driver, sapnote)
479
                jobs.append(job)
480
 
481
            for job in jobs:
482
                rc, sapnote = job.result()
483
                msg = "\tRC SAP Note %s: %s" % (sapnote, rc)
484
                self.log.info(msg)
485
                result[sapnote] = rc
486
                if rc:
487
                    sid = "0"*(10 - len(sapnote)) + sapnote
488
                    dlbag.append(sid)
489
                time.sleep(0.2)
490
 
491
        dlbuffer.set_text('')
407 t00mlabs 492
        # ~ popover = self.srvgui.get_widget('gtk_popover_toolbutton_import')
396 t00mlabs 493
        # ~ self.gui_hide_popover(popover)
340 t00mlabs 494
        if len(bag) > 0:
495
            webdriver.close(driver)
496
 
497
        self.srvsap.stop_fetching()
498
        db.save_notes()
499
        db.build_stats()
500
        self.log.info("Download completed.")
501
        self.srvuif.statusbar_msg("Download completed", True)
362 t00mlabs 502
        visor_sapnotes.populate(all_notes)
340 t00mlabs 503
        self.gui_show_visor_sapnotes()
504
        return result
505
 
506
 
507
    def expand_menuview(self):
508
        viewmenu = self.srvgui.get_widget('viewmenu')
509
        viewmenu.expand_all()
510
 
511
 
512
    def gui_viewmenu_filter(self, *args):
513
        entry = self.srvgui.get_widget('gtk_entry_filter_view')
514
        filter = entry.get_text()
515
        viewmenu = self.srvgui.get_widget('viewmenu')
516
        selection = viewmenu.get_selection()
517
 
518
        def gui_iterate_over_data(model, path, itr):
519
            rowkey = model.get(itr, 0)[0]
520
            rowtype, rowval = rowkey.split('@')
521
            dsc = model.get(itr, 1)[0]
522
            contents = model.get(itr, 1)[0]
523
            cleanstr = contents.replace('<b>', '')
524
            cleanstr = cleanstr.replace('</b>', '')
525
            model.set(itr, 1, '%s' % cleanstr)
526
            viewmenu.collapse_row(path)
527
 
528
            if len(filter) > 0:
529
                if filter.upper() in rowval.upper() or filter.upper() in dsc.upper():
530
                    viewmenu.expand_to_path (path)
531
                    selection.select_path(path)
532
                    model.set(itr, 1, '<b>%s</b>' % contents)
533
            else:
534
                return
535
 
536
        model = viewmenu.get_model()
537
        model.foreach(gui_iterate_over_data)
538
 
539
 
540
    def gui_viewmenu_select_first_entry(self):
541
        viewmenu = self.srvgui.get_widget('viewmenu')
542
        selection = viewmenu.get_selection()
543
        selection.select_path("0")
544
 
545
 
393 t00mlabs 546
    def gui_filter_visor(self, entry=None):
390 t00mlabs 547
        stack_visors = self.srvgui.get_widget('gtk_stack_visors')
548
        visible_stack_name = stack_visors.get_visible_child_name()
549
 
550
        if visible_stack_name == 'visor-sapnotes':
362 t00mlabs 551
            visor_sapnotes = self.srvgui.get_widget('visor_sapnotes')
408 t00mlabs 552
            visible_filter = self.srvgui.get_widget('visor_sapnotes_visible_filter')
340 t00mlabs 553
            visible_filter.refilter()
362 t00mlabs 554
            visor_sapnotes.update_total_sapnotes_count()
390 t00mlabs 555
        elif visible_stack_name == 'visor-annotations':
362 t00mlabs 556
            visor_annotations = self.srvgui.get_widget('visor_annotations')
557
            visor_annotations.populate()
400 t00mlabs 558
            visible_filter = self.srvgui.get_widget('visor_annotation_visible_filter')
340 t00mlabs 559
            visible_filter.refilter()
362 t00mlabs 560
            visor_annotations.update_total_annotations_count()
340 t00mlabs 561
 
562
 
563
    def gui_refresh_view(self, button=None, view=None):
564
        window = self.srvgui.get_widget('gtk_app_window_main')
565
        viewmenu = self.srvgui.get_widget('viewmenu')
566
        if view is None:
567
            view = viewmenu.get_view()
568
 
569
        if view is not None:
570
            viewlabel = self.srvgui.get_widget('gtk_label_current_view')
571
            name = "<b>%-10s</b>" % view.capitalize()
572
            viewlabel.set_markup(name)
573
        viewmenu.set_view(view)
574
        popover = self.srvgui.get_widget('gtk_popover_button_menu_views')
575
        popover.hide()
576
        self.gui_show_visor_sapnotes()
577
 
578
 
579
    def gui_toggle_menu_view(self, obj):
580
        paned = self.srvgui.get_widget('gtk_vbox_container_menu_view')
581
        button = self.srvgui.get_widget('gtk_toogletoolbutton_menu_view')
582
        if isinstance(obj, Gtk.ToggleToolButton):
583
            if button.get_active():
584
                paned.show_all()
585
            else:
586
                paned.hide()
587
        elif isinstance(obj, bool):
588
            if obj == True:
589
                button.set_active(True)
590
            else:
591
                button.set_active(False)
592
 
593
 
594
    def gui_toggle_fullscreen(self, button):
595
        icon_container = self.srvgui.get_widget('gtk_box_container_icon_fullscreen')
596
        icon_fullscreen = self.srvicm.get_new_image_icon('basico-fullscreen', 24, 24)
597
        icon_unfullscreen = self.srvicm.get_new_image_icon('basico-unfullscreen', 24, 24)
598
        active = button.get_active()
599
        window = self.srvgui.get_window()
600
        if active:
601
            self.srvgui.swap_widget(icon_container, icon_unfullscreen)
602
            window.fullscreen()
603
        else:
604
            self.srvgui.swap_widget(icon_container, icon_fullscreen)
605
            window.unfullscreen()
606
 
607
 
380 t00mlabs 608
    def action_annotation_create(self):
609
        self.gui_annotation_widget_show('', 'create')
610
 
611
 
397 t00mlabs 612
    def action_annotation_create_from_template(self, aid):
613
        new_aid = self.srvant.duplicate_from_template(aid)
614
        self.action_annotation_edit(new_aid)
615
 
616
 
380 t00mlabs 617
    def action_annotation_create_for_sapnote(self, sid):
618
        self.gui_annotation_widget_show(sid, 'create')
619
 
620
 
340 t00mlabs 621
    def action_annotation_edit(self, aid):
380 t00mlabs 622
        self.gui_annotation_widget_show(aid, 'edit')
340 t00mlabs 623
 
624
 
380 t00mlabs 625
    def action_annotation_preview(self, aid):
626
        self.gui_annotation_widget_show(aid, 'preview')
627
 
628
 
340 t00mlabs 629
    def action_annotation_duplicate(self, *args):
630
        self.log.debug("ACTION-DUPLICATE: %s" % args)
631
 
632
 
633
    def action_annotation_delete(self, *args):
362 t00mlabs 634
        visor_annotations = self.srvgui.get_widget('visor_annotations')
377 t00mlabs 635
        aids = visor_annotations.rows_toggled()
636
        answer = self.srvuif.warning_message_delete_annotations(None, 'Deleting annotations', 'Are you sure?', aids)
340 t00mlabs 637
        if answer is True:
377 t00mlabs 638
            for aid in aids:
639
                self.srvant.delete(aid)
362 t00mlabs 640
            visor_annotations.populate()
377 t00mlabs 641
            self.srvuif.statusbar_msg("Annotations deleted", True)
340 t00mlabs 642
        else:
377 t00mlabs 643
            self.log.info("Annotations hasn't been deleted")
340 t00mlabs 644
            self.srvuif.statusbar_msg("Action canceled. Nothing deleted.", True)
645
 
646
        self.srvuif.grab_focus()
647
 
648
 
649
    def action_annotation_accept(self, button, sid):
650
        widget_annotation = self.srvgui.get_widget('widget_annotation')
651
        visor_annotations = self.srvgui.get_widget('visor_annotations')
652
        visor_sapnotes = self.srvgui.get_widget('visor_sapnotes')
653
        viewmenu = self.srvgui.get_widget('viewmenu')
389 t00mlabs 654
        notebook = self.srvgui.get_widget('gtk_notebook_annotations_visor')
655
        notebook.set_current_page(0)
340 t00mlabs 656
 
657
        aid = widget_annotation.get_aid_from_widget()
377 t00mlabs 658
        annotation = widget_annotation.get_metadata_from_widget()
340 t00mlabs 659
 
660
        if self.srvant.is_valid(aid):
661
            self.srvant.update(annotation)
662
            title = self.srvant.get_title(aid)
663
            self.srvuif.statusbar_msg("Updated annotation: %s" % title, True)
664
        else:
665
            self.srvant.create(annotation)
666
            title = self.srvant.get_title(aid)
667
            self.srvuif.statusbar_msg('New annotation created: %s' % title, True)
362 t00mlabs 668
        visor_annotations.populate()
669
        visor_sapnotes.populate()
389 t00mlabs 670
        widget_annotation.clear()
671
        self.srvuif.set_widget_visibility('visortoolbar', True)
340 t00mlabs 672
        self.srvuif.grab_focus()
673
 
674
 
408 t00mlabs 675
    def action_annotation_save(self):
676
        widget_annotation = self.srvgui.get_widget('widget_annotation')
677
        aid = widget_annotation.get_aid_from_widget()
678
        annotation = widget_annotation.get_metadata_from_widget()
679
 
680
        if self.srvant.is_valid(aid):
681
            self.srvant.update(annotation)
682
            title = self.srvant.get_title(aid)
683
            self.srvuif.statusbar_msg("Updated annotation: %s" % title, True)
684
 
685
 
340 t00mlabs 686
    def action_annotation_cancel(self, *args):
687
        statusbar = self.srvgui.get_widget('widget_statusbar')
389 t00mlabs 688
        widget_annotation = self.srvgui.get_widget('widget_annotation')
689
        notebook = self.srvgui.get_widget('gtk_notebook_annotations_visor')
690
        notebook.set_current_page(0)
691
 
692
        widget_annotation.clear()
693
        self.srvuif.set_widget_visibility('visortoolbar', True)
694
        # ~ page = self.srvgui.get_key_value('current_visor_tab')
695
        # ~ notebook = self.srvgui.get_widget('gtk_notebook_visor')
696
        # ~ notebook.set_current_page(page)
400 t00mlabs 697
        # ~ self.log.debug('Annotation canceled')
340 t00mlabs 698
        self.srvuif.statusbar_msg("Annotation canceled")
385 t00mlabs 699
        self.gui_show_dashboard()
340 t00mlabs 700
        self.srvuif.grab_focus()
701
 
702
 
703
    def get_sapnotes_from_current_view(self, colname=None):
704
        viewmenu = self.srvgui.get_widget('viewmenu')
705
        view = viewmenu.get_view()
706
        rowtype = viewmenu.get_row_type()
707
        rowid = viewmenu.get_row_id()
708
 
709
        if view == 'collection':
710
            cols = self.srvclt.get_collections_by_row_title(colname)
711
            bag = []
712
            for colid in cols:
713
                bag.extend(self.srvdtb.get_notes_by_node('collection', colid))
714
        else:
715
            bag = self.srvdtb.get_notes_by_node(rowtype, rowid)
716
 
717
        return bag
718
 
719
 
720
    def action_collection_export_text_csv(self, *args):
721
        rootwin = self.srvgui.get_window()
722
        timestamp = self.srvutl.timestamp()
723
        filename = "%s%s.csv" % (LPATH['EXPORT'], timestamp)
724
        visor_sapnotes = self.srvgui.get_widget('visor_sapnotes')
725
 
726
        bag = visor_sapnotes.get_filtered_bag()
727
 
728
        dialog = Gtk.FileChooserDialog("Save file", rootwin,
729
            Gtk.FileChooserAction.SAVE,
730
                (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
731
                 Gtk.STOCK_SAVE, Gtk.ResponseType.OK))
732
        dialog.set_filename(filename)
733
        dialog.set_current_name(os.path.basename(filename))
734
        response = dialog.run()
735
 
736
        if response == Gtk.ResponseType.OK:
737
            export_path = dialog.get_filename()
738
            res = self.srvbnr.export_to_text_csv(bag, export_path)
739
            self.log.info("%d SAP Notes exported to CSV format: %s", len(bag), export_path)
740
            self.srvuif.statusbar_msg("%d SAP Notes exported to CSV format: %s" % (len(bag), export_path), True)
741
            self.srvuif.copy_text_to_clipboard(export_path)
742
        else:
743
            self.log.info("Export canceled by user")
744
            self.srvuif.statusbar_msg("Export canceled by user", True)
745
        dialog.destroy()
746
 
747
 
748
    def action_collection_export_excel(self, *args):
749
        rootwin = self.srvgui.get_window()
750
        timestamp = self.srvutl.timestamp()
751
        filename = "%s%s.xlsx" % (LPATH['EXPORT'], timestamp)
752
        visor_sapnotes = self.srvgui.get_widget('visor_sapnotes')
753
 
754
        bag = visor_sapnotes.get_filtered_bag()
755
 
756
        dialog = Gtk.FileChooserDialog("Save file", rootwin,
757
            Gtk.FileChooserAction.SAVE,
758
                (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
759
                 Gtk.STOCK_SAVE, Gtk.ResponseType.OK))
760
        dialog.set_filename(filename)
761
        dialog.set_current_name(os.path.basename(filename))
762
        response = dialog.run()
763
 
764
        if response == Gtk.ResponseType.OK:
765
            export_path = dialog.get_filename()
766
            res = self.srvbnr.export_to_excel(bag, export_path)
767
            if res:
768
                self.log.info("Selected SAP Notes exported to MS Excel format (xlsx): %s" % export_path)
769
                self.srvuif.statusbar_msg("%d SAP Notes exported to MS Excel format: %s" % (len(bag), export_path), True)
770
                self.srvuif.copy_text_to_clipboard(export_path)
771
            else:
772
                self.log.error(self.get_traceback())
773
        else:
774
            self.log.info("Export canceled by user")
775
            self.srvuif.statusbar_msg("Export canceled by user", True)
776
        dialog.destroy()
777
 
778
 
779
    def action_collection_export_basico(self, *args):
780
        rootwin = self.srvgui.get_window()
781
        timestamp = self.srvutl.timestamp()
782
        filename = "%s%s.bco" % (LPATH['EXPORT'], timestamp)
783
        visor_sapnotes = self.srvgui.get_widget('visor_sapnotes')
784
 
785
        bag = visor_sapnotes.get_filtered_bag()
786
 
787
        dialog = Gtk.FileChooserDialog("Save file", rootwin,
788
            Gtk.FileChooserAction.SAVE,
789
                (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
790
                 Gtk.STOCK_SAVE, Gtk.ResponseType.OK))
791
        dialog.set_filename(filename)
792
        dialog.set_current_name(os.path.basename(filename))
793
        response = dialog.run()
794
 
795
        if response == Gtk.ResponseType.OK:
796
            export_path = dialog.get_filename()
797
            target = self.srvbnr.export_to_basico(bag, export_path)
798
            self.log.info("%d SAP Notes exported to Basico %s format: %s", len(bag), APP['version'], target)
799
            self.srvuif.statusbar_msg("%d SAP Notes exported to Basico %s format: %s" % (len(bag), APP['version'], target), True)
800
            self.srvuif.copy_text_to_clipboard(export_path)
801
        else:
802
            self.log.info("Export canceled by user")
803
            self.srvuif.statusbar_msg("Export canceled by user", True)
804
        dialog.destroy()
805
 
806
 
807
    def action_collection_copy_to_clipboard(self, button):
808
        clipboard = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD)
809
        visor_sapnotes = self.srvgui.get_widget('visor_sapnotes')
810
 
811
        bag = visor_sapnotes.get_filtered_bag()
812
        text = ''
813
        for sid in bag:
814
            metadata = self.srvdtb.get_sapnote_metadata(sid)
815
            text += "SAP Note %s: %s - Component: %s\n" % (str(int(sid)), metadata['title'], metadata['componentkey'])
816
        clipboard.set_text(text, -1)
817
 
818
        msg = "%d SAP Notes copied to the clipboard: %s" % (len(bag), ', '.join(list(bag)))
819
        self.log.info(msg)
820
        msg = "%d SAP Notes copied to the clipboard" % len(bag)
821
        self.srvuif.statusbar_msg(msg, True)
822
 
823
 
367 t00mlabs 824
    def gui_annotation_previous_row(self, *args):
825
        visor_annotations = self.srvgui.get_widget('visor_annotations')
826
        visor_annotations.row_previous()
827
 
377 t00mlabs 828
 
367 t00mlabs 829
    def gui_annotation_next_row(self, *args):
830
        visor_annotations = self.srvgui.get_widget('visor_annotations')
831
        visor_annotations.row_next()
832
 
340 t00mlabs 833
    def gui_copy_to_clipboard_sapnote(self, widget, lsid, popover):
834
        visor_sapnotes = self.srvgui.get_widget('visor_sapnotes')
835
        clipboard = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD)
836
        text = ''
837
        for sid in lsid:
838
            metadata = self.srvdtb.get_sapnote_metadata(sid)
839
            text += "SAP Note %10s: %s - Component: %s\n" % (sid, metadata['title'], metadata['componentkey'])
840
        clipboard.set_text(text, -1)
841
        if popover is not None:
842
            popover.hide()
843
            self.srvuif.grab_focus()
844
 
845
 
846
    def gui_jump_to_sapnote(self, widget, sid):
847
        visor_sapnotes = self.srvgui.get_widget('visor_sapnotes')
362 t00mlabs 848
        visor_sapnotes.populate([sid])
340 t00mlabs 849
        self.gui_show_visor_sapnotes()
850
        self.srvuif.grab_focus()
851
        msg = "Jumping to SAP Note %s" % sid
852
        self.log.info(msg)
853
        self.srvuif.statusbar_msg(msg)
854
 
855
 
369 t00mlabs 856
    def gui_jump_to_annotation(self, widget, aid):
857
        paned = self.srvgui.get_widget('gtk_hpaned')
858
        notebook = self.srvgui.get_widget('gtk_notebook_visor')
859
        notebook_viewmenu = self.srvgui.get_widget('gtk_notebook_menuview')
860
        notebook_viewmenu.set_current_page(1)
861
        signal = self.srvgui.get_signal('gtk_notebook_visor', 'switch-page')
862
        GObject.signal_handler_block(notebook, signal)
863
        visor_annotations = self.srvgui.get_widget('visor_annotations')
864
        visor_annotations.populate([aid])
865
        self.gui_show_visor_annotations()
866
        self.srvuif.grab_focus()
867
        msg = "Jumping to annotation %s" % aid
868
        self.log.info(msg)
869
        self.srvuif.statusbar_msg(msg)
870
        GObject.signal_handler_unblock(notebook, signal)
871
        paned.set_position(400)
872
 
377 t00mlabs 873
 
340 t00mlabs 874
    def gui_link_to_sapnote(self, *args):
875
        pass
876
 
877
 
878
    def gui_sapnotes_select_all_none(self, witch, state):
362 t00mlabs 879
        visor_sapnotes = self.srvgui.get_widget('visor_sapnotes')
880
        model = visor_sapnotes.get_model()
340 t00mlabs 881
 
882
        def get_selected_sapnotes(model, path, itr):
883
            component = model.get(itr, 5)
884
            if component != 'Annotation':
885
                model.set(itr, 2, state)
886
 
887
        model.foreach(get_selected_sapnotes)
348 t00mlabs 888
 
889
 
385 t00mlabs 890
    # ~ def gui_maximize_annotation_window(self, *args):
891
        # ~ vpaned = self.srvgui.get_widget('gtk_vpaned_visor')
892
        # ~ stack_main = self.srvgui.get_widget('gtk_stack_main')
893
        # ~ toggle_button = self.srvgui.get_widget('gtk_togglebutton_maximize_annotation_widget')
894
        # ~ if toggle_button.get_active():
352 t00mlabs 895
            # ~ stack_main.hide()
385 t00mlabs 896
            # ~ vpaned.set_position(0)
897
        # ~ else:
352 t00mlabs 898
            # ~ stack_main.show_all()
385 t00mlabs 899
            # ~ vpaned.set_position(450)
356 t00mlabs 900
 
901
 
360 t00mlabs 902
    def gui_attachment_add_to_sapnote(self, button, sid):
903
        visor_attachemnts = self.srvgui.get_widget('visor_attachments')
904
        visor_annotations = self.srvgui.get_widget('visor_annotations')
905
        visor_sapnotes = self.srvgui.get_widget('visor_sapnotes')
377 t00mlabs 906
 
360 t00mlabs 907
        # Create annotation
908
        aid = self.srvant.gen_aid(sid)
909
        annotation = {}
910
        annotation["AID"] = aid
911
        annotation["Title"] = "Attachments added for SAP Note %s" % str(int(sid))
912
        annotation["Component"] = "Annotation"
913
        annotation["Type"] = "Note"
377 t00mlabs 914
        annotation["Category"] = "Inbox"
360 t00mlabs 915
        annotation["Priority"] = "Low"
377 t00mlabs 916
        annotation["Link"] = ""
360 t00mlabs 917
        annotation["LinkType"] = "Website"
918
        annotation["Origin"] = "Service-Attachment"
377 t00mlabs 919
 
360 t00mlabs 920
        # Get attachments from filechooser dialog
921
        attachments = self.gui_attachment_show_filechooser()
377 t00mlabs 922
 
360 t00mlabs 923
        # Add them to Basico database
924
        if attachments is not None:
925
            content = '== Attachments\n\n'
926
            for attachment in attachments:
927
                # only allow files (avoid directories)
928
                if os.path.isfile(attachment):
929
                    content += "* %s\n" % attachment
930
                    tid = self.srvatc.create(attachment, aid)
931
                    annotation["TID"] = tid
932
                    # ~ self.log.debug(annotation)
933
                annotation["Content"] = content
934
                self.srvant.create(annotation)
362 t00mlabs 935
            visor_attachemnts.populate()
936
            visor_annotations.populate()
937
            visor_sapnotes.populate()
360 t00mlabs 938
        else:
939
            self.log.warning("No files selected to attach")
940
 
941
 
942
    def gui_attachment_add_to_annotation(self, button):
364 t00mlabs 943
        widget_annotation = self.srvgui.get_widget('widget_annotation')
360 t00mlabs 944
        visor_attachemnts = self.srvgui.get_widget('visor_attachments')
945
        visor_annotations = self.srvgui.get_widget('visor_annotations')
356 t00mlabs 946
        aid = widget_annotation.get_aid_from_widget()
377 t00mlabs 947
 
360 t00mlabs 948
        # Create annotation
949
        sid = self.srvant.get_sid(aid)
950
        new_aid = self.srvant.gen_aid(sid)
951
        annotation = {}
952
        annotation["AID"] = new_aid
953
        annotation["Title"] = "Attachments added for annotation: %s" % self.srvant.get_title(aid)
954
        annotation["Component"] = "Annotation"
955
        annotation["Type"] = "Note"
377 t00mlabs 956
        annotation["Category"] = "Inbox"
360 t00mlabs 957
        annotation["Priority"] = "Low"
377 t00mlabs 958
        annotation["Link"] = ""
360 t00mlabs 959
        annotation["LinkType"] = "Website"
960
        annotation["Origin"] = "Service-Attachment"
377 t00mlabs 961
 
360 t00mlabs 962
        # Get attachments from filechooser dialog
356 t00mlabs 963
        attachments = self.gui_attachment_show_filechooser()
964
 
965
        # Add them to Basico database
966
        if attachments is not None:
360 t00mlabs 967
            content = '== Attachments\n\n'
356 t00mlabs 968
            for attachment in attachments:
969
                # only allow files (avoid directories)
970
                if os.path.isfile(attachment):
360 t00mlabs 971
                    content += "* %s\n" % attachment
972
                    tid = self.srvatc.create(attachment, aid)
973
                    annotation["TID"] = tid
974
                    # ~ self.log.debug(annotation)
975
                annotation["Content"] = content
976
                self.srvant.create(annotation)
977
                self.srvant.update_timestamp(aid)
362 t00mlabs 978
            visor_attachemnts.populate()
979
            visor_annotations.populate()
356 t00mlabs 980
        else:
981
            self.log.warning("No files selected to attach")
377 t00mlabs 982
 
983
 
395 t00mlabs 984
    def gui_attachment_add(self, *args):
360 t00mlabs 985
        visor_attachemnts = self.srvgui.get_widget('visor_attachments')
986
        visor_annotations = self.srvgui.get_widget('visor_annotations')
987
        visor_sapnotes = self.srvgui.get_widget('visor_sapnotes')
377 t00mlabs 988
 
360 t00mlabs 989
        # Create annotation
990
        aid = self.srvant.gen_aid('0000000000')
991
        annotation = {}
992
        annotation["AID"] = aid
993
        annotation["Title"] = "Attachments added"
994
        annotation["Component"] = "Annotation"
995
        annotation["Type"] = "Note"
377 t00mlabs 996
        annotation["Category"] = "Inbox"
360 t00mlabs 997
        annotation["Priority"] = "Low"
377 t00mlabs 998
        annotation["Link"] = ""
360 t00mlabs 999
        annotation["LinkType"] = "Website"
1000
        annotation["Origin"] = "Service-Attachment"
377 t00mlabs 1001
 
360 t00mlabs 1002
        # Get attachments from filechooser dialog
1003
        attachments = self.gui_attachment_show_filechooser()
377 t00mlabs 1004
 
360 t00mlabs 1005
        # Add them to Basico database
1006
        if attachments is not None:
1007
            content = '== Attachments\n\n'
1008
            for attachment in attachments:
1009
                # only allow files (avoid directories)
1010
                if os.path.isfile(attachment):
1011
                    content += "* %s\n" % attachment
1012
                    tid = self.srvatc.create(attachment, aid)
1013
                    annotation["TID"] = tid
1014
                    # ~ self.log.debug(annotation)
1015
                annotation["Content"] = content
1016
                self.srvant.create(annotation)
362 t00mlabs 1017
            visor_attachemnts.populate()
1018
            visor_annotations.populate()
360 t00mlabs 1019
        else:
1020
            self.log.warning("No files selected to attach")
356 t00mlabs 1021
 
395 t00mlabs 1022
 
356 t00mlabs 1023
    def gui_attachment_show_filechooser(self):
1024
        filenames = None
1025
        parentwin = self.srvgui.get_window()
1026
        dialog = Gtk.FileChooserDialog(title="Open file(s) ...",
1027
                                       parent=parentwin,
1028
                                       action=Gtk.FileChooserAction.OPEN,
377 t00mlabs 1029
                                       buttons=("_Cancel",
356 t00mlabs 1030
                                                Gtk.ResponseType.CANCEL,
1031
                                        "_Open", Gtk.ResponseType.ACCEPT))
1032
        dialog.set_select_multiple(True)
1033
        response = dialog.run()
1034
        if response == Gtk.ResponseType.ACCEPT:
1035
            filenames = dialog.get_filenames()
1036
            i = 0
1037
            while i < len(filenames):
1038
                filename = filenames[i]
1039
                self.log.debug("%s was selected", filename)
1040
                i += 1
1041
        dialog.destroy()
1042
        return filenames
377 t00mlabs 1043
 
368 t00mlabs 1044
    def copy_text_to_clipboard(self, widget, text):
1045
        self.srvuif.copy_text_to_clipboard(text)
380 t00mlabs 1046
        self.srvuif.grab_focus()