hsoft / moneyguru (http://hardcoded.net/moneyguru)

Future-aware personal finance application for Mac OS X and Windows.

Clone this repository (size: 8.3 MB): HTTPS / SSH
$ hg clone http://hg.hardcoded.net/moneyguru
commit 975: 4a48ab198a51
parent 974: 047f459046bd
branch: default
Added core.gui.column to facilitate column management in tables and trees. For now, all it does is helping with autofill, but its scope will grow shortly.
Virgil Dupras / hsoft
6 weeks ago

Changed (Δ1.8 KB):

raw changeset »

core/gui/column.py (28 lines added, 0 lines removed)

core/gui/entry_table.py (1 lines added, 0 lines removed)

core/gui/table.py (9 lines added, 4 lines removed)

core/gui/transaction_table.py (2 lines added, 0 lines removed)

core/gui/transaction_table_base.py (1 lines added, 5 lines removed)

core/tests/completion_test.py (5 lines added, 0 lines removed)

core/tests/gui/transaction_table_test.py (5 lines added, 2 lines removed)

Up to file-list core/gui/column.py:

1
# -*- coding: utf-8 -*-
2
# Created By: Virgil Dupras
3
# Created On: 2010-07-25
4
# Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
5
# 
6
# This software is licensed under the "HS" License as described in the "LICENSE" file, 
7
# which should be included with this package. The terms are also available at 
8
# http://www.hardcoded.net/licenses/hs_license
9
10
class Columns(object):
11
    def __init__(self, colnames):
12
        self.colnames = colnames[:] # We're altering the list, make a copy
13
    
14
    def columns_to_right(self, colname):
15
        column_index = self.colnames.index(colname)
16
        return self.colnames[column_index+1:]
17
    
18
    def move_column(self, colname, index):
19
        try:
20
            self.colnames.remove(colname)
21
        except ValueError:
22
            pass # move nothing
23
        else:
24
            self.colnames.insert(index, colname)
25
    
26
    def set_columns(self, colnames):
27
        self.colnames = colnames
28
    

Up to file-list core/gui/entry_table.py:

@@ -17,6 +17,7 @@ from .table import RowWithDebitAndCredit
17
17
from .transaction_table_base import TransactionTableBase
18
18
19
19
class EntryTable(TransactionTableBase):
20
    ALL_ATTRS = ['description', 'payee', 'transfer', 'increase', 'decrease']
20
21
    INVALIDATING_MESSAGES = TransactionTableBase.INVALIDATING_MESSAGES | set(['shown_account_changed'])
21
22
    
22
23
    def __init__(self, view, account_view):

Up to file-list core/gui/table.py:

@@ -12,9 +12,16 @@ from hsgui.table import Table, GUITable
12
12
13
13
from ..model.amount import Amount
14
14
from ..model.sort import sort_string
15
from .column import Columns
15
16
16
17
# Subclasses of this class must have a "view" and a "document" attribute
17
18
class GUITable(GUITableBase):
19
    ALL_ATTRS = []
20
    
21
    def __init__(self):
22
        GUITableBase.__init__(self)
23
        self.columns = Columns(self.ALL_ATTRS)
24
    
18
25
    def can_move(self, row_indexes, position):
19
26
        if not 0 <= position <= len(self):
20
27
            return False
@@ -83,10 +90,8 @@ class Row(RowBase):
83
90
    def _get_autofill_dest_attrs(self, key_attr, all_attrs):
84
91
        """Returns a set of attrs to fill depending on which columns are right to key_attr
85
92
        """
86
        columns = self.table._columns
87
        if columns:
88
            column_index = columns.index(key_attr)
89
            right_columns = set(columns[column_index + 1:])
93
        if self.table.columns.colnames:
94
            right_columns = set(self.table.columns.columns_to_right(key_attr))
90
95
            return set(all_attrs) & right_columns
91
96
        else:
92
97
            return set(all_attrs)

Up to file-list core/gui/transaction_table.py:

@@ -17,6 +17,8 @@ from .table import Row, RowWithDate, row
17
17
from .transaction_table_base import TransactionTableBase
18
18
19
19
class TransactionTable(TransactionTableBase):
20
    ALL_ATTRS = ['description', 'payee', 'from', 'to', 'amount']
21
    
20
22
    def __init__(self, view, transaction_view):
21
23
        TransactionTableBase.__init__(self, view, transaction_view)
22
24
    

Up to file-list core/gui/transaction_table_base.py:

@@ -19,7 +19,6 @@ class TransactionTableBase(GUITable, Vie
19
19
    def __init__(self, view, parent_view):
20
20
        ViewChild.__init__(self, view, parent_view)
21
21
        GUITable.__init__(self)
22
        self._columns = [] # empty columns == unrestricted autofill
23
22
    
24
23
    #--- Override
25
24
    def _is_edited_new(self):
@@ -58,10 +57,7 @@ class TransactionTableBase(GUITable, Vie
58
57
        return self.document.can_move_transactions(transactions, before, after)
59
58
    
60
59
    def change_columns(self, columns):
61
        """Call this when the order or the visibility of the columns change"""
62
        
63
        columns = [c if c != 'from_' else 'from' for c in columns]
64
        self._columns = columns
60
        self.columns.set_columns(columns)
65
61
    
66
62
    def duplicate_selected(self):
67
63
        self.document.duplicate_transactions(self.selected_transactions)

Up to file-list core/tests/completion_test.py:

@@ -200,6 +200,7 @@ def test_field_completion_is_case_sensit
200
200
@with_app(app_one_entry)
201
201
def test_field_completion_on_set_entry_transfer(app):
202
202
    # Setting a transfer autocompletes the amount and the description.
203
    app.etable.columns.move_column('transfer', 0)
203
204
    app.etable.add()
204
205
    row = app.etable.selected_row
205
206
    row.transfer = 'Salary'
@@ -222,6 +223,7 @@ def test_field_completion_on_set_entry_d
222
223
@with_app(app_one_entry)
223
224
def test_field_completion_on_set_entry_payee(app):
224
225
    # Setting a transfer autocompletes the amount and the description.
226
    app.etable.columns.move_column('payee', 0)
225
227
    app.etable.add()
226
228
    row = app.etable.selected_row
227
229
    row.payee = 'Payee'
@@ -345,16 +347,19 @@ def assert_completion_order_changed(app)
345
347
    eq_(complete_etable(app, 'd', 'description'), 'esc1')
346
348
    eq_(complete_etable(app, 'c', 'transfer'), 'at1')
347
349
    eq_(complete_etable(app, 'p', 'payee'), 'ay1')
350
    app.etable.columns.move_column('description', 0)
348
351
    app.etable.add()
349
352
    row = app.etable.selected_row
350
353
    row.description = 'desc1'
351
354
    eq_(app.etable[app.etable.selected_indexes[0]].payee, 'pay1')
352
355
    eq_(app.etable[app.etable.selected_indexes[0]].transfer, 'cat1')
356
    app.etable.columns.move_column('transfer', 0)
353
357
    app.etable.add()
354
358
    row = app.etable.selected_row
355
359
    row.transfer = 'cat1'
356
360
    eq_(app.etable[app.etable.selected_indexes[0]].description, 'desc1')
357
361
    eq_(app.etable[app.etable.selected_indexes[0]].payee, 'pay1')
362
    app.etable.columns.move_column('payee', 0)
358
363
    app.etable.add()
359
364
    row = app.etable.selected_row
360
365
    row.payee = 'pay1'

Up to file-list core/tests/gui/transaction_table_test.py:

@@ -868,6 +868,7 @@ def test_autofill_ignores_blank(app):
868
868
@with_app(app_autofill)
869
869
def test_autofill_on_set_from(app):
870
870
    # Setting 'from' autocompletes the rest.
871
    app.ttable.columns.move_column('from', 0)
871
872
    app.ttable.add()
872
873
    row = app.ttable.edited
873
874
    row.from_ = 'Salary'
@@ -878,7 +879,8 @@ def test_autofill_on_set_from(app):
878
879
879
880
@with_app(app_autofill)
880
881
def test_autofill_on_set_to(app):
881
    # Setting 'from' autocompletes the rest.
882
    # Setting 'to' autocompletes the rest.
883
    app.ttable.columns.move_column('to', 0)
882
884
    app.ttable.add()
883
885
    row = app.ttable.edited
884
886
    row.to = 'Checking'
@@ -901,6 +903,7 @@ def test_autofill_on_set_description(app
901
903
@with_app(app_autofill)
902
904
def test_autofill_on_set_payee(app):
903
905
    # Setting a transfer autocompletes the amount and the description.
906
    app.ttable.columns.move_column('payee', 0)
904
907
    app.ttable.add()
905
908
    row = app.ttable.edited
906
909
    row.payee = 'Payee'
@@ -932,7 +935,7 @@ def test_autofill_uses_the_latest_entere
932
935
def test_change_columns_fixed_from(app):
933
936
    # When 'from_' is passed in change_columns(), it is automatically changed to 'from'
934
937
    app.mw.select_transaction_table()
935
    app.ttable.change_columns(['from_', 'description', 'to', 'amount'])
938
    app.ttable.change_columns(['from', 'description', 'to', 'amount'])
936
939
    app.ttable[0].from_ = 'foo' # no crash
937
940
938
941