Files @ 751341c267ed
Branch filter:

Location: NPO-Accounting/experimental-accounting-api/accounting/gtkclient.py

Joar Wandborg
[storage] Added add_transaction abstract method
import sys
import logging
import threading
import pkg_resources

from functools import wraps
from datetime import datetime

from gi.repository import Gtk
from gi.repository import GLib
from gi.repository import GObject

from accounting.client import Client

_log = logging.getLogger(__name__)


def indicate_activity(func_or_str):
    description = None

    def decorator(func):
        @wraps(func)
        def wrapper(self, *args, **kw):
            self.status_description.set_text(description)
            self.activity_indicator.show()
            self.activity_indicator.start()

            return func(self, *args, **kw)

        return wrapper

    if callable(func_or_str):
        description = 'Working'
        return decorator(func_or_str)
    else:
        description = func_or_str
        return decorator


def indicate_activity_done(func):
    @wraps(func)
    def wrapper(self, *args, **kw):
        self.status_description.set_text('')
        self.activity_indicator.stop()
        self.activity_indicator.hide()

        return func(self, *args, **kw)

    return wrapper


class AccountingApplication:
    def __init__(self):
        #Gtk.Window.__init__(self, title='Accounting Client')

        self.client = Client()

        self.load_ui(pkg_resources.resource_filename(
            'accounting', 'res/client-ui.glade'))

        self.about_dialog.set_transient_for(self.accounting_window)

        self.accounting_window.connect('delete-event', Gtk.main_quit)
        self.accounting_window.set_border_width(0)
        self.accounting_window.set_default_geometry(640, 360)

        self.accounting_window.show_all()
        self.transaction_detail.hide()

    def load_ui(self, path):
        _log.debug('Loading UI...')
        builder = Gtk.Builder()
        builder.add_from_file(path)
        builder.connect_signals(self)

        for element in builder.get_objects():
            try:
                setattr(self, Gtk.Buildable.get_name(element), element)
                _log.debug('Loaded %s', Gtk.Buildable.get_name(element))
            except TypeError as exc:
                _log.error('%s could not be loaded: %s', element, exc)

        _log.debug('UI loaded')

    def on_transaction_view_cursor_changed(self, widget):
        selection = self.transaction_view.get_selection()
        selection.set_mode(Gtk.SelectionMode.SINGLE)
        xact_store, xact_iter = selection.get_selected()

        xact_id = xact_store.get_value(xact_iter, 0)
        _log.debug('selection: %s', xact_id)

        for transaction in self.transaction_data:
            if transaction.id == xact_id:
                self.transaction_header.set_text(transaction.payee)

                self.posting_store.clear()

                for posting in transaction.postings:
                    self.posting_store.append([
                        posting.account,
                        str(posting.amount.amount),
                        posting.amount.symbol
                    ])

                self.transaction_detail.show()
                break

    def on_show_about_activate(self, widget):
        _log.debug('Showing About')
        self.about_dialog.show_all()

    def on_about_dialog_response(self, widget, response_type):
        _log.debug('Closing About')
        if response_type == Gtk.ResponseType.CANCEL:
            self.about_dialog.hide()
        else:
            _log.error('Unexpected response_type: %d', response_type)

    @indicate_activity('Refreshing Transactions')
    def on_transaction_refresh_activate(self, widget):
        def load_transactions():
            transactions = self.client.get_register()
            GLib.idle_add(self.on_transactions_loaded, transactions)

        threading.Thread(target=load_transactions).start()

    @indicate_activity_done
    def on_transactions_loaded(self, transactions):
        _log.debug('transactions: %s', transactions)

        self.transaction_data = transactions
        self.transaction_store.clear()

        for transaction in transactions:
            self.transaction_store.append([
                transaction.id,
                transaction.date.strftime('%Y-%m-%d'),
                transaction.payee
            ])


def main(argv=None):
    logging.basicConfig(level=logging.DEBUG)

    GObject.threads_init()

    accounting = AccountingApplication()

    Gtk.main()

if __name__ == '__main__':
    sys.exit(main())