/* Copyright 2010-2011 Grégory Soutadé This file is part of KissCount. KissCount is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. KissCount is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with KissCount. If not, see . */ #include #include #include #include #include "GridAccount.hpp" #include "ChoiceDelegate.hpp" #include "DateDelegate.hpp" #include "FloatDelegate.hpp" #include "FormulaDelegate.hpp" #define SET_ROW_COLOR(row, backcolor, forecolor) for(int i=0; iitem(row, i)) setItem(row, i, new QTableWidgetItem("")); \ this->item(row, i)->setBackground(backcolor); \ this->item(row, i)->setForeground(forecolor); \ } #define SET_ROW_FONT(row, font) for(int i=0; iitem(row, i)) setItem(row, i, new QTableWidgetItem("")); \ this->item(row, i)->setFont(font); \ } #define SET_READ_ONLY(item) item->setFlags(item->flags() & ~Qt::ItemIsEditable); GridAccount::GridAccount(KissCount* kiss, QWidget *parent, bool canAddOperation, bool setWeek, bool synchronizeWithDatabase) : QTableWidget(parent), _fixCosts(0), _week1(0), _week2(0), _week3(0), _week4(0), _parent(parent), _kiss(kiss), _canAddOperation(canAddOperation), _setWeek(setWeek), _databaseSynchronization(synchronizeWithDatabase), _loadOperations(false), _curMonth(0), _curYear(0) { //DEFAULT_FONT(font); QFont font; int i; User* user = _kiss->GetUser(); std::vector::iterator accountIt; std::vector::iterator categoryIt; QTableWidgetItem* item; QLabel* label; setColumnCount(NUMBER_COLS_OPS); setRowCount(1); verticalHeader()->setHidden(true); horizontalHeader()->setHidden(true); setColumnWidth (DESCRIPTION, columnWidth(DESCRIPTION)*3); //SetDefaultCellFont(font); QString colsName[] = {"", _("Description"), _("Date"), _("Debit"), _("Credit"), _("Category"), _("Account"), "", ""}; for(i=0; isetText(colsName[i]); item->setBackground(view::OWN_CYAN); font = item->font(); font.setBold(true); item->setFont(font); SET_READ_ONLY(item); item->setTextAlignment(Qt::AlignHCenter|Qt::AlignVCenter); setItem(0, i, item); } label = new QLabel(); label->setPixmap(QPixmap(DELETE_ICON)); label->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter); setCellWidget(0, OP_DELETE, label); label = new QLabel(); label->setPixmap(QPixmap(CHECKED_ICON)); label->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter); setCellWidget(0, CHECKED, label); _accounts = new QString[user->GetAccountsNumber()]; for (i=0, accountIt = user->_accounts.begin(); accountIt != user->_accounts.end(); accountIt++, i++) _accounts[i] = accountIt->name; _categories = new QString[user->GetCategoriesNumber()] ; for(i=0, categoryIt = user->_categories.begin(); categoryIt != user->_categories.end(); categoryIt++, i++) { _categories[i] = categoryIt->name ; } // Connect(id, wxEVT_GRID_CELL_CHANGE, wxGridEventHandler(GridAccount::OnOperationModified), 0, this); resizeColumnToContents(TREE); resizeColumnToContents(CATEGORY); resizeColumnToContents(OP_DATE); resizeColumnToContents(ACCOUNT); resizeColumnToContents(OP_DELETE); resizeColumnToContents(CHECKED); } GridAccount::~GridAccount() { delete[] _categories; delete[] _accounts; } // wxPen GridAccount::GetColGridLinePen (int col) // {return wxPen(*wxBLACK, 1, wxSOLID);} // wxPen GridAccount::GetRowGridLinePen (int row) { // if (_canAddOperation) // { // if (row == 0 || row == _fixCosts || // row == _week1 || // row == _week2 || // row == _week3 || // row == _week4) // return wxPen(*wxBLACK, 1, wxSOLID); // } // else // if (row == 0) // return wxPen(*wxBLACK, 1, wxSOLID); // return GetCellBackgroundColour(row, 0); // } void GridAccount::ResetWeeks() { _week1 = _week2 = _week3 = _week4 = 0; } void GridAccount::SetWeek(int week, int line) { switch (week) { case 1: _week1 = line; break; case 2: _week2 = line; break; case 3: _week3 = line; break; case 4: _week4 = line; break; } } Operation& GridAccount::GetOperation(int id) throw (OperationNotFound) { std::vector::iterator it = std::find(_operations->begin(), _operations->end(), id); if (it != _operations->end()) return *it; throw OperationNotFound(); } void GridAccount::UpdateOperation(Operation& op) { std::vector::iterator it = std::find(_operations->begin(), _operations->end(), op.id); if (it != _operations->end()) { if (_databaseSynchronization) _kiss->UpdateOperation(op); *it = op; } } int GridAccount::GetDisplayedRow(int id) { std::vector::iterator it = std::find(_displayedOperations.begin(), _displayedOperations.end(), id); if (it != _displayedOperations.end()) return it-_displayedOperations.begin(); return -1; } void GridAccount::ClearGrid() { std::vector operations; LoadOperations(&operations, 0, 0); } void GridAccount::LoadOperations(std::vector* operations, int month, int year) { std::vector::iterator it; User* user = _kiss->GetUser(); int curLine = 0; Operation NULLop; NULLop.id = 0; _loadOperations = true; _operations = operations; _curMonth = month; _curYear = year; _displayedOperations.clear(); _displayedOperations.push_back(NULLop); // Header _fixCosts = 0; it = _operations->begin(); if (rowCount() > 1) clear(); ChoiceDelegate* categoryEditor = new ChoiceDelegate(this, _categories, user->GetCategoriesNumber()); setItemDelegateForColumn(CATEGORY, categoryEditor); ChoiceDelegate* accountEditor = new ChoiceDelegate(this, _accounts, user->GetAccountsNumber()); setItemDelegateForColumn(ACCOUNT, accountEditor); DateDelegate* dateEditor = new DateDelegate(this, month+1, year); setItemDelegateForColumn(OP_DATE, dateEditor); // FloatDelegate* floatEditor = new FloatDelegate(this); // setItemDelegateForColumn(DEBIT, floatEditor); // setItemDelegateForColumn(CREDIT, floatEditor); FormulaDelegate* formulaEditor = new FormulaDelegate(this); setItemDelegateForColumn(DEBIT, formulaEditor); setItemDelegateForColumn(CREDIT, formulaEditor); if (_canAddOperation) { for (;it != _operations->end() && it->fix_cost; it++) { if (it->parent) continue; if (_setWeek) InsertOperationWithWeek(user, *it, ++curLine, true, it->month, it->year); else InsertOperation(user, *it, ++curLine, true, it->month, it->year); } InsertOperation(user, NULLop, ++curLine, true, month, year); for (; it != _operations->end(); it++) { if (it->parent) continue; if (_setWeek) InsertOperationWithWeek(user, *it, ++curLine, false, it->month, it->year); else InsertOperation(user, *it, ++curLine, false, it->month, it->year); } InsertOperation(user, NULLop, ++curLine, false, month, year); } else { for (;it != _operations->end(); it++) { if (it->parent) continue; InsertOperation(user, *it, ++curLine, it->fix_cost, it->month, it->year); } } resizeColumnToContents(TREE); resizeColumnToContents(CATEGORY); resizeColumnToContents(OP_DATE); resizeColumnToContents(ACCOUNT); resizeColumnToContents(OP_DELETE); resizeColumnToContents(CHECKED); _loadOperations = false; } void GridAccount::ComputeWeeks() { std::vector::iterator it; int curLine, curWeek, week, i; if (!_canAddOperation) return; for (it = _displayedOperations.begin(), curLine=0; it != _displayedOperations.end(); it++, curLine++) { if (it->id && !it->fix_cost) break; } if (it == _displayedOperations.end()) return; ResetWeeks(); // curWeek = wxDateTime(it->day+1, (wxDateTime::Month)it->month, it->year).GetWeekOfMonth(); // it++; // for (i=1; it != _displayedOperations.end(); it++, curLine++) // { // if (!it->id || it->parent) continue; // week = wxDateTime(it->day+1, (wxDateTime::Month)it->month, it->year).GetWeekOfMonth(); // if (week != curWeek) // { // SetWeek(i++, curLine); // curWeek = week; // } // } } void GridAccount::InsertOperationWithWeek(User* user, Operation& op, int line, bool fix, int month, int year) { InsertOperation(user, op, line, fix, month, year); if (op.id && !fix) ComputeWeeks(); } #include void GridAccount::InsertOperation(User* user, Operation& op, int line, bool fix, int month, int year) { std::vector::iterator it; std::vector::iterator it2; int r, g, b, i; double amount; QColor color; QDate curDate = QDate::currentDate(); QString description, v; QFont font; Category cat ; Operation op2; QTableWidgetItem* item; QCheckBox* checkBox; // // First is header // if (op.id) _displayedOperations.insert(_displayedOperations.begin()+line, op); if (!user->_accounts.size()) return; insertRow(line); if (fix) { item = new QTableWidgetItem(_("Fix")); setItem(line, CATEGORY, item); SET_READ_ONLY(item); _fixCosts++; } //SetCellEditor(line, DEBIT, new wxGridCellFormulaEditor(op.formula)); //SetCellEditor(line, CREDIT, new wxGridCellFormulaEditor(op.formula)); if (op.id) { cat = user->GetCategory(op.category); description = op.description; UNESCAPE_CHARS(description); setItem(line, DESCRIPTION, new QTableWidgetItem(description)); item = new QTableWidgetItem(); setItem(line, OP_DATE, new QTableWidgetItem(v.sprintf("%02d/%02d/%d", op.day+1, month+1, year))); if (op.amount < 0) setItem(line, DEBIT, new QTableWidgetItem(v.sprintf("%.2lf", -op.amount))); else setItem(line, CREDIT, new QTableWidgetItem(v.sprintf("%.2lf", op.amount))); if (!op.meta) setItem(line, ACCOUNT, new QTableWidgetItem(user->GetAccountName(op.account))); if (!fix && !op.meta) setItem(line, CATEGORY, new QTableWidgetItem(cat.name)); checkBox = new QCheckBox(); checkBox->setTristate(false); setCellWidget(line, CHECKED, checkBox); // SetCellRenderer(line, OP_DELETE, new wxGridCellBoolRenderer ()); // SetCellEditor(line, OP_DELETE, new wxGridCellBoolEditor ()); if (op.meta && !op.amount) { amount = _kiss->MetaPositiveAmount(op.id); setItem(line, DEBIT, new QTableWidgetItem(v.sprintf("%.2lf", amount))); setItem(line, CREDIT, new QTableWidgetItem(v.sprintf("%.2lf", amount))); } if (op.category) color = cat.backcolor; else color = view::OWN_GREEN; if (op.checked) { r = ((color.red()*1.5) >= 0xFF) ? 0xFF : color.red()*1.5 ; g = ((color.green()*1.5) >= 0xFF) ? 0xFF : color.green()*1.5 ; b = ((color.blue()*1.5) >= 0xFF) ? 0xFF : color.blue()*1.5 ; color.setRgb(r, g, b, color.alpha()); checkBox->setCheckState(Qt::Checked); } SET_ROW_COLOR(line, color, cat.forecolor); if (op.category && cat.font.length()) { font = user->GetCategoryFont(cat.id); SET_ROW_FONT(line, font); } if (!_loadOperations) { if (op.meta) resizeColumnToContents(TREE); resizeColumnToContents(CATEGORY); resizeColumnToContents(ACCOUNT); } } else { if (curDate.month() == month && curDate.year() == year) { if (!fix) setItem(line, OP_DATE, new QTableWidgetItem(v.sprintf("%02d/%02d/%d", curDate.day(), month+1, year))); } if (fix) { SET_ROW_COLOR(line, view::OWN_YELLOW, Qt::black); } else { SET_ROW_COLOR(line, view::OWN_GREEN, Qt::black); } SET_READ_ONLY(this->item(line, CHECKED)); SET_READ_ONLY(this->item(line, OP_DELETE)); } this->item(line, OP_DATE)->setTextAlignment(Qt::AlignHCenter|Qt::AlignVCenter); this->item(line, DEBIT)->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter); this->item(line, CREDIT)->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter); this->item(line, OP_DELETE)->setTextAlignment(Qt::AlignHCenter|Qt::AlignVCenter); this->item(line, CHECKED)->setTextAlignment(Qt::AlignHCenter|Qt::AlignVCenter); if (op.id && op.meta) { // SetCellRenderer(line, TREE, new wxGridCellTreeButtonRenderer()); // SetCellEditor(line, TREE, new wxGridCellTreeButtonEditor()); SET_READ_ONLY(this->item(line, OP_DATE)); SET_READ_ONLY(this->item(line, CREDIT)); SET_READ_ONLY(this->item(line, DEBIT)); SET_READ_ONLY(this->item(line, CATEGORY)); SET_READ_ONLY(this->item(line, ACCOUNT)); } else SET_READ_ONLY(this->item(line, TREE)); resizeRowToContents(line); layout(); } void GridAccount::DeleteOperation(const Operation& op) { std::vector::iterator it = std::find(_operations->begin(), _operations->end(), op.id); if (it != _operations->end()) _operations->erase(it); } void GridAccount::InsertIntoGrid(Operation& op) { int i, a, start; User* user = _kiss->GetUser(); Operation parent; // No previous fix operations if (op.fix_cost && !_displayedOperations[1].id) i = 1; else { if (op.parent) start = GetDisplayedRow(op.parent); else start = 0; for(i=start; i<(int)_displayedOperations.size(); i++) { if (!_displayedOperations[i].id) continue; if (_displayedOperations[i].parent) continue; if ((_displayedOperations)[i].fix_cost && !op.fix_cost) continue; if (!(_displayedOperations)[i].fix_cost && op.fix_cost) break; if (user->_preferences["operation_order"] == "ASC") { if ((_displayedOperations)[i].day > op.day) break; } else { if ((_displayedOperations)[i].day < op.day) break; } } if (op.parent) { parent = GetOperation(op.parent); if ((i-start) > (int)(parent.childs.size())) i = start + parent.childs.size(); if (parent.day >= op.day) i = start + 1; } else if (i == (int)_displayedOperations.size() || i == _fixCosts) i--; else if (!(_displayedOperations)[i].fix_cost && op.fix_cost) i --; } for (a=0; a<(int)_operations->size(); a++) { if ((*_operations)[a].fix_cost && !op.fix_cost) continue; if (!(*_operations)[a].fix_cost && op.fix_cost) { a--; break; } if ((*_operations)[a].day > op.day) { a--; break; } } if (a < 0) a = 0; _operations->insert(_operations->begin()+a, op); InsertOperationWithWeek(user, (*_operations)[a], i, op.fix_cost, _curMonth, _curYear); } int GridAccount::RemoveMeta(Operation op, int line, bool removeRoot, bool deleteOp) { // std::vector::iterator it, it2; // wxGridCellTreeButtonRenderer* treeRenderer; // int i, deletedOperations = 0; // Operation op2; // treeRenderer = (wxGridCellTreeButtonRenderer*) GetCellRenderer(line, TREE); // for(i=0; i<(int)op.childs.size(); i++) // { // op2 = GetOperation(op.childs[i]); // if (op2.meta) // RemoveMeta(op2, line+1, true, deleteOp); // else // { // if (treeRenderer->IsCollapsed()) // { // DeleteRows(line+1, 1); // deletedOperations++; // if (op2.fix_cost) _fixCosts--; // _displayedOperations.erase(_displayedOperations.begin()+line+1); // } // if (deleteOp) // { // DeleteOperation(op2); // if (_databaseSynchronization) // _kiss->DeleteOperation(op2); // } // } // } // op.childs.clear(); // if (removeRoot) // { // DeleteRows(line, 1); // _displayedOperations.erase(_displayedOperations.begin()+line); // if (op.fix_cost) _fixCosts--; // if (deleteOp) // { // DeleteOperation(op); // if (_databaseSynchronization) // _kiss->DeleteOperation(op); // } // deletedOperations++; // } // treeRenderer->DecRef(); // return deletedOperations; return 0; } void GridAccount::CheckMeta(Operation& op, int line, bool check) { // std::vector::iterator it, it2; // wxGridCellTreeButtonRenderer* treeRenderer; // int i; // Operation op2; // wxColour color ; // unsigned char r, g, b; // User* user = _kiss->GetUser(); // treeRenderer = (wxGridCellTreeButtonRenderer*) GetCellRenderer(line, TREE); // for(i=0; i<(int)op.childs.size(); i++) // { // op2 = GetOperation(op.childs[i]); // op2.checked = check; // UpdateOperation(op2); // if (op2.meta) // CheckMeta(op2, line+1, check); // if (treeRenderer->IsCollapsed()) // { // SetCellValue(line+i+1, CHECKED, check ? wxT("1") : wxT("0")); // color = user->GetCategory(op2.category).backcolor; // if (check) // { // r = ((color.Red()*1.5) >= 0xFF) ? 0xFF : color.Red()*1.5 ; // g = ((color.Green()*1.5) >= 0xFF) ? 0xFF : color.Green()*1.5 ; // b = ((color.Blue()*1.5) >= 0xFF) ? 0xFF : color.Blue()*1.5 ; // color.Set(r, g, b, color.Alpha()); // } // SET_ROW_COLOR(line+i+1, color, user->GetCategory(op2.category).forecolor); // } // } // treeRenderer->DecRef(); } void GridAccount::OnOperationModified() { // User* user = _kiss->GetUser(); // int row = event.GetRow(); // int col = event.GetCol(); // Operation new_op, cur_op, op_tmp, op_tmp2; // int op_complete = 6, i, last_day; // wxString value ; // wxDateTime date; // bool need_insertion = false; // static bool inModification = false ; // wxColour color ; // unsigned char r, g, b; // wxGridCellTreeButtonRenderer* treeRenderer; // std::vector::iterator it; // Operation op, op2; // double amount; // wxFont font; // Category cat ; // // Avoid recursives calls // if (inModification || _loadOperations) return; // inModification = true ; // if (col == TREE) // { // treeRenderer = (wxGridCellTreeButtonRenderer*) GetCellRenderer(row, col); // op = _displayedOperations[row]; // if (!treeRenderer->IsCollapsed()) // { // for (i=1, it=op.childs.begin(); it!=op.childs.end(); it++, i++) // { // op2 = GetOperation(*it); // InsertOperationWithWeek(user, op2, row+i, op2.fix_cost, op2.month, op2.year); // } // } // else // { // RemoveMeta(op, row, false, false); // } // treeRenderer->DecRef(); // ComputeWeeks(); // inModification = false; // _parent->Fit(); // return; // } // if (col == DEBIT) // SetCellValue(row, CREDIT, ""); // else if (col == CREDIT) // SetCellValue(row, DEBIT, ""); // value = GetCellValue(row, DESCRIPTION); // if (value) // { // new_op.description = value; // op_complete--; // } // value = GetCellValue(row, OP_DATE); // if (value) // { // date.ParseFormat(value, wxT("%d/%m/%Y")); // new_op.day = date.GetDay()-1; // new_op.month = date.GetMonth(); // new_op.year = date.GetYear(); // op_complete--; // } // if (col == DESCRIPTION && // (!GetCellValue(row, CATEGORY) || // !GetCellValue(row, ACCOUNT))) // { // new_op.fix_cost = (row <= _fixCosts); // if (_kiss->SearchPreviousOperation(&op_tmp, new_op, _curMonth, _curYear, _canAddOperation)) // { // if (!GetCellValue(row, CATEGORY)) // { // new_op.category = op_tmp.category; // SetCellValue(row, CATEGORY, wxGetTranslation(user->GetCategoryName(new_op.category))); // op_complete--; // } // if (!GetCellValue(row, ACCOUNT)) // { // new_op.account = op_tmp.account; // SetCellValue(row, ACCOUNT, user->GetAccountName(new_op.account)); // op_complete--; // } // col = CATEGORY; // new_op.fix_cost = (new_op.category == user->GetCategoryId(wxT("Fix"))); // } // } // value = GetCellValue(row, DEBIT); // if (value) // { // value.ToDouble(&new_op.amount); // if (new_op.amount < 0) // { // new_op.amount *= -1.0; // SetCellValue(row, DEBIT, wxString::Format(wxT("%.2lf"), new_op.amount)); // } // if (new_op.amount != 0.0) new_op.amount *= -1.0; // op_complete--; // wxGridCellFormulaEditor* pEditor = (wxGridCellFormulaEditor*) GetCellEditor(row, DEBIT); // new_op.formula = pEditor->GetFormula(); // pEditor->DecRef(); // } // value = GetCellValue(row, CREDIT); // if (value) // { // value.ToDouble(&new_op.amount); // if (new_op.amount < 0) // { // new_op.amount *= -1.0; // SetCellValue(row, CREDIT, wxString::Format(wxT("%.2lf"), new_op.amount)); // } // op_complete--; // wxGridCellFormulaEditor* pEditor = (wxGridCellFormulaEditor*) GetCellEditor(row, CREDIT); // new_op.formula = pEditor->GetFormula(); // pEditor->DecRef(); // } // value = GetCellValue(row, CATEGORY); // if (value) // { // new_op.category = user->GetCategoryId(value); // op_complete--; // } // value = GetCellValue(row, ACCOUNT); // if (value) // { // new_op.account = user->GetAccountId(value); // op_complete--; // } // value = GetCellValue(row, CHECKED); // if (value && value != wxT("0")) // new_op.checked = true; // else // new_op.checked = false; // op_complete--; // cur_op = (_displayedOperations)[row] ; // if (col == CHECKED || col == CATEGORY) // { // color = user->GetCategory(new_op.category).backcolor; // if (new_op.checked) // { // r = ((color.Red()*1.5) >= 0xFF) ? 0xFF : color.Red()*1.5 ; // g = ((color.Green()*1.5) >= 0xFF) ? 0xFF : color.Green()*1.5 ; // b = ((color.Blue()*1.5) >= 0xFF) ? 0xFF : color.Blue()*1.5 ; // color.Set(r, g, b, color.Alpha()); // } // SET_ROW_COLOR(row, color, user->GetCategory(new_op.category).forecolor); // SET_ROW_FONT(row, user->GetCategoryFont(new_op.category)); // if (col == CHECKED) // { // cur_op.checked = new_op.checked; // UpdateOperation(cur_op); // inModification = false; // if (cur_op.meta) // CheckMeta(cur_op, row, cur_op.checked); // else // { // if (cur_op.parent) // { // op2 = GetOperation(cur_op.parent); // UpdateMeta(op2); // int row2 = GetDisplayedRow(op2.id); // SetCellValue(row2, CHECKED, op2.checked ? wxT("1") : wxT("0")); // color = user->GetCategory(op2.category).backcolor; // if (op2.checked) // { // r = ((color.Red()*1.5) >= 0xFF) ? 0xFF : color.Red()*1.5 ; // g = ((color.Green()*1.5) >= 0xFF) ? 0xFF : color.Green()*1.5 ; // b = ((color.Blue()*1.5) >= 0xFF) ? 0xFF : color.Blue()*1.5 ; // color.Set(r, g, b, color.Alpha()); // } // SET_ROW_COLOR(row2, color, user->GetCategory(op2.category).forecolor); // } // } // event.Skip(); // return; // } // } // if (col == OP_DELETE) // { // wxMessageDialog dialog(this, _("Are you sure want to delete : \n")+new_op.description, wxT("KissCount"), wxYES_NO); // if (dialog.ShowModal() == wxID_NO) // { // SetCellValue(row, col, wxT("0")); // inModification = false; // return; // } // } // // Modify a fix operation // if (row < _fixCosts || !_canAddOperation) // { // if (col == OP_DELETE) // { // if (cur_op.parent) // user->UnGroup(_displayedOperations[row]); // if (cur_op.meta) // RemoveMeta(_displayedOperations[row], row, true, true); // else // { // if (cur_op.parent) // { // op_tmp = GetOperation(cur_op.parent); // for (int a=0; a<(int)op_tmp.childs.size(); a++) // if (op_tmp.childs[a] == op.id) // { // op2.childs.erase(op_tmp.childs.begin()+a); // break; // } // } // DeleteRows(row, 1); // DeleteOperation(cur_op); // if (_databaseSynchronization) // _kiss->DeleteOperation(cur_op); // _displayedOperations.erase(_displayedOperations.begin()+row); // if (cur_op.parent && op_tmp.childs.size() < 2) // { // if (op_tmp.childs.size() == 1) // { // op_tmp2 = GetOperation(op_tmp.childs[0]); // op_tmp2.parent = ""; // UpdateOperation(op_tmp2); // row = GetDisplayedRow(op_tmp2.id); // _displayedOperations[row] = op_tmp2; // } // row = GetDisplayedRow(cur_op.parent); // DeleteRows(row, 1); // DeleteOperation(op_tmp); // if (_databaseSynchronization) // _kiss->DeleteOperation(op_tmp); // _displayedOperations.erase(_displayedOperations.begin()+row); // _fixCosts--; // } // _fixCosts--; // ComputeWeeks(); // } // inModification = false ; // event.Skip(); // return ; // } // new_op.id = cur_op.id; // new_op.fix_cost = true; // new_op.transfert = cur_op.transfert; // new_op.meta = cur_op.meta; // new_op.parent = cur_op.parent; // new_op.childs = cur_op.childs; // new_op._virtual = cur_op._virtual; // if (cur_op.day != new_op.day) // { // need_insertion = true; // DeleteRows(row, 1); // DeleteOperation(cur_op); // _displayedOperations.erase(_displayedOperations.begin()+row); // _fixCosts--; // } // else // { // UpdateOperation(new_op); // (_displayedOperations)[row] = new_op; // } // } // // Add a fixCost // else if (row == _fixCosts) // { // if (op_complete) { // inModification = false ; // return ; // } // need_insertion = true; // new_op.fix_cost = true; // new_op.meta = false; // new_op._virtual = false; // for(i=0; iAddOperation(new_op); // } // // Modify an operation // else if (row < (int)(_displayedOperations.size()-1)) // { // new_op.id = cur_op.id; // new_op.fix_cost = false; // new_op.transfert = cur_op.transfert; // new_op.meta = cur_op.meta; // new_op.parent = cur_op.parent; // new_op.childs = cur_op.childs; // new_op._virtual = cur_op._virtual; // if (col == OP_DELETE) // { // if (cur_op.parent) // user->UnGroup(_displayedOperations[row]); // if (cur_op.meta) // RemoveMeta(_displayedOperations[row], row, true, true); // else // { // if (cur_op.parent) // { // op_tmp = GetOperation(cur_op.parent); // for (int a=0; a<(int)op_tmp.childs.size(); a++) // if (op_tmp.childs[a] == op.id) // { // op2.childs.erase(op_tmp.childs.begin()+a); // break; // } // } // DeleteRows(row, 1); // DeleteOperation(cur_op); // _displayedOperations.erase(_displayedOperations.begin()+row); // if (_databaseSynchronization) // _kiss->DeleteOperation(cur_op); // if (cur_op.parent && op_tmp.childs.size() <= 1) // { // if (op_tmp.childs.size() == 1) // { // op_tmp2 = GetOperation(op_tmp.childs[0]); // op_tmp2.parent = ""; // UpdateOperation(op_tmp2); // row = GetDisplayedRow(op_tmp2.id); // _displayedOperations[row] = op_tmp2; // } // row = GetDisplayedRow(cur_op.parent); // DeleteRows(row, 1); // DeleteOperation(op_tmp); // if (_databaseSynchronization) // _kiss->DeleteOperation(op_tmp); // _displayedOperations.erase(_displayedOperations.begin()+row); // } // ComputeWeeks(); // } // inModification = false ; // event.Skip(); // return ; // } // if (cur_op.day != new_op.day) // { // need_insertion = true; // DeleteRows(row, 1); // DeleteOperation(cur_op); // _displayedOperations.erase(_displayedOperations.begin()+row); // } // else // { // UpdateOperation(new_op); // (_displayedOperations)[row] = new_op; // } // } // // Add an operation // else // { // if (op_complete) { // inModification = false ; // return ; // } // need_insertion = true; // new_op.fix_cost = false; // new_op.meta = false; // new_op._virtual = false; // for(i=0; iAddOperation(new_op); // } // if (user->GetAccount(new_op.account).blocked && new_op.amount < 0) // wxMessageBox(_("You made a debit on a blocked account"), _("Warning"), wxICON_WARNING | wxOK); // if (need_insertion) // { // InsertIntoGrid(new_op); // UpdateOperation(new_op); // } // if (new_op.parent) // { // row = GetDisplayedRow(new_op.parent); // new_op = _displayedOperations[row]; // last_day = new_op.day; // UpdateMeta(new_op); // _displayedOperations[row] = new_op; // cat = user->GetCategory(new_op.category); // if (new_op.category) // color = cat.backcolor; // else // color = view::OWN_GREEN; // if (new_op.checked) // { // r = ((color.Red()*1.5) >= 0xFF) ? 0xFF : color.Red()*1.5 ; // g = ((color.Green()*1.5) >= 0xFF) ? 0xFF : color.Green()*1.5 ; // b = ((color.Blue()*1.5) >= 0xFF) ? 0xFF : color.Blue()*1.5 ; // color.Set(r, g, b, color.Alpha()); // SetCellValue(row, CHECKED, wxT("1")); // } // else // SetCellValue(row, CHECKED, wxT("0")); // SET_ROW_COLOR(row, color, cat.forecolor); // if (new_op.category && cat.font) // { // font = user->GetCategoryFont(cat.id); // SET_ROW_FONT(row, font); // } // SetCellValue(row, OP_DATE, wxString::Format(wxT("%02d/%02d/%d"), new_op.day+1, _curMonth+1, _curYear)); // if (!_displayedOperations[row].amount) // { // amount = _kiss->MetaPositiveAmount(new_op.id); // SetCellValue(row, DEBIT, wxString::Format(wxT("%.2lf"), amount)); // SetCellValue(row, CREDIT, wxString::Format(wxT("%.2lf"), amount)); // } // else // { // if (_displayedOperations[row].amount < 0) // { // SetCellValue(row, DEBIT, wxString::Format(wxT("%.2lf"), -new_op.amount)); // SetCellValue(row, CREDIT, ""); // } // else // { // SetCellValue(row, DEBIT, ""); // SetCellValue(row, CREDIT, wxString::Format(wxT("%.2lf"), new_op.amount)); // } // } // // Move updated meta // if ((int)new_op.day != last_day) // { // int i; // RemoveMeta(new_op, row, true, false); // InsertIntoGrid(new_op); // row = GetDisplayedRow(new_op.id); // for (i=1, it=new_op.childs.begin(); it!=new_op.childs.end(); it++, i++) // { // op2 = GetOperation(*it); // InsertOperationWithWeek(user, op2, row+i, op2.fix_cost, _curMonth, _curYear); // } // treeRenderer = (wxGridCellTreeButtonRenderer*) GetCellRenderer(row, 0); // treeRenderer->Invert(); // treeRenderer->DecRef(); // } // } // inModification = false ; // event.Skip(); } void GridAccount::UpdateMeta(Operation& meta) { std::vector::iterator it; Operation op ; int category = 0; bool updateCat = false ; if (!meta.childs.size()) return ; meta.category = 0; meta.checked = true; meta.amount = 0; for(it=meta.childs.begin(); it!=meta.childs.end(); it++) { op = GetOperation(*it); if (op.year <= meta.year && op.month <= meta.month && op.day < meta.day) { meta.year = op.year; meta.month = op.month; meta.day = op.day; } meta.checked &= op.checked; if (!meta.description.length() && op.description.length()) meta.description = op.description; if (!category) { if (op.category) { category = op.category; updateCat = true; } } else { if (op.category && op.category != category) updateCat = false; } op.parent = meta.id; } if (updateCat) meta.category = category; meta.amount = _kiss->MetaAmount(meta.id); UpdateOperation(meta); } void GridAccount::GetSelectedOperations(std::vector* rows) { // std::vector::iterator it; // rows->clear(); // // Blocks. We always expect btl and bbr to have the same size, since their // // entries are supposed to correspond. // const wxGridCellCoordsArray& btl(GetSelectionBlockTopLeft()); // const wxGridCellCoordsArray& bbr(GetSelectionBlockBottomRight()); // size_t blockCount = btl.size(); // if (blockCount == bbr.size()) // { // for (size_t i = 0; i < blockCount; ++i) // { // const wxGridCellCoords& tl = btl[i]; // const wxGridCellCoords& br = bbr[i]; // for (int row = tl.GetRow(); row <= br.GetRow(); ++row) // { // it = std::find(rows->begin(), rows->end(), row); // if (it != rows->end() || !row) continue; // rows->push_back(row); // } // } // } // // Singly selected cells. // const wxGridCellCoordsArray& cells(GetSelectedCells()); // for (size_t i = 0; i < cells.size(); ++i) // { // int row = cells[i].GetRow(); // if (!row) continue; // it = std::find(rows->begin(), rows->end(), row); // if (it != rows->end()) continue; // rows->push_back(row); // } } void GridAccount::Group() { // std::vector selected, rows; // std::vector::iterator it; // std::vector ops; // std::vector::iterator it2; // std::vector::iterator it3; // wxString parent = ""; // Operation op, op2; // int fix = -1, i, a, row; // GetSelectedOperations(&selected); // for (size_t i = 0; i < selected.size(); ++i) // { // op = _displayedOperations[selected[i]] ; // if (op.id) // { // if (!parent) // { // if (op.parent) // { // parent = op.parent; // continue; // } // else if(op.meta) // parent = op.id; // } // else // { // if ((parent && op.parent && op.parent != parent)) // { // wxMessageBox(_("Cannot group these operations"), _("Error"), wxICON_ERROR | wxOK); // return ; // } // } // if (fix != -1 && ((!fix && op.fix_cost) || (fix && !op.fix_cost))) // { // wxMessageBox(_("Cannot group these operations"), _("Error"), wxICON_ERROR | wxOK); // return ; // } // if (fix == -1) // fix = op.fix_cost ? 1 : 0; // ops.push_back(op); // rows.push_back(selected[i]); // } // } // if (!ops.size()) return; // if (!parent) // { // if (rows.size() < 2) return; // op.parent = ""; // op.day = ops[0].day; // op.month = ops[0].month; // op.year = ops[0].year; // op.amount = 0; // op.description = ""; // op.category = ""; // op.fix_cost = fix; // op.account = ""; // op.checked = false; // op.transfert = ""; // op.formula = ""; // op.meta = true; // op.childs.clear(); // op.id = _kiss->AddOperation(op); // } // else // { // if (rows.size() < 1) return; // row = GetDisplayedRow(parent); // op = _displayedOperations[row]; // //if (op.id) return; // } // std::sort(rows.begin(), rows.end()); // for(i=0; i<(int)rows.size(); i++) // { // if (ops[i].meta) // RemoveMeta(ops[i], rows[i], true, false); // else // { // if (ops[i].fix_cost) _fixCosts--; // DeleteRows(rows[i], 1); // _displayedOperations.erase(_displayedOperations.begin()+rows[i]); // for(a=i+1; a<(int)rows.size(); a++) // if (rows[a] >= rows[i]) // rows[a]--; // } // } // for(it2=ops.begin(); it2!=ops.end(); it2++) // { // if (it2->id == parent) continue; // for (i=0, it3=op.childs.begin(); it3!=op.childs.end(); it3++, i++) // { // op2 = GetOperation(*it3); // if (*it3 == it2->id || // op2.day > it2->day) // break; // } // if (i) i--; // if (it3 == op.childs.end()) // op.childs.push_back(it2->id); // else if (*it3 == it2->id) // continue; // else // op.childs.insert(op.childs.begin()+i, it2->id); // it2->parent = op.id; // UpdateOperation(*it2); // } // UpdateMeta(op); // InsertIntoGrid(op); // UpdateOperation(op); } void GridAccount::UnGroup() { // std::vector rows, selected; // std::vector::iterator it; // std::vector ops; // std::vector ops2; // std::vector::iterator it2; // std::vector::iterator it3; // wxString parent = ""; // Operation op, op2; // int fix = -1, i, a, line; // GetSelectedOperations(&selected); // for (size_t i = 0; i < selected.size(); ++i) // { // op = _displayedOperations[selected[i]] ; // if (op.id) // { // if ((parent && op.parent != parent) // || (!op.parent && !op.meta)) // { // wxMessageBox(_("Cannot ungroup these operations"), _("Error"), wxICON_ERROR | wxOK); // return ; // } // if (fix != -1 && ((!fix && op.fix_cost) || (fix && !op.fix_cost))) // { // wxMessageBox(_("Cannot ungroup these operations"), _("Error"), wxICON_ERROR | wxOK); // return ; // } // if (fix == -1) // fix = op.fix_cost ? 1 : 0; // if(op.meta) // { // parent = op.id; // continue; // } // if (!parent && op.parent) // parent = op.parent; // ops.push_back(op); // rows.push_back(selected[i]); // } // } // if (!ops.size() && !parent) return; // removeLastGroup: // // Only one meta is selected // if (!ops.size()) // { // line = GetDisplayedRow(parent); // op = _displayedOperations[line]; // ops2 = op.childs; // RemoveMeta(op, line, true, false); // for(i=0; i<(int)ops2.size(); i++) // { // op2 = GetOperation(ops2[i]); // op2.parent = ""; // UpdateOperation(op2); // InsertIntoGrid(op2); // } // _kiss->DeleteOperation(op); // DeleteOperation(op); // } // else // { // if (!parent) return; // line = GetDisplayedRow(parent); // op2 = _displayedOperations[line]; // for(i=0; i<(int)ops.size(); i++) // { // op = ops[i]; // op.parent = 0; // UpdateOperation(op); // line = GetDisplayedRow(op.id); // DeleteRows(line, 1); // _displayedOperations.erase(_displayedOperations.begin()+line); // InsertIntoGrid(GetOperation(op.id)); // if (op.fix_cost) _fixCosts--; // for (a=0; a<(int)op2.childs.size(); a++) // if (op2.childs[a] == op.id) // { // op2.childs.erase(op2.childs.begin()+a); // break; // } // UpdateMeta(op2); // UpdateOperation(op2); // } // line = GetDisplayedRow(parent); // _displayedOperations[line] = op2; // if (op2.childs.size() < 2) // { // ops.clear(); // // Sorry ... // goto removeLastGroup; // } // UpdateOperation(op2); // } // ComputeWeeks(); } void GridAccount::MassUpdate(std::vector& rows, updateOperationFunc func, void** params) { // int i, b; // std::vector::iterator it; // Operation op, op2; // _parent->Disable(); // _parent->SetCursor(wxCursor(wxCURSOR_WAIT)); // _parent->Update(); // if (rows.size()) // { // for(i=0; i<(int)rows.size(); i++) // { // op = _displayedOperations[rows[i]]; // func (&op, params); // UpdateOperation(op); // 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); // } // } // ClearGrid(); // LoadOperations(_operations, 0, 0); // Layout(); // _parent->Enable(); // _parent->SetCursor(wxNullCursor); }