Subversion Repositories basico

Rev

Rev 254 | Rev 257 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

#!/usr/bin/python
# -*- coding: utf-8 -*-
# File: mod_win.py
# Author: Tomás Vírseda
# License: GPL v3
# Description: Gtk.ApplicationWindow implementation

import os
import stat
import time
import platform

import gi
gi.require_version('Gtk', '3.0')

from gi.repository import GLib
from gi.repository import GObject
from gi.repository import Gtk
from gi.repository import Gdk
from gi.repository import Gio
from gi.repository import Pango
from gi.repository.GdkPixbuf import Pixbuf

from basico.core.mod_env import APP
from basico.widgets.wdg_menuview import SAPNoteViewMenu
from basico.widgets.wdg_visor_sapnotes import SAPNotesVisor
from basico.widgets.wdg_visor_annotations import AnnotationsVisor
from basico.widgets.wdg_visor_toolbar import VisorToolbar
from basico.widgets.wdg_about import About
from basico.widgets.wdg_settingsview import SettingsView
from basico.widgets.wdg_logviewer import LogViewer
from basico.widgets.wdg_annot import AnnotationWidget
from basico.widgets.wdg_statusbar import Statusbar


class GtkAppWindow(Gtk.ApplicationWindow):
    def __init__(self, uiapp):
        self.setup_controller(uiapp)
        self.get_services()
        self.app = self.srvgui.get_app()
        self.srvgui.add_widget('uiapp', uiapp)
        self.setup_window(uiapp)
        self.setup_widgets()
        self.run()


    def get_services(self):
        self.srvbnr = self.controller.get_service("BNR")
        self.srvgui = self.controller.get_service("GUI")
        self.srvdtb = self.controller.get_service("DB")
        self.srvuif = self.controller.get_service("UIF")
        self.srvicm = self.controller.get_service('IM')
        self.srvclb = self.controller.get_service('Callbacks')
        self.srvant = self.controller.get_service('Annotation')


    def setup_controller(self, uiapp):
        self.controller = uiapp.get_controller()


    def setup_window(self, uiapp):
        Gtk.Window.__init__(self, title=APP['name'], application=uiapp)
        icon = self.srvicm.get_icon('basico-component', 48, 48)
        self.set_icon(icon)
        # FIXME
        # From docs: Don’t use this function. It sets the X xlib.Window
        # System “class” and “name” hints for a window.
        # But I have to do it or it doesn't shows the right title. ???
        self.set_wmclass (APP['name'], APP['name'])
        self.set_role(APP['name'])
        self.set_default_size(1024, 728)
        self.set_position(Gtk.WindowPosition.CENTER_ALWAYS)
        self.maximize ()
        self.setup_headerbar()
        self.show_all()


    def setup_headerbar(self):
        hb = self.srvgui.add_widget('gtk_headerbar_container', Gtk.HeaderBar())
        hb.set_show_close_button(True)
        hb.props.title = "Basico"
        hb.props.subtitle = "SAP Notes Manager for SAP Consultants"
        lhbox = self.setup_headerbar_left(hb)
        hb.pack_start(lhbox)
        rhbox = self.setup_headerbar_right(hb)

        hb.pack_end(rhbox)
        self.set_titlebar(hb)
        hb.show_all()


    def setup_headerbar_left(self, hb):
        # ~ '''Left headerbar side not used by now'''
        lhbox = Gtk.HBox()

        ### Dashboard / Visor
        hbox = Gtk.HBox()
        icon = self.srvicm.get_pixbuf_icon('basico-dashboard', 24, 24)
        image = Gtk.Image()
        image.set_from_pixbuf(icon)
        label = Gtk.Label()
        hbox.pack_start(image, False, False, 3)
        hbox.pack_start(label, False, False, 3)
        button = self.srvgui.add_widget('gtk_button_dashboard', Gtk.Button())
        button.add(hbox)
        button.set_relief(Gtk.ReliefStyle.NONE)
        lhbox.pack_start(button, False, False, 0)
        button.connect('clicked', self.srvclb.gui_show_dashboard)

        return lhbox


    def setup_headerbar_right(self, hb):
        rhbox = Gtk.HBox()

        ## System Menu
        button = Gtk.Button()
        icon = self.srvicm.get_pixbuf_icon('basico-menu-system', 24, 24)
        image = Gtk.Image()
        image.set_from_pixbuf(icon)
        button.set_image(image)
        button.set_relief(Gtk.ReliefStyle.NONE)
        popover = Gtk.Popover.new(button)
        self.srvgui.add_widget('gtk_popover_button_menu_system', popover)
        button.connect('clicked', self.srvclb.gui_show_popover, popover)
        rhbox.pack_end(button, False, False, 0)

        # Popover body
        box = Gtk.Box(spacing = 0, orientation="vertical")
        popover.add(box)

        ### About
        hbox = Gtk.Box(spacing = 0, orientation="horizontal")
        icon = self.srvicm.get_pixbuf_icon('basico-about', 48, 48)
        image = Gtk.Image()
        image.set_from_pixbuf(icon)
        label = Gtk.Label("About")
        hbox.pack_start(image, False, False, 3)
        hbox.pack_start(label, False, False, 3)
        button = Gtk.Button()
        button.add(hbox)
        button.set_relief(Gtk.ReliefStyle.NONE)
        button.connect('clicked', self.srvclb.gui_show_about)
        box.pack_end(button, False, False, 0)

        # ~ ### Help
        # ~ hbox = Gtk.Box(spacing = 0, orientation="horizontal")
        # ~ icon = self.srvicm.get_pixbuf_icon('basico-help', 48, 48)
        # ~ image = Gtk.Image()
        # ~ image.set_from_pixbuf(icon)
        # ~ label = Gtk.Label("Help")
        # ~ hbox.pack_start(image, False, False, 3)
        # ~ hbox.pack_start(label, False, False, 3)
        # ~ button = Gtk.Button()
        # ~ button.add(hbox)
        # ~ button.set_relief(Gtk.ReliefStyle.NONE)
        # ~ button.connect('clicked', self.srvclb.gui_show_help)
        # ~ box.pack_end(button, False, False, 0)

        ### Log viewer
        hbox = Gtk.Box(spacing = 0, orientation="horizontal")
        icon = self.srvicm.get_pixbuf_icon('basico-logviewer', 48, 48)
        image = Gtk.Image()
        image.set_from_pixbuf(icon)
        label = Gtk.Label("Log viewer")
        hbox.pack_start(image, False, False, 3)
        hbox.pack_start(label, False, False, 3)
        button = Gtk.Button()
        button.add(hbox)
        button.set_relief(Gtk.ReliefStyle.NONE)
        button.connect('clicked', self.srvclb.gui_show_log)
        box.pack_end(button, False, False, 0)

        ### Settings
        hbox = Gtk.Box(spacing = 0, orientation="horizontal")
        icon = self.srvicm.get_pixbuf_icon('basico-settings', 48, 48)
        image = Gtk.Image()
        image.set_from_pixbuf(icon)
        label = Gtk.Label("Settings")
        hbox.pack_start(image, False, False, 3)
        hbox.pack_start(label, False, False, 3)
        button = Gtk.Button()
        button.add(hbox)
        button.set_relief(Gtk.ReliefStyle.NONE)
        button.connect('clicked', self.srvclb.gui_show_settings)
        box.pack_start(button, False, False, 0)

        ### Backup
        hbox = Gtk.Box(spacing = 0, orientation="horizontal")
        icon = self.srvicm.get_pixbuf_icon('basico-backup-restore', 48, 48)
        image = Gtk.Image()
        image.set_from_pixbuf(icon)
        label = Gtk.Label("Backup/Restore")
        hbox.pack_start(image, False, False, 3)
        hbox.pack_start(label, False, False, 3)
        button = Gtk.Button()
        button.add(hbox)
        button.set_relief(Gtk.ReliefStyle.NONE)
        # ~ button.connect('clicked', self.srvbnr.backup)
        box.pack_start(button, False, False, 0)

        box_bnr = Gtk.VBox()
        popover_bnr = Gtk.Popover.new(button)
        popover_bnr.set_position(Gtk.PositionType.LEFT)
        popover_bnr.add(box_bnr)
        self.srvgui.add_widget('gtk_popover_button_menu_system', popover_bnr)
        button.connect('clicked', self.srvclb.gui_show_popover, popover_bnr)

        button_backup = self.srvuif.create_button('basico-backup', 48, 48, '<b>Backup database</b> ')
        button_restore = self.srvuif.create_button('basico-restore', 48, 48, '<b>Restore from backup</b>')
        button_restore.connect('clicked', self.srvclb.gui_show_filechooser_restore)
        button_cache = self.srvuif.create_button('basico-restore', 48, 48, '<b>Restore from cache</b>')
        button_cache.connect('clicked', self.srvbnr.restore_from_cache)
        box_bnr.pack_start(button_backup, False, False, 0)
        box_bnr.pack_start(button_restore, False, False, 0)
        box_bnr.pack_start(button_cache, False, False, 0)

        return rhbox


    def reveal_filechooser_restore(self, *args):
        revealer = self.srvgui.get_widget('gtk_revealer_restore')
        revealer.set_reveal_child(True)


    def file_chooser_button_clicked(self, filechooser):
        def find_child_classes(container, cls):
            return [widget for widget in container.get_children() if isinstance(widget, cls)]

        widget = find_child_classes(filechooser, Gtk.Button)
        self.controller.debug(widget.get_name())

    def file_chooser_close(self, *args):
        self.debug(args)

    def setup_widgets(self):
        # Mainbox
        mainbox = self.srvgui.add_widget('gtk_vbox_container_main', Gtk.VBox())
        mainbox.set_hexpand(True)
        paned = self.srvgui.add_widget('gtk_hpaned', Gtk.HPaned())
        paned.set_property('margin-bottom', 6)
        paned.set_wide_handle(False)
        paned.set_position(300)

        # Paned
        ## Left view
        box = self.srvgui.add_widget('gtk_vbox_container_menu_view', Gtk.VBox())
        box.set_property('margin-left', 6)
        box.set_property('margin-right', 6)
        box.set_property('margin-bottom', 0)

        ### Toolbar
        toolbar = Gtk.Toolbar()
        toolbar.get_style_context().add_class(Gtk.STYLE_CLASS_PRIMARY_TOOLBAR)

        #### Filter entry tool
        tool = Gtk.ToolItem.new()

        hbox = Gtk.HBox()
        viewfilter = self.srvgui.add_widget('gtk_entry_filter_view', Gtk.Entry())
        completion = self.srvgui.get_widget('gtk_entrycompletion_viewmenu')
        viewfilter.set_completion(completion)
        viewfilter.connect('activate', self.srvclb.gui_viewmenu_filter)

        icon = self.srvicm.get_pixbuf_icon('basico-refresh')
        viewfilter.set_icon_from_pixbuf(Gtk.EntryIconPosition.PRIMARY, icon)
        viewfilter.set_icon_sensitive(Gtk.EntryIconPosition.PRIMARY, True)
        viewfilter.set_icon_tooltip_markup (Gtk.EntryIconPosition.PRIMARY, "Refresh and collapse")

        icon = self.srvicm.get_pixbuf_icon('basico-filter')
        viewfilter.set_icon_from_pixbuf(Gtk.EntryIconPosition.SECONDARY, icon)
        viewfilter.set_icon_sensitive(Gtk.EntryIconPosition.SECONDARY, True)
        viewfilter.set_icon_tooltip_markup (Gtk.EntryIconPosition.SECONDARY, "Click here to expand the tree")
        viewfilter.set_placeholder_text("Filter this view...")

        def on_icon_pressed(entry, icon_pos, event):
            if icon_pos == Gtk.EntryIconPosition.PRIMARY:
                viewmenu = self.srvgui.get_widget('viewmenu')
                viewmenu.refresh()
            elif icon_pos == Gtk.EntryIconPosition.SECONDARY:
                self.srvclb.expand_menuview()

        viewfilter.connect("icon-press", on_icon_pressed)

        hbox.pack_start(viewfilter, True, True, 0)
        tool.add(hbox)
        tool.set_expand(True)
        toolbar.insert(tool, -1)

        box.pack_start(toolbar, False, False, 0)

        ### View treeview
        scr = Gtk.ScrolledWindow()
        scr.set_hexpand(True)
        scr.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
        scr.set_shadow_type(Gtk.ShadowType.IN)
        vwp = Gtk.Viewport()
        vwp.set_hexpand(True)
        viewsbox = self.srvgui.add_widget('gtk_box_container_views', Gtk.Box())
        viewsbox.set_hexpand(True)
        vwp.add(viewsbox)
        scr.add(vwp)
        box.pack_start(scr, True, True, 0)
        paned.add1(box)

        ## Right view
        box = Gtk.VBox()
        box.set_hexpand(True)
        stack_main = self.srvgui.add_widget('gtk_stack_main', Gtk.Stack())
        stack_main.set_transition_type(Gtk.StackTransitionType.SLIDE_LEFT_RIGHT)
        stack_main.set_transition_duration(2500)
        box.pack_start(stack_main, True, True, 0)

        ### Visor stack
        stack_child = self.setup_stack_visor()
        stack_main.add_titled(stack_child, "visor", "SAP Notes Visor")

        ### SAP Note Visor tab
        # ~ tab_sapnote_visor = self.setup_tab_sapnote_visor()
        # ~ stack_main.add_titled(stack_child, "visor", "SAP Notes Visor")

        ### Annotation Visor tab
        # ~ tab_annotation_visor = self.setup_tab_annotations_visor()
        # ~ stack_main.add_titled(stack_child, "visor", "SAP Notes Visor")

        ### About stack
        stack_child = self.setup_stack_about()
        stack_main.add_titled(stack_child, "about", "About Basico")

        ### Log stack
        stack_child = self.setup_stack_log()
        stack_main.add_titled(stack_child, "log", "Log Viewer")

        ### Settings stack
        stack_child = self.setup_stack_settings()
        stack_main.add_titled(stack_child, "settings", "Basico Settings")

        ## Annotations
        boxannotations = self.srvgui.add_widget('gtk_vbox_container_annotations', Gtk.VBox())

        stack_annot = self.srvgui.add_widget('gtk_stack_annotation', Gtk.Stack())
        stack_annot.set_transition_type(Gtk.StackTransitionType.SLIDE_LEFT_RIGHT)
        stack_annot.set_transition_duration(2500)

        stack_child = self.setup_stack_annotation()
        stack_annot.add_titled(stack_child, "comment", "New comment")
        stack_annot.child_set_property (stack_child, "icon-name", "basico-comments")

        # ~ stack_child = self.setup_stack_annotation_link()
        # ~ stack_annot.add_titled(stack_child, "link", "New link")
        # ~ stack_annot.child_set_property (stack_child, "icon-name", "basico-browse")

        self.srvuif.set_widget_visibility('gtk_vbox_container_annotations', False)
        boxannotations.add(stack_annot)


        box.pack_start(boxannotations, True, True, 6)
        paned.add2(box)
        mainbox.pack_start(paned, True, True, 0)

        # Statusbar
        statusbar = self.srvgui.add_widget('widget_statusbar', Statusbar(self.controller))
        mainbox.pack_start(statusbar, False, False, 0)

        # Menu Views
        vbox = Gtk.VBox()
        viewsbox = self.srvgui.get_widget('gtk_box_container_views')
        viewmenu = self.srvgui.add_widget('viewmenu', SAPNoteViewMenu(self.controller))
        viewmenu.set_hexpand(True)
        viewmenu.set_vexpand(True)
        vbox.pack_start(viewmenu, True, True, 0)
        self.srvgui.swap_widget(viewsbox, vbox)

        self.add(mainbox)
        self.show_all()


    def setup_stack_visor(self):
        box = Gtk.VBox()
        box.set_hexpand(True)

        ### Toolbar
        boxtoolbar = self.srvgui.add_widget('gtk_hbox_container_toolbar', Gtk.HBox())
        box.pack_start(boxtoolbar, False, False, 0)
        visortoolbar = self.srvgui.add_widget('visortoolbar', VisorToolbar(self.controller))
        self.srvgui.swap_widget(boxtoolbar, visortoolbar)

        ### Visor
        notebook = self.srvgui.add_widget('gtk_notebook_visor', Gtk.Notebook())
        notebook.connect('switch-page', self.srvclb.gui_visor_switch_page)
        notebook.set_show_border(False)
        notebook.set_hexpand(True)


        visor_sapnotes_page = self.setup_tab_sapnote_visor()
        visor_sapnotes_page.set_hexpand(True)
        tab_widget = self.srvuif.create_notebook_tab_label('basico-sapnote', '<b>SAP Notes</b>')
        notebook.append_page(visor_sapnotes_page, tab_widget)

        visor_annotations_page = self.setup_tab_annotations_visor()
        tab_widget = self.srvuif.create_notebook_tab_label('basico-annotation', '<b>Annotations</b>')
        notebook.append_page(visor_annotations_page, tab_widget)

        notebook.child_set_property(visor_sapnotes_page, "tab-expand", True)
        notebook.child_set_property(visor_sapnotes_page, "tab-fill", False)
        notebook.child_set_property(visor_annotations_page, "tab-expand", True)
        notebook.child_set_property(visor_annotations_page, "tab-fill", False)

        box.pack_start(notebook, True, True, 0)

        return box

    def setup_tab_sapnote_visor(self):
        box = Gtk.VBox()
        box.set_hexpand(True)

        # ~ ### Toolbar
        # ~ boxtoolbar = self.srvgui.add_widget('gtk_hbox_container_toolbar', Gtk.HBox())
        # ~ box.pack_start(boxtoolbar, False, False, 0)
        # ~ visortoolbar = self.srvgui.add_widget('visortoolbar', SAPNoteViewVisorToolbar(self.controller))
        # ~ self.srvgui.swap_widget(boxtoolbar, visortoolbar)

        ### Visor
        scr = Gtk.ScrolledWindow()
        scr.set_hexpand(True)
        scr.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
        scr.set_shadow_type(Gtk.ShadowType.NONE)
        vwp = Gtk.Viewport()
        vwp.set_hexpand(True)
        visor = self.srvgui.add_widget('visor_sapnotes', SAPNotesVisor(self.controller))
        visor.set_hexpand(True)
        visor.set_vexpand(True)
        vwp.add(visor)
        scr.add(vwp)
        box.pack_start(scr, True, True, 0)
        visor.show_all()
        box.show_all()
        return box


    def setup_tab_annotations_visor(self):
        box = Gtk.VBox()
        box.set_hexpand(True)

        # ~ ### Toolbar
        # ~ boxtoolbar = self.srvgui.add_widget('gtk_hbox_container_toolbar', Gtk.HBox())
        # ~ box.pack_start(boxtoolbar, False, False, 0)
        # ~ visortoolbar = self.srvgui.add_widget('visortoolbar', SAPNoteViewVisorToolbar(self.controller))
        # ~ self.srvgui.swap_widget(boxtoolbar, visortoolbar)

        ### Visor
        scr = Gtk.ScrolledWindow()
        scr.set_hexpand(True)
        scr.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
        scr.set_shadow_type(Gtk.ShadowType.NONE)
        vwp = Gtk.Viewport()
        vwp.set_hexpand(True)
        visor = self.srvgui.add_widget('visor_annotations', AnnotationsVisor(self.controller))
        visor.set_hexpand(True)
        visor.set_vexpand(True)
        vwp.add(visor)
        scr.add(vwp)
        box.pack_start(scr, True, True, 0)
        visor.show_all()
        box.show_all()
        return box

    def setup_stack_about(self):
        box = Gtk.VBox()
        box.set_hexpand(True)
        about = self.srvgui.add_widget('widget_about', About())
        box.pack_start(about, True, True, 0)
        box.show_all()
        return box


    def setup_stack_settings(self):
        box = Gtk.VBox()
        box.set_hexpand(True)
        settings = self.srvgui.add_widget('widget_settings', SettingsView(self.controller))
        box.pack_start(settings, True, True, 0)
        box.show_all()
        return box

    def setup_stack_log(self):
        box = Gtk.VBox()
        box.set_hexpand(True)
        logviewer = self.srvgui.add_widget('widget_logviewer', LogViewer(self.controller))
        box.pack_start(logviewer, True, True, 0)
        box.show_all()
        return box


    def setup_stack_annotation(self):
        return self.srvgui.add_widget('widget_annotation', AnnotationWidget(self.controller))


    def run(self):
        visor_annotations = self.srvgui.get_widget('visor_annotations')
        viewmenu = self.srvgui.get_widget('viewmenu')
        viewmenu.set_view('collection')
        self.srvclb.gui_show_dashboard()
        annotations = self.srvant.search_term('')
        visor_annotations.populate_annotations(annotations)