/************************* * * * * * * * * * * * * *************************** Copyright (c) 1999-2005 Ryan Bobko ryan@ostrich-emulators.com This program 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 2 of the License, or (at your option) any later version. This program 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 this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ************************** * * * * * * * * * * * * **************************/ #include "splitdialog.h" #include "qhacc.h" #include "qhacctable.h" #include "qhaccutils.h" #include "guiconstants.h" //#include "qhaccdialogs.h" #include "qhaccacctdlg.h" #include "qhacclineedits.h" #include "splitdialog.moc" #include #include #include #include #include #include #include /* * * * * * * * * * * * * * * * * * * * * * * * * * * * SPLIT TRANSACTION EDITOR * * * * * * * * * * * * * * * * * * * * * * * * * * * */ SplitEditor::SplitEditor( QHacc * engine, QHaccTable& splits, QWidget * p, const char * n ) : QDialog( p, n, true ){ resize( 420, 200 ); setCaption( tr( "QHacc Split Editor" ) ); QGridLayout * layout=new QGridLayout( this, 5, 6 ); cont=new AccountAreaFrame( engine, splits, this ); layout->addMultiCellWidget( cont, 0, 3, 0, 5 ); QPushButton * but=new QPushButton( tr( "okay" ), this ); connect( but, SIGNAL( clicked() ), SLOT( accept() ) ); layout->addMultiCellWidget( but, 4, 4, 0, 2 ); but=new QPushButton( tr( "cancel" ), this ); connect( but, SIGNAL( clicked() ), SLOT( reject() ) ); layout->addMultiCellWidget( but, 4, 4, 3, 5 ); } SplitEditor::~SplitEditor(){} QHaccTable SplitEditor::getSplits() const { return cont->getSplits(); } void SplitEditor::setSplits( QHaccTable& t ){ cont->clearSplits(); for( uint i=0; iaddSplit( t.at( i ) ); for( uint i=t.rows(); i<5; i++ ) cont->addSplit( Transaction() ); } /* * * * * * * * * * * * * * * * * * * * * * * * * * ACCOUNTAREA * * * * * * * * * * * * * * * * * * * * * * * * */ const int AccountArea::NAME=0; const int AccountArea::PID =1; const int AccountArea::ID =2; const int AccountArea::NUM =3; const int AccountArea::COLS=4; const int AccountArea::GRABCOLS[]={ QC::ANAME, QC::APID, QC::AID, QC::ANUM }; AccountArea::AccountArea( QHacc * eng, QHaccTable& splits, QWidget * p, const char * n ) : QScrollView( p, n ){ engine=eng; setMargins( 0, 20, 0, 0 ); setVScrollBarMode( AlwaysOn ); header=new QHeader( this ); header->setMovingEnabled( false ); header->resize( 400, 20 ); header->addLabel( tr( "Account" ), 200 ); header->addLabel( tr( "Deposit" ), 100 ); header->addLabel( tr( "Withdrawal" ), 100 ); header->setResizeEnabled( false ); header->setClickEnabled( false ); // get a list of accounts to fill in the choice boxes vector GCOLS; for( int i=0; i temp=engine->getAs( TableGet( GCOLS ) ); accts=new QHaccTable( *temp ); accts->addIndexOn( ID ); const bool useanums=engine->getBP( "USEANUMSFORNAMES" ); // we want full account names, so update our table for( uint i=0; irows(); i++ ){ TableRow acct=accts->at( i ); accts->updateWhere( TableSelect( ID, acct[ID] ), TableUpdate( NAME, AccountAreaFrame::displayAName( eng, acct, useanums ) ) ); QString name=engine->getFNameOfA( acct.getu( PID ) ); if( !name.isEmpty() ) name+=QC::ASEP; name+=acct.gets( NAME ); accts->updateWhere( TableSelect( ID, acct[ID] ), TableUpdate( NAME, TableCol( name ) ) ); } // add the splits to the editor uint rows=splits.rows(); QHaccChoiceEdit * last=0; for( uint i=0; isetFocus(); } AccountArea::~AccountArea(){ delete accts; } QHaccChoiceEdit * AccountArea::addSplit( const TableRow& split ){ uint y=getNumSplits()*lineSize(); //cout<<" addSplit: "<ignoreCase( engine->getBP( "AUTOCOMPNOCASE" ) ); edit->setEmptyText( tr( GUIC::DEATEXT ) ); QStringList str; QString atext; uint aid=( split.isNull() ? 0 : split.getu( QC::SACCTID ) ); // build the list of account choices for( uint i=0; irows(); i++ ){ TableRow acct=accts->at( i ); QString name=acct.gets( NAME ); edit->insertItem( name ); // if we find our account id, remember the acctname if( acct[ID]==aid ) atext=name; } edit->insertStringList( str ); edit->setText( atext ); int ls=lineSize(); edit->resize( header->sectionSize( 0 ), ls ); QHaccLineEdit * credit=new QHaccLineEdit( this ); credit->resize( header->sectionSize( 1 ), ls ); credit->setEmptyText( tr( GUIC::DEP ) ); QHaccLineEdit * debit=new QHaccLineEdit( this ); debit->resize( header->sectionSize( 2 ), ls ); debit->setEmptyText( tr( GUIC::WD ) ); const MonCon& conv=engine->converter(); if( !split.isNull() ) { QString sum=split[QC::SSUM].gets(); if( sum.endsWith( "%" ) || sum.endsWith( "%t" ) || sum.endsWith( "%a" ) ){ if( sum.startsWith( "-" ) ) debit->setText( sum.mid( 1 ) ); else credit->setText( sum ); } else if( sum==QC::REMAINDERVAL ) credit->setText( sum ); else if( sum=="p" || sum=="i" ) credit->setText( sum ); else{ QString shrs, prc; if( Utils::isMarket( split, &shrs, &prc ) ){ // we're dealing with market transactions here, so // we need to recreate the entry string for possible modifications // by the user int summer=conv.converti( prc, Engine, Engine ); const QString BEGIN=shrs+"@"; if( summer<0 ) debit->setText( BEGIN+conv.convert( 0-summer ) ); else credit->setText( BEGIN+conv.convert( summer ) ); } else{ // this is a plain old transaction int summer=conv.converti( split[QC::SSUM].gets(), Engine, Engine ); if( summer<0 ) debit->setText( conv.convert( 0-summer ) ); else credit->setText( conv.convert( summer ) ); } } } accounts.push_back( edit ); credits.push_back( credit ); debits.push_back( debit ); resizeContents( 400, getNumSplits()*ls ); QLineEdit * wdgs[]={ edit, credit, debit }; for( uint i=0; i<3; i++ ){ addChild( wdgs[i], header->sectionPos( i ), y ); wdgs[i]->show(); } edit->setFocus(); return edit; } uint AccountArea::getNumSplits() const { return accounts.size(); } int AccountArea::lineSize() const { return fontMetrics().height()+5; } void AccountArea::clearSplits(){ credits.clear(); debits.clear(); accounts.clear(); } QHaccTable AccountArea::getSplits(){ uint nspl=getNumSplits(); QHaccTable splits( QC::SCOLS, QC::SCOLTYPES, 0, nspl ); Split adder( QC::SCOLS ); const MonCon& conv=engine->converter(); QLineEdit ** carr=new QLineEdit *[nspl]; QLineEdit ** darr=new QLineEdit *[nspl]; QLineEdit ** aarr=new QLineEdit *[nspl]; list::iterator it=credits.begin(); int i=0; for( ; it!=credits.end(); ++it ) carr[i++]=*it; it=debits.begin(); i=0; for( ; it!=debits.end(); ++it ) darr[i++]=*it; list::iterator it2=accounts.begin(); it2=accounts.begin(); i=0; for( ; it2!=accounts.end(); ++it2 ) aarr[i++]=*it2; for ( uint i=0; itext(); QString debstr=darr[i]->text(); QString percsum, loansum, marksum, shares, price; bool perc=false; bool loan=false; bool mark=false; // even though these numbers come from the interface, // we don't care about using MonCon to convert them // because we're really just counting at this point int cr=conv.converti( credstr, Engine, Engine ); int db=conv.converti( debstr, Engine, Engine ); // figure out if we have any percentage amounts, the * in the last // check is for a remainder amount if( credstr.endsWith( "%" ) || credstr.endsWith( "%t" ) || credstr.endsWith( "%a" ) ){ perc=true; percsum=credstr; } else if( debstr.endsWith( "%" ) || debstr.endsWith( "%t" ) || debstr.endsWith( "%a" ) ){ perc=true; percsum="-"+debstr; } else if( debstr=="p" || credstr=="p" ){ loan=true; loansum="p"; } else if( debstr=="i" || credstr=="i" ){ loan=true; loansum="i"; } else if( credstr==QC::REMAINDERVAL || debstr==QC::REMAINDERVAL ){ perc=true; percsum=QC::REMAINDERVAL; } else if( Utils::isMarket( credstr, shares, price ) ){ mark=true; marksum=QString::number( shares.toFloat()*price.toFloat(), 'f', QC::DECIMALS ); } else if( Utils::isMarket( debstr, shares, price ) ){ mark=true; marksum=QString::number( shares.toFloat()*price.toFloat(), 'f', QC::DECIMALS ); } Account acct; if( cr-db!=0 || perc || loan ){ QLineEdit * acctname=aarr[i]; QString aval=acctname->text(); // make any necessary accounts if( AccountAreaFrame::verifyOrMakeA( engine, aval, acct ) ) acctname->setText( engine->getFNameOfA( acct ) ); if( !acct.isNull() ){ adder.set( QC::SACCTID, acct[QC::AID] ); QString str; if( perc ) str=percsum; else if( loan ) str=loansum; else if( mark ){ } // else do the display conversion using MonCon else str=conv.convert( cr-db, Preference, Engine ); adder.set( QC::SSUM, str ); splits+=adder; } } } delete [] carr; delete [] darr; delete [] aarr; return splits; } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * ACCOUNTAREA FRAME * * * * * * * * * * * * * * * * * * * * * * * * * * * */ AccountAreaFrame::AccountAreaFrame( QHacc * e, QHaccTable& tbl, QWidget * p, const char * n ) : QFrame( p, n ) { area=new AccountArea( e, tbl, this ); QPushButton * b=new QPushButton( tr( "add split" ), this ); connect( b, SIGNAL( clicked() ), SLOT( adder() ) ); QGridLayout * layout=new QGridLayout( this, 10, 1 ); layout->addMultiCellWidget( area, 0, 8, 0, 0 ); layout->addMultiCellWidget( b, 9, 9, 0, 0 ); } AccountAreaFrame::~AccountAreaFrame(){} QHaccTable AccountAreaFrame::getSplits(){ return area->getSplits(); } void AccountAreaFrame::addSplit( const TableRow& t ){ area->addSplit( t ); } void AccountAreaFrame::adder(){ area->addSplit( Transaction() ); } void AccountAreaFrame::clearSplits(){ area->clearSplits(); } bool AccountAreaFrame::verifyOrMakeA( QHacc * engine, const QString& aname, TableRow& acct ){ acct=TableRow(); if( aname.isEmpty() ){ AccountDlg qd( engine, acct, 0, 0, true ); if( qd.exec() ) acct=qd.getAccount(); } else{ acct=engine->getA( aname ); // if we didn't find the account, but we're using ANUMs, we need to // remove the number from the text before trying to get the account // from the engine if( acct.isNull() && engine->getBP( "USEANUMSFORNAMES" ) ){ int f=aname.find( "-" ); // find where the (possible) acct number starts if( f!=-1 ) acct=engine->getA( aname.mid( f+1 ) ); } } return !acct.isNull(); } QString AccountAreaFrame::displayAName( QHacc * engine, const TableRow& shortacct, bool useanums ){ const QString anum=shortacct[AccountArea::NUM].gets(); QString anamer=shortacct[AccountArea::NAME].gets(); bool longnamer=( useanums && !anum.isEmpty() ); if( shortacct[AccountArea::PID]==0 ){ // no parent if( longnamer ) anamer=anum+"-"+anamer; } else{ anamer=engine->getFNameOfA( shortacct[AccountArea::PID].getu() ) +QC::ASEP+anamer; if( longnamer ) anamer=anum+"-"+anamer; } return anamer; }