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