Subversion Repositories basico

Rev

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