F:/KPlato/koffice/kplato/kptaccountsview.cc

Aller à la documentation de ce fichier.
00001 /* This file is part of the KDE project
00002   Copyright (C) 2005 - 2006 Dag Andersen kplato@kde.org>
00003 
00004   This library is free software; you can redistribute it and/or
00005   modify it under the terms of the GNU Library General Public
00006   License as published by the Free Software Foundation;
00007   version 2 of the License, or (at your option) any later version.
00008 
00009   This library is distributed in the hope that it will be useful,
00010   but WITHOUT ANY WARRANTY; without even the implied warranty of
00011   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012   Library General Public License for more details.
00013 
00014   You should have received a copy of the GNU Library General Public License
00015   along with this library; see the file COPYING.LIB.  If not, write to
00016   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00017   Boston, MA 02110-1301, USA.
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     //kDebug()<<k_funcinfo<<endl;
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     //kDebug()<<k_funcinfo<<endl;
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     //kDebug()<<k_funcinfo<<endl;
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     //m_dlv->setSizes(list);
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     //kDebug()<<k_funcinfo<<endl;
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         /*        a->setOpen(true);
00158                 a->setExpandable(!it.peekPrevious()->isElement());*/
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         /*        AccountsView::AccountItem *a = new AccountsView::AccountItem(i18n("Subaccounts"), acc, parent);
00168                 DoubleListViewBase::SlaveListItem *i = new DoubleListViewBase::SlaveListItem(a, parent->period);
00169                 a->period = i;*/
00170 
00171         initAccList( acc->accountList(), parent );
00172     }
00173     //     AccountsView::AccountItem *a = new AccountsView::AccountItem(i18n("Variance"), acc, parent, true);
00174     //     DoubleListViewBase::SlaveListItem *i = new DoubleListViewBase::SlaveListItem(a, parent->period, true);
00175     //     a->period = i;
00176     //
00177     //     a = new AccountsView::AccountItem(i18n("Actual"), acc, parent);
00178     //     i = new DoubleListViewBase::SlaveListItem(a, parent->period);
00179     //     a->period = i;
00180     //
00181     //     a = new AccountsView::AccountItem(i18n("Planned"), acc, parent);
00182     //     i = new DoubleListViewBase::SlaveListItem(a, parent->period);
00183     //     a->period = i;
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         /*        a->setOpen(true);
00193                 a->setExpandable(!it.peekPrevious()->isElement());*/
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     //kDebug()<<k_funcinfo<<endl;
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     // Add columns for selected period/periods
00225     QDate start = m_project.startTime().date();
00226     QDate end = m_date;
00227     //kDebug()<<k_funcinfo<<start<<" - "<<end<<endl;
00228     QStringList df;
00229     if ( m_period == 0 ) { //Daily
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 ) { //Weekly
00254         //TODO make this user controlled
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             //kDebug()<<k_funcinfo<<c<<": "<<dt<<"-"<<pend<<" : "<<end<<endl;
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 ); // 1. next week
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 ) { //Monthly
00302         //TODO make this user controlled
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             //kDebug()<<k_funcinfo<<c<<": "<<dt<<"-"<<pend<<" : "<<end<<endl;
00310             m << cal->monthName( dt, true ) + QString( " %1" ).arg( dt.year() );
00311             dt = pend.addDays( 1 ); // 1. next month
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 ); // 1. next month
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     //kDebug()<<k_funcinfo<<endl;
00353     uint top, left, bottom, right;
00354     printer.margins( &top, &left, &bottom, &right );
00355     //kDebug()<<m.width()<<"x"<<m.height()<<" : "<<top<<", "<<left<<", "<<bottom<<", "<<right<<" : "<<size()<<endl;
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     //kDebug()<<"p="<<preg<<endl;
00362     //p.drawRect(preg.x(), preg.y(), preg.width()-1, preg.height()-1);
00363     double scale = qMin( ( double ) preg.width() / ( double ) size().width(), ( double ) preg.height() / ( double ) ( size().height() ) );
00364     //kDebug()<<"scale="<<scale<<endl;
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     //kDebug()<<k_funcinfo<<"---->"<<endl;
00378     QList<int> list;
00379     list << context.accountsviewsize << context.periodviewsize;
00380     //m_dlv->setSizes(list); //NOTE: Doesn't always work!
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     //kDebug()<<k_funcinfo<<"<----"<<endl;
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         /*        if (m_accounts.findAccount(*it)) {
00395                     QTreeWidgetItemIterator lit(m_dlv->masterListView());
00396                     for (; lit.current(); ++lit) {
00397                         if (lit.current()->text(0) == (*it)) {
00398                             m_dlv->setOpen(lit.current(), false);
00399                             break;
00400                         }
00401                     }
00402                 }*/
00403     }
00404 }
00405 
00406 void AccountsView::getContext( Context::Accountsview &context ) const
00407 {
00408     //kDebug()<<k_funcinfo<<endl;
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     //kDebug()<<k_funcinfo<<"sizes="<<sizes()[0]<<","<<sizes()[1]<<endl;
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     /*    for (QTreeWidgetItem *i = item; i; i = i->nextSibling()) {
00425             if (!i->isOpen()) {
00426                 context.closedItems.append(i->text(0));
00427                 //kDebug()<<k_funcinfo<<"add closed "<<i->text(0)<<endl;
00428             }
00429             getContextClosedItems(context, i->firstChild());
00430         }*/
00431 }
00432 
00433 void AccountsView::slotConfigure()
00434 {
00435     //kDebug()<<k_funcinfo<<endl;
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 }  //KPlato namespace
00454 
00455 #include "kptaccountsview.moc"

Généré le Wed Nov 22 23:40:55 2006 pour KPlato par  doxygen 1.5.1-p1