diff --git a/TODO b/TODO index 49b62df..295b00d 100644 --- a/TODO +++ b/TODO @@ -2,7 +2,6 @@ Version 0.1 Statistics Copy and paste -Ascending/Descending order thanks to user preference Import/Export module Using tabulation to navigate throw interface (Search Panel) Improve Scrolled Windows @@ -12,6 +11,8 @@ Windows version Better build system for wxFreeChart (hacked by me) Others translation Remove program version from translation +Handle bad SQL return +Category color/font =============================================================== Next version @@ -22,3 +23,4 @@ Auto completion (already up into wxwidgets 2.9) Undo/redo Database auto saving at startup Documentation +Use caches for created panels (avoid destroying/creating panels for nothing) \ No newline at end of file diff --git a/init.sql b/init.sql index a619184..923bc97 100644 --- a/init.sql +++ b/init.sql @@ -5,9 +5,9 @@ CREATE TABLE account_amount(id INTEGER PRIMARY KEY, account REFERENCES account(i CREATE TABLE operation(id INTEGER PRIMARY KEY, 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)); CREATE TABLE category(id INTEGER PRIMARY KEY, user REFERENCES user(id), parent REFERENCES category(id), name VARCHAR(255), color VARCHAR(255), font VARCHAR(255)); CREATE TABLE preference(id INTEGER PRIMARY KEY, user REFERENCES user(id), name VARCHAR(255), value VARCHAR(255)); -CREATE TABLE default_preference(id INTEGER PRIMARY KEY, type VARCHAR(255), name VARCHAR(255), value VARCHAR(255)); INSERT INTO kisscount ("db_version") VALUES ("1"); +-- CREATE TABLE default_preference(id INTEGER PRIMARY KEY, type VARCHAR(255), name VARCHAR(255), value VARCHAR(255)); -- -- No password -- INSERT INTO user ("id", "name", "password") VALUES ("0", "Greg", "da39a3ee5e6b4b0d3255bfef95601890afd80709"); -- INSERT INTO account ("id", "user", "name", "number", "shared", "default_account") VALUES ("0", "0", "Compte Courant", "000" , "0", "1"); diff --git a/src/controller/KissCount.cpp b/src/controller/KissCount.cpp index b4e39b5..ab90172 100644 --- a/src/controller/KissCount.cpp +++ b/src/controller/KissCount.cpp @@ -283,8 +283,17 @@ void KissCount::KillMe() void KissCount::SetLanguage(wxLanguage language) { - _db->SetLanguage(_user, language); _user->_preferences[wxT("language")] = wxString::Format(wxT("%d"), language) ; + _db->UpdatePreference(_user, wxT("language")); +} + +/* + ASC (default) or DESC + */ +void KissCount::SetOperationOrder(const wxString& order) +{ + _user->_preferences[wxT("operation_order")] = order; + _db->UpdatePreference(_user, wxT("operation_order")); } std::vector* KissCount::Search(wxString* description, wxDateTime* dateFrom, wxDateTime* dateTo, diff --git a/src/controller/KissCount.h b/src/controller/KissCount.h index a2738a6..5e08f4b 100644 --- a/src/controller/KissCount.h +++ b/src/controller/KissCount.h @@ -66,6 +66,7 @@ class KissCount void KillMe(); void SetLanguage(wxLanguage language); + void SetOperationOrder(const wxString& order); std::vector* Search(wxString* description, wxDateTime* dateFrom, wxDateTime* dateTo, wxString* amountFrom, wxString* amountTo, diff --git a/src/model/Database.cpp b/src/model/Database.cpp index c7777ab..29c4465 100644 --- a/src/model/Database.cpp +++ b/src/model/Database.cpp @@ -201,11 +201,13 @@ User* Database::LoadUser(const wxString& name) return NULL; user = new User(); - + user->_id = set.GetAsString(wxT("id")); user->_name = set.GetAsString(wxT("name")); user->_password = wxT("") ; // Security reasons set.GetAsString("password"); + user->_preferences[wxT("operation_order")] = wxT("ASC") ; + set.Finalize(); req = wxT("SELECT * FROM account WHERE user='") + user->_id + wxT("' ORDER BY default_account DESC, name ASC"); @@ -295,7 +297,8 @@ void Database::LoadYear(User* user, int year) req += wxT("')"); req += wxT(" OR user='") + user->_id + wxT("')"); req += wxT(" AND year='") + wxString::Format(wxT("%d"), year) + wxT("'"); - req += wxT(" ORDER BY fix_cost DESC, year,month,day ASC"); + req += wxT(" ORDER BY fix_cost DESC, year, month ASC, day "); + req += user->_preferences[wxT("operation_order")]; EXECUTE_SQL_QUERY(req, set, ); @@ -883,12 +886,14 @@ void Database::KillMe(User* user) EXECUTE_SQL_UPDATE(req, ); } -void Database::SetLanguage(User* user, wxLanguage language) +void Database::UpdatePreference(User* user, const wxString& preference) { wxString req; + wxString value = user->_preferences[preference]; + req = wxT("UPDATE preference SET ") ; - req += wxT("name='language'"); - req += wxT(", value='") + wxString::Format(wxT("%d"), language) + wxT("'"); + req += wxT("name='") + preference + wxT("'"); + req += wxT(", value='") + value + wxT("'"); req += wxT(" WHERE user='") + user->_id + wxT("'"); try @@ -897,8 +902,8 @@ void Database::SetLanguage(User* user, wxLanguage language) { req = wxT("INSERT INTO preference ('user', 'name', 'value') VALUES ('") ; req += user->_id + wxT("'"); - req += wxT(" ,'language'"); - req += wxT(" ,'") + wxString::Format(wxT("%d"), language) + wxT("'"); + req += wxT(" ,'") + preference + wxT("'"); + req += wxT(" ,'") + value + wxT("'"); req += wxT(")"); EXECUTE_SQL_UPDATE(req, ); } @@ -1003,7 +1008,10 @@ std::vector* Database::Search(User* user, wxString* description, wxDa req += wxT("')"); } - req += wxT(" ORDER BY year,month,day ASC"); + req += wxT(" ORDER BY year ") ; + req += user->_preferences[wxT("operation_order")] ; + req += wxT(", month ") + user->_preferences[wxT("operation_order")] ; + req += wxT(", day ") + user->_preferences[wxT("operation_order")] ; // std::cout << req.mb_str() << "\n"; diff --git a/src/model/Database.h b/src/model/Database.h index 8a78259..ff66417 100644 --- a/src/model/Database.h +++ b/src/model/Database.h @@ -66,7 +66,7 @@ class Database void ChangeName(User* user, const wxString& name); void NewUser(const wxString& name); - void SetLanguage(User* user, wxLanguage language); + void UpdatePreference(User* user, const wxString& preference); std::vector* Search(User* user, wxString* description, wxDateTime* dateFrom, wxDateTime* dateTo, wxString* amountFrom, wxString* amountTo, diff --git a/src/view/AccountPanel.cpp b/src/view/AccountPanel.cpp index e272c4b..1a54e1a 100644 --- a/src/view/AccountPanel.cpp +++ b/src/view/AccountPanel.cpp @@ -385,7 +385,7 @@ void AccountPanel::InsertOperation(User* user, Operation* op, int line, bool fix if (fix) _fixCosts++; - if (op) + if (op && !fix) { for (it = _curOperations->begin(), curLine=1; it->fix_cost && it != _curOperations->end(); @@ -736,8 +736,16 @@ void AccountPanel::OnOperationModified(wxGridEvent& event) { if ((*_curOperations)[i].fix_cost && !fix_op) continue; if (!(*_curOperations)[i].fix_cost && fix_op) break; - if ((*_curOperations)[i].day > new_op.day) - break; + if (user->_preferences[wxT("operation_order")] == wxT("ASC")) + { + if ((*_curOperations)[i].day > new_op.day) + break; + } + else + { + if ((*_curOperations)[i].day < new_op.day) + break; + } } _curOperations->insert(_curOperations->begin()+i ,new_op); diff --git a/src/view/PreferencesPanel.cpp b/src/view/PreferencesPanel.cpp index cce8f6a..11715df 100644 --- a/src/view/PreferencesPanel.cpp +++ b/src/view/PreferencesPanel.cpp @@ -22,7 +22,8 @@ along with KissCount. If not, see . enum {ACCOUNT_NAME, ACCOUNT_NUMBER, ACCOUNT_SHARED, ACCOUNT_DEFAULT, ACCOUNT_DELETE, NUMBER_COLS_ACCOUNT}; enum {CATEGORY_NAME, CATEGORY_COLOR, CATEGORY_FONT, CATEGORY_DELETE, NUMBER_COLS_CATEGORY}; -enum {CATEGORIES_GRID_ID=1, ACCOUNTS_GRID_ID, NAME_ID, CHANGE_NAME_ID, CHANGE_PASSWORD_ID, KILL_ME_ID, LANGUAGE_ID}; +enum {CATEGORIES_GRID_ID=1, ACCOUNTS_GRID_ID, NAME_ID, CHANGE_NAME_ID, CHANGE_PASSWORD_ID, KILL_ME_ID, LANGUAGE_ID, + OPERATION_ORDER_ID}; BEGIN_EVENT_TABLE(PreferencesPanel, wxPanel) EVT_BUTTON(CHANGE_NAME_ID, PreferencesPanel::OnChangeName) @@ -30,6 +31,7 @@ EVT_BUTTON(CHANGE_PASSWORD_ID, PreferencesPanel::OnChangePassword) EVT_BUTTON(KILL_ME_ID, PreferencesPanel::OnKillMe) EVT_GRID_CMD_CELL_CHANGE(CATEGORIES_GRID_ID, PreferencesPanel::OnCategoryModified) EVT_GRID_CMD_CELL_CHANGE(ACCOUNTS_GRID_ID, PreferencesPanel::OnAccountModified) +EVT_COMBOBOX(OPERATION_ORDER_ID, PreferencesPanel::OnOperationOrderChange) EVT_COMBOBOX(LANGUAGE_ID, PreferencesPanel::OnLanguageChange) EVT_SHOW(PreferencesPanel::OnShow) END_EVENT_TABLE() @@ -37,8 +39,10 @@ END_EVENT_TABLE() PreferencesPanel::PreferencesPanel(KissCount* kiss, wxUI *parent) : wxPanel(&(*parent)), _kiss(kiss), _wxUI(parent) { wxBoxSizer *vbox = new wxBoxSizer(wxVERTICAL); + wxBoxSizer *hbox1 = new wxBoxSizer(wxHORIZONTAL); + wxBoxSizer *hbox2 = new wxBoxSizer(wxHORIZONTAL); //wxBoxSizer *hbox = new wxBoxSizer(wxHORIZONTAL); - wxStaticBox* staticUser, *staticAccount, *staticCategories, *staticLanguage; + wxStaticBox* staticUser, *staticAccount, *staticCategories, *staticLanguage, *staticOperationOrder; User* user = _kiss->GetUser(); wxGridBagSizer *gridBagSizer; wxStaticText* label; @@ -51,6 +55,7 @@ PreferencesPanel::PreferencesPanel(KissCount* kiss, wxUI *parent) : wxPanel(&(*p staticAccount = new wxStaticBox(this, wxID_ANY, _("Accounts")); staticCategories = new wxStaticBox(this, wxID_ANY, _("Categories")); staticLanguage = new wxStaticBox(this, wxID_ANY, _("Language")); + staticOperationOrder = new wxStaticBox(this, wxID_ANY, _("Operation order")); // User staticBoxSizer = new wxStaticBoxSizer (staticUser, wxVERTICAL); @@ -84,8 +89,8 @@ PreferencesPanel::PreferencesPanel(KissCount* kiss, wxUI *parent) : wxPanel(&(*p staticBoxSizer->Add(_accountsGrid); - vbox->Add(staticBoxSizer); - vbox->Add(-1, 20); + hbox1->Add(staticBoxSizer); + hbox1->Add(-1, 20); // Categories staticBoxSizer = new wxStaticBoxSizer (staticCategories, wxVERTICAL); @@ -96,9 +101,25 @@ PreferencesPanel::PreferencesPanel(KissCount* kiss, wxUI *parent) : wxPanel(&(*p InitCategories(user); - vbox->Add(staticBoxSizer); + hbox1->Add(staticBoxSizer); + hbox1->Add(-1, 20); + + vbox->Add(hbox1); vbox->Add(-1, 20); + // Operation Order + staticBoxSizer = new wxStaticBoxSizer (staticOperationOrder, wxVERTICAL); + + _operationOrder = new wxComboBox(this, OPERATION_ORDER_ID); + _operationOrder->SetWindowStyle(wxCB_READONLY); + + staticBoxSizer->Add(_operationOrder); + + hbox2->Add(staticBoxSizer); + hbox2->Add(-1, 20); + + InitOperationOrder(user); + // Language staticBoxSizer = new wxStaticBoxSizer (staticLanguage, wxVERTICAL); @@ -107,12 +128,15 @@ PreferencesPanel::PreferencesPanel(KissCount* kiss, wxUI *parent) : wxPanel(&(*p staticBoxSizer->Add(_language); - vbox->Add(staticBoxSizer); + hbox2->Add(staticBoxSizer); + hbox2->Add(-1, 20); InitLanguage(user); _language->Fit(); + vbox->Add(hbox2); + Fit(); SetMinSize(GetSize()); @@ -226,6 +250,17 @@ void PreferencesPanel::InitLanguage(User* user) _language->Select(select); } +void PreferencesPanel::InitOperationOrder(User* user) +{ + _operationOrder->Append(_("Ascending")); + _operationOrder->Append(_("Descending")); + + if (user->_preferences[wxT("operation_order")] == wxT("ASC")) + _operationOrder->Select(0); + else + _operationOrder->Select(1); +} + void PreferencesPanel::OnAccountModified(wxGridEvent& event) { int op_complete = 2; @@ -511,6 +546,16 @@ void PreferencesPanel::OnChangePassword(wxCommandEvent& event) p.ShowModal(); } +void PreferencesPanel::OnOperationOrderChange(wxCommandEvent& event) +{ + if (_operationOrder->GetCurrentSelection() == 0) + _kiss->SetOperationOrder(wxT("ASC")); + else + _kiss->SetOperationOrder(wxT("DESC")); + + _wxUI->NeedReload(); +} + void PreferencesPanel::OnLanguageChange(wxCommandEvent& event) { wxLanguage language = languages[_language->GetSelection()].language; @@ -522,7 +567,6 @@ void PreferencesPanel::OnLanguageChange(wxCommandEvent& event) } else wxMessageBox(_("Language not changed"), _("KissCount"), wxICON_ERROR | wxOK); - } void PreferencesPanel::OnShow(wxShowEvent& event) diff --git a/src/view/PreferencesPanel.h b/src/view/PreferencesPanel.h index 99f8b43..d69880b 100644 --- a/src/view/PreferencesPanel.h +++ b/src/view/PreferencesPanel.h @@ -48,6 +48,7 @@ class PreferencesPanel: public wxPanel void OnCategoryModified(wxGridEvent& event); void OnChangeName(wxCommandEvent& event); void OnChangePassword(wxCommandEvent& event); + void OnOperationOrderChange(wxCommandEvent& event); void OnLanguageChange(wxCommandEvent& event); void OnShow(wxShowEvent& event); void OnKillMe(wxCommandEvent& event); @@ -59,10 +60,12 @@ class PreferencesPanel: public wxPanel wxGrid* _categoriesGrid; wxTextCtrl* _name; wxBitmapComboBox* _language; + wxComboBox* _operationOrder; void InitAccounts(User* user); void InitCategories(User* user); void InitLanguage(User* user); + void InitOperationOrder(User* user); DECLARE_EVENT_TABLE(); }; diff --git a/src/view/SearchPanel.cpp b/src/view/SearchPanel.cpp index 5590068..041057c 100644 --- a/src/view/SearchPanel.cpp +++ b/src/view/SearchPanel.cpp @@ -40,6 +40,7 @@ SearchPanel::SearchPanel(KissCount* kiss, wxUI *parent) : wxScrolledWindow(&(*pa User* user = _kiss->GetUser(); std::vector::iterator accountIt; std::vector::iterator categoryIt; + wxDateTime firstOfMonth; wxBoxSizer *vbox = new wxBoxSizer(wxVERTICAL); SetSizer(vbox); @@ -47,9 +48,14 @@ SearchPanel::SearchPanel(KissCount* kiss, wxUI *parent) : wxScrolledWindow(&(*pa _checkDateFrom = new wxCheckBox(this, wxID_ANY, _("Date from")); _checkDateTo = new wxCheckBox(this, wxID_ANY, _("Date to")); + _checkDateFrom->SetValue(wxT("1")); + _checkDateTo->SetValue(wxT("1")); + wxGridBagSizer *gridBagSizer = new wxGridBagSizer(3, 9); - _calendarFrom = new wxCalendarCtrl(this, CALENDAR_FROM_ID, wxDefaultDateTime, wxDefaultPosition, wxDefaultSize, + firstOfMonth.SetToCurrent(); + firstOfMonth.SetDay(1); + _calendarFrom = new wxCalendarCtrl(this, CALENDAR_FROM_ID, firstOfMonth, wxDefaultPosition, wxDefaultSize, wxCAL_MONDAY_FIRST); _calendarTo = new wxCalendarCtrl(this, CALENDAR_TO_ID, wxDefaultDateTime, wxDefaultPosition, wxDefaultSize, wxCAL_MONDAY_FIRST);