Subversion Repositories basico

Rev

Rev 240 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

#!/usr/bin/python
# -*- coding: utf-8 -*-
# File: sapnoteviewmenu.py
# Author: Tomás Vírseda
# License: GPL v3
# Description: SAPNoteViewMenu Widget

# ~ from enum import IntEnum
import traceback as tb
from cgi import escape
from collections import OrderedDict

import gi
gi.require_version('Gdk', '3.0')
gi.require_version('Gtk', '3.0')
from gi.repository import Gdk
from gi.repository import Gio
from gi.repository import Gtk
from gi.repository import Pango
from gi.repository.GdkPixbuf import Pixbuf
from gi.repository import Pango
from datetime import datetime
from dateutil import parser as dateparser

from basico.core.service import Service
from basico.widgets.sapnoteview import SAPNoteView
from basico.widgets.collections import CollectionsMgtView


class SAPNoteViewMenu(SAPNoteView, Service):
    view = 'component'

    def __init__(self, app):
        SAPNoteView.__init__(self, app)
        self.app = app
        self.row_type = None


    def prepare(self):
        # ~ self.renderer_title.set_property("editable", True)
        # ~ self.renderer_title.connect('edited', self.edit_title)
        self.column_rowtype.set_visible(False)
        self.column_checkbox.set_visible(False)
        self.column_icon.set_visible(False)
        self.column_component.set_visible(True)
        self.column_cat.set_visible(False)
        self.column_sntype.set_visible(False)
        self.column_sid.set_visible(False)
        self.column_priority.set_visible(True)
        self.column_lang.set_visible(False)
        self.column_rel.set_visible(False)

        # TreeView common
        self.set_can_focus(True)
        self.set_headers_visible(False)
        self.set_enable_search(True)
        self.set_hover_selection(False)
        self.set_grid_lines(Gtk.TreeViewGridLines.NONE)
        self.set_level_indentation(0)
        self.sig_selection_changed = self.selection.connect('changed', self.row_changed)
        self.connect('button_press_event', self.right_click)

    def refresh(self):
        visor = self.gui.get_widget('visor')
        try:
            self.set_view(self.view)
            if self.row_type is not None:
                matches = self.db.get_notes_by_node(self.row_type, self.cid)
                visor.populate_sapnotes(matches)
        except Exception as error:
            self.debug(error)
            self.print_traceback()


    def row_changed(self, selection):
        if self.current_status is None:
            visor = self.gui.get_widget('visor')
            # ~ self.uif.set_widget_visibility('widget_annotation', False)

            try:
                model, treeiter = selection.get_selected()
                row = model[treeiter][0]
                self.row_type, self.cid = row.split('@')
                self.debug("%s - %s" % (self.row_type, self.cid))
                iter_has_child = model.iter_has_child(treeiter)

                if self.row_type == 'collection':
                    if not iter_has_child:
                        matches = self.db.get_notes_by_node(self.row_type, self.cid)
                        visor.populate_sapnotes(matches, self.cid)
                    else:
                        matches = self.db.get_notes_by_node(self.row_type, self.cid)
                        if len(matches) > 0:
                            visor.populate_sapnotes(matches)
                        else:
                            visor.populate_sapnotes([])
                else:
                    matches = self.db.get_notes_by_node(self.row_type, self.cid)
                    visor.populate_sapnotes(matches, self.cid)
            except AttributeError as error:
                pass
            except TypeError:
                pass
            except Exception as error:
                self.debug(error)
                # ~ self.print_traceback()


    def right_click(self, treeview, event, data=None):
        if event.button == 3:
            rect = Gdk.Rectangle()
            rect.x = x = int(event.x)
            rect.y = y = int(event.y)
            pthinfo = treeview.get_path_at_pos(x,y)
            if pthinfo is not None:
                path,col,cellx,celly = pthinfo
                model = treeview.get_model()
                treeiter = model.get_iter(path)
                rid = model[treeiter][0]
                rtype = rid[:rid.find('@')]
                if rtype == 'collection':
                    popcollections = self.gui.add_widget('gtk_popover_button_manage_collections_single_note', Gtk.Popover.new(treeview))
                    popcollections.set_position(Gtk.PositionType.RIGHT)
                    popcollections.set_pointing_to(rect)
                    popcollections.add(CollectionsMgtView(self.app, '0000000000', popcollections))
                    self.cb.gui_show_popover(None, popcollections)


    def set_view(self, view=None):
        statusbar = self.gui.get_widget('widget_statusbar')
        # FIXME: Get last view visited from config
        if view is None:
            view ='chronologic'

        iconview = self.gui.get_widget('gtk_image_current_view')
        icon = self.im.get_pixbuf_icon('basico-%s' % view, 24, 24)
        iconview.set_from_pixbuf(icon)
        iconview.show_all()
        self.view = view
        self.debug("Set current view to: %s" % view)

        # Change label
        viewlabel = self.gui.get_widget('gtk_label_current_view')
        name = "<b>%s</b>" % view.capitalize()
        viewlabel.set_markup(name)
        viewlabel.set_xalign(0.0)
        viewlabel.set_justify(Gtk.Justification.LEFT)
        viewlabel.show_all()
        self.populate([])

        # ~ self.info('Displaying view: %s' % view.capitalize())


    def get_view(self):
        return self.view


    def populate(self, sapnotes=[]):
        self.current_status = "working"
        self.column_component.set_title('Categories')
        self.set_headers_visible(False) # Set
        self.column_sid.set_visible(True)
        self.column_icon.set_visible(False)
        self.column_component.set_visible(True)
        self.column_component.set_expand(True)
        self.column_title.set_visible(False)
        self.column_title.set_expand(True)
        self.column_priority.set_expand(False)
        self.column_cat.set_visible(False)
        self.column_sid.set_expand(False)
        tgbshowmenu = self.gui.get_widget('gtk_toogletoolbutton_menu_view')
        tgbshowmenu.set_active(True)

        if len(sapnotes) == 0:
            sapnotes = self.db.get_notes()

        if self.view == 'component':
            self.populate_by_components(sapnotes)
        elif self.view == 'description':
            self.populate_by_component_descriptions(sapnotes)
        elif self.view == 'bookmarks':
            self.populate_by_bookmarks()
        elif self.view == 'projects':
            self.populate_by_projects(sapnotes)
        elif self.view == 'collections':
            self.populate_by_collections(sapnotes)
        elif self.view == 'tags':
            self.populate_by_tags(sapnotes)
        elif self.view == 'category':
            self.populate_by_category(sapnotes)
        elif self.view == 'chronologic':
            self.populate_by_chronologic(sapnotes)
        elif self.view == 'priority':
            self.populate_by_priority(sapnotes)
        elif self.view == 'type':
            self.populate_by_type(sapnotes)
        elif self.view == 'collection':
            self.populate_by_collection(sapnotes)
        elif self.view == 'annotation':
            self.populate_annotations()
        else:
            self.populate_by_components(sapnotes)

        self.debug("View '%s' populated" % (self.view))
        self.cb.gui_show_dashboard()
        self.current_status = None


    def populate_by_bookmarks(self):
        matches = []
        sapnotes = self.db.get_notes()
        for sid in sapnotes:
            if sapnotes[sid]['bookmark']:
                matches.append(sid)
        matches.sort()

        visor = self.gui.get_widget('visor')
        self.cb.gui_toggle_menu_view(False)
        visor.populate_sapnotes(matches)
        statusbar = self.gui.get_widget('widget_statusbar')
        self.info('View %s populated with %d SAP Notes</b>' % (self.view.capitalize(), len(matches)))


    def populate_by_components(self, sapnotes, only_bookmarks=False):
        self.model.clear()
        self.treepids = {}

        if len(sapnotes) == 0:
            return

        scomp = set()
        dcomp = {}

        for sid in sapnotes:
            compkey = escape(sapnotes[sid]['componentkey'])
            comptxt = escape(sapnotes[sid]['componenttxt'])
            scomp.add(compkey)
            dcomp[compkey] = comptxt
        lcomp = list(scomp)
        lcomp.sort()

        for compkey in lcomp:
            subkeys = compkey.split('-')
            ppid = None
            for i in range(1, len(subkeys)+1):
                key = ('-').join(subkeys[0:i])
                try:
                    ppid = self.treepids[key]
                except:
                    if i == len(subkeys):
                        title = dcomp[compkey]
                    else:
                        title = ""
                    node = self.get_node_component(key, title)
                    ppid = self.model.append(ppid, node)
                    self.treepids[key] = ppid


    def populate_by_priority(self, sapnotes):
        self.model.clear()
        treepids = {}

        if len(sapnotes) == 0:
            return

        scomp = set()
        dcomp = {}
        pset = set()

        for sid in sapnotes:
            try:
                priority = sapnotes[sid]['priority']
                pset.add(priority)
            except: pass

        plist = []
        plist.extend(pset)
        plist.sort()

        for priority in plist:
            node = self.get_node_priority(priority)
            pid = self.model.append(None, node)
            treepids[priority] = pid


    def populate_by_type(self, sapnotes):
        self.model.clear()
        treepids = {}

        if len(sapnotes) == 0:
            return

        scomp = set()
        dcomp = {}
        pset = set()

        for sid in sapnotes:
            try:
                sntype = sapnotes[sid]['type']
                pset.add(sntype)
            except: pass

        plist = []
        plist.extend(pset)
        plist.sort()

        for sntype in plist:
            node = self.get_node_type(sntype)
            pid = self.model.append(None, node)
            treepids[sntype] = pid


    def populate_by_component_descriptions(self, sapnotes, only_bookmarks=False):
        self.model.clear()
        self.treepids = {}

        if len(sapnotes) == 0:
            return

        scomp = set()
        dcomp = {}

        for sid in sapnotes:
            compkey = escape(sapnotes[sid]['componentkey'])
            comptxt = escape(sapnotes[sid]['componenttxt'])
            scomp.add(compkey)
            dcomp[compkey] = comptxt
        lcomp = list(scomp)
        lcomp.sort()

        for compkey in lcomp:
            subkeys = compkey.split('-')
            ppid = None
            for i in range(1, len(subkeys)+1):
                key = ('-').join(subkeys[0:i])
                try:
                    ppid = self.treepids[key]
                except:
                    if i == len(subkeys):
                        title = dcomp[compkey]
                    else:
                        title = ""
                    node = self.get_node_component_desc(key, title)
                    ppid = self.model.append(ppid, node)
                    self.treepids[key] = ppid


    def populate_by_category(self, sapnotes):
        self.model.clear()
        treepids = {}

        if len(sapnotes) == 0:
            return

        scomp = set()
        dcomp = {}
        catset = set()

        for sid in sapnotes:
            try:
                cat = sapnotes[sid]['category']
                catset.add(cat)
            except: pass

        catlist = []
        catlist.extend(catset)
        catlist.sort()

        for cat in catlist:
            node = self.get_node_category(cat)
            pid = self.model.append(None, node)
            treepids[cat] = pid


    def populate_by_collection(self, sapnotes):
        #FIXME: manage collections
        treepids = {}
        scomp = set()
        dcomp = {}
        self.model.clear()
        self.clts = self.app.get_service('Collections')
        collections = self.clts.get_all()
        od = OrderedDict(sorted(collections.items(), key=lambda t: t[1]))

        for tid in od:
            compkey = od[tid]
            subkeys = compkey.split(' ')
            ppid = None
            for i in range(1, len(subkeys)+1):
                key = (' ').join(subkeys[0:i])
                try:
                    ppid = treepids[key]
                except:
                    title = key
                    node = self.get_node_collection(tid, title)
                    ppid = self.model.append(ppid, node)
                    treepids[key] = ppid

        # ~ for tid in od:
            # ~ node = self.get_node_collection(tid, od[tid])
            # ~ pid = self.model.append(None, node)


    def populate_annotations(self, annotations=None):
        visor = self.gui.get_widget('visor')
        self.cb.gui_toggle_menu_view(False)
        visor.populate_annotations(annotations)


    def populate_by_chronologic(self, sapnotes):
        self.model.clear()
        treepids = {}

        if len(sapnotes) == 0:
            return

        years = set()
        months = set()
        days = set()
        for sid in sapnotes:
            try:
                downloaded = dateparser.parse(sapnotes[sid]['feedupdate'])
                year = "%d" % downloaded.year
                month = "%02d" % downloaded.month
                day = "%02d" % downloaded.day
                key_year    = year
                key_month   = year + month
                key_day     = year + month + day
                years.add(key_year)
                months.add(key_month)
                days.add(key_day)
            except:
                pass
        years = list(years)
        years.sort(reverse=True)
        months = list(months)
        months.sort(reverse=True)
        days = list(days)
        days.sort(reverse=True)

        for key_year in years:
            try:
                treepids[key_year]
            except:
                adate = key_year + '0101'
                downloaded = dateparser.parse(adate)
                node = self.get_node_date_year(downloaded, key_year)
                treepids[key_year] = self.model.append(None, node)

        for key_month in months:
            try:
                treepids[key_month]
            except:
                adate = key_month + '01'
                downloaded = dateparser.parse(adate)
                node = self.get_node_date_month(downloaded, key_month)
                key_year = key_month[0:4]
                treepids[key_month] = self.model.append(treepids[key_year], node)

        for key_day in days:
            try:
                treepids[key_day]
            except:
                downloaded = dateparser.parse(key_day)
                key_month = key_day[0:6]
                node = self.get_node_date_day(downloaded, key_day)
                treepids[key_day] = self.model.append(treepids[key_month], node)



    def edit_title(self, widget, path, target):
        model = self.get_model()
        treeiter = model.get_iter(path)
        row = model[treeiter][0]
        rowtype, cid = row.split('@')
        iter_has_child = model.iter_has_child(treeiter)

        if rowtype == 'collection':
            if not iter_has_child:
                if len(target) > 0:
                    self.clts.rename(cid, target)
                    self.populate()
                # ~ source = self.clts.get_name_by_cid(cid)
                # ~ self.debug("Collection renamed from '%s' to '%s'" % (source, target))