Change int in double for Search

Add SearchBanner & Search Pannel
Enable MassUpdate
This commit is contained in:
Grégory Soutadé 2011-12-03 11:23:55 +01:00
parent 7b8f6edff5
commit 9b0222323a
11 changed files with 647 additions and 48 deletions

View File

@ -404,7 +404,7 @@ const QString& KissCount::GetOperationOrder()
}
std::vector<Operation>* KissCount::Search(QString* description, QDate* dateFrom, QDate* dateTo,
int* amountFrom, int* amountTo,
double* amountFrom, double* amountTo,
std::vector<int> categories, int types, std::vector<int> accounts)
{

View File

@ -101,7 +101,7 @@ public:
const QString& GetOperationOrder();
std::vector<Operation>* Search(QString* description, QDate* dateFrom, QDate* dateTo,
int* amountFrom, int* amountTo,
double* amountFrom, double* amountTo,
std::vector<int> categories, int types, std::vector<int> accounts);
bool SearchPreviousOperation(Operation* res, Operation& op, int month, int year, bool limitToType);

View File

@ -1258,7 +1258,7 @@ void Database::UpdatePreference(User* user, const QString& preference)
}
std::vector<Operation>* Database::Search(User* user, QString* description, QDate* dateFrom, QDate* dateTo,
int* amountFrom, int* amountTo,
double* amountFrom, double* amountTo,
std::vector<int> categories, int types, std::vector<int> accounts, bool wildcards)
{
QSqlRecord set;
@ -1408,7 +1408,7 @@ std::vector<Operation>* Database::Search(User* user, QString* description, QDate
req += ", month " + user->_preferences["operation_order"] ;
req += ", day " + user->_preferences["operation_order"] ;
// std::cout << req.mb_str() << "\n";
// std::cout << req.toStdString() << "\n";
EXECUTE_SQL_QUERY(req, res);

View File

@ -125,7 +125,7 @@ public:
void UpdatePreference(User* user, const QString& preference);
std::vector<Operation>* Search(User* user, QString* description, QDate* dateFrom, QDate* dateTo,
int* amountFrom, int* amountTo,
double* amountFrom, double* amountTo,
std::vector<int> categories, int types, std::vector<int> accounts, bool wildcards);
void GetStats(User* user, int monthFrom, int yearFrom, int monthTo,

219
src/view/SearchBanner.cpp Normal file
View File

@ -0,0 +1,219 @@
/*
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 <http://www.gnu.org/licenses/>.
*/
#include "SearchBanner.hpp"
SearchBanner::SearchBanner(KissCount* kiss, QFrame *parent, void* caller, OnButtonEnter enterCallback) : QFrame(parent), _kiss(kiss), _caller(caller), _enterCallback(enterCallback), _operations(0)
{
DEFAULT_FONT(font);
User* user = _kiss->GetUser();
std::vector<Account>::iterator accountIt;
std::vector<Category>::iterator categoryIt;
QDate firstOfMonth = QDate::currentDate();
_checkDateFrom = new QCheckBox(_("Date from"));
_checkDateTo = new QCheckBox(_("Date to"));
_checkDateFrom->setCheckState(Qt::Checked);
_checkDateTo->setCheckState(Qt::Checked);
QGridLayout *gridBagSizer = new QGridLayout(this);
firstOfMonth.setDate(firstOfMonth.year(), firstOfMonth.month(), 1);
_calendarFrom = new QCalendarWidget(this);
_calendarFrom->setGridVisible(false);
_calendarFrom->setFirstDayOfWeek(Qt::Monday);
// _calendarFrom->setNavigationBarVisible(false);
_calendarFrom->setVerticalHeaderFormat(QCalendarWidget::NoVerticalHeader);
_calendarTo = new QCalendarWidget(this);
_calendarTo->setGridVisible(false);
_calendarTo->setFirstDayOfWeek(Qt::Monday);
// _calendarTo->setNavigationBarVisible(false);
_calendarTo->setVerticalHeaderFormat(QCalendarWidget::NoVerticalHeader);
_description = new QLineEdit(this);
_description->setMinimumWidth(_description->width()*2);
connect(_description, SIGNAL(returnPressed ()), this, SLOT(OnEnter()));
_amountFrom = new QLineEdit(this);
_amountTo = new QLineEdit(this);
_category = new QListWidget(this);
QListWidgetItem * item = new QListWidgetItem(_("Unknown"), _category);
item->setCheckState (Qt::Unchecked);
for(categoryIt = user->_categories.begin(); categoryIt != user->_categories.end(); categoryIt++)
{
item = new QListWidgetItem(_(categoryIt->name.toStdString().c_str()), _category);
item->setCheckState (Qt::Unchecked);
}
_optype = new QListWidget(this);
item = new QListWidgetItem(_("Fix"), _optype);
item->setCheckState (Qt::Unchecked);
item = new QListWidgetItem(_("Non fix"), _optype);
item->setCheckState (Qt::Unchecked);
item = new QListWidgetItem(_("Checked"), _optype);
item->setCheckState (Qt::Unchecked);
item = new QListWidgetItem(_("Not checked"), _optype);
item->setCheckState (Qt::Unchecked);
_account = new QListWidget(this);
item = new QListWidgetItem(_("Unknown"), _account);
item->setCheckState (Qt::Unchecked);
for(accountIt = user->_accounts.begin(); accountIt != user->_accounts.end(); accountIt++)
{
item = new QListWidgetItem(accountIt->name, _account);
item->setCheckState (Qt::Unchecked);
}
QLabel* labelDescription = new QLabel(_("Description"));
QLabel* labelAmountFrom = new QLabel(_("Amount from"));
QLabel* labelAmountTo = new QLabel(_("Amount to"));
QLabel* labelCategory = new QLabel(_("Category"));
QLabel* labelOperations = new QLabel(_("Operations"));
QLabel* labelAccount = new QLabel(_("Account"));
gridBagSizer->addWidget(labelDescription, 0, 0);
gridBagSizer->addWidget(_description, 1, 0);
gridBagSizer->addWidget(_checkDateFrom, 0, 1);
gridBagSizer->addWidget(_calendarFrom, 1, 1);
gridBagSizer->addWidget(_checkDateTo, 0, 2);
gridBagSizer->addWidget(_calendarTo, 1, 2);
gridBagSizer->addWidget(labelAmountFrom, 0, 3);
gridBagSizer->addWidget(_amountFrom, 1, 3);
gridBagSizer->addWidget(labelAmountTo, 0, 4);
gridBagSizer->addWidget(_amountTo, 1, 4);
gridBagSizer->addWidget(labelCategory, 0, 5);
gridBagSizer->addWidget(_category, 1, 5);
gridBagSizer->addWidget(labelOperations, 0, 6);
gridBagSizer->addWidget(_optype, 1, 6);
gridBagSizer->addWidget(labelAccount, 0, 7);
gridBagSizer->addWidget(_account, 1, 7);
}
SearchBanner::~SearchBanner()
{
if (_operations) delete _operations;
}
std::vector<Operation> * SearchBanner::Search()
{
QString *description=0;
double *amountFrom=0, *amountTo=0;
std::vector<int> categories, accounts;
QDate *dateFrom=0, *dateTo=0;
User* user= _kiss->GetUser();
int i, types=0;
std::vector<Operation>::iterator it;
bool ok;
if (_operations)
{
delete _operations;
_operations = 0;
}
if (_checkDateFrom->checkState() == Qt::Checked)
{
dateFrom = new QDate();
*dateFrom = _calendarFrom->selectedDate().addMonths(-1);
}
if (_checkDateTo->checkState() == Qt::Checked)
{
dateTo = new QDate();
*dateTo = _calendarTo->selectedDate().addMonths(-1);
}
if (dateFrom && dateTo && *dateFrom > *dateTo)
{
QMessageBox::critical(0, _("Error"), _("Invalid date range"));
goto end;
}
if (_amountFrom->text().length())
{
amountFrom = new double;
*amountFrom = _amountFrom->text().toDouble(&ok);
if (!ok)
{
QMessageBox::critical(0, _("Error"), _("Invalid amount from"));
goto end;
}
if (*amountFrom < 0) *amountFrom *= -1;
}
if (_amountTo->text().length())
{
amountTo = new double;
*amountTo = _amountTo->text().toDouble(&ok);
if (!ok)
{
QMessageBox::critical(0, _("Error"), _("Invalid amount to"));
goto end;
}
if (*amountTo < 0) *amountTo *= -1;
}
if (amountFrom && amountTo && *amountFrom > *amountTo)
{
QMessageBox::critical(0, _("Error"), _("Invalid amount range"));
goto end;
}
if (_description->text().length())
{
description = new QString;
*description = _description->text();
}
for(i=0; i<user->GetCategoriesNumber()+1; i++)
if (_category->item(i)->checkState() == Qt::Checked)
categories.push_back((i) ? user->_categories[i-1].id : 0);
types |= (_optype->item(0)->checkState() == Qt::Checked) ? Database::FIX_OP : 0;
types |= (_optype->item(1)->checkState() == Qt::Checked) ? Database::NON_FIX_OP : 0;
types |= (_optype->item(2)->checkState() == Qt::Checked) ? Database::CHECKED_OP : 0;
types |= (_optype->item(3)->checkState() == Qt::Checked) ? Database::NOT_CHECKED_OP : 0;
for(i=0; i<user->GetAccountsNumber()+1; i++)
if (_account->item(i)->checkState() == Qt::Checked)
accounts.push_back((i) ? user->_accounts[i-1].id : 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()
{
if (_enterCallback)
_enterCallback(_caller);
}

55
src/view/SearchBanner.hpp Normal file
View File

@ -0,0 +1,55 @@
/*
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 <http://www.gnu.org/licenses/>.
*/
#ifndef SEARCHBANNER_H
#define SEARCHBANNER_H
#include <QtGui>
#include "view.hpp"
#include <model/model.hpp>
typedef void (*OnButtonEnter)(void* caller);
class SearchBanner: public QFrame
{
Q_OBJECT;
public:
SearchBanner(KissCount* kiss, QFrame* parent, void* caller=0, OnButtonEnter enterCallback=0);
~SearchBanner();
std::vector<Operation> * Search();
private slots:
void OnEnter();
private:
KissCount* _kiss;
void* _caller;
OnButtonEnter _enterCallback;
std::vector<Operation> *_operations;
QCalendarWidget* _calendarFrom, *_calendarTo;
QCheckBox *_checkDateFrom, *_checkDateTo;
QLineEdit* _description, *_amountFrom, *_amountTo;
QListWidget* _category, *_account, *_optype;
};
#endif

236
src/view/SearchPanel.cpp Normal file
View File

@ -0,0 +1,236 @@
/*
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 <http://www.gnu.org/licenses/>.
*/
#include "SearchPanel.hpp"
SearchPanel::SearchPanel(KissCount* kiss, wxUI *parent) : KissPanel(kiss, parent), _operations(0)
{
DEFAULT_FONT(font);
std::vector<Account>::iterator accountIt;
std::vector<Category>::iterator categoryIt;
QVBoxLayout *vbox = new QVBoxLayout;
QVBoxLayout *vbox2 = new QVBoxLayout;
QHBoxLayout *hbox = new QHBoxLayout;
setLayout(vbox);
_searchButton = new QPushButton(_("Search"));
connect(_searchButton, SIGNAL(clicked()), this, SLOT(OnButtonSearch()));
_banner = new SearchBanner(kiss, this, this, OnEnter);
vbox->addWidget(_banner);
vbox->addWidget(_searchButton);
_grid = new GridAccount(_kiss, this, false, false, true);
hbox->addWidget(_grid);
_changeAccountButton = new QPushButton(_("Change account"));
_changeCategoryButton = new QPushButton(_("Change category"));
_renameButton = new QPushButton(_("Rename"));
connect(_changeAccountButton, SIGNAL(clicked()), this, SLOT(OnButtonChangeAccount()));
connect(_changeCategoryButton, SIGNAL(clicked()), this, SLOT(OnButtonChangeCategory()));
connect(_renameButton, SIGNAL(clicked()), this, SLOT(OnButtonRename()));
vbox2->addWidget(_changeAccountButton);
vbox2->addWidget(_changeCategoryButton);
vbox2->addWidget(_renameButton);
hbox->addLayout(vbox2);
vbox->addLayout(hbox);
}
SearchPanel::~SearchPanel()
{
}
KissPanel* SearchPanel::CreatePanel()
{
return new SearchPanel(_kiss, _wxUI);
}
QPushButton* SearchPanel::GetButton()
{
if (!_KissButton)
{
_KissButton = new QPushButton(QIcon(SEARCH_ICON), "", this);
_KissButton->setFixedSize(128, 128);
_KissButton->setIconSize(QSize(128, 128));
}
return _KissButton;
}
QString SearchPanel::GetToolTip()
{
return _("Search");
}
void SearchPanel::OnEnter(void* caller)
{
SearchPanel* _this = (SearchPanel*) caller;
_this->OnButtonSearch();
}
void SearchPanel::OnButtonSearch()
{
_operations = _banner->Search();
if (!_operations) return;
if (_operations->size() > 1)
QMessageBox::information(0, _("KissCount"), QString::number(_operations->size()) + _(" entries found"));
else if (_operations->size() == 1)
QMessageBox::information(0, _("KissCount"), _("1 entry found"));
else
{
QMessageBox::information(0, _("KissCount"), _("No entry found"));
return;
}
_grid->LoadOperations(_operations, 0, 0);
_wxUI->layout();
}
static void ChangeAccount(Operation* op, void** params)
{
int* account = (int*) params[0];
op->account = *account;
}
void SearchPanel::OnButtonChangeAccount()
{
int i, a;
std::vector<int> rows;
User* user = _kiss->GetUser();
QStringList accounts;
std::vector<Operation>::iterator it;
int account;
void * params[] = {&account};
QString res;
if (!_operations) return;
_grid->GetSelectedOperations(&rows);
accounts << _("None");
for(i=0; i < user->GetAccountsNumber(); i++)
accounts << user->_accounts[i].name;
res = QInputDialog::getItem(this, "KissCount", _("Choose a new account"), accounts, 0, false);
a = (res.length()) ? accounts.indexOf(res) : 0;
account = (a) ? user->_accounts[a-1].id : 0;
_grid->MassUpdate(rows, true, ChangeAccount, params);
_wxUI->NeedReload();
}
static void ChangeCategory(Operation* op, void** params)
{
int* category = (int*) params[0];
bool* fix = (bool*) params[1];
op->category = *category;
op->fix_cost = * fix;
}
void SearchPanel::OnButtonChangeCategory()
{
int i, a;
std::vector<int> rows;
User* user = _kiss->GetUser();
QStringList categories;
std::vector<Operation>::iterator it;
QString res;
int category;
bool fix;
void * params[] = {&category, &fix};
if (!_operations) return;
_grid->GetSelectedOperations(&rows);
categories << _("None");
for(i=0; i < user->GetCategoriesNumber(); i++)
categories << _(user->_categories[i].name.toStdString().c_str());
res = QInputDialog::getItem(this, "KissCount", _("Choose a new category"), categories, 0, false);
if (res.length())
{
a = categories.indexOf(res);
category = user->_categories[a-1].id ;
fix = user->_categories[a-1].fix_cost;
}
else
{
category = 0;
fix = false;
}
_grid->MassUpdate(rows, true, ChangeCategory, params);
_wxUI->NeedReload();
}
static void ChangeName(Operation* op, void** params)
{
QString* description = (QString*) params[0];
op->description = *description;
}
void SearchPanel::OnButtonRename()
{
std::vector<int> rows;
std::vector<Operation>::iterator it;
QString description;
void * params[] = {&description};
if (!_operations) return;
_grid->GetSelectedOperations(&rows);
description = QInputDialog::getText(this, "", _("Enter a new description"));
if (!description.length()) return;
_grid->MassUpdate(rows, false, ChangeName, params);
_wxUI->NeedReload();
}
void SearchPanel::OnShow()
{
_wxUI->setWindowTitle(_kiss->GetUser()->_name + " - " + _("Search"));
}
void SearchPanel::OnOperationModified()
{
_wxUI->NeedReload();
}

65
src/view/SearchPanel.hpp Normal file
View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#ifndef SEARCHPANEL_H
#define SEARCHPANEL_H
#include <QtGui>
#include "view.hpp"
#include "grid/GridAccount.hpp"
#include "AccountPanel.hpp"
#include "SearchBanner.hpp"
#include <model/model.hpp>
class GridAccount;
class SearchPanel: public KissPanel
{
Q_OBJECT;
public:
SearchPanel(KissCount* kiss, wxUI *parent);
~SearchPanel();
KissPanel* CreatePanel();
QPushButton* GetButton();
QString GetToolTip();
void OnShow();
private slots:
/* void OnEnter(wxCommandEvent& event); */
void OnButtonSearch();
void OnOperationModified();
void OnButtonChangeAccount();
void OnButtonChangeCategory();
void OnButtonRename();
private:
std::vector<Operation> *_operations;
SearchBanner* _banner;
GridAccount *_grid;
QPushButton* _searchButton, *_renameButton, *_changeAccountButton, *_changeCategoryButton;
static void OnEnter(void* caller);
};
#endif

View File

@ -1321,6 +1321,22 @@ void GridAccount::Group()
InsertIntoGrid(op);
}
void GridAccount::GetSelectedOperations(std::vector<int>* rows)
{
Operation op;
rows->clear();
QModelIndexList selected = selectedIndexes();
for (int i = 0; i < selected.size(); ++i)
{
op = _displayedOperations[selected[i].row()] ;
if (op.id)
rows->push_back(selected[i].row());
}
}
void GridAccount::UnGroup()
{
@ -1436,56 +1452,62 @@ removeLastGroup:
ComputeWeeks();
}
void GridAccount::MassUpdate(std::vector<int>& rows, updateOperationFunc func, void** params)
void GridAccount::MassUpdate(std::vector<int>& rows, bool do_childs, updateOperationFunc func, void** params)
{
// int i, b;
// std::vector<Operation>::iterator it;
// Operation op, op2;
int i, b;
std::vector<Operation>::iterator it;
Operation op, op2;
// _parent->Disable();
_parent->setEnabled(false);
// _parent->SetCursor(wxCursor(wxCURSOR_WAIT));
_parent->setCursor(Qt::BusyCursor);
// _parent->Update();
if (rows.size())
{
for(i=0; i<(int)rows.size(); i++)
{
op = _displayedOperations[rows[i]];
// if (rows.size())
// {
// for(i=0; i<(int)rows.size(); i++)
// {
// op = _displayedOperations[rows[i]];
func (&op, params);
// func (&op, params);
UpdateOperation(op);
// UpdateOperation(op);
if (op.meta && do_childs)
{
for(b=0; b<(int)op.childs.size(); b++)
{
op2 = GetOperation(op.childs[b]);
func (&op2, params);
UpdateOperation(op2);
}
}
}
}
else
{
for(it=_operations->begin(); it!=_operations->end(); it++)
{
func (&(*it), params);
if (_databaseSynchronization)
_kiss->UpdateOperation(*it);
// if (op.meta)
// {
// for(b=0; b<(int)op.childs.size(); b++)
// {
// op2 = GetOperation(op.childs[b]);
// func (&op2, params);
// UpdateOperation(op2);
// }
// }
// }
// }
// else
// {
// for(it=_operations->begin(); it!=_operations->end(); it++)
// {
// func (&(*it), params);
// if (_databaseSynchronization)
// _kiss->UpdateOperation(*it);
// }
// }
if (it->meta && do_childs)
{
for(b=0; b<(int)it->childs.size(); b++)
{
op2 = GetOperation(it->childs[b]);
func (&op2, params);
UpdateOperation(op2);
}
}
}
}
// ClearGrid();
LoadOperations(_operations, 0, 0);
// LoadOperations(_operations, 0, 0);
layout();
// Layout();
_parent->setEnabled(true);
// _parent->Enable();
// _parent->SetCursor(wxNullCursor);
_parent->setCursor(Qt::ArrowCursor);
}

View File

@ -50,7 +50,9 @@ public:
void InsertOperationWithWeek(User* user, Operation& op, int line, bool fix, int month, int year) ;
void InsertOperation(User* user, Operation& op, int line, bool fix, int month, int year) ;
void MassUpdate(std::vector<int>& rows, updateOperationFunc func, void** params);
void GetSelectedOperations(std::vector<int>* rows);
void MassUpdate(std::vector<int>& rows, bool do_childs, updateOperationFunc func, void** params);
void Group();
void UnGroup();

View File

@ -20,9 +20,9 @@
#include <QMessageBox>
#include "AccountPanel.hpp"
#include "SearchPanel.hpp"
/*#include "PreferencesPanel.hpp"
#include "UsersDialog.hpp"
#include "SearchPanel.hpp"
#include "StatsPanel.hpp"
#include "ImportPanel.hpp"
#include "ExportPanel.hpp"
@ -165,7 +165,7 @@ void wxUI::InitPanels()
ADD_PANEL(AccountPanel);
// ADD_PANEL(StatsPanel, 1);
// ADD_PANEL(SearchPanel, 2);
ADD_PANEL(SearchPanel);
// ADD_PANEL(PreferencesPanel, 3);
// ADD_PANEL(ImportPanel, 4);
// ADD_PANEL(ExportPanel, 5);