Fix a lot of bugs (again)
This commit is contained in:
		
							
								
								
									
										11
									
								
								TODO
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								TODO
									
									
									
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| Version 0.1 | Version 0.2 | ||||||
|  |  | ||||||
| Statistics (need to add months/years label on graph) | Statistics (need to add months/years label on graph) | ||||||
| Auto completion (already up into wxwidgets 2.9) | Auto completion (already up into wxwidgets 2.9) | ||||||
| @@ -6,21 +6,20 @@ Using tabulation to navigate throw interface (Search Panel) | |||||||
| Improve Scrolled Windows and widgets placement | Improve Scrolled Windows and widgets placement | ||||||
| Can type a letter with a comboboxes | Can type a letter with a comboboxes | ||||||
| Windows version | Windows version | ||||||
| Need packaging | Need packaging (.deb) | ||||||
| Better build system for wxFreeChart (hacked by me) |  | ||||||
|  |  | ||||||
| Cool for 0.1: | Cool for 0.2: | ||||||
| Database auto saving at startup | Database auto saving at startup | ||||||
| Use caches for created panels (avoid destroying/creating panels for nothing) | Use caches for created panels (avoid destroying/creating panels for nothing) | ||||||
| Add search function to web view | Add search function to web view | ||||||
| Need optimizations by caching operations and categories | Need optimizations by caching operations and categories (using hastables) | ||||||
|  |  | ||||||
| =============================================================== | =============================================================== | ||||||
| Next version | Next version | ||||||
|  |  | ||||||
| More translations | More translations | ||||||
| Import/Export module | Import/Export module | ||||||
| Printing (maybe in html) | Printing (maybe in xml/html) | ||||||
| Refactor web view code | Refactor web view code | ||||||
| Plugins ? | Plugins ? | ||||||
|  |  | ||||||
|   | |||||||
| @@ -41,8 +41,9 @@ END_EVENT_TABLE() | |||||||
|  |  | ||||||
| enum {GRID_ID}; | enum {GRID_ID}; | ||||||
| GridAccount::GridAccount(KissCount* kiss, wxWindow *parent, wxWindowID id) : wxGrid(parent, id), _fixCosts(0), _week1(0),  | GridAccount::GridAccount(KissCount* kiss, wxWindow *parent, wxWindowID id) : wxGrid(parent, id), _fixCosts(0), _week1(0),  | ||||||
| 									     _week2(0), _week3(0), _week4(0), _kiss(kiss), | 												_week2(0), _week3(0), _week4(0), _kiss(kiss), | ||||||
| 									     _loadOperations(false), _curMonth(0), _curYear(0) | 												_loadOperations(false),  | ||||||
|  | 												_curMonth(0), _curYear(0) | ||||||
| { | { | ||||||
|     wxBitmap deleteBitmap(wxT(DELETE_ICON)); |     wxBitmap deleteBitmap(wxT(DELETE_ICON)); | ||||||
|     wxBitmap checkedBitmap(wxT(CHECKED_ICON)); |     wxBitmap checkedBitmap(wxT(CHECKED_ICON)); | ||||||
| @@ -107,12 +108,15 @@ wxPen GridAccount::GetColGridLinePen (int col) | |||||||
| {return wxPen(*wxBLACK, 1, wxSOLID);}  | {return wxPen(*wxBLACK, 1, wxSOLID);}  | ||||||
|  |  | ||||||
| wxPen GridAccount::GetRowGridLinePen (int row) { | wxPen GridAccount::GetRowGridLinePen (int row) { | ||||||
|     if (row == 0 || row == _fixCosts || |   if (_canAddOperation) | ||||||
|         row == _week1 || |     { | ||||||
|         row == _week2 || |       if (row == 0 || row == _fixCosts || | ||||||
|         row == _week3 || | 	  row == _week1 || | ||||||
|         row == _week4) | 	  row == _week2 || | ||||||
|  | 	  row == _week3 || | ||||||
|  | 	  row == _week4) | ||||||
|         return wxPen(*wxBLACK, 1, wxSOLID); |         return wxPen(*wxBLACK, 1, wxSOLID); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     return GetCellBackgroundColour(row, 0); |     return GetCellBackgroundColour(row, 0); | ||||||
| }  | }  | ||||||
| @@ -149,8 +153,8 @@ void GridAccount::UpdateOperation(Operation& op) | |||||||
|     for(i=0; i < (int)_operations->size(); i++) |     for(i=0; i < (int)_operations->size(); i++) | ||||||
| 	if ((*_operations)[i].id == op.id) | 	if ((*_operations)[i].id == op.id) | ||||||
| 	{ | 	{ | ||||||
| 	    (*_operations)[i] = op; |  | ||||||
| 	    _kiss->UpdateOperation(op); | 	    _kiss->UpdateOperation(op); | ||||||
|  | 	    (*_operations)[i] = op; | ||||||
| 	    break; | 	    break; | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| @@ -184,31 +188,41 @@ void GridAccount::LoadOperations(std::vector<Operation>* operations, bool canAdd | |||||||
|      |      | ||||||
|     it = _operations->begin(); |     it = _operations->begin(); | ||||||
|  |  | ||||||
|     for (;it != _operations->end() && it->fix_cost; it++) |     if (_canAddOperation) | ||||||
|     { |     { | ||||||
| 	if (it->parent.Length()) continue; | 	for (;it != _operations->end() && it->fix_cost; it++) | ||||||
|  | 	{ | ||||||
|  | 	    if (it->parent.Length()) continue; | ||||||
|  |  | ||||||
| 	if (setWeek) | 	    if (setWeek) | ||||||
| 	    InsertOperationWithWeek(user, *it, ++curLine, true, it->month, it->year); | 		InsertOperationWithWeek(user, *it, ++curLine, true, it->month, it->year); | ||||||
| 	else | 	    else | ||||||
| 	    InsertOperation(user, *it, ++curLine, true, it->month, it->year); | 		InsertOperation(user, *it, ++curLine, true, it->month, it->year); | ||||||
|     } | 	} | ||||||
|  |  | ||||||
|     if (canAddOperation) |  | ||||||
| 	InsertOperation(user, NULLop, ++curLine, true, month, year); | 	InsertOperation(user, NULLop, ++curLine, true, month, year); | ||||||
|  |  | ||||||
|     for (; it != _operations->end(); it++) | 	for (; it != _operations->end(); it++) | ||||||
|     { | 	{ | ||||||
| 	if (it->parent.Length()) continue; | 	    if (it->parent.Length()) continue; | ||||||
|  |  | ||||||
| 	if (setWeek) | 	    if (setWeek) | ||||||
| 	    InsertOperationWithWeek(user, *it, ++curLine, false, it->month, it->year); | 		InsertOperationWithWeek(user, *it, ++curLine, false, it->month, it->year); | ||||||
| 	else | 	    else | ||||||
| 	    InsertOperation(user, *it, ++curLine, false, it->month, it->year); | 		InsertOperation(user, *it, ++curLine, false, it->month, it->year); | ||||||
|     } | 	} | ||||||
|  |  | ||||||
|     if (canAddOperation) |  | ||||||
| 	InsertOperation(user, NULLop, ++curLine, false, month, year); | 	InsertOperation(user, NULLop, ++curLine, false, month, year); | ||||||
|  |     } | ||||||
|  |     else | ||||||
|  |     { | ||||||
|  | 	for (;it != _operations->end(); it++) | ||||||
|  | 	{ | ||||||
|  | 	    if (it->parent.Length()) continue; | ||||||
|  |  | ||||||
|  | 	    InsertOperation(user, *it, ++curLine, true, it->month, it->year); | ||||||
|  | 	} | ||||||
|  |     } | ||||||
|  |  | ||||||
|     AutoSizeColumn(TREE, false); |     AutoSizeColumn(TREE, false); | ||||||
|     AutoSizeColumn(CATEGORY, false); |     AutoSizeColumn(CATEGORY, false); | ||||||
| @@ -225,6 +239,8 @@ void GridAccount::ComputeWeeks() | |||||||
|     std::vector<Operation>::iterator it; |     std::vector<Operation>::iterator it; | ||||||
|     int curLine, curWeek, week, i; |     int curLine, curWeek, week, i; | ||||||
|  |  | ||||||
|  |     if (!_canAddOperation) return; | ||||||
|  |  | ||||||
|     for (it = _displayedOperations.begin(), curLine=0; |     for (it = _displayedOperations.begin(), curLine=0; | ||||||
| 	 it != _displayedOperations.end();  | 	 it != _displayedOperations.end();  | ||||||
| 	 it++, curLine++) | 	 it++, curLine++) | ||||||
| @@ -240,7 +256,7 @@ void GridAccount::ComputeWeeks() | |||||||
|     it++; |     it++; | ||||||
|     for (i=1; it != _displayedOperations.end(); it++, curLine++) |     for (i=1; it != _displayedOperations.end(); it++, curLine++) | ||||||
|     { |     { | ||||||
| 	if (!it->id.Length()) continue; | 	if (!it->id.Length() || it->parent.Length()) continue; | ||||||
| 	week = wxDateTime(it->day+1, (wxDateTime::Month)it->month, it->year).GetWeekOfMonth(); | 	week = wxDateTime(it->day+1, (wxDateTime::Month)it->month, it->year).GetWeekOfMonth(); | ||||||
| 	if (week != curWeek) | 	if (week != curWeek) | ||||||
| 	{ | 	{ | ||||||
| @@ -455,15 +471,21 @@ void GridAccount::DeleteOperation(const Operation& op) | |||||||
|  |  | ||||||
| void GridAccount::InsertIntoGrid(Operation& op) | void GridAccount::InsertIntoGrid(Operation& op) | ||||||
| { | { | ||||||
|     int i, a; |     int i, a, start; | ||||||
|     User* user = _kiss->GetUser(); |     User* user = _kiss->GetUser(); | ||||||
|  |     Operation parent; | ||||||
|  |  | ||||||
|     // No previous fix operations |     // No previous fix operations | ||||||
|     if (op.fix_cost && !_displayedOperations[1].id.Length()) |     if (op.fix_cost && !_displayedOperations[1].id.Length()) | ||||||
| 	i = 1; | 	i = 1; | ||||||
|     else |     else | ||||||
|     { |     { | ||||||
| 	for(i=0; i<(int)_displayedOperations.size(); i++) | 	if (op.parent.Length()) | ||||||
|  | 	    start = GetDisplayedRow(op.parent); | ||||||
|  | 	else | ||||||
|  | 	    start = 0; | ||||||
|  |  | ||||||
|  | 	for(i=start; i<(int)_displayedOperations.size(); i++) | ||||||
| 	{ | 	{ | ||||||
| 	    if (!_displayedOperations[i].id.Length()) continue; | 	    if (!_displayedOperations[i].id.Length()) continue; | ||||||
| 	    if (_displayedOperations[i].parent.Length()) continue; | 	    if (_displayedOperations[i].parent.Length()) continue; | ||||||
| @@ -481,7 +503,15 @@ void GridAccount::InsertIntoGrid(Operation& op) | |||||||
| 	    } | 	    } | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if (i == (int)_displayedOperations.size() || | 	if (op.parent.Length()) | ||||||
|  | 	{ | ||||||
|  | 	    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 == _fixCosts)  | ||||||
| 	    i--; | 	    i--; | ||||||
| 	else if (!(_displayedOperations)[i].fix_cost && op.fix_cost) | 	else if (!(_displayedOperations)[i].fix_cost && op.fix_cost) | ||||||
| @@ -509,7 +539,7 @@ void GridAccount::InsertIntoGrid(Operation& op) | |||||||
|     InsertOperationWithWeek(user, (*_operations)[a], i, op.fix_cost, _curMonth, _curYear); |     InsertOperationWithWeek(user, (*_operations)[a], i, op.fix_cost, _curMonth, _curYear); | ||||||
| } | } | ||||||
|  |  | ||||||
| void GridAccount::RemoveMeta(Operation& op, int line, bool removeRoot, bool deleteOp) | void GridAccount::RemoveMeta(Operation op, int line, bool removeRoot, bool deleteOp) | ||||||
| { | { | ||||||
|     std::vector<Operation*>::iterator it, it2; |     std::vector<Operation*>::iterator it, it2; | ||||||
|     wxGridCellTreeButtonRenderer* treeRenderer; |     wxGridCellTreeButtonRenderer* treeRenderer; | ||||||
| @@ -604,7 +634,7 @@ void GridAccount::OnOperationModified(wxGridEvent& event) | |||||||
|     int row = event.GetRow(); |     int row = event.GetRow(); | ||||||
|     int col = event.GetCol(); |     int col = event.GetCol(); | ||||||
|     Operation new_op, cur_op, op_tmp, op_tmp2; |     Operation new_op, cur_op, op_tmp, op_tmp2; | ||||||
|     int op_complete = 6, i; |     int op_complete = 6, i, last_day; | ||||||
|     wxString value ; |     wxString value ; | ||||||
|     wxDateTime date; |     wxDateTime date; | ||||||
|     bool need_insertion = false, fix_op=false; |     bool need_insertion = false, fix_op=false; | ||||||
| @@ -644,6 +674,7 @@ void GridAccount::OnOperationModified(wxGridEvent& event) | |||||||
|  |  | ||||||
| 	treeRenderer->DecRef(); | 	treeRenderer->DecRef(); | ||||||
|  |  | ||||||
|  | 	ComputeWeeks(); | ||||||
| 	inModification = false; | 	inModification = false; | ||||||
| 	return; | 	return; | ||||||
|     } |     } | ||||||
| @@ -856,7 +887,6 @@ void GridAccount::OnOperationModified(wxGridEvent& event) | |||||||
| 	    DeleteOperation(cur_op); | 	    DeleteOperation(cur_op); | ||||||
|             _displayedOperations.erase(_displayedOperations.begin()+row); |             _displayedOperations.erase(_displayedOperations.begin()+row); | ||||||
|             _fixCosts--; |             _fixCosts--; | ||||||
|             UpdateOperation(new_op); |  | ||||||
| 	} | 	} | ||||||
|         else |         else | ||||||
| 	{ | 	{ | ||||||
| @@ -956,7 +986,6 @@ void GridAccount::OnOperationModified(wxGridEvent& event) | |||||||
|             DeleteRows(row, 1); |             DeleteRows(row, 1); | ||||||
| 	    DeleteOperation(cur_op); | 	    DeleteOperation(cur_op); | ||||||
|             _displayedOperations.erase(_displayedOperations.begin()+row); |             _displayedOperations.erase(_displayedOperations.begin()+row); | ||||||
|             UpdateOperation(new_op); |  | ||||||
| 	} | 	} | ||||||
|         else |         else | ||||||
| 	{ | 	{ | ||||||
| @@ -993,7 +1022,10 @@ void GridAccount::OnOperationModified(wxGridEvent& event) | |||||||
| 	wxMessageBox(_("You made a debit on a blocked account"), _("Warning"), wxICON_WARNING | wxOK); | 	wxMessageBox(_("You made a debit on a blocked account"), _("Warning"), wxICON_WARNING | wxOK); | ||||||
|  |  | ||||||
|     if (need_insertion) |     if (need_insertion) | ||||||
|  |     { | ||||||
| 	InsertIntoGrid(new_op); | 	InsertIntoGrid(new_op); | ||||||
|  | 	UpdateOperation(new_op); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     if (new_op.parent.Length()) |     if (new_op.parent.Length()) | ||||||
|     { |     { | ||||||
| @@ -1001,6 +1033,8 @@ void GridAccount::OnOperationModified(wxGridEvent& event) | |||||||
| 	 | 	 | ||||||
| 	new_op = _displayedOperations[row]; | 	new_op = _displayedOperations[row]; | ||||||
|  |  | ||||||
|  | 	last_day = new_op.day; | ||||||
|  |  | ||||||
| 	UpdateMeta(new_op); | 	UpdateMeta(new_op); | ||||||
|  |  | ||||||
| 	_displayedOperations[row] = new_op; | 	_displayedOperations[row] = new_op; | ||||||
| @@ -1032,6 +1066,8 @@ void GridAccount::OnOperationModified(wxGridEvent& event) | |||||||
|             SET_ROW_FONT(row, font); |             SET_ROW_FONT(row, font); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |         SetCellValue(row, DATE, wxString::Format(wxT("%02d/%02d/%d"), new_op.day+1, _curMonth+1, _curYear)); | ||||||
|  |  | ||||||
| 	if (!_displayedOperations[row].amount) | 	if (!_displayedOperations[row].amount) | ||||||
| 	{ | 	{ | ||||||
| 	    amount = _kiss->MetaPositiveAmount(new_op.id); | 	    amount = _kiss->MetaPositiveAmount(new_op.id); | ||||||
| @@ -1052,6 +1088,23 @@ void GridAccount::OnOperationModified(wxGridEvent& event) | |||||||
| 		SetCellValue(row, CREDIT, wxString::Format(wxT("%.2lf"), new_op.amount)); | 		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 ; |     inModification = false ; | ||||||
| @@ -1059,51 +1112,53 @@ void GridAccount::OnOperationModified(wxGridEvent& event) | |||||||
|     event.Skip(); |     event.Skip(); | ||||||
| } | } | ||||||
|  |  | ||||||
| void GridAccount::UpdateMeta(Operation& op) | void GridAccount::UpdateMeta(Operation& meta) | ||||||
| { | { | ||||||
|     std::vector<wxString>::iterator it; |     std::vector<wxString>::iterator it; | ||||||
|     Operation op_ ; |     Operation op ; | ||||||
|     wxString category = wxT(""); |     wxString category = wxT(""); | ||||||
|     bool updateCat = false ; |     bool updateCat = false ; | ||||||
|  |  | ||||||
|     op.category = wxT(""); |     if (!meta.childs.size()) return ; | ||||||
|     op.checked = true; |  | ||||||
|     op.amount = 0; |  | ||||||
|  |  | ||||||
|     for(it=op.childs.begin(); it!=op.childs.end(); it++) |     meta.category = wxT(""); | ||||||
|  |     meta.checked = true; | ||||||
|  |     meta.amount = 0; | ||||||
|  |  | ||||||
|  |     for(it=meta.childs.begin(); it!=meta.childs.end(); it++) | ||||||
|     { |     { | ||||||
| 	op_ = GetOperation(*it); | 	op = GetOperation(*it); | ||||||
| 	if (op_.year <= op.year && op_.month <= op.month && op_.day < op.day) | 	if (op.year <= meta.year && op.month <= meta.month && op.day < meta.day) | ||||||
| 	{ | 	{ | ||||||
| 	    op.year = op_.year; | 	    meta.year = op.year; | ||||||
| 	    op.month = op_.month; | 	    meta.month = op.month; | ||||||
| 	    op.day = op_.day; | 	    meta.day = op.day; | ||||||
| 	} | 	} | ||||||
| 	op.checked &= op_.checked; | 	meta.checked &= op.checked; | ||||||
| 	if (!op.description.Length() && op_.description.Length()) | 	if (!meta.description.Length() && op.description.Length()) | ||||||
| 	    op.description = op_.description; | 	    meta.description = op.description; | ||||||
| 	if (!category.Length()) | 	if (!category.Length()) | ||||||
| 	{ | 	{ | ||||||
| 	    if (op_.category.Length()) | 	    if (op.category.Length()) | ||||||
| 	    { | 	    { | ||||||
| 		category = op_.category; | 		category = op.category; | ||||||
| 		updateCat = true; | 		updateCat = true; | ||||||
| 	    } | 	    } | ||||||
| 	} | 	} | ||||||
| 	else | 	else | ||||||
| 	{ | 	{ | ||||||
| 	    if (op_.category.Length() && op_.category != category) | 	    if (op.category.Length() && op.category != category) | ||||||
| 		updateCat = false; | 		updateCat = false; | ||||||
| 	} | 	} | ||||||
| 	op_.parent = op.id; | 	op.parent = meta.id; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     if (updateCat) |     if (updateCat) | ||||||
| 	op.category = category; | 	meta.category = category; | ||||||
|  |  | ||||||
|     op.amount = _kiss->MetaAmount(op.id); |     meta.amount = _kiss->MetaAmount(meta.id); | ||||||
|  |  | ||||||
|     UpdateOperation(op); |     UpdateOperation(meta); | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
|   | |||||||
| @@ -40,7 +40,7 @@ enum {TREE, DESCRIPTION, DATE, DEBIT, CREDIT, CATEGORY, ACCOUNT, DELETE, CHECKED | |||||||
| class GridAccount : public wxGrid | class GridAccount : public wxGrid | ||||||
| { | { | ||||||
| public: | public: | ||||||
|     GridAccount(KissCount* kiss, wxWindow *parent, wxWindowID id); |   GridAccount(KissCount* kiss, wxWindow *parent, wxWindowID id); | ||||||
|     ~GridAccount(); |     ~GridAccount(); | ||||||
|    |    | ||||||
|     wxPen GetColGridLinePen (int col); |     wxPen GetColGridLinePen (int col); | ||||||
| @@ -62,6 +62,7 @@ public: | |||||||
|  |  | ||||||
| private: | private: | ||||||
|     KissCount* _kiss; |     KissCount* _kiss; | ||||||
|  |     bool _displayLines; | ||||||
|     wxString* _categories, *_accounts; |     wxString* _categories, *_accounts; | ||||||
|     std::vector<Operation>* _operations; |     std::vector<Operation>* _operations; | ||||||
|     bool _canAddOperation, _loadOperations; |     bool _canAddOperation, _loadOperations; | ||||||
| @@ -74,7 +75,7 @@ private: | |||||||
|     void InsertIntoGrid(Operation& op); |     void InsertIntoGrid(Operation& op); | ||||||
|     void DeleteOperation(const Operation& op); |     void DeleteOperation(const Operation& op); | ||||||
|     void UpdateMeta(Operation& op); |     void UpdateMeta(Operation& op); | ||||||
|     void RemoveMeta(Operation& op, int line, bool removeRoot, bool deleteOp); |     void RemoveMeta(Operation op, int line, bool removeRoot, bool deleteOp); | ||||||
|     void CheckMeta(Operation& op, int line, bool check); |     void CheckMeta(Operation& op, int line, bool check); | ||||||
|  |  | ||||||
|     Operation& GetOperation(const wxString& id); |     Operation& GetOperation(const wxString& id); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user