From 40ca2a0f25ed22f09d0d65c8115d7444da4eebc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9gory=20Soutad=C3=A9?= Date: Sat, 2 Jul 2011 16:39:32 +0200 Subject: [PATCH] Add (XML) Export engine Add Export Panel Factorise SearchBanner Bug fix : - (Import/Export engines initialization) - virtual field not set in Search method - when deleting on search results - Auto completion now does not require date --- ressources/icons/export-icon.png | Bin 0 -> 9193 bytes src/model/export/ExportEngine.cpp | 81 ++++++++++ src/model/export/ExportEngine.h | 78 +++++++++ src/model/export/XMLExportEngine.cpp | 174 +++++++++++++++++++++ src/model/export/XMLExportEngine.h | 47 ++++++ src/view/ExportPanel.cpp | 153 ++++++++++++++++++ src/view/ExportPanel.h | 65 ++++++++ src/view/SearchBanner.cpp | 226 +++++++++++++++++++++++++++ src/view/SearchBanner.h | 60 +++++++ 9 files changed, 884 insertions(+) create mode 100644 ressources/icons/export-icon.png create mode 100644 src/model/export/ExportEngine.cpp create mode 100644 src/model/export/ExportEngine.h create mode 100644 src/model/export/XMLExportEngine.cpp create mode 100644 src/model/export/XMLExportEngine.h create mode 100644 src/view/ExportPanel.cpp create mode 100644 src/view/ExportPanel.h create mode 100644 src/view/SearchBanner.cpp create mode 100644 src/view/SearchBanner.h diff --git a/ressources/icons/export-icon.png b/ressources/icons/export-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..2e0edd7e90ae8d0c30d93a7f8c583e536a12c008 GIT binary patch literal 9193 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 literal 0 HcmV?d00001 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