diff --git a/ressources/icons/export-icon.png b/ressources/icons/export-icon.png new file mode 100644 index 0000000..2e0edd7 Binary files /dev/null and b/ressources/icons/export-icon.png differ diff --git a/src/model/export/ExportEngine.cpp b/src/model/export/ExportEngine.cpp new file mode 100644 index 0000000..d276358 --- /dev/null +++ b/src/model/export/ExportEngine.cpp @@ -0,0 +1,81 @@ +/* + 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 "ExportEngine.h" + +ExportEngine::ExportEngine() +{ +} + +ExportEngine::~ExportEngine() +{ +} + +bool ExportEngine::HandleFile(const wxString& path, User* user, Database* db, KissCount* kiss) +{ + _path = path; + _user = user; + _db = db; + _kiss = kiss; + + return path.EndsWith(_shortExt) || path.EndsWith(_shortExt.Upper()); +} + +bool ExportEngine::SaveFile(std::vector* operations) +{ + int i; + wxString account, category; + AccountAmount accountAmount; + + if (!operations) return NULL; + + _accounts.clear(); + _categories.clear(); + _accountAmounts.clear(); + + for(i=0; i<(int)operations->size(); i++) + { + account = (*operations)[i].account; + category = (*operations)[i].category; + + accountAmount.account = account; + accountAmount.month = (*operations)[i].month; + accountAmount.year = (*operations)[i].year; + + if (account.Length()) + { + if (!_accounts.count(account)) + _accounts[account]++; + + if (!_accountAmounts.count(accountAmount)) + _accountAmounts[accountAmount] = _kiss->GetAccountAmount(accountAmount.account, accountAmount.month, accountAmount.year); + } + + if (category.Length() && !_categories.count(category)) + _categories[category]++; + } + + return true; +} + +wxString ExportEngine::GetFileExt() +{ + return wxGetTranslation(_longExt); +} + diff --git a/src/model/export/ExportEngine.h b/src/model/export/ExportEngine.h new file mode 100644 index 0000000..4ecf2f9 --- /dev/null +++ b/src/model/export/ExportEngine.h @@ -0,0 +1,78 @@ +/* + 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 . +*/ + +#ifndef EXPORTENGINE_H +#define EXPORTENGINE_H + +#include +#include + +class KissCount; + +class AccountAmount { +public: + wxString account; + int month; + int year; + bool operator()(const AccountAmount& x, const AccountAmount& y) const + { + long x1, y1; + + if (x.account != y.account) + { + x.account.ToLong(&x1); + y.account.ToLong(&y1); + + return x1 < y1; + } + + return (x.year < y.year && x.month < y.month); + } +}; + +class ExportEngine { +public: + ExportEngine(); + ~ExportEngine(); + + // Get supported file extension. Example : + // "OFX files (*.ofx)|*.ofx" + virtual wxString GetFileExt(); + + // Handle the file + virtual bool HandleFile(const wxString& path, User* user, Database* db, KissCount* kiss)=0; + + // Save operations (ExportEngin pre fill _accounts, _categories and _accountAmounts) + virtual bool SaveFile(std::vector* operations)=0; + +protected: + wxString _path; + Database* _db; + User* _user; + KissCount* _kiss; + + wxString _shortExt; + wxString _longExt; + + std::map _accounts; + std::map _categories; + std::map _accountAmounts; +}; + +#endif diff --git a/src/model/export/XMLExportEngine.cpp b/src/model/export/XMLExportEngine.cpp new file mode 100644 index 0000000..760a462 --- /dev/null +++ b/src/model/export/XMLExportEngine.cpp @@ -0,0 +1,174 @@ +/* + 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 "XMLExportEngine.h" + +static XMLExportEngine xmlExportEngine; + +XMLExportEngine::XMLExportEngine() +{ + KissCount::RegisterExportEngine(this); + + _shortExt = wxT("xml"); + _longExt = _("XML files (*.xml)|*.xml"); +} + +XMLExportEngine::~XMLExportEngine() +{ +} + +bool XMLExportEngine::HandleFile(const wxString& path, User* user, Database* db, KissCount* kiss) +{ + return ExportEngine::HandleFile(path, user, db, kiss); +} + +bool XMLExportEngine::SaveAccounts() +{ + Account account; + std::map::iterator it; + + for(it=_accounts.begin(); it!=_accounts.end(); it++) + { + account = _user->GetAccount(it->first); + + xmlTextWriterStartElement(_writer, (const xmlChar*) "account"); + xmlTextWriterWriteAttribute(_writer, (const xmlChar*) "id", (const xmlChar*) account.id.utf8_str().data()); + xmlTextWriterWriteAttribute(_writer, (const xmlChar*) "name", (const xmlChar*) account.name.utf8_str().data()); + xmlTextWriterWriteAttribute(_writer, (const xmlChar*) "number", (const xmlChar*) account.number.utf8_str().data()); + xmlTextWriterWriteAttribute(_writer, (const xmlChar*) "shared", (const xmlChar*) (account.shared ? "1" : "0")); + xmlTextWriterWriteAttribute(_writer, (const xmlChar*) "blocked", (const xmlChar*) (account.blocked ? "1" : "0")); + xmlTextWriterWriteAttribute(_writer, (const xmlChar*) "default", (const xmlChar*) (account._default ? "1" : "0")); + xmlTextWriterWriteAttribute(_writer, (const xmlChar*) "is_owner", (const xmlChar*) (account.is_owner ? "1" : "0")); + xmlTextWriterWriteAttribute(_writer, (const xmlChar*) "virtual", (const xmlChar*) (account._virtual ? "1" : "0")); + xmlTextWriterEndElement(_writer); + } + + return true; +} + +bool XMLExportEngine::SaveAccountAmounts() +{ + std::map::iterator it; + + for(it=_accountAmounts.begin(); it!=_accountAmounts.end(); it++) + { + xmlTextWriterStartElement(_writer, (const xmlChar*) "account_amount"); + xmlTextWriterWriteAttribute(_writer, (const xmlChar*) "account", (const xmlChar*) it->first.account.utf8_str().data()); + xmlTextWriterWriteFormatAttribute(_writer, (const xmlChar*) "month", "%d", it->first.month); + xmlTextWriterWriteFormatAttribute(_writer, (const xmlChar*) "year", "%d", it->first.year); + xmlTextWriterWriteFormatAttribute(_writer, (const xmlChar*) "amount", "%.2lf", it->second); + xmlTextWriterEndElement(_writer); + } + + return true; +} + +bool XMLExportEngine::SaveCategories() +{ + Category category; + std::map::iterator it; + int rgb; + + for(it=_categories.begin(); it!=_categories.end(); it++) + { + category = _user->GetCategory(it->first); + + xmlTextWriterStartElement(_writer, (const xmlChar*) "category"); + xmlTextWriterWriteAttribute(_writer, (const xmlChar*) "id", (const xmlChar*) category.id.utf8_str().data()); + xmlTextWriterWriteAttribute(_writer, (const xmlChar*) "name", (const xmlChar*) category.name.utf8_str().data()); + xmlTextWriterWriteAttribute(_writer, (const xmlChar*) "font", (const xmlChar*) category.font.utf8_str().data()); + rgb = category.backcolor.Blue(); + rgb |= category.backcolor.Green() << 8; + rgb |= category.backcolor.Red() << 16; + xmlTextWriterWriteFormatAttribute(_writer, (const xmlChar*) "backcolor", "%08X", rgb); + rgb = category.forecolor.Blue(); + rgb |= category.forecolor.Green() << 8; + rgb |= category.forecolor.Red() << 16; + xmlTextWriterWriteFormatAttribute(_writer, (const xmlChar*) "forecolor", "%08X", rgb); + xmlTextWriterWriteAttribute(_writer, (const xmlChar*) "fix_cost", (const xmlChar*) (category.fix_cost ? "1" : "0")); + xmlTextWriterEndElement(_writer); + } + + return true; +} + +bool XMLExportEngine::SaveOperations(std::vector* operations) +{ + std::vector::iterator it; + + for(it=operations->begin(); it!=operations->end(); it++) + { + xmlTextWriterStartElement(_writer, (const xmlChar*) "operation"); + xmlTextWriterWriteAttribute(_writer, (const xmlChar*) "id", (const xmlChar*) it->id.utf8_str().data()); + xmlTextWriterWriteAttribute(_writer, (const xmlChar*) "parent", (const xmlChar*) it->parent.utf8_str().data()); + xmlTextWriterWriteFormatAttribute(_writer, (const xmlChar*) "day", "%d", it->day); + xmlTextWriterWriteFormatAttribute(_writer, (const xmlChar*) "month", "%d", it->month); + xmlTextWriterWriteFormatAttribute(_writer, (const xmlChar*) "year", "%d", it->year); + xmlTextWriterWriteFormatAttribute(_writer, (const xmlChar*) "amount", "%.2lf", it->amount); + xmlTextWriterWriteAttribute(_writer, (const xmlChar*) "description", (const xmlChar*) it->description.utf8_str().data()); + xmlTextWriterWriteAttribute(_writer, (const xmlChar*) "category", (const xmlChar*) it->category.utf8_str().data()); + xmlTextWriterWriteAttribute(_writer, (const xmlChar*) "fix_cost", (const xmlChar*) (it->fix_cost ? "1" : "0")); + xmlTextWriterWriteAttribute(_writer, (const xmlChar*) "account", (const xmlChar*) it->account.utf8_str().data()); + xmlTextWriterWriteAttribute(_writer, (const xmlChar*) "checked", (const xmlChar*) (it->checked ? "1" : "0")); + xmlTextWriterWriteAttribute(_writer, (const xmlChar*) "transfert", (const xmlChar*) it->transfert.utf8_str().data()); + xmlTextWriterWriteAttribute(_writer, (const xmlChar*) "formula", (const xmlChar*) it->formula.utf8_str().data()); + xmlTextWriterWriteAttribute(_writer, (const xmlChar*) "meta", (const xmlChar*) (it->meta ? "1" : "0")); + xmlTextWriterWriteAttribute(_writer, (const xmlChar*) "virtual", (const xmlChar*) (it->_virtual ? "1" : "0")); + xmlTextWriterEndElement(_writer); + } + + return true; +} + +bool XMLExportEngine::SaveFile(std::vector* operations) +{ + int rc; + + rc = ExportEngine::SaveFile(operations); + + if (!rc) return false; + + _writer = xmlNewTextWriterFilename(_path.mb_str(), 0); + + if (!_writer) + { + std::cout << "Error can't open the file" << std::endl; + return false; + } + + rc = xmlTextWriterStartDocument(_writer, NULL, "UTF-8", NULL); + + if (rc < 0) return false; + + xmlTextWriterStartElement(_writer, (const xmlChar*) "kisscount"); + xmlTextWriterWriteAttribute(_writer, (const xmlChar*) "version", (const xmlChar*) "1"); + + SaveAccounts(); + SaveAccountAmounts(); + SaveCategories(); + SaveOperations(operations); + + xmlTextWriterEndElement(_writer); + + xmlTextWriterEndDocument(_writer); + + xmlFreeTextWriter(_writer); + + return true; +} diff --git a/src/model/export/XMLExportEngine.h b/src/model/export/XMLExportEngine.h new file mode 100644 index 0000000..f91c0f8 --- /dev/null +++ b/src/model/export/XMLExportEngine.h @@ -0,0 +1,47 @@ +/* + 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 . +*/ + +#ifndef XMLEXPORTENGINE_H +#define XMLEXPORTENGINE_H + +#include +#include + +#include +#include +#include "ExportEngine.h" + +class XMLExportEngine : public ExportEngine { +public: + XMLExportEngine(); + ~XMLExportEngine(); + + bool HandleFile(const wxString& path, User* user, Database* db, KissCount* kiss); + bool SaveFile(std::vector* operations); + +private: + xmlTextWriterPtr _writer; + + bool SaveAccounts(); + bool SaveAccountAmounts(); + bool SaveCategories(); + bool SaveOperations(std::vector* operations); +}; + +#endif diff --git a/src/view/ExportPanel.cpp b/src/view/ExportPanel.cpp new file mode 100644 index 0000000..efa0499 --- /dev/null +++ b/src/view/ExportPanel.cpp @@ -0,0 +1,153 @@ +/* + 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 "ExportPanel.h" + +enum {EXPORT_ID=1, SEARCH_ID, GRID_ID}; + +BEGIN_EVENT_TABLE(ExportPanel, wxPanel) +EVT_BUTTON(EXPORT_ID, ExportPanel::OnButtonExport) +EVT_BUTTON(SEARCH_ID, ExportPanel::OnButtonSearch) +EVT_SHOW(ExportPanel::OnShow) +END_EVENT_TABLE() + +ExportPanel::ExportPanel(KissCount* kiss, wxUI *parent) : KissPanel(kiss, parent), _operations(NULL) +{ + DEFAULT_FONT(font); + std::vector::iterator accountIt; + std::vector::iterator categoryIt; + wxDateTime firstOfMonth; + wxRect rect = wxDisplay().GetGeometry(); + + wxBoxSizer *vbox = new wxBoxSizer(wxVERTICAL); + wxBoxSizer *vbox2 = new wxBoxSizer(wxVERTICAL); + wxBoxSizer *hbox = new wxBoxSizer(wxHORIZONTAL); + + SetSizer(vbox); + + _searchButton = new wxButton(this, SEARCH_ID, _("Search")); + + _banner = new SearchBanner(kiss, this, this, OnEnter); + + vbox->Add(_banner, 0, wxGROW|wxALL, 5); + vbox->Add(_searchButton, 0, wxALL, 5); + + _grid = new GridAccount(_kiss, this, GRID_ID, false, false, false); + + hbox->Add(_grid, 0, wxGROW|wxALL, 5); + + _exportButton = new wxButton(this, EXPORT_ID, _("Export")); + + vbox2->Add(_exportButton, wxALL, 15); + + hbox->Add(vbox2, 0, wxALL, 15); + + vbox->Add(hbox, 0, wxGROW|wxALL, 5); + + 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); +} + +ExportPanel::~ExportPanel() +{ +} + +KissPanel* ExportPanel::CreatePanel() +{ + return new ExportPanel(_kiss, _wxUI); +} + +wxBitmapButton* ExportPanel::GetButton(int id) +{ + if (!_KissButton) + _KissButton = new wxBitmapButton(_wxUI, id, wxBitmap(wxT(EXPORT_ICON), wxBITMAP_TYPE_PNG), wxDefaultPosition, wxSize(128, 128)); + + return _KissButton; +} + +wxString ExportPanel::GetToolTip() +{ + return _("Export"); +} + +void ExportPanel::OnEnter(void* caller, wxCommandEvent& event) +{ + ExportPanel* _this = (ExportPanel*) caller; + + _this->OnButtonExport(event); +} + +void ExportPanel::OnButtonSearch(wxCommandEvent& event) +{ + _operations = _banner->Search(); + + if (!_operations) return; + + if (_operations->size() > 1) + wxMessageBox(wxString::Format(wxT("%d"), _operations->size()) + _(" entries found"), wxT("KissCount"), wxICON_INFORMATION | wxOK); + else if (_operations->size() == 1) + wxMessageBox(_("1 entry found"), wxT("KissCount"), wxICON_INFORMATION | wxOK); + else + { + wxMessageBox(_("No entry found"), wxT("KissCount"), wxICON_INFORMATION | wxOK); + return; + } + + _grid->LoadOperations(_operations, 0, 0); + + _wxUI->Layout(); +} + +void ExportPanel::OnButtonExport(wxCommandEvent& event) +{ + if (!_operations || !_operations->size()) + { + wxMessageBox(_("No operation to save"), wxT("Error"), wxICON_ERROR | wxOK); + return; + } + + wxFileDialog saveFileDialog(this, _("Save as"), wxT(""), wxT(""), + _kiss->GetExportEngineExtensions(), wxFD_SAVE|wxFD_OVERWRITE_PROMPT); + + if (saveFileDialog.ShowModal() == wxID_CANCEL) + return; + + _exportEngine = _kiss->GetExportEngine(saveFileDialog.GetPath()); + + if (!_exportEngine) + { + wxMessageBox(_("Any engine can process this file !"), wxT("KissCount"), wxICON_INFORMATION | wxOK); + + return ; + } + + if (_exportEngine->SaveFile(_operations)) + wxMessageBox(_("Operations successfuly saved"), wxT("KissCount"), wxICON_INFORMATION | wxOK); + else + wxMessageBox(_("Failed to save operations"), wxT("Error"), wxICON_ERROR | wxOK); + +} + +void ExportPanel::OnShow(wxShowEvent& event) +{ + _wxUI->SetTitle(_("KissCount - Export")); +} diff --git a/src/view/ExportPanel.h b/src/view/ExportPanel.h new file mode 100644 index 0000000..67c2be8 --- /dev/null +++ b/src/view/ExportPanel.h @@ -0,0 +1,65 @@ +/* + 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 . +*/ + +#ifndef EXPORTPANEL_H +#define EXPORTPANEL_H + +#include +#include +#include +#include +#include "view.h" +#include "grid/CalendarEditor.h" +#include "grid/wxGridCellBitmapRenderer.h" +#include "grid/GridAccount.h" +#include "SearchBanner.h" +#include +#include + +class GridAccount; +class SearchBanner; +class ExportEngine; + +class ExportPanel: public KissPanel +{ +public: + ExportPanel(KissCount* kiss, wxUI *parent); + ~ExportPanel(); + + KissPanel* CreatePanel(); + wxBitmapButton* GetButton(int id); + wxString GetToolTip(); + void OnShow(wxShowEvent& event); + + void OnButtonSearch(wxCommandEvent& event); + void OnButtonExport(wxCommandEvent& event); + +private: + std::vector *_operations; + SearchBanner* _banner; + GridAccount *_grid; + wxButton* _searchButton, *_exportButton; + ExportEngine* _exportEngine; + + static void OnEnter(void* caller, wxCommandEvent& event); + + DECLARE_EVENT_TABLE(); +}; + +#endif diff --git a/src/view/SearchBanner.cpp b/src/view/SearchBanner.cpp new file mode 100644 index 0000000..3ffd8d9 --- /dev/null +++ b/src/view/SearchBanner.cpp @@ -0,0 +1,226 @@ +/* + 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 "SearchBanner.h" + +enum {DESCRIPTION_ID=1, CALENDAR_FROM_ID, CALENDAR_TO_ID}; + +BEGIN_EVENT_TABLE(SearchBanner, wxPanel) +EVT_CALENDAR_SEL_CHANGED(CALENDAR_TO_ID, SearchBanner::OnCalendarToChange) +EVT_TEXT_ENTER(DESCRIPTION_ID, SearchBanner::OnEnter) +END_EVENT_TABLE() + +#define UNESCAPE_CHARS(s) { \ + s.Replace(wxT("\\\""), wxT("\""), true); \ + s.Replace(wxT("\\\'"), wxT("\'"), true); \ + } + +SearchBanner::SearchBanner(KissCount* kiss, wxPanel *parent, void* caller, OnButtonEnter enterCallback) : wxPanel(parent), _kiss(kiss), _caller(caller), _enterCallback(enterCallback), _operations(NULL) +{ + DEFAULT_FONT(font); + User* user = _kiss->GetUser(); + std::vector::iterator accountIt; + std::vector::iterator categoryIt; + wxDateTime firstOfMonth; + wxRect rect = wxDisplay().GetGeometry(); + + wxBoxSizer *vbox = new wxBoxSizer(wxVERTICAL); + + SetSizer(vbox); + + _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, 10); + + 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); + + + _description = new wxTextCtrl(this, DESCRIPTION_ID); + _description->SetWindowStyle(_description->GetWindowStyle() | wxTE_PROCESS_ENTER); + wxSize size = _description->GetSize(); + size.SetWidth(size.GetWidth()*2); + _description->SetMinSize(size); + _amountFrom = new wxTextCtrl(this, wxID_ANY); + _amountTo = new wxTextCtrl(this, wxID_ANY); + + _category = new wxCheckListBox(this, wxID_ANY); + _category->Append(_("Unknown")); + for(categoryIt = user->_categories.begin(); categoryIt != user->_categories.end(); categoryIt++) + _category->Append(wxGetTranslation(categoryIt->name)); + + wxString stypes[] = {_("Fix"), _("Non fix"), _("Checked"), _("Not checked")}; + _optype = new wxCheckListBox(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 4, stypes); + + _account = new wxCheckListBox(this, wxID_ANY); + _account->Append(_("Unknown")); + for(accountIt = user->_accounts.begin(); accountIt != user->_accounts.end(); accountIt++) + _account->Append(accountIt->name); + + wxStaticText* labelDescription = new wxStaticText(this, wxID_ANY, _("Description")); + wxStaticText* labelAmountFrom = new wxStaticText(this, wxID_ANY, _("Amount from")); + wxStaticText* labelAmountTo = new wxStaticText(this, wxID_ANY, _("Amount to")); + wxStaticText* labelCategory = new wxStaticText(this, wxID_ANY, _("Category")); + wxStaticText* labelOperations = new wxStaticText(this, wxID_ANY, _("Operations")); + wxStaticText* labelAccount = new wxStaticText(this, wxID_ANY, _("Account")); + + gridBagSizer->Add(labelDescription, wxGBPosition(0, 0)); + gridBagSizer->Add(_description, wxGBPosition(1, 0)); + gridBagSizer->Add(_checkDateFrom, wxGBPosition(0, 1)); + gridBagSizer->Add(_calendarFrom, wxGBPosition(1, 1)); + gridBagSizer->Add(_checkDateTo, wxGBPosition(0, 2)); + gridBagSizer->Add(_calendarTo, wxGBPosition(1, 2)); + gridBagSizer->Add(labelAmountFrom, wxGBPosition(0, 3)); + gridBagSizer->Add(_amountFrom, wxGBPosition(1, 3)); + gridBagSizer->Add(labelAmountTo, wxGBPosition(0, 4)); + gridBagSizer->Add(_amountTo, wxGBPosition(1, 4)); + gridBagSizer->Add(labelCategory, wxGBPosition(0, 5)); + gridBagSizer->Add(_category, wxGBPosition(1, 5)); + gridBagSizer->Add(labelOperations, wxGBPosition(0, 6)); + gridBagSizer->Add(_optype, wxGBPosition(1, 6)); + gridBagSizer->Add(labelAccount, wxGBPosition(0, 7)); + gridBagSizer->Add(_account, wxGBPosition(1, 7)); + + vbox->Add(gridBagSizer, 0, wxGROW|wxALL, 5); +} + +SearchBanner::~SearchBanner() +{ + if (_operations) delete _operations; +} + +std::vector * SearchBanner::Search() +{ + wxString *description=NULL, *amountFrom=NULL, *amountTo=NULL; + std::vector categories, accounts; + wxDateTime *dateFrom=NULL, *dateTo=NULL; + User* user= _kiss->GetUser(); + int i, types=0; + std::vector::iterator it; + double af, at; + + if (_operations) + { + delete _operations; + _operations = NULL; + } + + if (_checkDateFrom->IsChecked()) + { + dateFrom = new wxDateTime; + *dateFrom = _calendarFrom->GetDate(); + } + + if (_checkDateTo->IsChecked()) + { + dateTo = new wxDateTime; + *dateTo = _calendarTo->GetDate(); + } + + if (dateFrom && dateTo && *dateFrom > *dateTo) + { + wxMessageBox(_("Invalid date range"), _("Error"), wxICON_ERROR | wxOK); + goto end; + } + + if (_amountFrom->GetLineText(0).Length()) + { + amountFrom = new wxString; + *amountFrom = _amountFrom->GetLineText(0); + if (!amountFrom->ToDouble(&af)) + { + wxMessageBox(_("Invalid amount from"), _("Error"), wxICON_ERROR | wxOK); + goto end; + } + + if (af < 0) af *= -1; + } + + if (_amountTo->GetLineText(0).Length()) + { + amountTo = new wxString; + *amountTo = _amountTo->GetLineText(0); + if (!amountTo->ToDouble(&at)) + { + wxMessageBox(_("Invalid amount to"), _("Error"), wxICON_ERROR | wxOK); + goto end; + } + + if (at < 0) at *= -1; + } + + if (amountFrom && amountTo && af > at) + { + wxMessageBox(_("Invalid amount range"), _("Error"), wxICON_ERROR | wxOK); + goto end; + } + + if (_description->GetLineText(0).Length()) + { + description = new wxString; + *description = _description->GetLineText(0); + } + + for(i=0; iGetCategoriesNumber(); i++) + if (_category->IsChecked(i)) + categories.push_back((i) ? user->_categories[i-1].id : wxT("0")); + + types |= (_optype->IsChecked(0)) ? FIX_OP : 0; + types |= (_optype->IsChecked(1)) ? NON_FIX_OP : 0; + types |= (_optype->IsChecked(2)) ? CHECKED_OP : 0; + types |= (_optype->IsChecked(3)) ? NOT_CHECKED_OP : 0; + + for(i=0; iGetAccountsNumber(); i++) + if (_account->IsChecked(i)) + accounts.push_back((i) ? user->_accounts[i-1].id : wxT("0")); + + _operations = _kiss->Search(description, dateFrom, dateTo, amountFrom, amountTo, categories,types, accounts); + +end: + delete dateFrom; + delete dateTo; + delete amountFrom; + delete amountTo; + + return _operations; +} + +void SearchBanner::OnEnter(wxCommandEvent& event) +{ + if (_enterCallback) + _enterCallback(_caller, event); +} + +void SearchBanner::OnCalendarFromChange(wxCalendarEvent& event) +{ + _checkDateFrom->SetValue(true); +} + +void SearchBanner::OnCalendarToChange(wxCalendarEvent& event) +{ + _checkDateTo->SetValue(true); +} diff --git a/src/view/SearchBanner.h b/src/view/SearchBanner.h new file mode 100644 index 0000000..bf3bc7b --- /dev/null +++ b/src/view/SearchBanner.h @@ -0,0 +1,60 @@ +/* + 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 . +*/ + +#ifndef SEARCHBANNER_H +#define SEARCHBANNER_H + +#include +#include +#include +#include +#include "view.h" +#include "grid/CalendarEditor.h" + +#include + +typedef void (*OnButtonEnter)(void* caller, wxCommandEvent& event); + +class SearchBanner: public wxPanel +{ +public: + SearchBanner(KissCount* kiss, wxPanel* parent, void* caller=NULL, OnButtonEnter enterCallback=NULL); + ~SearchBanner(); + + void OnEnter(wxCommandEvent& event); + void OnButtonSearch(wxCommandEvent& event); + void OnCalendarFromChange(wxCalendarEvent& event); + void OnCalendarToChange(wxCalendarEvent& event); + + std::vector * Search(); + +private: + KissCount* _kiss; + void* _caller; + OnButtonEnter _enterCallback; + + std::vector *_operations; + wxCalendarCtrl* _calendarFrom, *_calendarTo; + wxCheckBox *_checkDateFrom, *_checkDateTo; + wxTextCtrl* _description, *_amountFrom, *_amountTo; + wxCheckListBox* _category, *_account, *_optype; + DECLARE_EVENT_TABLE(); +}; + +#endif