/* Copyright 2010-2011 Grégory Soutadé This file is part of KissCount. KissCount is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. KissCount is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with KissCount. If not, see . */ #include #include #include #include #include #include #include #include #include #include "ImportPanel.hpp" enum {OPEN_FILE_ID=1, BUTTON_OPEN_ID, NAME_ID, BUTTON_LOAD_ID, BUTTON_INTEGRATE_ID, CHECK_SAVE_ID, OPS_GRID_ID}; BEGIN_EVENT_TABLE(ImportPanel, wxPanel) EVT_GRID_CMD_CELL_CHANGE(OPS_GRID_ID, ImportPanel::OnOperationModified) EVT_BUTTON(BUTTON_OPEN_ID, ImportPanel::OnFile) EVT_BUTTON(BUTTON_INTEGRATE_ID, ImportPanel::OnIntegrate) EVT_TEXT_ENTER(OPEN_FILE_ID, ImportPanel::OnFileEnter) EVT_BUTTON(BUTTON_LOAD_ID, ImportPanel::OnLoadOperations) EVT_SHOW(ImportPanel::OnShow) 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); _fileTxt = new wxTextCtrl(this, OPEN_FILE_ID); _fileTxt->SetWindowStyle(_fileTxt->GetWindowStyle() | wxTE_PROCESS_ENTER); _fileTxt->GetSize(&w, &h); wxSize size(rect.width/3, h); _fileTxt->SetMinSize(size); buttonOpen = new wxButton(this, BUTTON_OPEN_ID, wxT("...")); _buttonLoadOperations = new wxButton(this, BUTTON_LOAD_ID, _("Load operations")); _buttonLoadOperations->Disable(); _buttonIntegrate = new wxButton(this, BUTTON_INTEGRATE_ID, _("Integrate operations")); _buttonIntegrate->Disable(); _checkSaveImportPatterns = new wxCheckBox(this, CHECK_SAVE_ID, _("Save import patterns")); hbox->Add(_fileTxt, 0, wxGROW|wxALL, 5); hbox->Add(buttonOpen, 0, wxALL, 5); hbox->Add(_buttonLoadOperations, 0, wxALL, 5); hbox->Add(_buttonIntegrate, 0, wxALL, 5); hbox->Add(_checkSaveImportPatterns, 0, wxALL, 5); vbox->Add(hbox, 0); _accountsGrid = new wxGrid(this, wxID_ANY); _accountsGrid->CreateGrid(0, 3); _accountsGrid->SetRowLabelSize(0); _accountsGrid->SetColLabelValue(0, _("File account")); _accountsGrid->SetColLabelValue(1, _("Account name")); _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(vbox2, 0, wxGROW|wxALL, 15); _hbox->Add(_operationsGrid, 0, wxGROW|wxALL, 15); vbox->Add(_hbox, wxGROW); Fit(); SetMinSize(wxSize(rect.width-rect.x-15, rect.height-rect.y-128-25)); SetMaxSize(wxSize(rect.width-rect.x-15, rect.height-rect.y-128-25)); SetScrollbars(10, 10, 100/10, 100/10); } KissPanel* ImportPanel::CreatePanel() { return new ImportPanel(_kiss, _wxUI); } wxBitmapButton* ImportPanel::GetButton(int id) { if (!_KissButton) _KissButton = new wxBitmapButton(_wxUI, id, wxBitmap(wxT(IMPORT_ICON), wxBITMAP_TYPE_PNG), wxDefaultPosition, wxSize(128, 128)); return _KissButton; } wxString ImportPanel::GetToolTip() { return _("Import"); } void ImportPanel::OnShow(wxShowEvent& event) { _wxUI->SetTitle(_("KissCount - Import")); } void ImportPanel::OnFile(wxCommandEvent& WXUNUSED(event)) { wxFileDialog openFileDialog(this, _("Choose a database to open"), wxT(""), wxT(""), _kiss->GetImportEngineExtensions(), wxFD_OPEN|wxFD_FILE_MUST_EXIST); if (openFileDialog.ShowModal() == wxID_CANCEL) return; _fileTxt->Clear(); *_fileTxt << openFileDialog.GetPath(); ProcessFile(); } void ImportPanel::OnFileEnter(wxCommandEvent& WXUNUSED(event)) { ProcessFile(); } void ImportPanel::ProcessFile() { 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); _buttonLoadOperations->Disable(); _buttonIntegrate->Disable(); _accountsGrid->ClearGrid(); _categoriesGrid->ClearGrid(); _operationsGrid->ClearGrid(); _importEngine = _kiss->GetImportEngine(path); if (!_importEngine) { wxMessageBox(_("Any engine can process this file !"), wxT("KissCount"), wxICON_INFORMATION | wxOK); return ; } _importEngine->ParseFile(_unresolvedAccounts, _unresolvedCategories); if (_unresolvedAccounts.size()) { int nb_accounts = user->GetAccountsNumber(); userAccounts = new wxString[nb_accounts+1]; userAccounts[0] = _("Create one"); for(i=0; i_accounts[i].name; accountEditor = new wxGridCellChoiceEditor(nb_accounts+1, userAccounts, false); _buttonLoadOperations->Enable(); _accountsGrid->AppendRows(_unresolvedAccounts.size()); for (i=0; i<(int)_unresolvedAccounts.size(); i++) { _accountsGrid->SetCellValue(i, 0, _unresolvedAccounts[i].number); _accountsGrid->SetReadOnly(i, 0); _accountsGrid->SetCellValue(i, 1, _unresolvedAccounts[i].name); _accountsGrid->SetCellValue(i, 2, userAccounts[0]); _accountsGrid->SetCellEditor(i, 2, accountEditor); } _accountsGrid->AutoSize(); _accountsGrid->Layout(); } if (_unresolvedCategories.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(_unresolvedCategories.size()); for (i=0; i<(int)_unresolvedCategories.size(); i++) { _categoriesGrid->SetCellValue(i, 0, _unresolvedCategories[i].name); _categoriesGrid->SetReadOnly(i, 0); _categoriesGrid->SetCellValue(i, 2, userCategories[0]); _categoriesGrid->SetCellEditor(i, 2, categoryEditor); } _categoriesGrid->AutoSize(); _categoriesGrid->Layout(); } if (!_unresolvedAccounts.size() && !_unresolvedCategories.size()) { OnLoadOperations(event); } Layout(); } void ImportPanel::OnLoadOperations(wxCommandEvent& WXUNUSED(event)) { int i, nbAccounts=0, nbCategories=0; User* user = _kiss->GetUser(); Account account; Category category; std::map accounts; std::map categories; wxString oldid; for(i=0; i<_accountsGrid->GetNumberRows(); i++) { if (_accountsGrid->GetCellValue(i, 2) == _("Create one")) nbAccounts++; else accounts[_accountsGrid->GetCellValue(i, 0)] = user->GetAccountId(_accountsGrid->GetCellValue(i, 1)); } for(i=0; i<_categoriesGrid->GetNumberRows(); i++) { if (_categoriesGrid->GetCellValue(i, 2) == _("Create one")) nbCategories++; else categories[_categoriesGrid->GetCellValue(i, 0)] = user->GetAccountId(_categoriesGrid->GetCellValue(i, 1)); } if (nbAccounts || nbCategories) { wxString message; if (nbAccounts) { message += wxString::Format(_("%d accounts"), nbAccounts); if (nbCategories) message += _(" and "); } if (nbCategories) message += wxString::Format(_("%d categories"), nbCategories); message += _(" will be created, is it ok ?"); wxMessageDialog dialog(_wxUI, message, wxT("KissCount"), wxYES_NO); if (dialog.ShowModal() == wxID_NO) return; for(i=0; i<_accountsGrid->GetNumberRows(); i++) { if (_accountsGrid->GetCellValue(i, 2) == _("Create one")) { account = _unresolvedAccounts[i] ; if (_accountsGrid->GetCellValue(i, 1).Length()) account.name = _accountsGrid->GetCellValue(i, 1); else account.name = _accountsGrid->GetCellValue(i, 0); account.number = _accountsGrid->GetCellValue(i, 0); oldid = account.id; _resolvedAccounts[oldid] = accounts[_accountsGrid->GetCellValue(i, 0)] = _kiss->AddAccount(account); } } _accountsGrid->DeleteRows(0, _accountsGrid->GetNumberRows ()); for(i=0; i<_categoriesGrid->GetNumberRows(); i++) { if (_categoriesGrid->GetCellValue(i, 2) == _("Create one")) { category = _unresolvedCategories[i] ; if (_categoriesGrid->GetCellValue(i, 1).Length()) category.name = _categoriesGrid->GetCellValue(i, 1); else category.name = _categoriesGrid->GetCellValue(i, 0); oldid = category.id; _resolvedCategories[oldid] = categories[_categoriesGrid->GetCellValue(i, 0)] = category.id = _kiss->AddCategory(category); } } _categoriesGrid->DeleteRows(0, _categoriesGrid->GetNumberRows ()); _wxUI->NeedReload(); } _operations = _importEngine->GetOperations(accounts, categories); if (_operations->size()) { _hbox->Detach(_operationsGrid); delete _operationsGrid; _operationsGrid = new GridAccount(_kiss, this, OPS_GRID_ID, false, false, false); _hbox->Add(_operationsGrid, 0, wxGROW|wxALL, 15); _operationsGrid->LoadOperations(_operations, 0, 0); _buttonIntegrate->Enable(); _buttonLoadOperations->Disable(); Fit(); } else { wxMessageBox(_("No operation found into this file"), wxT("KissCount"), wxICON_INFORMATION | wxOK); } } void ImportPanel::OnIntegrate(wxCommandEvent& WXUNUSED(event)) { int i; std::map mapid; wxString oldid, account; bool update; std::map accountAmounts; std::map::iterator it; double amount; if (!_operations->size()) return; wxMessageDialog dialog(_wxUI, _("Are you sure want to integrate these operations ?"), wxT("KissCount"), wxYES_NO); if (dialog.ShowModal() == wxID_NO) return; _buttonIntegrate->Disable(); for(i=0; i<(int)_operations->size(); i++) { oldid = (*_operations)[i].id; _kiss->AddOperation((*_operations)[i], false); mapid[oldid] = (*_operations)[i].id; } for(i=0; i<(int)_operations->size(); i++) { update = false; if ((*_operations)[i].parent.Length()) { (*_operations)[i].parent = mapid[(*_operations)[i].parent]; update = true; } if ((*_operations)[i].transfert.Length()) { (*_operations)[i].transfert = mapid[(*_operations)[i].transfert]; update = true; } if (update) _kiss->UpdateOperation((*_operations)[i], false); } accountAmounts = _importEngine->GetAccountAmounts(); for(it=accountAmounts.begin(); it!=accountAmounts.end(); it++) { account = it->first.account; if (_resolvedAccounts.count(account)) account = _resolvedAccounts[account]; amount = _kiss->GetAccountAmount(account, it->first.month, it->first.year); if (!amount) _kiss->SetAccountAmount(account, it->first.month, it->first.year, it->second); } if (_checkSaveImportPatterns->IsChecked()) _kiss->UpdateImportPattern(); _operations->clear(); _operationsGrid->ClearGrid(); wxMessageBox(_("Operations successfully imported"), wxT("KissCount"), wxICON_INFORMATION | wxOK); _wxUI->NeedReload(); } void ImportPanel::OnOperationModified(wxGridEvent& event) { int col = event.GetCol(); int row; static bool update = false; if (col != DESCRIPTION && col != CATEGORY && col != ACCOUNT) return ; if (update) return; update = true; row = event.GetRow(); _operationsGrid->ClearGrid(); if (_importEngine->UpdatePattern(row-1) > 1) _operationsGrid->LoadOperations(_operations, 0, 0); Fit(); update = false; }