#include "AccountPanel.h" enum {DESCRIPTION, DATE, DEBIT, CREDIT, CATEGORY, ACCOUNT, DELETE, CHECKED, NUMBER_COLS_OPS}; enum {ACCOUNT_NUMBER, ACCOUNT_NAME, ACCOUNT_INIT, ACCOUNT_CUR, ACCOUNT_FINAL, NUMBER_COLS_ACCOUNTS}; enum {CUR_CREDIT, CUR_DEBIT, TOTAL_CREDIT, TOTAL_DEBIT, REMAINS, STATS_ROW, CATS_STATS}; enum {CALENDAR_TREE_ID=10, OPS_GRID_ID, ACCOUNTS_GRID_ID, MENU_GENERATE_ID, MENU_DELETE_ID}; static wxString colsName[] = {_("Description"), _("Date"), _("Debit"), _("Credit"), _("Category"), _("Account"), _(""), _("")}; BEGIN_EVENT_TABLE(AccountPanel, wxPanel) EVT_GRID_CMD_CELL_CHANGE(OPS_GRID_ID, AccountPanel::OnOperationModified) EVT_GRID_CMD_CELL_CHANGE(ACCOUNTS_GRID_ID, AccountPanel::OnAccountModified) EVT_TREE_ITEM_RIGHT_CLICK(CALENDAR_TREE_ID, AccountPanel::OnTreeRightClick) EVT_TREE_SEL_CHANGED(CALENDAR_TREE_ID, AccountPanel::OnTreeChange) EVT_TREE_KEY_DOWN(CALENDAR_TREE_ID, AccountPanel::OnTreeChange) EVT_MENU(MENU_GENERATE_ID, AccountPanel::OnMenuGenerate) EVT_MENU(MENU_DELETE_ID, AccountPanel::OnMenuDelete) EVT_SHOW(AccountPanel::OnShow) END_EVENT_TABLE() AccountPanel::AccountPanel(KissCount* kiss, wxUI *parent) : wxPanel(&(*parent)), _curMonth(-1), _curYear(-1), _kiss(kiss), _wxUI(parent), _tree(this, CALENDAR_TREE_ID, wxDefaultPosition, wxDefaultSize, wxTR_HIDE_ROOT) { wxBoxSizer *hbox = new wxBoxSizer(wxHORIZONTAL); wxBoxSizer *vbox = new wxBoxSizer(wxVERTICAL); wxBoxSizer *vbox2 = new wxBoxSizer(wxVERTICAL); wxChartPanel* chart ; int i ; DEFAULT_FONT(font); User* user = _kiss->GetUser(); std::vector::iterator accountIt; std::vector::iterator categoryIt; wxColour categoryColors[] = {wxColour(0x00, 0x45, 0x86), wxColour(0xFF, 0x3E, 0x0E), wxColour(0xFF, 0xD3, 0x20), wxColour(0x58, 0x9D, 0x1B), wxColour(0x7E, 0x00, 0x21), wxColour(0x83, 0xCC, 0xFF), wxColour(0x31, 0x40, 0x04), wxColour(0xB0, 0xCF, 0x00), wxColour(0x4B, 0x1F, 0x6F), wxColour(0xFF, 0x93, 0x0E), wxColour(0xC5, 0x00, 0x0D), wxColour(0x00, 0x84, 0xD1)}; wxBitmap bitmap(_(DELETE_ICON)); SetSizer(hbox); ColorScheme* colorScheme = new ColorScheme(categoryColors, WXSIZEOF(categoryColors)); _pie = new PiePlot(); _accounts = new wxString[user->GetAccountsNumber()]; for (i=0, accountIt = user->_accounts.begin(); accountIt != user->_accounts.end(); accountIt++, i++) _accounts[i] = accountIt->name; _categories = new wxString[user->GetCategoriesNumber()] ; for(i=0, categoryIt = user->_preferences._categories.begin(); categoryIt != user->_preferences._categories.end(); categoryIt++, i++) { _categories[i] = categoryIt->name ; _categoriesIndexes[categoryIt->name] = i; } _dataset = new CategorySimpleDataset(_categories, user->GetCategoriesNumber()); _categoriesValues = new double[user->GetCategoriesNumber()]; for(i=0; iGetCategoriesNumber(); i++) _categoriesValues[i] = 0.0; _dataset->AddSerie(_("Serie 1"), _categoriesValues, user->GetCategoriesNumber()); _dataset->SetRenderer(new CategoryRenderer(*colorScheme)); _pie->SetDataset(_dataset); _pie->SetColorScheme(colorScheme); _pie->SetLegend(new Legend(wxBOTTOM, wxCENTER)); _grid = new GridAccount(this, OPS_GRID_ID); _grid->CreateGrid(1, NUMBER_COLS_OPS); _grid->SetColLabelSize(0); _grid->SetRowLabelSize(0); _grid->CreateGrid(1, NUMBER_COLS_OPS); _grid->SetColSize (0, _grid->GetColSize(0)*3); _grid->SetDefaultCellFont(font); font.SetWeight(wxFONTWEIGHT_BOLD); for(i=0; iSetCellValue(0, i, colsName[i]); _grid->SetCellBackgroundColour(0, i, OWN_CYAN); _grid->SetCellFont(0, i, font); _grid->SetReadOnly(0, i, true); _grid->SetCellAlignment(0, i, wxALIGN_CENTRE, wxALIGN_CENTRE); } _grid->SetCellRenderer(0, DELETE, new wxGridCellBitmapRenderer(bitmap)); font.SetWeight(wxFONTWEIGHT_NORMAL); _accountsGrid = new wxGrid(this, ACCOUNTS_GRID_ID); _accountsGrid->CreateGrid(0, NUMBER_COLS_ACCOUNTS); _accountsGrid->SetRowLabelSize(0); _accountsGrid->SetDefaultCellFont(font); _accountsGrid->SetColLabelValue(ACCOUNT_NUMBER, _("Account number")); _accountsGrid->SetColLabelValue(ACCOUNT_NAME, _("Account name")); _accountsGrid->SetColLabelValue(ACCOUNT_INIT, _("Initial value")); _accountsGrid->SetColLabelValue(ACCOUNT_CUR, _("Current value")); _accountsGrid->SetColLabelValue(ACCOUNT_FINAL, _("Final value")); _accountsGrid->AutoSizeColumns(true); _statsGrid = new wxGrid(this, -1); chart = new wxChartPanel(this); chart->SetChart(new Chart(_pie, _("Cost repartition"))); chart->Fit(); chart->Layout(); chart->SetMinSize(// chart->GetSize() wxSize(200,250)); hbox->Add(&_tree, 0); vbox2->Add(_accountsGrid, 0); vbox2->Add(-1, 10); vbox2->Add(_grid, 0); hbox->Add(vbox2, 0); vbox->Add(_statsGrid, 0); vbox->Add(-1, 10); vbox->Add(chart, 0); hbox->Add(-1, 10); hbox->Add(vbox, 0); ChangeUser(); Fit(); SetMinSize(GetSize()); } AccountPanel::~AccountPanel() { delete[] _categoriesValues; delete[] _categories; delete[] _accounts; } void AccountPanel::InitStatsGrid(User* user) { int i; DEFAULT_FONT(font); if (!_statsGrid->GetNumberRows()) { _statsGrid->CreateGrid(user->GetCategoriesNumber()+6, 2); _statsGrid->SetColLabelSize(0); _statsGrid->SetRowLabelSize(0); _statsGrid->EnableEditing(false); } else { _statsGrid->DeleteRows(0, _statsGrid->GetNumberRows()); _statsGrid->InsertRows(0, user->GetCategoriesNumber()+6); } _statsGrid->SetDefaultCellFont(font); _statsGrid->SetCellValue(TOTAL_CREDIT, 0, _("Total Credit")); _statsGrid->SetCellValue(TOTAL_DEBIT, 0, _("Total Debit")); _statsGrid->AutoSizeColumn(0, false); for(i=0; iGetCategoriesNumber(); i++) { _statsGrid->SetCellValue(CATS_STATS+i, 0, _categories[i]); _statsGrid->SetCellAlignment(CATS_STATS+i, 1, wxALIGN_RIGHT, wxALIGN_CENTRE); } font.SetWeight(wxFONTWEIGHT_BOLD); _statsGrid->SetCellFont(CUR_CREDIT, 0, font); _statsGrid->SetCellFont(CUR_DEBIT, 0, font); _statsGrid->SetCellFont(REMAINS, 0, font); _statsGrid->SetCellFont(REMAINS, 1, font); _statsGrid->SetCellValue(CUR_CREDIT, 0, _("Cur Credit")); _statsGrid->SetCellValue(CUR_DEBIT, 0, _("Cur Debit")); _statsGrid->SetCellValue(REMAINS, 0, _("Remains")); _statsGrid->SetCellAlignment(CUR_DEBIT, 1, wxALIGN_RIGHT, wxALIGN_CENTRE); _statsGrid->SetCellAlignment(CUR_CREDIT, 1, wxALIGN_RIGHT, wxALIGN_CENTRE); _statsGrid->SetCellAlignment(TOTAL_DEBIT, 1, wxALIGN_RIGHT, wxALIGN_CENTRE); _statsGrid->SetCellAlignment(TOTAL_CREDIT, 1, wxALIGN_RIGHT, wxALIGN_CENTRE); _statsGrid->SetCellAlignment(REMAINS, 1, wxALIGN_RIGHT, wxALIGN_CENTRE); } void AccountPanel::ChangeUser() { User* user = _kiss->GetUser(); int curYear = -1; std::map >* >::iterator it; wxDateTime curDate; wxTreeItemId rootNode, curNode; InitStatsGrid(user); _tree.DeleteAllItems(); rootNode = _tree.AddRoot(_("")); curDate.SetToCurrent(); for(it = user->_operations.begin(); it != user->_operations.end(); it++) { if ((int)it->first <= curDate.GetYear()) { curYear = it->first; curNode = _tree.AppendItem(rootNode, wxString::Format(wxT("%d"), it->first)); } else _tree.AppendItem(rootNode, wxString::Format(wxT("%d"), it->first)); } if (curYear != -1) { _tree.SelectItem(curNode, true); LoadYear(curYear); } } void AccountPanel::LoadYear(int year, bool showMonth) { User* user = _kiss->GetUser(); int curMonth = -1; wxDateTime curDate; wxTreeItemId parentNode, curMonthNode; std::map > ops ; std::vector::iterator it; if (user->_operations[year]) { if (showMonth) ShowMonth(-1, year); return; } _curYear = year ; _kiss->LoadYear(year); ops = _kiss->GetAllOperations(); curDate.SetToCurrent(); parentNode = _tree.GetSelection(); for (it = ops[year].begin(); it != ops[year].end(); it++) { if (curMonth == -1 || (year == curDate.GetYear() && *it <= curDate.GetMonth())) { curMonth = *it; curMonthNode = _tree.AppendItem(parentNode, months[*it]); } else _tree.AppendItem(parentNode, months[*it]); } _tree.Expand(parentNode); if (showMonth) { _tree.SelectItem(curMonthNode, true); ShowMonth(curMonth, year); } _wxUI->Layout(); } #define SET_ROW_COLOR(row, color) for(int i=0; iSetCellBackgroundColour(row, i, color);\ } void AccountPanel::ShowMonth(int month, int year) { std::vector operations; std::vector::iterator it; _fixCosts = 0; int curLine = 0; User* user = _kiss->GetUser(); DEFAULT_FONT(font); std::vector::iterator categoryIt; std::map >::iterator monthIt; wxDateTime curDate; curDate.SetToCurrent(); if (month == -1) { // Near month if (year == curDate.GetYear()) { for (monthIt = user->_operations[year]->begin(); monthIt != user->_operations[year]->end(); monthIt++) { if ((int)monthIt->first <= curDate.GetMonth()) { month = monthIt->first; } } } // First month if (month == -1) { monthIt = user->_operations[year]->begin(); month = monthIt->first; } } _curYear = year; _curMonth = month; _wxUI->SetTitle(user->_name + _(" - ") + months[month] + _(" ") + wxString::Format(wxT("%d"), year)); if (_grid->GetNumberRows() > 1) _grid->DeleteRows(1, _grid->GetNumberRows()-1); // Operations are ordered _curOperations = &((*user->_operations[year])[month]); it = _curOperations->begin(); for (;it != _curOperations->end() && it->fix_cost; it++) InsertOperation(user, &(*it), ++curLine, true); InsertOperation(user, NULL, ++curLine, true); _grid->_fixCosts = _fixCosts--; for (; it != _curOperations->end(); it++) InsertOperation(user, &(*it), ++curLine, false); InsertOperation(user, NULL, ++curLine, false); _grid->AutoSizeColumn(CATEGORY, false); _grid->AutoSizeColumn(DATE, false); _grid->AutoSizeColumn(ACCOUNT, false); _grid->AutoSizeColumn(DELETE, false); _grid->AutoSizeColumn(CHECKED, false); InitAccountsGrid(user, month, year); UpdateStats(); Fit(); SetMinSize(GetSize()); } void AccountPanel::InsertOperation(User* user, operation* op, int line, bool fix) { std::vector::iterator it; int curLine, curWeek, week, i; int r, g, b; wxColour color; if (!op && !user->_accounts.size()) return; _grid->InsertRows(line, 1); _grid->SetCellEditor(line, DEBIT, new wxGridCellFloatEditor(-1, 2)); _grid->SetCellEditor(line, CREDIT, new wxGridCellFloatEditor(-1, 2)); wxGridCellChoiceEditor* accountEditor = new wxGridCellChoiceEditor(user->GetAccountsNumber(), _accounts, false); _grid->SetCellEditor(line, ACCOUNT, accountEditor); wxGridCellChoiceEditor* categoryEditor = new wxGridCellChoiceEditor(user->GetCategoriesNumber()-1, _categories+1, false); _grid->SetCellEditor(line, CATEGORY, categoryEditor); if (fix) { _fixCosts++; _grid->SetCellValue(line, CATEGORY, _("Fixe")); _grid->SetReadOnly(line, CATEGORY); } if (op) { _grid->SetCellEditor(line, DATE, new CalendarEditor(op->day+1, op->month, op->year)); _grid->SetCellValue(line, DESCRIPTION, op->description); _grid->SetCellValue(line, DATE, wxString::Format(wxT("%02d/%02d/%d"), op->day+1, op->month+1, op->year)); if (op->amount < 0) _grid->SetCellValue(line, DEBIT, wxString::Format(wxT("%.2lf"), -op->amount)); else _grid->SetCellValue(line, CREDIT, wxString::Format(wxT("%.2lf"), op->amount)); _grid->SetCellValue(line, ACCOUNT, user->GetAccountName(op->account)); if (!fix) _grid->SetCellValue(line, CATEGORY, user->GetCategoryName(op->category)); _grid->SetCellRenderer(line, DELETE, new wxGridCellBoolRenderer ()); _grid->SetCellEditor(line, DELETE, new wxGridCellBoolEditor ()); _grid->SetCellRenderer(line, CHECKED, new wxGridCellBoolRenderer ()); _grid->SetCellEditor(line, CHECKED, new wxGridCellBoolEditor ()); color = user->GetCategory(op->category).color; 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.Set(r, g, b, color.Alpha()); _grid->SetCellValue(line, CHECKED, _("1")); } SET_ROW_COLOR(line, color); } else { _grid->SetCellEditor(line, DATE, new CalendarEditor(1, _curMonth, _curYear)); if (fix) SET_ROW_COLOR(line, OWN_YELLOW) else SET_ROW_COLOR(line, OWN_GREEN); _grid->SetReadOnly(line, CHECKED, true); _grid->SetReadOnly(line, DELETE, true); } _grid->SetCellAlignment(line, DEBIT, wxALIGN_RIGHT, wxALIGN_CENTRE); _grid->SetCellAlignment(line, CREDIT, wxALIGN_RIGHT, wxALIGN_CENTRE); _grid->SetCellAlignment(line, DELETE, wxALIGN_CENTRE, wxALIGN_CENTRE); _grid->SetCellAlignment(line, CHECKED, wxALIGN_CENTRE, wxALIGN_CENTRE); if (op) { for (it = _curOperations->begin(), curLine=1; it->fix_cost && it != _curOperations->end(); it++, curLine++) ; if (it == _curOperations->end()) return; curLine++; curWeek = wxDateTime(it->day+1, (wxDateTime::Month)it->month, it->year).GetWeekOfMonth(); for (i=1, it++; it != _curOperations->end(); it++, curLine++) { week = wxDateTime(it->day+1, (wxDateTime::Month)it->month, it->year).GetWeekOfMonth(); if (week != curWeek) { _grid->SetWeek(i++, curLine); curWeek = week; } } } _wxUI->Layout(); } void AccountPanel::InitAccountsGrid(User* user, int month, int year) { std::vector::iterator it; int curLine = 0; double value; int i, a; DEFAULT_FONT(font); if (_accountsGrid->GetNumberRows()) _accountsGrid->DeleteRows(0, _accountsGrid->GetNumberRows()); font.SetWeight(wxFONTWEIGHT_BOLD); for (i=0, it = user->_accounts.begin(); it != user->_accounts.end(); i++, it++, curLine++) { _accountsGrid->AppendRows(); _accountsGrid->SetCellValue(curLine, ACCOUNT_NUMBER, it->number); _accountsGrid->SetCellValue(curLine, ACCOUNT_NAME, it->name); value = _kiss->GetAccountAmount(it->id, month, year); _accountsGrid->SetCellValue(curLine, ACCOUNT_INIT, wxString::Format(wxT("%.2lf"), value)); _accountsGrid->SetCellEditor(curLine, ACCOUNT_INIT, new wxGridCellFloatEditor(-1, 2)); for (a=0; aSetReadOnly(curLine, a, a != ACCOUNT_INIT); _accountsGrid->SetCellFont(curLine, ACCOUNT_CUR, font); _accountsInitValues[it->id] = value; _accountsGrid->SetCellAlignment(curLine, ACCOUNT_INIT, wxALIGN_RIGHT, wxALIGN_CENTRE); _accountsGrid->SetCellAlignment(curLine, ACCOUNT_CUR, wxALIGN_RIGHT, wxALIGN_CENTRE); _accountsGrid->SetCellAlignment(curLine, ACCOUNT_FINAL, wxALIGN_RIGHT, wxALIGN_CENTRE); } _accountsGrid->AutoSizeColumns(true); } void AccountPanel::UpdateStats() { int i; User* user = _kiss->GetUser(); std::vector::iterator it; double curCredit, curDebit, totalCredit, totalDebit, remains, value; wxDateTime curDate; std::map curAccountAmount, finalAccountAmount; std::map::iterator doubleIt; std::map::iterator intIt; std::vector::iterator accountIt; curDate.SetToCurrent(); curCredit = curDebit = totalCredit = totalDebit = 0.0; for (i=0; iGetCategoriesNumber(); i++) _categoriesValues[i] = 0.0; for (doubleIt=_accountsInitValues.begin(); doubleIt!=_accountsInitValues.end(); doubleIt++) { curAccountAmount[doubleIt->first] = _accountsInitValues[doubleIt->first]; finalAccountAmount[doubleIt->first] = _accountsInitValues[doubleIt->first]; } for (it=_curOperations->begin(); it!=_curOperations->end(); it++) { if (it->amount > 0) { if (curDate.GetDay() >= it->day && curDate.GetMonth() >= (int)it->month && curDate.GetYear() >= (int)it->year) { curCredit += it->amount; curAccountAmount[it->account] += it->amount; } totalCredit += it->amount; finalAccountAmount[it->account] += it->amount; } else { _categoriesValues[_categoriesIndexes[user->GetCategoryName(it->category)]] += -it->amount ; if (curDate.GetDay() >= it->day && curDate.GetMonth() >= (int)it->month && curDate.GetYear() >= (int)it->year) { curDebit += -it->amount; curAccountAmount[it->account] += it->amount; } totalDebit += -it->amount; finalAccountAmount[it->account] += it->amount; } } remains = totalCredit - totalDebit; _statsGrid->SetCellValue(CUR_CREDIT, 1, wxString::Format(wxT("%.2lf"), curCredit)); _statsGrid->SetCellValue(CUR_DEBIT, 1, wxString::Format(wxT("%.2lf"), curDebit)); _statsGrid->SetCellValue(TOTAL_CREDIT, 1, wxString::Format(wxT("%.2lf"), totalCredit)); _statsGrid->SetCellValue(TOTAL_DEBIT, 1, wxString::Format(wxT("%.2lf"), totalDebit)); _statsGrid->SetCellTextColour(REMAINS, 1, (remains >= 0) ? wxColor(0x00, 0xFF, 0x00) : wxColor(0xFF, 0x00, 0x00)); _statsGrid->SetCellValue(REMAINS, 1, wxString::Format(wxT("%.2lf"), remains)); for(i=0; iGetCategoriesNumber()+1; i++) _statsGrid->SetCellValue(CATS_STATS+i, 1, wxString::Format(wxT("%.2lf"), _categoriesValues[i])); for (i=0, accountIt=user->_accounts.begin(); accountIt!=user->_accounts.end(); accountIt++, i++) { value = curAccountAmount[accountIt->id]; _accountsGrid->SetCellValue(i, ACCOUNT_CUR, wxString::Format(wxT("%.2lf"), value)); _accountsGrid->SetCellTextColour(i, ACCOUNT_CUR, (value >= 0.0) ? wxColor(0x00, 0x00, 0x00) : wxColor(0xFF, 0x00, 0x00)); value = finalAccountAmount[accountIt->id]; _accountsGrid->SetCellValue(i, ACCOUNT_FINAL, wxString::Format(wxT("%.2lf"), value)); } _pie->DatasetChanged(_dataset); } void AccountPanel::OnOperationModified(wxGridEvent& event) { User* user = _kiss->GetUser(); int row = event.GetRow()-1; int col = event.GetCol(); struct operation new_op, cur_op; int op_complete = 6, i; wxString value ; wxDateTime date; bool need_insertion = false, fix_op=false; static bool inModification = false ; wxColour color ; unsigned char r, g, b; // Avoid recursives calls if (inModification) return; inModification = true ; if (event.GetCol() == DEBIT) _grid->SetCellValue(event.GetRow(), CREDIT, _("")); else if (event.GetCol() == CREDIT) _grid->SetCellValue(event.GetRow(), DEBIT, _("")); value = _grid->GetCellValue(event.GetRow(), DESCRIPTION); if (value != _("")) { new_op.description = value; op_complete--; } value = _grid->GetCellValue(event.GetRow(), DATE); if (value != _("")) { date.ParseFormat(value, _("%d/%m/%Y")); new_op.day = date.GetDay()-1; new_op.month = date.GetMonth(); new_op.year = date.GetYear(); op_complete--; } value = _grid->GetCellValue(event.GetRow(), DEBIT); if (value != _("")) { value.ToDouble(&new_op.amount); new_op.amount *= -1.0; op_complete--; } value = _grid->GetCellValue(event.GetRow(), CREDIT); if (value != _("")) { value.ToDouble(&new_op.amount); op_complete--; } value = _grid->GetCellValue(event.GetRow(), CATEGORY); if (value != _("")) { new_op.category = user->GetCategoryId(value); op_complete--; } value = _grid->GetCellValue(event.GetRow(), ACCOUNT); if (value != _("")) { new_op.account = user->GetAccountId(value); op_complete--; } value = _grid->GetCellValue(event.GetRow(), CHECKED); if (value != _("") && value != _("0")) new_op.checked = true; else new_op.checked = false; op_complete--; if (col == CHECKED || col == CATEGORY) { color = user->GetCategory(new_op.category).color; 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(event.GetRow(), color); } if (col == DELETE) { wxMessageDialog dialog(_wxUI, _("Are you sure want to delete : \n")+new_op.description, _("KissCount"), wxYES_NO); if (dialog.ShowModal() == wxID_NO) { _grid->SetCellValue(event.GetRow(), event.GetCol(), _("0")); inModification = false; return; } } // Penser au fix implosif // Modify a fix operation if (row < _fixCosts) { cur_op = (*_curOperations)[row] ; if (col == DELETE) { _grid->DeleteRows(event.GetRow(), 1); _curOperations->erase(_curOperations->begin()+row); _kiss->DeleteOperation(cur_op); _grid->_fixCosts = _fixCosts--; UpdateStats(); inModification = false ; return ; } new_op.id = cur_op.id; if (cur_op.day != new_op.day) { need_insertion = true; _grid->DeleteRows(event.GetRow(), 1); _curOperations->erase(_curOperations->begin()+row); _fixCosts--; } else (*_curOperations)[row] = new_op; _kiss->UpdateOperation(new_op); fix_op = true; } // Add a fixCost else if (row == _fixCosts) { if (op_complete) { inModification = false ; return ; } need_insertion = true; fix_op = true; new_op.fix_cost = true; for(i=0; iSetCellValue(event.GetRow(), i, _("")); } new_op.id = _kiss->AddOperation(new_op); } // Modify an operation else if (row <= user->GetOperationsNumber(_curMonth, _curYear)) { row--; cur_op = (*_curOperations)[row] ; new_op.id = cur_op.id; if (col == DELETE) { _grid->DeleteRows(event.GetRow(), 1); _curOperations->erase(_curOperations->begin()+row); _kiss->DeleteOperation(cur_op); UpdateStats(); inModification = false ; return ; } if (cur_op.day != new_op.day) { need_insertion = true; _grid->DeleteRows(event.GetRow(), 1); _curOperations->erase(_curOperations->begin()+row); } else (*_curOperations)[row] = new_op; _kiss->UpdateOperation(new_op); } // Add an operation else { row--; if (op_complete) { inModification = false ; return ; } need_insertion = true; fix_op = false; new_op.fix_cost = false; for(i=0; iSetCellValue(event.GetRow(), i, _("")); } new_op.id = _kiss->AddOperation(new_op); } if (need_insertion) { for(i=0; i<(int)_curOperations->size(); i++) { if ((*_curOperations)[i].fix_cost && !fix_op) continue; if (!(*_curOperations)[i].fix_cost && fix_op) break; if ((*_curOperations)[i].day > new_op.day) { if (i) { // First Operation if ((*_curOperations)[i-1].fix_cost && !fix_op) break; i--; } break; } } _curOperations->insert(_curOperations->begin()+i ,new_op); i++; // For header if (!fix_op) i++; InsertOperation(user, &new_op, i, fix_op); if (fix_op) _grid->_fixCosts = _fixCosts+1; } UpdateStats(); inModification = false ; } void AccountPanel::OnAccountModified(wxGridEvent& event) { User* user = _kiss->GetUser(); int row = event.GetRow(); double amount; _accountsGrid->GetCellValue(row, event.GetCol()).ToDouble(&amount); _kiss->SetAccountAmount(_curMonth, _curYear, user->GetAccountId(_accounts[row]), amount); } void AccountPanel::OnTreeRightClick(wxTreeEvent& event) { wxMenu menu(0); menu.Append(MENU_GENERATE_ID, _("Generate month")); menu.AppendSeparator(); if (_tree.GetCount() > 1) menu.Append(MENU_DELETE_ID, _("Delete")); PopupMenu(&menu, event.GetPoint()); } void AccountPanel::OnTreeChange(wxTreeEvent& event) { int month=-1, year; int i; wxString monthString; static bool inModification = false ; if (inModification) return; inModification = true; monthString = _tree.GetItemText(event.GetItem()); for (i=0; i<12; i++) if (monthString == months[i]) { month = i; break; } if (month == -1) { year = wxAtoi(monthString); // Error if (year == 0) { inModification = false; return; } if (year == _curYear) { inModification = false; return; } // _tree.CollapseAll(); // _tree.Expand(event.GetItem()); LoadYear(year, false); } else { year = wxAtoi(_tree.GetItemText(_tree.GetItemParent(event.GetItem()))); // Error if (year == 0) { inModification = false; return; } if (year != _curYear || month != _curMonth) { ShowMonth(month, year); } } inModification = false; } void AccountPanel::GetTreeSelection(int* month, int* year) { wxString monthString; int i; *month = -1; *year = -1; monthString = _tree.GetItemText(_tree.GetSelection()); for (i=0; i<12; i++) if (monthString == months[i]) { *month = i; break; } if (*month == -1) { *year = wxAtoi(monthString); // Error if (year == 0) { *month = -1; *year = -1; return; } } else { *year = wxAtoi(_tree.GetItemText(_tree.GetItemParent(_tree.GetSelection()))); // Error if (year == 0) { *month = -1; *year = -1; return; } } } void AccountPanel::OnMenuGenerate(wxCommandEvent& event) { int month, year; GetTreeSelection(&month, &year); GenerateDialog g(_kiss, _wxUI, month, year); g.ShowModal(); } void AccountPanel::OnMenuDelete(wxCommandEvent& event) { int month, year; wxString message; wxTreeItemId curNode, node ; std::map > ops ; GetTreeSelection(&month, &year); ops = _kiss->GetAllOperations(); if (ops.size() == 1 && ops[year].size() == 1) { wxMessageBox(_("It must be at least one month"), _("Error"), wxICON_ERROR | wxOK); return; } message = _("Are you sure want to delete "); if (month != -1) message += months[month] + _(" "); message += wxString::Format(_("%d"), year); message += _(" operations ?"); wxMessageDialog dialog(_wxUI, message, _("KissCount"), wxYES_NO); if (dialog.ShowModal() == wxID_NO) return; curNode = _tree.GetSelection(); if (ops[year].size() == 1 && month != -1) curNode = _tree.GetItemParent(curNode); _kiss->DeleteOperations(month, year); node = _tree.GetNextSibling(curNode); if (!node.IsOk()) node = _tree.GetPrevSibling(curNode); _tree.Delete(curNode); if (!node.IsOk()) ChangeUser(); else { _tree.SelectItem(node); GetTreeSelection(&month, &year); if (month == -1) month = ops[year][0]; ShowMonth(month, year); } } void AccountPanel::GenerateMonth(int month, int year) { wxTreeItemId root, years, node ; wxTreeItemIdValue cookie; wxString monthString, yearString; std::map >::iterator it; int i; User* user = _kiss->GetUser(); root = _tree.GetRootItem(); yearString = wxString::Format(wxT("%d"), year); monthString = months[month]; if (_tree.GetChildrenCount(root, true) < 1) { node = _tree.AppendItem(root, yearString); node = _tree.AppendItem(node, monthString); _tree.SelectItem(node, true); ShowMonth(month, year); return ; } years = _tree.GetFirstChild(root, cookie); while (years.IsOk()) { if (_tree.GetItemText(years) == yearString) break; if (wxAtoi(_tree.GetItemText(years)) > year) { years = _tree.GetPrevSibling(years); if (!years.IsOk()) years = _tree.PrependItem(root, yearString); else years = _tree.InsertItem(root, years, yearString); break; } years = _tree.GetNextSibling(years); } if (!years.IsOk()) { years = _tree.GetFirstChild(root, cookie); if (wxAtoi(_tree.GetItemText(years)) > year) years = _tree.PrependItem(root, yearString); else years = _tree.AppendItem(root, yearString); } if (!_tree.GetChildrenCount(years, true)) node = _tree.AppendItem(years, monthString); else { for(i=0, it = user->_operations[year]->begin(); it != user->_operations[year]->end(); it++, i++) { if ((int)it->first > month) break; } years = _tree.InsertItem(years, i, monthString); } _tree.SelectItem(node, true); ShowMonth(month, year); } void AccountPanel::OnShow(wxShowEvent& event) { if (_curMonth != -1) _wxUI->SetTitle(_kiss->GetUser()->_name + _(" - ") + months[_curMonth] + _(" ") + wxString::Format(wxT("%d"), _curYear)); else _wxUI->SetTitle(_kiss->GetUser()->_name); }