Subversion Repositories basico

Rev

Rev 74 | Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4 t00mlabs 1
#!/usr/bin/python
2
# -*- coding: utf-8 -*-
3
# File: window.py
4
# Author: Tomás Vírseda
5
# License: GPL v3
6
# Description: Gtk.ApplicationWindow implementation
7
 
8
import os
9
import stat
10
import threading
11
import time
12
import platform
13
 
14
import gi
15
gi.require_version('Gtk', '3.0')
16
gi.require_version('WebKit', '3.0')
17
 
18
from gi.repository import GLib
19
from gi.repository import GObject
20
from gi.repository import Gtk
21
from gi.repository import Gdk
22
from gi.repository import Gio
23
from gi.repository import Pango
24
from gi.repository import WebKit
25
from gi.repository.GdkPixbuf import Pixbuf
26
 
27
from .log import get_logger
28
from .sapnoteview import SAPNoteView
29
 
30
#~ from .browser import WebBrowser
31
 
32
MONOSPACE_FONT = 'Lucida Console' if platform.system() == 'Windows' else 'monospace'
33
 
34
class GtkAppWindow(Gtk.ApplicationWindow):
35
    def __init__(self, uiapp):
36
        self.setup_controller(uiapp)
37
        self.get_services()
38
        self.gui.add_widget('uiapp', uiapp)
39
        self.gui.set_key('cmbvalue', 'search')
40
        self.settings = {}
41
        self.settings['fullscreen'] = False
42
        self.current_notes = {}
43
 
44
        self.setup_window()
45
        self.setup_widgets()
46
        self.setup_app()
47
        self.check_settings()
48
 
49
 
50
    def check_settings(self):
51
        # SAP module settings
52
        settings = self.sap.get_default_settings()
53
        for key in settings:
54
            try:
55
                self.sap.get_config_value(key)
56
            except:
57
                self.sap.set_config_value(key, settings[key])
58
                #~ self.log.warning("Setting '%s' does not exists" % setting)
59
 
60
 
61
    def setup_controller(self, uiapp):
62
        self.uiapp = uiapp
63
        self.controller = uiapp.get_controller()
64
 
65
 
66
    def setup_app(self):
67
        sapnoteview = self.gui.get_widget('sapnoteview')
68
        searchentry = self.gui.get_widget("stySearchInfo")
69
        viewlabel = self.gui.get_widget('lblViewCurrent')
70
        try:
71
            name = sapnoteview.get_view()
72
        except:
73
            name = 'components'
74
        sapnoteview.set_view(name)
75
        label = "<span size='20000'><b>%-10s</b></span>" % name.capitalize()
76
        viewlabel.set_markup(label)
77
        self.cb.refresh_view()
78
        searchentry.set_text('')
79
        self.cb.search_notes()
80
        sapnoteview.check_states()
81
 
82
 
83
    def setup_window(self):
84
        app_title = self.controller.get_app_info('name')
85
        Gtk.Window.__init__(self, title=app_title, application=self.uiapp)
86
        self.gui.add_widget('mainwindow', self)
87
        icon = self.im.get_icon('basico')
88
        self.set_icon(icon)
89
        # FIXME
90
        # From docs: Don’t use this function. It sets the X xlib.Window
91
        # System “class” and “name” hints for a window.
92
        # But I have to do it or it doesn't shows the right title. ???
93
        self.set_wmclass (app_title, app_title)
94
        self.set_role(app_title)
95
        #~ self.set_icon_from_file(self.env.get_var('ICONS') + '/basico.png')
96
        self.set_default_size(1024, 728)
97
        self.set_position(Gtk.WindowPosition.CENTER_ALWAYS)
98
        #~ self.connect('destroy', Gtk.main_quit)
99
        self.show_all()
100
 
101
 
102
    def setup_menu_views(self):
103
        # View label
104
        self.gui.add_widget('lblViewCurrent')
105
 
106
        ## Views Menu
107
        views_menu = self.gui.add_widget('mnuviews', Gio.Menu())
108
 
109
        # Last added view
110
        #~ TODO
111
        #~ views_menu.append_item(self.uif.create_item('View last added', 'app.view-lastadded', ''))
112
        #~ self.app.add_action(self.uif.create_action("view-lastadded", self.cb_show_dlnotes_window))
113
 
114
        # Most used view
115
        #~ TODO
116
        #~ views_menu.append_item(self.uif.create_item('View most used', 'app.view-mostused', ''))
117
        #~ self.app.add_action(self.uif.create_action("view-mostused", self.cb_show_dlnotes_window))
118
 
119
        # Tasks view
120
        views_menu.append_item(self.uif.create_item('View by tasks', 'app.view-tasks', 'emblem-system'))
121
        self.app.add_action(self.uif.create_action("view-tasks", self.cb.refresh_view, 'tasks'))
122
 
123
        # Projects view
124
        #~ views_menu.append_item(self.uif.create_item('View by projects', 'app.view-projects', ''))
125
        #~ self.app.add_action(self.uif.create_action("view-projects", self.cb.refresh_view, 'projects'))
126
 
127
        # Components view
128
        views_menu.append_item(self.uif.create_item('View by components', 'app.view-components', ''))
129
        self.app.add_action(self.uif.create_action("view-components", self.cb.refresh_view, 'components'))
130
 
131
        # Bookmarks view
132
        views_menu.append_item(self.uif.create_item('View bookmarks', 'app.view-bookmarks', ''))
133
        self.app.add_action(self.uif.create_action("view-bookmarks", self.cb.refresh_view, 'bookmarks'))
134
 
135
 
136
        # Annotations view
137
        #~ TODO
138
        #~ views_menu.append_item(self.uif.create_item('View by annotations', 'app.view-annotations', ''))
139
        #~ self.app.add_action(self.uif.create_action("view-annotations", self.cb_show_dlnotes_window))
140
 
141
        # Set menu model in button
142
        btnviews = self.gui.get_widget('mnuBtnViews')
143
        btnviews.set_menu_model(views_menu)
144
 
145
 
146
    def setup_menu_settings(self):
147
        ### SETTINGS POPOVER
148
        menu = Gio.Menu()
149
        #~ self.gui.add_widget("menu", menu)
150
        menu.append_item(self.uif.create_item('Fullscreen', 'app.settings-fullscreen', 'gtk-fullscreen'))
151
        menu.append_item(self.uif.create_item('Rename current project', 'app.project-rename', 'preferences-desktop-personal'))
152
        menu.append_item(self.uif.create_item('Refresh current project', 'app.project-refresh', 'view-refresh'))
153
        menu.append_item(self.uif.create_item('Close current project', 'app.project-close', 'window-close'))
154
        menu.append_item(self.uif.create_item('Delete current project', 'app.project-delete', 'list-remove'))
155
        menu.append_item(self.uif.create_item('Export current project', 'app.project-delete', 'document-save-as'))
156
        window = self.gui.get_window()
157
        window.set_app_menu(menu)
158
        app = self.gui.get_app()
159
        app.add_action(self.uif.create_item("settings-fullscreen"))
160
 
161
        #~ popover_action_group = Gio.SimpleActionGroup()
162
        btnsettings = self.gui.get_widget("mnuBtnViews")
163
        popover_settings = Gtk.Popover.new_from_model(btnsettings, menu)
164
        popover_settings.set_position(Gtk.PositionType.BOTTOM)
165
        btnsettings.connect('clicked', lambda _: popover_settings.show_all())
166
 
167
 
168
    def setup_menus(self):
169
        self.setup_menu_views()
170
        #~ self.setup_menu_actions()
171
        #~ self.setup_menu_settings()
172
 
173
    def show_home_page(self, *args):
174
        notebook = self.gui.get_widget('notebook')
175
        notebook.set_current_page(0)
176
 
177
    def show_settings_page(self, *args):
178
        sapnoteview = self.gui.get_widget('sapnoteview')
179
        sapnoteview.set_view('settings')
180
        notebook = self.gui.get_widget('notebook')
181
        notebook.set_current_page(2)
182
 
183
    def show_browser_page(self, *args):
184
        notebook = self.gui.get_widget('notebook')
185
        notebook.set_current_page(1)
186
 
187
 
188
    def show_search(self, *args):
189
        revsearch = self.gui.get_widget('revSearch')
190
        tgbsearch = self.gui.get_widget('tgbSearch')
191
        if tgbsearch.get_active():
192
            revsearch.set_reveal_child(True)
193
            revsearch.set_no_show_all(False)
194
            revsearch.show_all()
195
        else:
196
            revsearch.set_reveal_child(False)
197
            revsearch.set_no_show_all(True)
198
            revsearch.hide()
199
 
200
 
201
    def show_addsapnotes_dialog(self, *args):
202
        sapnoteview = self.gui.get_widget('sapnoteview')
203
        sapnoteview.set_view('download')
204
        notebook = self.gui.get_widget('notebook')
205
        notebook.set_current_page(1)
206
 
207
 
208
    def setup_widgets(self):
209
        self.mainbox = self.gui.get_widget('mainbox')
210
        self.mainbox.reparent(self)
211
 
212
        self.setup_menus()
213
 
214
        notesbox = self.gui.get_widget('notesbox')
215
        sapnoteview = SAPNoteView(self.controller)
216
        self.gui.add_widget('sapnoteview', sapnoteview)
217
        #~ self.log.debug("SAPNoteView widget added")
218
        self.gui.add_widget('combobox')
219
        search = self.gui.add_widget('stySearchInfo')
220
        #~ search.connect('search_changed', self.search_notes)
221
        search.connect('activate', self.cb.search_notes)
222
        self.setup_combobox()
223
        self.swap_widget(notesbox, sapnoteview)
224
 
225
        # Buttons
226
        btnabout = self.gui.get_widget('btnAbout')
227
        btnabout.connect('clicked', self.uiapp.cb_show_about)
228
 
229
        btnsettings = self.gui.get_widget('btnSettings')
230
        btnsettings.connect('clicked', self.show_settings_page)
231
 
232
        btnaddnote = self.gui.get_widget('btnStartDlNotes')
233
        btnaddnote.connect('clicked', self.cb.import_notes)
234
 
235
        refreshview = self.gui.get_widget('btnRefreshSAPNoteView')
236
        refreshview.connect('clicked', self.cb.refresh_and_clear_view)
237
 
238
        btnShowAddSAPNotesDlg = self.gui.get_widget('btnShowAddSAPNotesDlg')
239
        btnShowAddSAPNotesDlg.connect('clicked', self.show_addsapnotes_dialog)
240
 
241
        btnStopDlNotes = self.gui.get_widget('btnStopDlNotes')
242
        btnStopDlNotes.connect('clicked', self.cb.stop_dl_notes)
243
 
244
        tgbsearch = self.gui.get_widget('tgbSearch')
245
        tgbsearch.connect('toggled', self.show_search)
246
        revsearch = self.gui.get_widget('revSearch')
247
        revsearch.hide()
248
        revsearch.set_no_show_all(True)
249
 
250
        toggle= self.gui.get_widget('tgbFullScreen')
251
        toggle.connect('toggled', self.uif.fullscreen)
252
        switch = self.gui.get_widget('schExpandCollapse')
253
        switch.connect('state-set', sapnoteview.expand_collapse)
254
        switch = self.gui.get_widget('schSelectNotesAllNone')
255
        switch.connect('state-set', sapnoteview.select_all_none)
256
 
257
        button = self.gui.get_widget('btnQuit')
258
        button.connect('clicked', self.gui.quit)
259
 
260
        # Actions button
261
        button = self.gui.get_widget('mnuBtnActions')
262
 
263
        # Prefs for SAP module
264
        button = self.gui.add_widget('btnPrefsSAPApply')
265
        button.connect('clicked', self.cb.apply_preferences)
266
 
267
        button = self.gui.add_widget('btnPrefsSAPCancel')
268
        button.connect('clicked', self.cb.refresh_view)
269
 
270
        button = self.gui.add_widget('btnPrefsSAPReset')
271
        button.connect('clicked', self.sap.default_preferences)
272
 
273
        # Notebook Import Widget
274
        ntbimport = self.gui.add_widget('ntbAddSAPNotes')
275
 
276
        try:
277
            sap_settings = self.sap.get_custom_settings()
278
        except:
279
            self.log.error(self.controller.get_traceback())
280
            sap_settings = self.sap.get_default_settings()
281
            self.log.debug("SAP Default settings loaded")
282
 
283
        for setting in sap_settings:
284
            widget = self.gui.add_widget(setting)
285
            widget.set_text(sap_settings[setting])
286
 
287
        # Stats
288
        statsviewer = self.gui.add_widget('scrStatsViewer')
289
 
290
        btnstats = self.gui.add_widget('btnStatsByCompMain')
291
        btnstats.connect('clicked', self.cb.update_components_stats)
292
        iconwdg = self.gui.add_widget('imgStatsByCompMain')
293
        icon = self.im.get_pixbuf_icon('component', 64, 64)
294
        iconwdg.set_from_pixbuf(icon)
295
 
296
        btnstats = self.gui.add_widget('btnStatsByCategory')
297
        btnstats.connect('clicked', self.cb.update_categories_stats)
298
        iconwdg = self.gui.add_widget('imgStatsByCategory')
299
        icon = self.im.get_pixbuf_icon('category', 64, 64)
300
        iconwdg.set_from_pixbuf(icon)
301
 
302
        self.show_all()
303
        self.log.debug("GUI loaded")
304
 
305
 
306
    def __completion_func(self, completion, key, iter):
307
        model = completion.get_model()
308
        text = model.get_value(iter, 0)
309
        if key.upper() in text.upper():
310
            return True
311
        return False
312
 
313
 
314
    def setup_combobox_completions(self, key):
315
        model = Gtk.ListStore(str)
316
        search = self.gui.get_widget("stySearchInfo")
317
        completion = Gtk.EntryCompletion()
318
        completion.set_model(model)
319
        completion.set_text_column(0)
320
        completion.set_match_func(self.__completion_func)
321
        search.set_completion(completion)
322
        #~ self.log.debug("Completion Key: %s" % key)
323
 
324
        stats = self.sap.get_stats()
325
 
326
        try:
327
            items = list(stats[key])
328
            items.sort()
329
            for item in items:
330
                model.append([item])
331
        except:
332
            pass
333
 
334
 
335
    def cb_combobox_changed(self, combobox):
336
        model = combobox.get_model()
337
        treeiter = combobox.get_active_iter()
338
        key = model[treeiter][0]
339
        self.gui.set_key('cmbvalue', key)
340
        self.setup_combobox_completions(key)
341
 
342
 
343
    def setup_combobox(self):
344
        combobox = self.gui.get_widget('combobox')
345
        model = Gtk.TreeStore(str, str)
346
        combobox.set_model(model)
347
 
348
        ## key
349
        cell = Gtk.CellRendererText()
350
        cell.set_visible(False)
351
        combobox.pack_start(cell, True)
352
        combobox.add_attribute(cell, 'text', 0)
353
 
354
        ## value
355
        cell = Gtk.CellRendererText()
356
        cell.set_alignment(0.0, 0.5)
357
        combobox.pack_start(cell, expand=False)
358
        combobox.add_attribute(cell, 'markup', 1)
359
        combobox.connect('changed', self.cb_combobox_changed)
360
 
361
        model.append(None, ['search', 'Search in all database'])
362
        model.append(None, ['project', 'Filter by project name'])
363
        model.append(None, ['task', 'Filter by task name'])
364
        model.append(None, ['component', 'Filter by component'])
365
        model.append(None, ['category', 'Filter by category'])
366
        model.append(None, ['type', 'Filter by type'])
367
        model.append(None, ['id', 'Filter by Id'])
368
        model.append(None, ['title', 'Filter by title'])
369
        model.append(None, ['priority', 'Filter by priority'])
370
        model.append(None, ['version', 'Filter by version'])
371
        #~ model.append(None, ['released', 'Filter by release date'])
372
 
373
        combobox.set_active(0)
374
 
375
 
376
    def get_services(self):
377
        """Load services to be used in this class
378
        """
379
        self.gui = self.controller.get_service("GUI")
380
        self.app = self.gui.get_app()
381
        LOG_FILE = self.controller.get_file('LOG')
382
        self.log = get_logger('GtkAppWindow', LOG_FILE)
383
        self.sap = self.controller.get_service("SAP")
384
        self.uif = self.controller.get_service("UIF")
385
        self.prefs = self.controller.get_service("Settings")
386
        self.im = self.controller.get_service('IM')
387
        self.cb = self.controller.get_service('Callbacks')
388
 
389
 
390
    def swap_widget(self, container, combobox):
391
        """Shortcut to GUI.swap_widget method
392
        """
393
        self.gui.swap_widget(container, combobox)