00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "kptaccountsview.h"
00021
00022 #include "kptaccountsviewconfigdialog.h"
00023 #include "kptcontext.h"
00024 #include "kptdatetime.h"
00025 #include "kptproject.h"
00026 #include "kptview.h"
00027 #include "kpteffortcostmap.h"
00028
00029 #include <QApplication>
00030 #include <QComboBox>
00031 #include <QDateTime>
00032 #include <q3datetimeedit.h>
00033 #include <QLabel>
00034 #include <QLayout>
00035 #include <QPainter>
00036 #include <qpalette.h>
00037 #include <QPushButton>
00038 #include <q3popupmenu.h>
00039 #include <QSizePolicy>
00040 #include <q3paintdevicemetrics.h>
00041 #include <QHBoxLayout>
00042 #include <QVBoxLayout>
00043
00044 #include <kcalendarsystem.h>
00045 #include <kglobal.h>
00046 #include <klocale.h>
00047 #include <kprinter.h>
00048
00049 #include <kdebug.h>
00050
00051 namespace KPlato
00052 {
00053
00054 AccountsView::AccountItem::AccountItem( Account *a, QTreeWidget *parent, bool highlight )
00055 : DoubleListViewBase::MasterListItem( parent, a->name(), highlight ),
00056 account( a )
00057 {
00058 if ( parent->columnCount() >= 3 ) {
00059 setText( 2, a->description() );
00060 }
00061
00062 }
00063 AccountsView::AccountItem::AccountItem( Account *a, QTreeWidgetItem *p, bool highlight )
00064 : DoubleListViewBase::MasterListItem( p, a->name(), highlight ),
00065 account( a )
00066 {
00067 if ( treeWidget() && columnCount() >= 3 ) {
00068 setText( 2, a->description() );
00069 }
00070
00071 }
00072
00073 AccountsView::AccountItem::AccountItem( QString text, Account *a, QTreeWidgetItem *parent, bool highlight )
00074 : DoubleListViewBase::MasterListItem( parent, text, highlight ),
00075 account( a )
00076 {
00077
00078 }
00079
00080 void AccountsView::AccountItem::add
00081 ( int col, const QDate &date, const EffortCost &ec )
00082 {
00083 EffortCost & cm = costMap.add( date, ec );
00084 if ( m_slaveItem )
00085 m_slaveItem->setText( col, KGlobal::locale() ->formatMoney( cm.cost(), "", 0 ) );
00086 }
00087
00088 AccountsView::AccountsView( Project &project, View *view, QWidget *parent )
00089 : ViewBase( view, parent ),
00090 m_project( project ),
00091 m_accounts( project.accounts() )
00092 {
00093
00094 m_date = QDate::currentDate();
00095 m_period = 0;
00096 m_periodTexts << i18n( "Day" ) << i18n( "Week" ) << i18n( "Month" );
00097 m_cumulative = false;
00098
00099 QVBoxLayout *lay1 = new QVBoxLayout( this, 0, KDialog::spacingHint() );
00100
00101 QHBoxLayout *lay2 = new QHBoxLayout( 0, 0, KDialog::spacingHint() );
00102 m_label = new QLabel( this );
00103 m_label->setFrameShape( QLabel::StyledPanel );
00104 m_label->setFrameShadow( QLabel::Sunken );
00105 m_label->setAlignment( int( Qt::TextWordWrap | Qt::AlignVCenter ) );
00106 lay2->addWidget( m_label );
00107 m_changeBtn = new QPushButton( i18n( "Configure..." ), this );
00108 m_changeBtn->setSizePolicy( QSizePolicy( ( QSizePolicy::SizeType ) 0, ( QSizePolicy::SizeType ) 0, 0, 0, m_changeBtn->sizePolicy().hasHeightForWidth() ) );
00109 lay2->addWidget( m_changeBtn );
00110 lay1->addLayout( lay2 );
00111
00112 m_dlv = new DoubleListViewBase( this, true );
00113 m_dlv->setNameHeader( i18n( "Account" ) );
00114
00115 init();
00116
00117 lay1->addWidget( m_dlv );
00118
00119 connect( this, SIGNAL( configChanged() ), SLOT( slotUpdate() ) );
00120 connect( m_changeBtn, SIGNAL( clicked() ), SLOT( slotConfigure() ) );
00121
00122 QList<int> list = m_dlv->sizes();
00123 int tot = list[ 0 ] + list[ 1 ];
00124 list[ 0 ] = qMin( 35, tot );
00125 list[ 1 ] = tot - list[ 0 ];
00126
00127 }
00128
00129 void AccountsView::setZoom( double zoom )
00130 {
00131 Q_UNUSED( zoom );
00132 }
00133
00134 void AccountsView::init()
00135 {
00136 m_date = QDate::currentDate();
00137 m_period = 0;
00138 initAccList( m_accounts.accountList() );
00139 }
00140
00141 void AccountsView::draw()
00142 {
00143
00144 Context::Accountsview context;
00145 getContextClosedItems( context, m_dlv->masterListView() ->topLevelItem( 0 ) );
00146 initAccList( m_accounts.accountList() );
00147 setContextClosedItems( context );
00148 slotUpdate();
00149 }
00150
00151 void AccountsView::initAccList( const AccountList &list )
00152 {
00153 m_dlv->clearLists();
00154 AccountListIterator it = list;
00155 for ( it.toBack(); it.hasPrevious(); it.previous() ) {
00156 AccountsView::AccountItem * a = new AccountsView::AccountItem( it.peekPrevious(), m_dlv->masterListView() );
00157
00158
00159 initAccSubItems( it.peekPrevious(), a );
00160 }
00161 createPeriods();
00162 }
00163
00164 void AccountsView::initAccSubItems( Account *acc, AccountsView::AccountItem *parent )
00165 {
00166 if ( !acc->accountList().isEmpty() ) {
00167
00168
00169
00170
00171 initAccList( acc->accountList(), parent );
00172 }
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185 }
00186
00187 void AccountsView::initAccList( const AccountList &list, AccountsView::AccountItem *parent )
00188 {
00189 AccountListIterator it = list;
00190 for ( it.toBack(); it.hasPrevious(); it.previous() ) {
00191 AccountsView::AccountItem * a = new AccountsView::AccountItem( it.peekPrevious(), parent );
00192
00193
00194 initAccSubItems( it.peekPrevious(), a );
00195 }
00196 }
00197
00198 void AccountsView::clearPeriods()
00199 {
00200 m_dlv->clearSlaveList();
00201 }
00202
00203 void AccountsView::createPeriods()
00204 {
00205 m_dlv->createSlaveItems();
00206 }
00207
00208 void AccountsView::slotUpdate()
00209 {
00210
00211 QApplication::setOverrideCursor( Qt::WaitCursor );
00212 createPeriods();
00213 KLocale *locale = KGlobal::locale();
00214 const KCalendarSystem *cal = locale->calendar();
00215
00216 QString t;
00217 if ( m_cumulative ) {
00218 t += " <b>" + i18n( "Cumulative" ) + "</b> ";
00219 }
00220 t += i18n( "Cut-off date:%1", "<b>" + locale->formatDate( m_date, true ) + "</b>" );
00221 t += " " + i18n( "Periodicity:%1", "<b>" + periodText( m_period ) + "</b>" );
00222 m_label->setText( t );
00223
00224
00225 QDate start = m_project.startTime().date();
00226 QDate end = m_date;
00227
00228 QStringList df;
00229 if ( m_period == 0 ) {
00230 for ( QDate dt = start; dt <= end; dt = cal->addDays( dt, 1 ) ) {
00231 df << locale->formatDate( dt, true );
00232 }
00233 m_dlv->setSlaveLabels( df );
00234 foreach ( QTreeWidgetItem * i, m_dlv->masterItems() ) {
00235 AccountsView::AccountItem * item = dynamic_cast<AccountsView::AccountItem*>( i );
00236 if ( !item || !item->account || !item->account->isElement() ) {
00237 continue;
00238 }
00239 item->costMap = m_accounts.plannedCost( *( item->account ), start, end );
00240 double cost = 0.0;
00241 int col = 0;
00242 for ( QDate d = start; d <= end; d = cal->addDays( d, 1 ), ++col ) {
00243 EffortCost & ec = item->costMap.effortCostOnDate( d );
00244 cost = ( m_cumulative ? cost + ec.cost() : ec.cost() );
00245 item->setSlaveItem( col, cost );
00246 m_cumulative ? item->setTotal( cost ) : item->addToTotal( cost );
00247 }
00248 }
00249 m_dlv->calculate();
00250 QApplication::restoreOverrideCursor();
00251 return ;
00252 }
00253 if ( m_period == 1 ) {
00254
00255 int weekStartDay = locale->weekStartDay();
00256 QStringList t;
00257 QDate dt = start;
00258 QDate pend = cal->addDays( dt, 7 + weekStartDay - 1 - cal->dayOfWeek( dt ) );
00259 int c = 0;
00260 for ( ; pend <= end; ++c ) {
00261
00262 int y;
00263 int w = cal->weekNumber( dt, &y );
00264 t << i18nc( "<week>-<year>", "%1-%2", w, y );
00265 dt = pend.addDays( 1 );
00266 pend = cal->addDays( pend, 7 );
00267 if ( ( pend.year() == end.year() ) && ( pend.weekNumber() == end.weekNumber() ) ) {
00268 pend = end;
00269 }
00270 }
00271 m_dlv->setSlaveLabels( t );
00272 if ( c == 0 ) {
00273 QApplication::restoreOverrideCursor();
00274 return ;
00275 }
00276 foreach ( QTreeWidgetItem * i, m_dlv->masterItems() ) {
00277 AccountsView::AccountItem * item = dynamic_cast<AccountsView::AccountItem*>( i );
00278 if ( !item || !item->account || !item->account->isElement() ) {
00279 continue;
00280 }
00281 item->costMap = m_accounts.plannedCost( *( item->account ), start, end );
00282 double cost = 0.0;
00283 QDate d = start;
00284 QDate pend = cal->addDays( d, 7 + weekStartDay - 1 - cal->dayOfWeek( d ) );
00285 for ( int col = 0; pend <= end; ++col ) {
00286 double cst = item->costMap.cost( d, d.daysTo( pend ) + 1 );
00287 cost = ( m_cumulative ? cost + cst : cst );
00288 item->setSlaveItem( col, cost );
00289 m_cumulative ? item->setTotal( cost ) : item->addToTotal( cost );
00290 d = pend.addDays( 1 );
00291 pend = cal->addDays( pend, 7 );
00292 if ( ( pend.year() == end.year() ) && ( pend.weekNumber() == end.weekNumber() ) ) {
00293 pend = end;
00294 }
00295 }
00296 }
00297 m_dlv->calculate();
00298 QApplication::restoreOverrideCursor();
00299 return ;
00300 }
00301 if ( m_period == 2 ) {
00302
00303 QStringList m;
00304 QDate dt = start;
00305 QDate pend;
00306 cal->setYMD( pend, dt.year(), dt.month(), dt.daysInMonth() );
00307 int c = 0;
00308 for ( ; pend <= end; ++c ) {
00309
00310 m << cal->monthName( dt, true ) + QString( " %1" ).arg( dt.year() );
00311 dt = pend.addDays( 1 );
00312 pend = cal->addDays( pend, dt.daysInMonth() );
00313 if ( ( pend.year() == end.year() ) && ( pend.month() == end.month() ) ) {
00314 pend = end;
00315 }
00316 }
00317 m_dlv->setSlaveLabels( m );
00318 if ( c == 0 ) {
00319 QApplication::restoreOverrideCursor();
00320 return ;
00321 }
00322 foreach ( QTreeWidgetItem * i, m_dlv->masterItems() ) {
00323 AccountsView::AccountItem * item = dynamic_cast<AccountsView::AccountItem*>( i );
00324 if ( !item || !item->account || !item->account->isElement() ) {
00325 continue;
00326 }
00327 item->costMap = m_accounts.plannedCost( *( item->account ), start, end );
00328 double cost = 0.0;
00329 QDate d = start;
00330 cal->setYMD( pend, d.year(), d.month(), d.daysInMonth() );
00331 for ( int col = 0; pend <= end; ++col ) {
00332 double cst = item->costMap.cost( d, d.daysTo( pend ) + 1 );
00333 cost = ( m_cumulative ? cost + cst : cst );
00334 item->setSlaveItem( col, cost );
00335 m_cumulative ? item->setTotal( cost ) : item->addToTotal( cost );
00336 d = pend.addDays( 1 );
00337 pend = cal->addDays( pend, d.daysInMonth() );
00338 if ( ( pend.year() == end.year() ) && ( pend.month() == end.month() ) ) {
00339 pend = end;
00340 }
00341 }
00342 }
00343 m_dlv->calculate();
00344 QApplication::restoreOverrideCursor();
00345 return ;
00346 }
00347 QApplication::restoreOverrideCursor();
00348 }
00349
00350 void AccountsView::print( KPrinter &printer )
00351 {
00352
00353 uint top, left, bottom, right;
00354 printer.margins( &top, &left, &bottom, &right );
00355
00356 QPainter p;
00357 p.begin( &printer );
00358 p.setViewport( left, top, printer.width() - left - right, printer.height() - top - bottom );
00359 p.setClipRect( left, top, printer.width() - left - right, printer.height() - top - bottom );
00360 QRect preg = p.clipRegion().boundingRect();
00361
00362
00363 double scale = qMin( ( double ) preg.width() / ( double ) size().width(), ( double ) preg.height() / ( double ) ( size().height() ) );
00364
00365 if ( scale < 1.0 ) {
00366 p.scale( scale, scale );
00367 }
00368 QPixmap labelPixmap = QPixmap::grabWidget( m_label );
00369 p.drawPixmap( m_label->pos(), labelPixmap );
00370 p.translate( 0, m_label->size().height() );
00371 m_dlv->paintContents( &p );
00372 p.end();
00373 }
00374
00375 bool AccountsView::setContext( Context::Accountsview &context )
00376 {
00377
00378 QList<int> list;
00379 list << context.accountsviewsize << context.periodviewsize;
00380
00381 m_date = context.date;
00382 if ( !m_date.isValid() )
00383 m_date = QDate::currentDate();
00384 m_period = context.period;
00385 m_cumulative = context.cumulative;
00386 setContextClosedItems( context );
00387
00388 return true;
00389 }
00390
00391 void AccountsView::setContextClosedItems( Context::Accountsview &context )
00392 {
00393 for ( QStringList::ConstIterator it = context.closedItems.begin(); it != context.closedItems.end(); ++it ) {
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403 }
00404 }
00405
00406 void AccountsView::getContext( Context::Accountsview &context ) const
00407 {
00408
00409 context.accountsviewsize = m_dlv->sizes() [ 0 ];
00410 context.periodviewsize = m_dlv->sizes() [ 1 ];
00411 context.date = m_date;
00412 context.period = m_period;
00413 context.cumulative = m_cumulative;
00414
00415
00416 getContextClosedItems( context, m_dlv->masterListView() ->topLevelItem( 0 ) );
00417 }
00418
00419
00420 void AccountsView::getContextClosedItems( Context::Accountsview &context, QTreeWidgetItem *item ) const
00421 {
00422 if ( item == 0 )
00423 return ;
00424
00425
00426
00427
00428
00429
00430
00431 }
00432
00433 void AccountsView::slotConfigure()
00434 {
00435
00436 AccountsviewConfigDialog * dia = new AccountsviewConfigDialog( m_date, m_period, m_periodTexts, m_cumulative, this );
00437 if ( dia->exec() ) {
00438 m_date = dia->date();
00439 m_period = dia->period();
00440 m_cumulative = dia->isCumulative();
00441 emit configChanged();
00442 }
00443 delete dia;
00444 }
00445
00446 QString AccountsView::periodText( int offset )
00447 {
00448 if ( offset < m_periodTexts.count() )
00449 return m_periodTexts[ offset ];
00450 return QString();
00451 }
00452
00453 }
00454
00455 #include "kptaccountsview.moc"