From 3eea053d54499274c28efd94fb1cda91bd558d1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9gory=20Soutad=C3=A9?= Date: Wed, 22 Sep 2010 21:02:29 +0200 Subject: [PATCH] * Goup/Ungroup initial work * Add INSTALL file * Adapt KissCount to new resolution --- INSTALL | 25 +++++++++++++++++ init.sql | 2 +- src/controller/KissCount.cpp | 17 ++++++++++- src/controller/KissCount.h | 2 ++ src/model/Database.cpp | 16 ++++++++++- src/model/Operation.h | 2 ++ src/model/User.cpp | 53 +++++++++++++++++++++++++++++++++++ src/model/User.h | 3 ++ src/view/AccountPanel.cpp | 29 +++++++++++++++++-- src/view/AccountPanel.h | 4 ++- src/view/SearchPanel.cpp | 3 +- src/view/StatsPanel.cpp | 17 +++++++---- src/view/grid/GridAccount.cpp | 42 +++++++++++++++++++++++++-- src/view/grid/GridAccount.h | 3 ++ src/view/wxUI.cpp | 2 +- 15 files changed, 203 insertions(+), 17 deletions(-) create mode 100644 INSTALL diff --git a/INSTALL b/INSTALL new file mode 100644 index 0000000..ced7d13 --- /dev/null +++ b/INSTALL @@ -0,0 +1,25 @@ +** Dependencies for compilation (on Debian) ** + +libsqlite3-dev +libwxgtk2.8-dev +g++ +make + + +** Compilation of extra libraries ** +cd lib/wxsqlite3-1.9.9 +./configure +make +cd - +cd lib/freechart +make # wxFreechart is already configured +cd - + + +** Compilation of KissCount ** +make + + +** Execution ** +export LD_LIBRARY_PATH=$PWD/lib/freechart/lib:$PWD/lib/wxsqlite3-1.9.9/lib/ +./kc diff --git a/init.sql b/init.sql index d921189..eb96374 100644 --- a/init.sql +++ b/init.sql @@ -2,7 +2,7 @@ CREATE TABLE kisscount(db_version VARCHAR(20)); CREATE TABLE user (id INTEGER PRIMARY KEY, name VARCHAR(255), password VARCHAR(255)); CREATE TABLE account(id INTEGER PRIMARY KEY, user REFERENCES user(id), name VARCHAR(255), number VARCHAR(255), shared CHAR(1), default_account CHAR(1)); CREATE TABLE account_amount(id INTEGER PRIMARY KEY, account REFERENCES account(id), year INTEGER, month INTEGER, amount FLOAT); -CREATE TABLE operation(id INTEGER PRIMARY KEY, parent REFERENCES operation(id), user REFERENCES user(id), account REFERENCES account(id), year INTEGER, month INTEGER, day INTEGER, amount FLOAT, description VARCHAR(255), category REFERENCES category(id), fix_cost CHAR(1), checked CHAR(1), formula VARCHAR(255), transfert REFERENCES operation(id)); +CREATE TABLE operation(id INTEGER PRIMARY KEY, parent REFERENCES operation(id), user REFERENCES user(id), account REFERENCES account(id), year INTEGER, month INTEGER, day INTEGER, amount FLOAT, description VARCHAR(255), category REFERENCES category(id), fix_cost CHAR(1), checked CHAR(1), formula VARCHAR(255), transfert REFERENCES operation(id), meta CHAR(1)); CREATE TABLE category(id INTEGER PRIMARY KEY, user REFERENCES user(id), parent REFERENCES category(id), name VARCHAR(255), backcolor VARCHAR(10), forecolor VARCHAR(10), font VARCHAR(255)); CREATE TABLE preference(id INTEGER PRIMARY KEY, user REFERENCES user(id), name VARCHAR(255), value VARCHAR(255)); INSERT INTO kisscount ("db_version") VALUES ("1"); \ No newline at end of file diff --git a/src/controller/KissCount.cpp b/src/controller/KissCount.cpp index 3217b54..4a4f1ca 100644 --- a/src/controller/KissCount.cpp +++ b/src/controller/KissCount.cpp @@ -21,7 +21,9 @@ KissCount::KissCount(const char* bdd_filename) : _user(NULL) { - _wxUI = new wxUI(this, wxT("KissCount"), wxPoint(50, 50), wxSize(1024, 768)); + wxRect rect = wxDisplay().GetGeometry(); + + _wxUI = new wxUI(this, wxT("KissCount"), wxPoint(50, 50), wxSize(rect.width-rect.x, rect.height-rect.y)); _wxUI->SetLanguage(wxLocale::GetSystemLanguage()); @@ -218,6 +220,7 @@ std::map > KissCount::GetAllOperations() void KissCount::GenerateMonth(int monthFrom, int yearFrom, int monthTo, int yearTo) { std::vector::iterator it; + std::map meta; Operation op; _db->GenerateMonth(_user, monthFrom, yearFrom, monthTo, yearTo); @@ -239,8 +242,20 @@ void KissCount::GenerateMonth(int monthFrom, int yearFrom, int monthTo, int year op.year = yearTo; op.checked = false; op.id = AddOperation(op); + if (op.meta) + meta[it->id] = op.id; (*_user->_operations[yearTo])[monthTo].push_back(op); } + + // Re Generate parents + for(it = (*_user->_operations[yearFrom])[monthFrom].begin(); + it != (*_user->_operations[yearFrom])[monthFrom].end() + && it->fix_cost; + it++) + { + if (it->parent.Length()) + it->parent = meta[it->parent]; + } } _wxUI->GenerateMonth(monthTo, yearTo); } diff --git a/src/controller/KissCount.h b/src/controller/KissCount.h index 9c162ef..7357e28 100644 --- a/src/controller/KissCount.h +++ b/src/controller/KissCount.h @@ -27,6 +27,8 @@ #include #include +#include + #define APP_VERSION "v0.1 beta" class wxUI; diff --git a/src/model/Database.cpp b/src/model/Database.cpp index 0f763c2..e982dbd 100644 --- a/src/model/Database.cpp +++ b/src/model/Database.cpp @@ -371,9 +371,11 @@ void Database::LoadYear(User* user, int year) op.checked = set.GetBool(wxT("checked")); op.transfert = set.GetAsString(wxT("transfert")); op.formula = set.GetAsString(wxT("formula")); + op.meta = set.GetBool(wxT("meta")); (*user->_operations[op.year])[op.month].push_back(op); } + user->ResolveGroups(year); set.Finalize(); } @@ -427,6 +429,7 @@ bool Database::GetOperation(const wxString& id, Operation* op) op->checked = set.GetBool(wxT("checked")); op->transfert = set.GetAsString(wxT("transfert")); op->formula = set.GetAsString(wxT("formula")); + op->meta = set.GetBool(wxT("meta")); return true; } @@ -506,6 +509,10 @@ void Database::UpdateOperation(Operation& op) else req += wxT(", checked='0'"); req += wxT(", transfert='") + op.transfert + wxT("'"); + if (op.meta) + req += wxT(", meta='1'"); + else + req += wxT(", meta='0'"); req += wxT(", formula='") + op.formula + wxT("'"); req += wxT(" WHERE id='") + op.id + wxT("'"); @@ -521,7 +528,7 @@ wxString Database::AddOperation(User* user, Operation& op) ESCAPE_CHARS(op.description); - req = wxT("INSERT INTO operation ('user', 'parent', 'account', 'year', 'month', 'day', 'amount', 'description', 'category', 'fix_cost', 'formula', 'transfert') VALUES ('") ; + req = wxT("INSERT INTO operation ('user', 'parent', 'account', 'year', 'month', 'day', 'amount', 'description', 'category', 'fix_cost', 'formula', 'transfert', 'meta') VALUES ('") ; req += user->_id + wxT("'"); req += wxT(", '") + op.parent + wxT("'"); req += wxT(", '") + op.account + wxT("'"); @@ -537,6 +544,10 @@ wxString Database::AddOperation(User* user, Operation& op) req += wxT(", '0'") ; req += wxT(", '") + op.formula + wxT("'"); req += wxT(", '") + op.transfert + wxT("'"); + if (op.meta) + req += wxT(", '1'") ; + else + req += wxT(", '0'") ; req += wxT(")"); EXECUTE_SQL_UPDATE(req, wxT("0")); @@ -850,6 +861,7 @@ void Database::GenerateMonth(User* user, int monthFrom, int yearFrom, int monthT req += wxT(" account='") + it->id + wxT("'"); req += wxT(" AND year='") + wxString::Format(wxT("%d"), yearFrom) + wxT("'"); req += wxT(" AND month='") + wxString::Format(wxT("%d"), monthFrom) + wxT("'"); + req += wxT(" AND meta='0'"); EXECUTE_SQL_QUERY(req, set, ); @@ -1194,6 +1206,7 @@ void Database::GetStats(User* user, const wxString& monthFrom, const wxString& y req += wxT(" AND (year < '") + yearTo + wxT("' OR (year == '") + yearTo + wxT("' AND month <= '") + monthTo + wxT("'))"); req += wxT(" AND (transfert='' OR transfert IS NULL)"); req += wxT(" AND amount < 0"); + req += wxT(" AND meta='0'"); EXECUTE_SQL_QUERY(req, set, ); @@ -1217,6 +1230,7 @@ std::vector::iterator accountIt; { req = wxT("SELECT SUM(amount) AS amount FROM operation WHERE account='") + accountIt->id + wxT("'"); req += wxT(" AND checked='0'"); + req += wxT(" AND meta='0'"); req += wxT(" AND (year < '") + wxString::Format(wxT("%d"), year) + wxT("'") ; req += wxT(" OR (year == '") + wxString::Format(wxT("%d"), year) + wxT("'") ; req += wxT(" AND month < '") + wxString::Format(wxT("%d"), month) + wxT("'") ; diff --git a/src/model/Operation.h b/src/model/Operation.h index be0b2a0..6c4d4a5 100644 --- a/src/model/Operation.h +++ b/src/model/Operation.h @@ -35,6 +35,8 @@ public: bool checked; wxString transfert; wxString formula; + bool meta; + std::vector childs; } ; #endif diff --git a/src/model/User.cpp b/src/model/User.cpp index 9467129..d4daec8 100644 --- a/src/model/User.cpp +++ b/src/model/User.cpp @@ -160,3 +160,56 @@ void User::LinkOrUnlinkOperation(Operation& op) op.transfert = wxT(""); } } + +void User::Group(Operation* op) +{ + std::vector::iterator it; + std::vector::iterator it2; + + for (it = (*_operations[op->year])[op->month].begin(); it != (*_operations[op->year])[op->month].end(); it++) + { + if (it->id == op->parent) + { + for (it2 = it->childs.begin(); it2 != it->childs.end(); it2++) + if ((*it2)->id == op->id) + break; + // Already into childs + if (it2 != it->childs.end()) return; + it->childs.push_back(op); + break; + } + } +} + +void User::UnGroup(Operation* op) +{ + std::vector::iterator it; + std::vector::iterator it2; + + for (it = (*_operations[op->year])[op->month].begin(); it != (*_operations[op->year])[op->month].end(); it++) + { + if (it->id == op->parent) + { + for (it2 = it->childs.begin(); it2 != it->childs.end(); it2++) + if ((*it2)->id == op->id) + { + it->childs.erase(it2); + return; + } + break; + } + } +} + +void User::ResolveGroups(int year) +{ + unsigned int i; + std::map >::iterator it; + + for (it = _operations[year]->begin(); it != _operations[year]->end(); it++) + { + for (i=0; isecond.size(); i++) + if (it->second[i].parent.Length()) + Group(&((*_operations[year])[it->first])[i]); + } +} diff --git a/src/model/User.h b/src/model/User.h index 00b709c..6c208d4 100644 --- a/src/model/User.h +++ b/src/model/User.h @@ -54,6 +54,9 @@ public: int GetOperationsNumber(int month, int year); wxLanguage GetLanguage(); void LinkOrUnlinkOperation(Operation& op); + void Group(Operation* op); + void UnGroup(Operation* op); + void ResolveGroups(int year); }; #endif diff --git a/src/view/AccountPanel.cpp b/src/view/AccountPanel.cpp index c8bdfdd..0c4d94f 100644 --- a/src/view/AccountPanel.cpp +++ b/src/view/AccountPanel.cpp @@ -21,7 +21,7 @@ enum {ACCOUNT_NUMBER, ACCOUNT_NAME, ACCOUNT_INIT, ACCOUNT_CUR, ACCOUNT_FINAL, NUMBER_COLS_ACCOUNTS}; enum {CUR_CREDIT, CUR_DEBIT, TOTAL_CREDIT, TOTAL_DEBIT, REMAINS, STATS_ROW, CATS_STATS}; -enum {CALENDAR_TREE_ID=1, OPS_GRID_ID, CALENDAR_ID, ACCOUNTS_GRID_ID, MENU_GENERATE_ID, MENU_DELETE_ID, CHECK_MODE_ID}; +enum {CALENDAR_TREE_ID=1, OPS_GRID_ID, CALENDAR_ID, ACCOUNTS_GRID_ID, MENU_GENERATE_ID, MENU_DELETE_ID, CHECK_MODE_ID, GROUP_ID, UNGROUP_ID}; BEGIN_EVENT_TABLE(AccountPanel, wxPanel) EVT_GRID_CMD_CELL_CHANGE(OPS_GRID_ID, AccountPanel::OnOperationModified) @@ -34,6 +34,8 @@ EVT_MENU(MENU_DELETE_ID, AccountPanel::OnMenuDelete) EVT_SHOW(AccountPanel::OnShow) EVT_CALENDAR_SEL_CHANGED(CALENDAR_ID, AccountPanel::OnCalendarChange) EVT_CHECKBOX(CHECK_MODE_ID, AccountPanel::OnCheckMode) +EVT_BUTTON(GROUP_ID, AccountPanel::OnGroup) +EVT_BUTTON(UNGROUP_ID, AccountPanel::OnUnGroup) END_EVENT_TABLE() AccountPanel::AccountPanel(KissCount* kiss, wxUI *parent) : wxScrolledWindow(&(*parent)), _curMonth(-1), _curYear(-1), _kiss(kiss), _wxUI(parent), _tree(this, CALENDAR_TREE_ID, wxDefaultPosition, wxDefaultSize, wxTR_HIDE_ROOT) @@ -42,12 +44,14 @@ AccountPanel::AccountPanel(KissCount* kiss, wxUI *parent) : wxScrolledWindow(&(* wxBoxSizer *hbox2 = new wxBoxSizer(wxHORIZONTAL); wxBoxSizer *vbox = new wxBoxSizer(wxVERTICAL); wxBoxSizer *vbox2 = new wxBoxSizer(wxVERTICAL); + wxBoxSizer *vbox3 = new wxBoxSizer(wxVERTICAL); wxChartPanel* chart ; int i ; User* user = _kiss->GetUser(); std::vector::iterator accountIt; std::vector::iterator categoryIt; DEFAULT_FONT(font); + wxRect rect = wxDisplay().GetGeometry(); SetSizer(hbox); @@ -119,7 +123,16 @@ AccountPanel::AccountPanel(KissCount* kiss, wxUI *parent) : wxScrolledWindow(&(* _tree.SetIndent(5); - hbox->Add(&_tree, 0); + wxButton* buttonGroup = new wxButton(this, GROUP_ID, _("Group")); + wxButton* buttonUnGroup = new wxButton(this, GROUP_ID, _("UnGroup")); + + vbox3->Add(&_tree, 0); + vbox3->Add(-1, 30); + vbox3->Add(buttonGroup, 0); + vbox3->Add(-1, 10); + vbox3->Add(buttonUnGroup, 0); + + hbox->Add(vbox3, 0); hbox2->Add(_accountsGrid, 0); hbox2->Add(_calendar, 0); vbox2->Add(hbox2, 0); @@ -138,7 +151,7 @@ AccountPanel::AccountPanel(KissCount* kiss, wxUI *parent) : wxScrolledWindow(&(* Fit(); - SetMinSize(wxSize(1024, 640)); + SetMinSize(wxSize(rect.width-rect.x, rect.height-rect.y-128)); SetScrollbars(10, 10, 100/10, 100/10); } @@ -808,3 +821,13 @@ void AccountPanel::OnCheckMode(wxCommandEvent& event) { UpdateStats(); } + +void AccountPanel::OnGroup(wxCommandEvent& event) +{ + _grid->Group(); +} + +void AccountPanel::OnUnGroup(wxCommandEvent& event) +{ + _grid->UnGroup(); +} diff --git a/src/view/AccountPanel.h b/src/view/AccountPanel.h index 23d97f4..7e2a150 100644 --- a/src/view/AccountPanel.h +++ b/src/view/AccountPanel.h @@ -58,6 +58,9 @@ public: void OnMenuDelete(wxCommandEvent& event); void OnShow(wxShowEvent& event); void OnCalendarChange(wxCalendarEvent& event); + void OnCheckMode(wxCommandEvent& event); + void OnGroup(wxCommandEvent& event); + void OnUnGroup(wxCommandEvent& event); int _curMonth, _curYear; @@ -83,7 +86,6 @@ private: void UpdateStats(); void InsertOperation(User* user, Operation* op, int line, bool fix); void GetTreeSelection(int* month, int* year); - void OnCheckMode(wxCommandEvent& event); DECLARE_EVENT_TABLE(); }; diff --git a/src/view/SearchPanel.cpp b/src/view/SearchPanel.cpp index f029238..472b997 100644 --- a/src/view/SearchPanel.cpp +++ b/src/view/SearchPanel.cpp @@ -41,6 +41,7 @@ SearchPanel::SearchPanel(KissCount* kiss, wxUI *parent) : wxScrolledWindow(&(*pa std::vector::iterator accountIt; std::vector::iterator categoryIt; wxDateTime firstOfMonth; + wxRect rect = wxDisplay().GetGeometry(); wxBoxSizer *vbox = new wxBoxSizer(wxVERTICAL); SetSizer(vbox); @@ -108,7 +109,7 @@ SearchPanel::SearchPanel(KissCount* kiss, wxUI *parent) : wxScrolledWindow(&(*pa Fit(); - SetMinSize(wxSize(1024, 640)); + SetMinSize(wxSize(rect.width-rect.x, rect.height-rect.y-128)); SetScrollbars(10, 10, 100/10, 100/10); Hide(); diff --git a/src/view/StatsPanel.cpp b/src/view/StatsPanel.cpp index b59059b..af89dfe 100644 --- a/src/view/StatsPanel.cpp +++ b/src/view/StatsPanel.cpp @@ -133,15 +133,15 @@ StatsPanel::StatsPanel(KissCount* kiss, wxUI *parent) : wxPanel(&(*parent)), _ki chart->SetMinSize(// chart->GetSize() wxSize(200,250)); - wxCommandEvent event ; - OnRangeChange(event); - _vbox2->Add(-1, 10); _vbox2->Add(chart); vbox->Add(hbox); vbox->Add(_hbox2); + wxCommandEvent event ; + OnRangeChange(event); + Fit(); Hide(); @@ -284,16 +284,21 @@ void StatsPanel::OnShow(wxShowEvent& event) void StatsPanel::OnRangeChange(wxCommandEvent& event) { - int monthFrom, monthTo, yearFrom, yearTo; + long monthFrom, monthTo, yearFrom, yearTo; + + if (!_yearFrom->GetStringSelection().Length() || + !_yearTo->GetStringSelection().Length()) + return; monthFrom = _monthFrom->GetCurrentSelection(); - _yearFrom->GetStringSelection().ToLong((long*)&yearFrom); + _yearFrom->GetStringSelection().ToLong(&yearFrom); monthTo = _monthTo->GetCurrentSelection(); - _yearTo->GetStringSelection().ToLong((long*)&yearTo); + _yearTo->GetStringSelection().ToLong(&yearTo); if (yearTo > yearFrom || (yearFrom == yearTo && monthFrom >= monthTo)) { + std::cout << monthFrom << " " << monthTo << " " << _yearFrom->GetStringSelection().mb_str() << " " << yearFrom << " " << yearTo << "\n" ; wxMessageBox(_("Invalide date range"), _("KissCount"), wxICON_ERROR | wxOK); return; } diff --git a/src/view/grid/GridAccount.cpp b/src/view/grid/GridAccount.cpp index 560012d..ad4efb3 100644 --- a/src/view/grid/GridAccount.cpp +++ b/src/view/grid/GridAccount.cpp @@ -88,6 +88,13 @@ GridAccount::GridAccount(KissCount* kiss, wxWindow *parent, wxWindowID id) : wxG } Connect(id, wxEVT_GRID_CELL_CHANGE, wxGridEventHandler(GridAccount::OnOperationModified), NULL, this); + + AutoSizeColumn(TREE, false); + AutoSizeColumn(CATEGORY, false); + AutoSizeColumn(DATE, false); + AutoSizeColumn(ACCOUNT, false); + AutoSizeColumn(DELETE, false); + AutoSizeColumn(CHECKED, false); } GridAccount::~GridAccount() @@ -141,19 +148,27 @@ void GridAccount::LoadOperations(std::vector* operations, bool canAdd it = _operations->begin(); for (;it != _operations->end() && it->fix_cost; it++) + { + if (it->parent.Length()) continue; + if (setWeek) InsertOperationWithWeek(user, &(*it), ++curLine, true, it->month, it->year); else InsertOperation(user, &(*it), ++curLine, true, it->month, it->year); + } if (canAddOperation) InsertOperation(user, NULL, ++curLine, true, month, year); for (; it != _operations->end(); it++) + { + if (it->parent.Length()) continue; + if (setWeek) InsertOperationWithWeek(user, &(*it), ++curLine, false, it->month, it->year); else InsertOperation(user, &(*it), ++curLine, false, it->month, it->year); + } if (canAddOperation) InsertOperation(user, NULL, ++curLine, false, month, year); @@ -224,8 +239,20 @@ void GridAccount::InsertOperation(User* user, Operation* op, int line, bool fix, InsertRows(line, 1); - SetCellRenderer(line, TREE, new wxGridCellTreeButtonRenderer()); - SetCellEditor(line, TREE, new wxGridCellTreeButtonEditor()); + if (op && op->meta) + { + SetCellRenderer(line, TREE, new wxGridCellTreeButtonRenderer()); + SetCellEditor(line, TREE, new wxGridCellTreeButtonEditor()); + + SetReadOnly(line, DATE, true); + SetReadOnly(line, CREDIT, true); + SetReadOnly(line, DEBIT, true); + SetReadOnly(line, CATEGORY, true); + SetReadOnly(line, ACCOUNT, true); + } + else + SetReadOnly(line, TREE, true); + SetCellEditor(line, DEBIT, new wxGridCellFloatEditor(wxID_ANY, 2)); SetCellEditor(line, CREDIT, new wxGridCellFloatEditor(wxID_ANY, 2)); wxGridCellChoiceEditor* accountEditor = new wxGridCellChoiceEditor(user->GetAccountsNumber(), _accounts, false); @@ -304,6 +331,7 @@ void GridAccount::InsertOperation(User* user, Operation* op, int line, bool fix, SetReadOnly(line, DELETE, true); } + SetCellAlignment(line, DATE, wxALIGN_CENTRE, wxALIGN_CENTRE); SetCellAlignment(line, DEBIT, wxALIGN_RIGHT, wxALIGN_CENTRE); SetCellAlignment(line, CREDIT, wxALIGN_RIGHT, wxALIGN_CENTRE); SetCellAlignment(line, DELETE, wxALIGN_CENTRE, wxALIGN_CENTRE); @@ -626,3 +654,13 @@ void GridAccount::OnOperationModified(wxGridEvent& event) inModification = false ; event.Skip(); } + +void GridAccount::Group() +{ + +} + +void GridAccount::UnGroup() +{ + +} diff --git a/src/view/grid/GridAccount.h b/src/view/grid/GridAccount.h index 89aab74..e5c9d82 100644 --- a/src/view/grid/GridAccount.h +++ b/src/view/grid/GridAccount.h @@ -47,6 +47,9 @@ public: void InsertOperationWithWeek(User* user, Operation* op, int line, bool fix, int month, int year) ; void InsertOperation(User* user, Operation* op, int line, bool fix, int month, int year) ; + void Group(); + void UnGroup(); + void OnCellLeftClick(wxGridEvent& evt); void OnOperationModified(wxGridEvent& event); diff --git a/src/view/wxUI.cpp b/src/view/wxUI.cpp index 996f158..99d3f3f 100644 --- a/src/view/wxUI.cpp +++ b/src/view/wxUI.cpp @@ -188,7 +188,7 @@ void wxUI::ShowPanel(wxPanel* panel) int month, year=-1, account=0, preferences=0, search=0, stats=0; wxShowEvent event; - if (!panel || panel == _curPanel) return; + if (!panel || (panel == _curPanel && !_needReload)) return; if (_curPanel) {