Click here to Skip to main content
15,896,153 members
Articles / Programming Languages / C++

Personal Finance Application

Rate me:
Please Sign up or sign in to vote.
4.38/5 (11 votes)
10 Jan 2007CPOL4 min read 88.1K   7.9K   69  
Utility to keep track of personal finances
// CashMDlg.cpp: archivo de implementaci�n
//

#include "stdafx.h"
#include "CashM.h"
#include "CashMDlg.h"
#include "DlgTree.h"
#include "DlgStats.h"
#include "DlgCurrencies.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


CCashMDlg::CCashMDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CCashMDlg::IDD, pParent)
{
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CCashMDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_GRID, m_Grid);  
	// associate the grid window with a C++ object
}

BEGIN_MESSAGE_MAP(CCashMDlg, CDialog)
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	
	//}}AFX_MSG_MAP
	ON_BN_CLICKED(ID_NEW, &CCashMDlg::OnBnClickedNew)
	ON_BN_CLICKED(ID_EDIT, &CCashMDlg::OnBnClickedEdit)
	ON_BN_CLICKED(ID_DELETE, &CCashMDlg::OnBnClickedDelete)
	ON_EN_CHANGE(IDC_ED_FILTER, &CCashMDlg::OnChangeFilter)

	ON_NOTIFY(GVN_SELCHANGED, IDC_GRID, &CCashMDlg::OnGridRowChange)
	
	ON_WM_SIZE()
END_MESSAGE_MAP()


BOOL CCashMDlg::OnInitDialog()
{
	CDialog::OnInitDialog();
	
	InfoAddLoaded = FALSE;
	Refresh = FALSE;

	LoadKeys();
	SetIcon(m_hIcon, TRUE);
	SetIcon(m_hIcon, FALSE);

	m_Grid.SetRedraw(FALSE);
	GridFormat();
	GridLoad();
	m_Grid.SetRedraw(TRUE, TRUE);

	CRect Ancho;
	GetClientRect(Ancho);
	OnSize(SIZE_RESTORED, Ancho.Width(), Ancho.Height());
	
	return TRUE;
}

void CCashMDlg::OnPaint()
{
	if (IsIconic())
	{
		CPaintDC dc(this); 

		SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();
	}
}

HCURSOR CCashMDlg::OnQueryDragIcon()
{
	return static_cast<HCURSOR>(m_hIcon);
}


void CCashMDlg::GridFormat()
{
	//Format Grid
	m_Grid.SetColumnCount(6);
	m_Grid.SetFixedRowCount(1);
	m_Grid.EnableDragAndDrop(FALSE);
	m_Grid.SetEditable(FALSE);
	m_Grid.SetListMode(TRUE);
	m_Grid.SetSingleRowSelection(TRUE);
	m_Grid.SetFixedBkColor(RGB(100,130,209));
	m_Grid.GetDefaultCell(TRUE, FALSE)->SetTextClr(RGB(255,255,255));
	m_Grid.SetHeaderSort(TRUE);
	LOGFONT* fhead = m_Grid.GetDefaultCell(TRUE, FALSE)->GetFont();
	fhead->lfWeight = FW_BOLD;
	strcpy(fhead->lfFaceName,_T("Tahoma"));
	fhead->lfHeight = -11;
	m_Grid.GetDefaultCell(TRUE, FALSE)->SetFont(fhead);
	//Headers
	m_Grid.GetCell(0,0)->SetText(LS(IDS_CASH_GRID_DATE));
	m_Grid.GetCell(0,1)->SetText(LS(IDS_CASH_GRID_FROM));
	m_Grid.GetCell(0,2)->SetText(LS(IDS_CASH_GRID_TO));
	m_Grid.GetCell(0,3)->SetText(LS(IDS_CASH_GRID_AMOUNT));
	m_Grid.GetCell(0,4)->SetText(LS(IDS_CASH_GRID_OBS));
	m_Grid.GetCell(0,5)->SetText("ID");

	m_Grid.SetColumnWidth(5, 0);
}
void CCashMDlg::GridLoad()
{
	CString stramount, strid;

	m_Grid.SetRowCount(1);
	CppSQLite3Query q = m_app->db.execQuery("SELECT * FROM CASHM ORDER BY ID_DATE");
	
	Citemkey* resultfrom = new Citemkey();
	Citemkey* resultto = new Citemkey();

	m_Grid.SetRedraw(FALSE,FALSE);
	while (!q.eof())
	{

		SearchAccounts(resultfrom, q.getIntField("ACCOUNT_FROM"));
		SearchAccounts(resultto, q.getIntField("ACCOUNT_TO"));
		
		//stramount.Format("%8.2f", q.getFloatField("AMOUNT"));
		stramount = NumberFormat(q.getFloatField("AMOUNT"),2);

		strid.Format("%d", q.getIntField("ID"));

		GridAdd(q.getStringField("ID_DATE"),resultfrom->Name,resultto->Name,stramount,q.getStringField("OBS"),strid);

		q.nextRow();
	}
	m_Grid.SetRedraw(TRUE,TRUE);
	q.finalize();
}
void CCashMDlg::GridAdd(CString date, CString from, CString to, CString amount, CString obs, CString id)
{
	int irowcount;
	if (dlginfoadd.pEdit)
		irowcount = currow;
	else
	{
		irowcount = m_Grid.GetRowCount();
		m_Grid.SetRowCount(irowcount + 1);
	}
	m_Grid.GetCell(irowcount,0)->SetText(date);
	m_Grid.GetCell(irowcount,1)->SetText(from);
	m_Grid.GetCell(irowcount,2)->SetText(to);
	m_Grid.GetCell(irowcount,3)->SetText(amount);
	m_Grid.GetCell(irowcount,4)->SetText(obs);
	m_Grid.GetCell(irowcount,5)->SetText(id);
	if (!dlginfoadd.pEdit)
	{
		int format = m_Grid.GetCell(irowcount,3)->GetFormat();
		format+= DT_RIGHT;
		m_Grid.GetCell(irowcount,3)->SetFormat(format);
	}
	else
		m_Grid.Invalidate();
}

void CCashMDlg::RefreshAccounts()
{
	if (gridrefresh)
	{
		if (InfoAddLoaded)
		{
			Refresh = TRUE;
		}
		GridLoad();
	}
}
void CCashMDlg::OnBnClickedNew()
{
	dlginfoadd.pEdit = FALSE;
	if (InfoAddLoaded)
	{
		if (Refresh)
		{
			dlginfoadd.LoadKeys();
			dlginfoadd.LoadAccountsXML();
			Refresh = FALSE;
		}
		dlginfoadd.EmptyForm();
		dlginfoadd.ShowWindow(SW_SHOW);
		this->GetParent()->EnableWindow(FALSE);
	}
	else
	{
		InfoAddLoaded = TRUE;
		dlginfoadd.pdlgmain = this;
		dlginfoadd.db = &m_app->db;
		dlginfoadd.Create(IDD_INFOADD, this);
		dlginfoadd.EmptyForm();
		dlginfoadd.ShowWindow(SW_SHOW);
		this->GetParent()->EnableWindow(FALSE);
	}
}
void CCashMDlg::LoadKeys()
{
	arraccounts.RemoveAll();
	CppSQLite3Query q = m_app->db.execQuery("SELECT ACCOUNTS.*, CURRENCIES.CONVERSION CONV FROM ACCOUNTS INNER JOIN CURRENCIES ON ACCOUNTS.ID_CUR = CURRENCIES.ID ORDER BY ACCOUNTS.ID");	
	Citemkey item;
	while (!q.eof())
	{
		item.Id = q.getIntField("ID");
		item.Modifiers = q.getIntField("SHORTCUT1");
		item.wVirtualKeyCode = q.getIntField("SHORTCUT2");
		item.Name = q.getStringField("NAME");
		item.IdParent = q.getIntField("ID_PARENT");
		item.curconversion = q.getFloatField("CONV");
		item.RMinus = q.getIntField("RMINUS");
		item.RPlus = q.getIntField("RPLUS");
		arraccounts.Add(item);
		q.nextRow();
	}
	q.finalize();
}
void CCashMDlg::SearchAccounts(Citemkey* item, int id)
{
	Citemkey* itemfind = new Citemkey();
	Citemkey* resultado = NULL;
	
	itemfind->Id = id;
	
	resultado = (Citemkey*)bsearch(itemfind, (void*)&arraccounts[0], (size_t)arraccounts.GetSize(), 
		sizeof(Citemkey), (int(*)(const void*,const void*))CCashMDlg::OrderById);

	item->Id = resultado->Id;
	item->Name = resultado->Name;
	item->Modifiers = resultado->Modifiers;
	item->wVirtualKeyCode = resultado->wVirtualKeyCode;
	item->IdParent = resultado->IdParent;
	item->curconversion = resultado->curconversion;
	item->RMinus = resultado->RMinus;
	item->RPlus = resultado->RPlus;
}
int CCashMDlg::OrderById(void* p1,void* p2)
{
	short n=0;
	Citemkey* a1 = (Citemkey*)p1;
	Citemkey* a2 = (Citemkey*)p2; 

	if(a1->Id < a2->Id)
		n=-1;
	else if (a1->Id > a2->Id)
		n=1;

	return n;
}


void CCashMDlg::OnBnClickedDelete()
{
	CString strid;
	if (currow < 1 || m_Grid.GetRowCount() <= 1)
	{
		AfxMessageBox(LS(IDS_ROW_NOROW));
		return;
	}
	if (AfxMessageBox(LS(IDS_ROW_DELETE_ASK), MB_YESNO)==IDYES)
	{
		strid = m_Grid.GetCell(currow, 5)->GetText();
		m_app->db.execDML("DELETE FROM CASHM WHERE ID = " + strid);
		m_Grid.SetRedraw(FALSE);
		m_Grid.DeleteRow(currow);
		m_Grid.SetRedraw(TRUE, TRUE);
	}
}
void CCashMDlg::OnGridRowChange(NMHDR *pNotifyStruct, LRESULT* /*pResult*/)
{
	NM_GRIDVIEW* pItem = (NM_GRIDVIEW*) pNotifyStruct;
	currow = pItem->iRow;
}
void CCashMDlg::OnChangeFilter()
{
	CString strfilter,strcell;
	BOOL match;

	GetDlgItem(IDC_ED_FILTER)->GetWindowTextA(strfilter);
	strfilter = strfilter.MakeUpper();

	m_Grid.SetRedraw(FALSE);
	for (int i=1;i<= m_Grid.GetRowCount() - 1;i++)
	{
		match = FALSE;
		for (int j=0;j<= m_Grid.GetColumnCount() - 1;j++)
		{
			strcell = m_Grid.GetCell(i, j)->GetText();
			strcell = strcell.MakeUpper();
			if (strcell.Find(strfilter)>=0)
			{
				match = TRUE;
				break;
			}
		}
		if (match)
			m_Grid.SetRowHeight(i,m_Grid.GetDefCellHeight());
		else
			m_Grid.SetRowHeight(i,0);
	}
	m_Grid.SetRedraw(TRUE, TRUE);
}
BOOL CCashMDlg::PreTranslateMessage(MSG* pMsg)
{
	if(pMsg->message == WM_KEYDOWN)
	{
		UINT asc = pMsg->wParam;
		switch(asc)
		{
			case VK_ESCAPE:
				return FALSE;
			case VK_RETURN:
				CWnd * pWnd = CWnd::GetFocus();
				TCHAR buf [21];
				GetClassName(pWnd->GetSafeHwnd(), buf, 20 );
				CString strcontrol(buf);
				if(pWnd != NULL && strcontrol!="Button")
					return FALSE;
					break;
		}
	}
	return CDialog::PreTranslateMessage(pMsg);
}

void CCashMDlg::OnBnClickedStats()
{
	CDlgStats dlgstats;
	dlgstats.db = &m_app->db;
	dlgstats.pdlgmain = this;
	dlgstats.DoModal();
}


void CCashMDlg::OnBnClickedCurrencies()
{
	CDlgCurrencies dlgcurrencies;
	dlgcurrencies.db = &m_app->db;
	dlgcurrencies.DoModal();
}
void CCashMDlg::OnSize(UINT nType, int cx, int cy)
{
	int lblfilterw=30,scrollw=30;

	if (cx <= 1 || cy <= 1 ) 
        return;
	if (!::IsWindow(m_Grid.m_hWnd))
		return;

	GetDlgItem(IDC_FILTER)->SetWindowPos(&wndTop, INTSEP,INTSEP, lblfilterw,THEIGHT, SWP_SHOWWINDOW);
	GetDlgItem(IDC_ED_FILTER)->SetWindowPos(&wndTop, INTSEP + lblfilterw,INTSEP, cx - lblfilterw - INTSEP * 2,THEIGHT, SWP_SHOWWINDOW);
	
	m_Grid.SetWindowPos(&wndTop, INTSEP,INTSEP * 2 + THEIGHT, cx - INTSEP*2,cy - INTSEP * 4 - THEIGHT - BHEIGHT, SWP_SHOWWINDOW);
	
	int sep = INTSEP;
	GetDlgItem(ID_NEW)->SetWindowPos(&wndTop, sep,cy - INTSEP - BHEIGHT, BWIDTH,BHEIGHT, SWP_SHOWWINDOW);
	sep+=BWIDTH + INTSEP;
	GetDlgItem(ID_EDIT)->SetWindowPos(&wndTop, sep,cy - INTSEP - BHEIGHT, BWIDTH,BHEIGHT, SWP_SHOWWINDOW);
	sep+=BWIDTH + INTSEP;
	GetDlgItem(ID_DELETE)->SetWindowPos(&wndTop, sep,cy - INTSEP - BHEIGHT, BWIDTH,BHEIGHT, SWP_SHOWWINDOW);

	m_Grid.SetColumnWidth(0,70);
	m_Grid.SetColumnWidth(3,80);
	int gwidth = cx - INTSEP*2 - scrollw - 150;

	m_Grid.SetColumnWidth(1,gwidth*0.3);
	m_Grid.SetColumnWidth(2,gwidth*0.3);
	m_Grid.SetColumnWidth(4,gwidth*0.4);
}
void CCashMDlg::OnBnClickedEdit()
{
	if (currow < 1 || m_Grid.GetRowCount() <= 1)
	{
		AfxMessageBox(LS(IDS_ROW_NOROW));
		return;
	}
	dlginfoadd.pEdit = TRUE;
	if (InfoAddLoaded)
	{
		if (Refresh)
		{
			dlginfoadd.LoadKeys();
			dlginfoadd.LoadAccountsXML();
			Refresh = FALSE;
		}
		LoadEditForm();
		dlginfoadd.LoadFromTo();
		dlginfoadd.ShowWindow(SW_SHOW);
		this->GetParent()->EnableWindow(FALSE);
	}
	else
	{
		InfoAddLoaded = TRUE;
		dlginfoadd.pdlgmain = this;
		dlginfoadd.db = &m_app->db;
		LoadEditForm();
		dlginfoadd.Create(IDD_INFOADD, this);
		dlginfoadd.ShowWindow(SW_SHOW);
		this->GetParent()->EnableWindow(FALSE);
	}	
}
void CCashMDlg::LoadEditForm()
{
	dlginfoadd.InfoEdit(m_Grid.GetCell(currow,0)->GetText(),
					    m_Grid.GetCell(currow,1)->GetText(),
						m_Grid.GetCell(currow,2)->GetText(),
						m_Grid.GetCell(currow,3)->GetText(),
						m_Grid.GetCell(currow,4)->GetText(),
						m_Grid.GetCell(currow,5)->GetText());
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer
Argentina Argentina
System developer from Argentina.

Programmed in VB 5,6,.NET, C#, Java, PL-SQL, Transac-SQL, C, C++ and even some "calculator" language.

Love to build small, useful applications.
Usually building big and complicated apps based on solid, reliable components.

Hobbies: reading, photography, chess, paddle, running.

Comments and Discussions