diff --git a/ChangeLog b/ChangeLog index f3ee6ce..763239a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,4 @@ -v0.2 (23/03/2011) +v0.2 (25/04/2011) ** User ** Better use of sizers (so better interface!) @@ -38,3 +38,5 @@ v0.2 (23/03/2011) Categories fonts not updated for new category --> crash New category had read only fields in PreferencesPanel Update all panels after generating/deleting month + Don't take in account unknown categories (in stats) + Don't try to draw more than MAX_CATEGORIES (12) in charts diff --git a/src/model/import/GrisbiImportEngine.cpp b/src/model/import/GrisbiImportEngine.cpp index 9916c25..d5d0de1 100644 --- a/src/model/import/GrisbiImportEngine.cpp +++ b/src/model/import/GrisbiImportEngine.cpp @@ -63,6 +63,7 @@ void GrisbiImportEngine::LoadCategory(GrisbiImportEngine* _this, const char** at { wxString name, id; int i; + Category cat; for (i=0; attrs[i]; i+=2) { @@ -82,8 +83,10 @@ void GrisbiImportEngine::LoadCategory(GrisbiImportEngine* _this, const char** at } } - _this->_categories[id] = wxT("unknown-") + id; - _this->_unresolvedCategories.push_back(name); + _this->_categories[id] = wxT("unknown-") + name; + cat.id = id; + cat.name = name; + _this->_unresolvedCategories.push_back(cat); } void GrisbiImportEngine::LoadOperation(GrisbiImportEngine* _this, const char** attrs) @@ -96,8 +99,8 @@ void GrisbiImportEngine::LoadOperation(GrisbiImportEngine* _this, const char** a op.id = wxString::Format(wxT("%d"), ++id); op.parent = wxT(""); - op.account = wxT("0"); - op.category = wxT("0"); + op.account = wxT("unknwon-0"); + op.category = wxT("unknwon-0"); op.fix_cost = false; op.checked = false; op.transfert = wxT(""); diff --git a/src/model/import/ImportEngine.cpp b/src/model/import/ImportEngine.cpp index ea67397..c68e642 100644 --- a/src/model/import/ImportEngine.cpp +++ b/src/model/import/ImportEngine.cpp @@ -282,12 +282,13 @@ void ImportEngine::MatchPattern(wxString& originalKey, Operation& op) } } -std::vector ImportEngine::ParseFile() +void ImportEngine::ParseFile(std::vector& accounts, std::vector& categories) { - return _unresolvedAccounts; + accounts = _unresolvedAccounts; + categories = _unresolvedCategories; } -std::vector* ImportEngine::GetOperations(std::map& accounts) +std::vector* ImportEngine::GetOperations(std::map& accounts, std::map& categories) { int i; @@ -295,6 +296,8 @@ std::vector* ImportEngine::GetOperations(std::map { if (_operations[i].account.StartsWith(wxT("unknown-"))) _operations[i].account = accounts[_operations[i].account.Mid(8)]; + if (_operations[i].category.StartsWith(wxT("unknown-"))) + _operations[i].category = categories[_operations[i].category.Mid(8)]; } if (_kiss->GetOperationOrder() == wxT("ASC")) diff --git a/src/model/import/ImportEngine.h b/src/model/import/ImportEngine.h index ad80feb..b6949d5 100644 --- a/src/model/import/ImportEngine.h +++ b/src/model/import/ImportEngine.h @@ -47,10 +47,10 @@ public: virtual bool HandleFile(const wxString& path, User* user, Database* db, KissCount* kiss)=0; // Parse the file and return accounts that doesn't match - virtual std::vector ParseFile(); + virtual void ParseFile(std::vector& accounts, std::vector& categories); // Final Step - virtual std::vector* GetOperations(std::map& accounts); + virtual std::vector* GetOperations(std::map& accounts, std::map& categories); void MatchPattern(wxString& key, Operation& op); int UpdatePattern(int pos); @@ -68,7 +68,7 @@ protected: std::map _accounts; std::map _categories; std::vector _unresolvedAccounts; - std::vector _unresolvedCategories; + std::vector _unresolvedCategories; std::vector _operations; std::map _descriptions; diff --git a/src/view/AccountPanel.cpp b/src/view/AccountPanel.cpp index 6762f7e..d4fa4a4 100644 --- a/src/view/AccountPanel.cpp +++ b/src/view/AccountPanel.cpp @@ -54,6 +54,7 @@ AccountPanel::AccountPanel(KissCount* kiss, wxUI *parent) : KissPanel(kiss, pare std::vector::iterator categoryIt; DEFAULT_FONT(font); wxRect rect = wxDisplay().GetGeometry(); + int nbCategories; SetSizer(hbox); @@ -82,14 +83,16 @@ AccountPanel::AccountPanel(KissCount* kiss, wxUI *parent) : KissPanel(kiss, pare _categories[i] = wxGetTranslation(categoryIt->name) ; _categoriesIndexes[categoryIt->name] = i; } - - _dataset = new CategorySimpleDataset(_categories, user->GetCategoriesNumber()); + + nbCategories = (user->GetCategoriesNumber() <= MAX_CATEGORY) ? user->GetCategoriesNumber() : MAX_CATEGORY; _categoriesValues = new double[user->GetCategoriesNumber()]; for(i=0; iGetCategoriesNumber(); i++) - _categoriesValues[i] = 0.0; + _categoriesValues[i] = 0.0; - _dataset->AddSerie(_("Serie 1"), _categoriesValues, user->GetCategoriesNumber()); + _dataset = new CategorySimpleDataset(_categories, nbCategories); + _dataset->AddSerie(_("Serie 1"), _categoriesValues, nbCategories); + _dataset->SetRenderer(new CategoryRenderer(*colorScheme)); _pie->SetDataset(_dataset); _pie->SetColorScheme(colorScheme); @@ -509,7 +512,7 @@ void AccountPanel::UpdateStats() } else { - if (!op.transfert.Length()) + if (!op.transfert.Length() && user->GetCategoryName(op.category) != _("Unknown")) _categoriesValues[_categoriesIndexes[user->GetCategoryName(op.category)]] += -op.amount ; if (!op.transfert.Length() || op._virtual) @@ -545,7 +548,7 @@ void AccountPanel::UpdateStats() } else { - if (!op.transfert.Length()) + if (!op.transfert.Length() && user->GetCategoryName(op.category) != _("Unknown")) _categoriesValues[_categoriesIndexes[user->GetCategoryName(op.category)]] += -op.amount ; if (!op.transfert.Length() && !op._virtual) @@ -583,7 +586,7 @@ void AccountPanel::UpdateStats() } else { - if (!op.transfert.Length()) + if (!op.transfert.Length() && user->GetCategoryName(op.category) != _("Unknown")) _categoriesValues[_categoriesIndexes[user->GetCategoryName(op.category)]] += -op.amount ; if (!op.transfert.Length() && !op._virtual) diff --git a/src/view/ImportPanel.cpp b/src/view/ImportPanel.cpp index 84048d4..d00a9d0 100644 --- a/src/view/ImportPanel.cpp +++ b/src/view/ImportPanel.cpp @@ -33,12 +33,14 @@ END_EVENT_TABLE() ImportPanel::ImportPanel(KissCount* kiss, wxUI *parent) : KissPanel(kiss, parent) { wxBoxSizer *vbox = new wxBoxSizer(wxVERTICAL); + wxBoxSizer *vbox2 = new wxBoxSizer(wxVERTICAL); wxBoxSizer *hbox = new wxBoxSizer(wxHORIZONTAL); _hbox = new wxBoxSizer(wxHORIZONTAL); wxButton* buttonOpen; wxRect rect = wxDisplay().GetGeometry(); int w, h; wxStaticBox* staticAccount = new wxStaticBox(this, wxID_ANY, _("Unresolved accounts")); + wxStaticBox* staticCategory = new wxStaticBox(this, wxID_ANY, _("Unresolved categories")); SetSizer(vbox); @@ -73,12 +75,25 @@ ImportPanel::ImportPanel(KissCount* kiss, wxUI *parent) : KissPanel(kiss, parent _accountsGrid->SetColLabelValue(2, _("Internal account")); _accountsGrid->Fit(); + _categoriesGrid = new wxGrid(this, wxID_ANY); + _categoriesGrid->CreateGrid(0, 3); + _categoriesGrid->SetRowLabelSize(0); + _categoriesGrid->SetColLabelValue(0, _("File category")); + _categoriesGrid->SetColLabelValue(1, _("Category name")); + _categoriesGrid->SetColLabelValue(2, _("Internal category")); + _categoriesGrid->Fit(); + wxStaticBoxSizer* staticBoxSizer = new wxStaticBoxSizer (staticAccount, wxVERTICAL); staticBoxSizer->Add(_accountsGrid, 0, wxGROW|wxALL, 2); + vbox2->Add(staticBoxSizer, wxGROW|wxALL); + + staticBoxSizer = new wxStaticBoxSizer (staticCategory, wxVERTICAL); + staticBoxSizer->Add(_categoriesGrid, 0, wxGROW|wxALL, 2); + vbox2->Add(staticBoxSizer, wxGROW|wxALL); _operationsGrid = new GridAccount(kiss, this, OPS_GRID_ID, false, false, false); - _hbox->Add(staticBoxSizer, 0, wxGROW|wxALL, 15); + _hbox->Add(vbox2, 0, wxGROW|wxALL, 15); _hbox->Add(_operationsGrid, 0, wxGROW|wxALL, 15); vbox->Add(_hbox, wxGROW); @@ -136,11 +151,15 @@ void ImportPanel::OnFileEnter(wxCommandEvent& WXUNUSED(event)) void ImportPanel::ProcessFile() { std::vector accounts; + std::vector categories; User* user = _kiss->GetUser(); int i; wxGridCellChoiceEditor* accountEditor; wxString* userAccounts; std::map resolvedAccounts; + wxGridCellChoiceEditor* categoryEditor; + wxString* userCategories; + std::map resolvedCategories; wxCommandEvent event; wxString path = _fileTxt->GetLineText(0); @@ -148,6 +167,7 @@ void ImportPanel::ProcessFile() _buttonLoadOperations->Disable(); _buttonIntegrate->Disable(); _accountsGrid->ClearGrid(); + _categoriesGrid->ClearGrid(); _operationsGrid->ClearGrid(); _importEngine = _kiss->GetImportEngine(path); @@ -159,7 +179,7 @@ void ImportPanel::ProcessFile() return ; } - accounts = _importEngine->ParseFile(); + _importEngine->ParseFile(accounts, categories); if (accounts.size()) { @@ -190,7 +210,37 @@ void ImportPanel::ProcessFile() _accountsGrid->AutoSize(); _accountsGrid->Layout(); } - else + + if (categories.size()) + { + int nb_categories = user->GetCategoriesNumber(); + userCategories = new wxString[nb_categories+1]; + + userCategories[0] = _("Create one"); + + for(i=0; i_categories[i].name; + + categoryEditor = new wxGridCellChoiceEditor(nb_categories+1, userCategories, false); + + _buttonLoadOperations->Enable(); + + _categoriesGrid->AppendRows(categories.size()); + + for (i=0; i<(int)categories.size(); i++) + { + _categoriesGrid->SetCellValue(i, 0, categories[i].name); + _categoriesGrid->SetReadOnly(i, 0); + _categoriesGrid->SetCellValue(i, 2, userCategories[0]); + + _categoriesGrid->SetCellEditor(i, 2, categoryEditor); + } + + _categoriesGrid->AutoSize(); + _categoriesGrid->Layout(); + } + + if (!accounts.size() && !categories.size()) { OnLoadOperations(event); } @@ -200,27 +250,44 @@ void ImportPanel::ProcessFile() void ImportPanel::OnLoadOperations(wxCommandEvent& WXUNUSED(event)) { std::map resolvedAccounts; - int i, nbAccounts; + std::map resolvedCategories; + int i, nbAccounts=0, nbCategories=0; User* user = _kiss->GetUser(); Account account; + Category category; - for(i=0; i<_accountsGrid->GetNumberRows(); i++) - { - resolvedAccounts[_accountsGrid->GetCellValue(i, 0)] = - user->GetAccountId(_accountsGrid->GetCellValue(i, 1)); - } - - nbAccounts = 0; for(i=0; i<_accountsGrid->GetNumberRows(); i++) { if (_accountsGrid->GetCellValue(i, 2) == _("Create one")) nbAccounts++; + else + resolvedAccounts[_accountsGrid->GetCellValue(i, 0)] = + user->GetAccountId(_accountsGrid->GetCellValue(i, 1)); } - if (nbAccounts) + for(i=0; i<_categoriesGrid->GetNumberRows(); i++) { - wxString message = wxString::Format(wxT("%d"), nbAccounts); - message += _(" account(s) will be created, is it ok ?"); + if (_categoriesGrid->GetCellValue(i, 2) == _("Create one")) + nbCategories++; + else + resolvedCategories[_categoriesGrid->GetCellValue(i, 0)] = + user->GetAccountId(_categoriesGrid->GetCellValue(i, 1)); + } + + if (nbAccounts || nbCategories) + { + wxString message; + + if (nbAccounts) + { + message += wxString::Format(wxT("%d accounts"), nbAccounts); + if (nbCategories) message += wxT(" and "); + } + + if (nbCategories) + message += wxString::Format(wxT("%d categories"), nbCategories); + + message += _(" will be created, is it ok ?"); wxMessageDialog dialog(_wxUI, message, wxT("KissCount"), wxYES_NO); if (dialog.ShowModal() == wxID_NO) @@ -247,10 +314,29 @@ void ImportPanel::OnLoadOperations(wxCommandEvent& WXUNUSED(event)) _accountsGrid->DeleteRows(0, _accountsGrid->GetNumberRows ()); + for(i=0; i<_categoriesGrid->GetNumberRows(); i++) + { + if (_categoriesGrid->GetCellValue(i, 2) == _("Create one")) + { + if (_categoriesGrid->GetCellValue(i, 1).Length()) + category.name = _categoriesGrid->GetCellValue(i, 1); + else + category.name = _categoriesGrid->GetCellValue(i, 0); + category.parent = wxT("0"); + category.backcolor = OWN_GREEN ; + category.forecolor = *wxBLACK; + category.fix_cost = false; + + resolvedCategories[_categoriesGrid->GetCellValue(i, 0)] = category.id = _kiss->AddCategory(category); + } + } + + _categoriesGrid->DeleteRows(0, _categoriesGrid->GetNumberRows ()); + _wxUI->NeedReload(); } - _operations = _importEngine->GetOperations(resolvedAccounts); + _operations = _importEngine->GetOperations(resolvedAccounts, resolvedCategories); if (_operations->size()) { diff --git a/src/view/ImportPanel.h b/src/view/ImportPanel.h index 3c30f71..89b460a 100644 --- a/src/view/ImportPanel.h +++ b/src/view/ImportPanel.h @@ -53,7 +53,7 @@ public: private: wxBoxSizer *_hbox; - wxGrid* _accountsGrid; + wxGrid* _accountsGrid, *_categoriesGrid; wxTextCtrl* _fileTxt; GridAccount* _operationsGrid; ImportEngine* _importEngine; diff --git a/src/view/StatsPanel.cpp b/src/view/StatsPanel.cpp index 3fec614..023642c 100644 --- a/src/view/StatsPanel.cpp +++ b/src/view/StatsPanel.cpp @@ -38,6 +38,7 @@ StatsPanel::StatsPanel(KissCount* kiss, wxUI *parent) : KissPanel(kiss, parent), std::vector::iterator categoryIt; std::map > operations; std::map >::iterator it; + int nbCategories; SetSizer(vbox); @@ -110,14 +111,16 @@ StatsPanel::StatsPanel(KissCount* kiss, wxUI *parent) : KissPanel(kiss, parent), _pie = new PiePlot(); - _dataset = new CategorySimpleDataset(_categories, user->GetCategoriesNumber()); + nbCategories = (user->GetCategoriesNumber() <= MAX_CATEGORY) ? user->GetCategoriesNumber() : MAX_CATEGORY; + + _dataset = new CategorySimpleDataset(_categories, nbCategories); ColorScheme* colorScheme = new ColorScheme(categoryColors, WXSIZEOF(categoryColors)); _categoriesValues = new double[user->GetCategoriesNumber()]; for(i=0; iGetCategoriesNumber(); i++) _categoriesValues[i] = 0.0; - _dataset->AddSerie(_("Serie 1"), _categoriesValues, user->GetCategoriesNumber()); + _dataset->AddSerie(_("Serie 1"), _categoriesValues, nbCategories); _dataset->SetRenderer(new CategoryRenderer(*colorScheme)); _pie->SetDataset(_dataset); _pie->SetColorScheme(colorScheme); diff --git a/src/view/wxUI.cpp b/src/view/wxUI.cpp index b6b2663..25e9fb7 100644 --- a/src/view/wxUI.cpp +++ b/src/view/wxUI.cpp @@ -28,7 +28,7 @@ EVT_BUTTON(BUTTON_QUIT_ID, wxUI::OnButtonQuit) END_EVENT_TABLE() wxString months[12] ; -wxColour categoryColors[12] = {wxColour(0x00, 0x45, 0x86), +wxColour categoryColors[MAX_CATEGORY] = {wxColour(0x00, 0x45, 0x86), wxColour(0xFF, 0x3E, 0x0E), wxColour(0xFF, 0xD3, 0x20), wxColour(0x58, 0x9D, 0x1B), diff --git a/src/view/wxUI.h b/src/view/wxUI.h index e7c8c52..1cc0bbe 100644 --- a/src/view/wxUI.h +++ b/src/view/wxUI.h @@ -48,6 +48,8 @@ class PreferencesPanel; extern wxString months[12]; extern wxColour categoryColors[12]; +#define MAX_CATEGORY 12 + class wxUI: public wxFrame { public: