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

Aller à la documentation de ce fichier.
00001 /* This file is part of the KDE project
00002   Copyright (C) 2002 - 2005 Dag Andersen <danders@get2net.dk>
00003   Copyright (C) 2006 Raphael Langerhorst <raphael.langerhorst@kdemail.net>
00004 
00005   This library is free software; you can redistribute it and/or
00006   modify it under the terms of the GNU Library General Public
00007   License as published by the Free Software Foundation;
00008   version 2 of the License, or (at your option) any later version.
00009 
00010   This library is distributed in the hope that it will be useful,
00011   but WITHOUT ANY WARRANTY; without even the implied warranty of
00012   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013   Library General Public License for more details.
00014 
00015   You should have received a copy of the GNU Library General Public License
00016   along with this library; see the file COPYING.LIB.  If not, write to
00017   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00018 * Boston, MA 02110-1301, USA.
00019 */
00020 
00021 #include "kptganttview.h"
00022 
00023 #include "kptappointment.h"
00024 #include "kptpart.h"
00025 #include "kptview.h"
00026 #include "kptcanvasitem.h"
00027 #include "kptnode.h"
00028 #include "kptpart.h"
00029 #include "kptproject.h"
00030 #include "kpttask.h"
00031 #include "kptresource.h"
00032 #include "kptdatetime.h"
00033 #include "kpttaskappointmentsview.h"
00034 #include "kptrelation.h"
00035 #include "kptcontext.h"
00036 #include "kptschedule.h"
00037 
00038 #include "KDGanttView.h"
00039 #include "KDGanttViewItem.h"
00040 #include "KDGanttViewTaskItem.h"
00041 #include "KDGanttViewSummaryItem.h"
00042 #include "KDGanttViewEventItem.h"
00043 
00044 #include <kdebug.h>
00045 
00046 #include <q3listview.h>
00047 #include <q3popupmenu.h>
00048 
00049 #include <QLineEdit>
00050 #include <QWidget>
00051 #include <QLabel>
00052 #include <QLayout>
00053 #include <QSpinBox>
00054 #include <QSplitter>
00055 #include <QStringList>
00056 #include <QTabWidget>
00057 #include <QPainter>
00058 
00059 #include <klocale.h>
00060 #include <kglobal.h>
00061 #include <kprinter.h>
00062 #include <kmessagebox.h>
00063 
00064 namespace KPlato
00065 {
00066 
00067 class MyKDGanttView : public KDGanttView
00068 {
00069 public:
00070     MyKDGanttView( QWidget *parent, const char *name )
00071             : KDGanttView( parent, name )
00072     {
00073         setAllConnectorsEnabled( false );
00074         setConnectorEnabled( KDGanttViewItem::TaskLinkStart, true );
00075         setConnectorEnabled( KDGanttViewItem::TaskLinkEnd, true );
00076         setAutoScrollEnabled( true );
00077     }
00078     /*    virtual QSize sizeHint() const {
00079             return minimumSizeHint(); //HACK: koshell splitter minimumSize problem
00080         }*/
00081 };
00082 
00083 GanttView::GanttView( QWidget *parent, bool readWrite, const char* name )
00084         : ViewBase( parent ),
00085         m_readWrite( readWrite ),
00086         m_currentItem( 0 ),
00087         m_taskView( 0 ),
00088         m_firstTime( true ),
00089         m_project( 0 )
00090 {
00091     kDebug() << " ---------------- KPlato: Creating GanttView ----------------" << endl;
00092 
00093     QVBoxLayout *l = new QVBoxLayout( this );
00094     l->setMargin( 0 );
00095     m_splitter = new QSplitter( this );
00096     l->addWidget( m_splitter );
00097     m_splitter->setOrientation( Qt::Vertical );
00098 
00099     m_gantt = new MyKDGanttView( m_splitter, "Gantt view" );
00100 
00101     m_showExpected = true;
00102     m_showOptimistic = false;
00103     m_showPessimistic = false;
00104     m_showResources = false; // FIXME
00105     m_showTaskName = false; // FIXME
00106     m_showTaskLinks = false; // FIXME
00107     m_showProgress = false; //FIXME
00108     m_showPositiveFloat = false; //FIXME
00109     m_showCriticalTasks = false; //FIXME
00110     m_showCriticalPath = false; //FIXME
00111     m_showNoInformation = false; //FIXME
00112     m_showAppointments = false;
00113 
00114     m_gantt->setHeaderVisible( true );
00115     m_gantt->addColumn( i18nc( "Work Breakdown Structure", "WBS" ) );
00116     // HACK: need changes to kdgantt
00117     KDGanttViewTaskItem *item = new KDGanttViewTaskItem( m_gantt );
00118     Q3ListView *lv = item->listView();
00119     lv->header() ->moveSection( 1, 0 );
00120 
00121     m_gantt->setScale( KDGanttView::Day );
00122     m_gantt->setShowLegendButton( false );
00123     m_gantt->setShowHeaderPopupMenu();
00124     m_taskView = new TaskAppointmentsView( m_splitter );
00125     // hide TaskAppointmentsView
00126     /*    Q3ValueList<int> list = sizes();
00127         list[0] += list[1];
00128         list[1] = 0;
00129         setSizes(list);*/
00130     m_taskView->hide();
00131 
00132     setReadWriteMode( readWrite );
00133 
00134     connect( m_gantt, SIGNAL( lvContextMenuRequested ( KDGanttViewItem *, const QPoint &, int ) ), SLOT ( popupMenuRequested( KDGanttViewItem *, const QPoint &, int ) ) );
00135 
00136     connect( m_gantt, SIGNAL( lvCurrentChanged( KDGanttViewItem* ) ), SLOT ( currentItemChanged( KDGanttViewItem* ) ) );
00137 
00138     connect( m_gantt, SIGNAL( lvItemDoubleClicked( KDGanttViewItem* ) ), SLOT ( slotItemDoubleClicked( KDGanttViewItem* ) ) );
00139 
00140     m_taskLinks.setAutoDelete( true );
00141 
00142     if ( m_gantt->firstChild() ) {
00143         m_gantt->firstChild() ->listView() ->setCurrentItem( m_gantt->firstChild() );
00144         m_gantt->firstChild() ->listView() ->setFocus();
00145     }
00146 }
00147 
00148 void GanttView::setZoom( double zoom )
00149 {
00150     kDebug() << "setting gantt zoom: " << zoom << endl;
00151     //m_gantt->setZoomFactor(zoom,true); NO!!! setZoomFactor() is something else
00152     m_taskView->setZoom( zoom );
00153 }
00154 
00155 void GanttView::show()
00156 {
00157     m_gantt->show();
00158 }
00159 
00160 void GanttView::clear()
00161 {
00162     m_gantt->clear();
00163     m_taskView->clear();
00164 }
00165 
00166 void GanttView::setShowTaskLinks( bool on )
00167 {
00168     m_showTaskLinks = on;
00169     m_gantt->setShowTaskLinks( on );
00170 }
00171 
00172 void GanttView::draw( Project &project )
00173 {
00174     m_project = &project;
00175     //kDebug()<<k_funcinfo<<endl;
00176     Schedule::Type type = Schedule::Expected;
00177     if ( m_showOptimistic ) {
00178         type = Schedule::Optimistic;
00179     } else if ( m_showPessimistic ) {
00180         type = Schedule::Pessimistic;
00181     }
00182     Schedule *sch = project.findSchedule( type );
00183     if ( sch ) {
00184         project.setCurrentSchedule( sch->id() );
00185     }
00186     //kDebug()<<k_funcinfo<<"Schedule: "<<(sch?sch->typeToString():"None")<<endl;
00187     m_gantt->setUpdateEnabled( false );
00188 
00189     clear();
00190     drawChildren( NULL, project );
00191     drawRelations();
00192 
00193     if ( m_firstTime ) {
00194         m_gantt->centerTimelineAfterShow( project.startTime().addDays( -1 ) );
00195         m_firstTime = false;
00196     }
00197     m_gantt->setUpdateEnabled( true );
00198     currentItemChanged( m_currentItem );
00199 }
00200 
00201 void GanttView::drawChanges( Project &project )
00202 {
00203     m_project = &project; //FIXME Only draw changes on same project
00204     drawChanges();
00205 }
00206 
00207 void GanttView::drawChanges()
00208 {
00209     //kDebug()<<k_funcinfo<<endl;
00210     Schedule::Type type = Schedule::Expected;
00211     if ( m_showOptimistic ) {
00212         type = Schedule::Optimistic;
00213     } else if ( m_showPessimistic ) {
00214         type = Schedule::Pessimistic;
00215     }
00216     Schedule *sch = m_project->findSchedule( type );
00217     if ( sch ) {
00218         m_project->setCurrentSchedule( sch->id() );
00219     }
00220     //kDebug()<<k_funcinfo<<"Schedule: "<<(sch?sch->typeToString():"None")<<endl;
00221     m_gantt->setUpdateEnabled( false );
00222     resetDrawn( m_gantt->firstChild() );
00223     updateChildren( m_project ); // don't draw project
00224     removeNotDrawn( m_gantt->firstChild() );
00225 
00226     m_taskLinks.clear();
00227     drawRelations();
00228 
00229     m_gantt->setUpdateEnabled( true );
00230     if ( m_currentItem == 0 && m_gantt->firstChild() ) {
00231         m_gantt->firstChild() ->listView() ->setCurrentItem( m_gantt->firstChild() );
00232         currentItemChanged( m_gantt->firstChild() ); //hmmm
00233     }
00234     currentItemChanged( m_currentItem );
00235 }
00236 
00237 void GanttView::drawOnPainter( QPainter* painter, const QRect rect )
00238 {
00239     // Assume clipping is already set
00240 
00241     // Fill out the rect by adding ticks to right side of the timeline
00242     QSize s = m_gantt->drawContents( 0, false, true );
00243     while ( s.width() < rect.width() ) {
00244         m_gantt->addTicksRight();
00245         m_gantt->setTimelineToEnd();
00246         s = m_gantt->drawContents( 0, false, true );
00247     }
00248     kDebug() << k_funcinfo << rect << " : " << s << endl;
00249     painter->save();
00250 
00251     //    QValueList<int> sizes = m_taskView->sizes();
00252     //    if (sizes.count() >= 2)
00253     //    {
00254     //        int first = sizes[0];
00255     //        int second = sizes[1];
00256     //        sizes.pop_front();
00257     //        sizes.pop_front();
00258     //        sizes.prepend(first+second);
00259     //        sizes.prepend(0);
00260     //        m_taskView->setSizes(sizes);
00261     //    }
00262     //    else
00263     //        kWarning() << "Apparently the task view splitter contains less than 2 parts!" << endl;
00264 
00265     //    bool showlistview = m_gantt->showListView();
00266     //    int listviewwidth = m_gantt->listViewWidth();
00267     //    m_gantt->setShowListView(false);
00268     //    m_gantt->setListViewWidth(0);
00269 
00270     //    m_gantt->setGanttMaximumWidth(rect.x());
00271     m_gantt->drawContents( painter, false, true );
00272     //    m_gantt->setShowListView(showlistview);
00273     //    m_gantt->setListViewWidth(listviewwidth);
00274 
00275     //   m_taskView->drawContents(painter); //TODO doesn't seem to do very much
00276     painter->restore();
00277 }
00278 
00279 KDGanttViewItem *GanttView::findItem( Node *node )
00280 {
00281     return findItem( node, m_gantt->firstChild() );
00282 }
00283 
00284 KDGanttViewItem *GanttView::findItem( Node *node, KDGanttViewItem *item )
00285 {
00286     for ( ; item; item = item->nextSibling() ) {
00287         if ( node == getNode( item ) ) {
00288             return item;
00289         }
00290         KDGanttViewItem *i = findItem( node, item->firstChild() );
00291         if ( i )
00292             return i;
00293     }
00294     return 0;
00295 }
00296 
00297 Node *GanttView::getNode( KDGanttViewItem *item ) const
00298 {
00299     if ( item ) {
00300         if ( item->type() == KDGanttViewItem::Event ) {
00301             return static_cast<GanttViewEventItem *>( item ) ->getTask();
00302         } else if ( item->type() == KDGanttViewItem::Task ) {
00303             return static_cast<GanttViewTaskItem *>( item ) ->getTask();
00304         } else if ( item->type() == KDGanttViewItem::Summary ) {
00305             return static_cast<GanttViewSummaryItem *>( item ) ->getNode();
00306         }
00307     }
00308     return 0;
00309 }
00310 
00311 bool GanttView::isDrawn( KDGanttViewItem *item )
00312 {
00313     if ( item ) {
00314         if ( item->type() == KDGanttViewItem::Event ) {
00315             return static_cast<GanttViewEventItem *>( item ) ->isDrawn();
00316         } else if ( item->type() == KDGanttViewItem::Task ) {
00317             return static_cast<GanttViewTaskItem *>( item ) ->isDrawn();
00318         } else if ( item->type() == KDGanttViewItem::Summary ) {
00319             return static_cast<GanttViewSummaryItem *>( item ) ->isDrawn();
00320         } else {
00321             kWarning() << k_funcinfo << "Unknown item type: " << item->type() << endl;
00322         }
00323     }
00324     return false;
00325 }
00326 
00327 void GanttView::setDrawn( KDGanttViewItem *item, bool state )
00328 {
00329     if ( item ) {
00330         if ( item->type() == KDGanttViewItem::Event ) {
00331             static_cast<GanttViewEventItem *>( item ) ->setDrawn( state );
00332         } else if ( item->type() == KDGanttViewItem::Task ) {
00333             static_cast<GanttViewTaskItem *>( item ) ->setDrawn( state );
00334         } else if ( item->type() == KDGanttViewItem::Summary ) {
00335             static_cast<GanttViewSummaryItem *>( item ) ->setDrawn( state );
00336         } else {
00337             kWarning() << k_funcinfo << "Unknown item type: " << item->type() << endl;
00338         }
00339     }
00340     return ;
00341 }
00342 
00343 void GanttView::resetDrawn( KDGanttViewItem *_item )
00344 {
00345     KDGanttViewItem * nextItem, *item = _item;
00346     for ( ; item; item = nextItem ) {
00347         nextItem = item->nextSibling();
00348         setDrawn( item, false );
00349         resetDrawn( item->firstChild() ); // then my children
00350     }
00351 }
00352 
00353 void GanttView::removeNotDrawn( KDGanttViewItem *_item )
00354 {
00355     KDGanttViewItem * nextItem, *item = _item;
00356     for ( ; item; item = nextItem ) {
00357         nextItem = item->nextSibling();
00358         if ( !isDrawn( item ) ) {
00359             if ( item == m_currentItem )
00360                 m_currentItem = 0;
00361             deleteItem( item );
00362         } else {
00363             removeNotDrawn( item->firstChild() ); // then my children
00364         }
00365     }
00366 }
00367 
00368 void GanttView::deleteItem( KDGanttViewItem *item )
00369 {
00370     //kDebug()<<k_funcinfo<<item->listViewText()<<endl;
00371     if ( item->parent() )
00372         item->parent() ->takeItem( item );
00373     else
00374         item->listView() ->takeItem( item );
00375     delete item;
00376 }
00377 
00378 KDGanttViewItem *GanttView::correctType( KDGanttViewItem *item, Node *node )
00379 {
00380     //kDebug()<<k_funcinfo<<item->listViewText()<<": "<<item->type()<<" node: "<<node->type()<<endl;
00381     switch ( node->type() ) {
00382         case Node::Type_Project:
00383             return item;
00384             break;
00385         case Node::Type_Summarytask:
00386         case Node::Type_Subproject:
00387             if ( item->type() == KDGanttViewItem::Summary )
00388                 return item;
00389             break;
00390         case Node::Type_Task:
00391             if ( item->type() == KDGanttViewItem::Task )
00392                 return item;
00393             break;
00394         case Node::Type_Milestone:
00395             if ( item->type() == KDGanttViewItem::Event )
00396                 return item;
00397             break;
00398         default:
00399             return item;
00400             break;
00401     }
00402     KDGanttViewItem *newItem = addNode( item->parent(), node, item );
00403     newItem->setOpen( item->isOpen() );
00404     deleteItem( item );
00405     return newItem;
00406 }
00407 
00408 void GanttView::correctPosition( KDGanttViewItem *item, Node *node )
00409 {
00410     KDGanttViewItem * after = findItem( node->siblingBefore() );
00411     if ( after ) {
00412         item->moveItem( after );
00413     }
00414 }
00415 
00416 KDGanttViewItem *GanttView::correctParent( KDGanttViewItem *item, Node *node )
00417 {
00418     KDGanttViewItem * p = findItem( node->getParent() );
00419     if ( p == item->parent() ) {
00420         return item;
00421     }
00422     KDGanttViewItem *newItem = addNode( p, node );
00423     newItem->setOpen( item->isOpen() );
00424     deleteItem( item );
00425     return newItem;
00426 }
00427 
00428 void GanttView::updateChildren( Node *parentNode )
00429 {
00430     //kDebug()<<k_funcinfo<<endl;
00431     foreach ( Node * n, parentNode->childNodeIterator() ) {
00432         updateNode( n );
00433     }
00434 }
00435 
00436 void GanttView::updateNode( Node *node )
00437 {
00438     //kDebug()<<k_funcinfo<<node->name()<<endl;
00439     KDGanttViewItem * item = findItem( node );
00440     if ( !item ) {
00441         item = addNode( findItem( node->getParent() ), node, findItem( node->siblingBefore() ) );
00442         if ( item && node->type() == Node::Type_Summarytask )
00443             updateChildren( node );
00444         return ;
00445     }
00446     item = correctType( item, node );
00447     item = correctParent( item, node );
00448     correctPosition( item, node );
00449 
00450     modifyNode( node );
00451 
00452     if ( node->type() == Node::Type_Summarytask )
00453         updateChildren( node );
00454 }
00455 
00456 void GanttView::modifyChildren( Node *node )
00457 {
00458     //kDebug()<<k_funcinfo<<endl;
00459     foreach ( Node * n, node->childNodeIterator() ) {
00460         modifyNode( n );
00461         modifyChildren( n );
00462     }
00463 }
00464 
00465 void GanttView::modifyNode( Node *node )
00466 {
00467     //kDebug()<<k_funcinfo<<endl;
00468     KDGanttViewItem * item = findItem( node );
00469     if ( !item ) {
00470         kDebug() << k_funcinfo << " Item not found" << endl;
00471         return ;
00472     }
00473     if ( node->type() == Node::Type_Project ) {
00474         return modifyProject( item, node );
00475     }
00476     if ( node->type() == Node::Type_Subproject ) {
00477         return modifyProject( item, node );
00478     }
00479     if ( node->type() == Node::Type_Summarytask ) {
00480         return modifySummaryTask( item, static_cast<Task *>( node ) );
00481     }
00482     if ( node->type() == Node::Type_Task ) {
00483         return modifyTask( item, static_cast<Task *>( node ) );
00484     }
00485     if ( node->type() == Node::Type_Milestone ) {
00486         return modifyMilestone( item, static_cast<Task *>( node ) );
00487     }
00488     return ;
00489 }
00490 
00491 void GanttView::modifyProject( KDGanttViewItem *item, Node *node )
00492 {
00493     //kDebug()<<k_funcinfo<<endl;
00494     item->setListViewText( node->name() );
00495     item->setListViewText( 1, node->wbs() );
00496     item->setStartTime( node->startTime() );
00497     item->setEndTime( node->endTime() );
00498     //item->setOpen(true);
00499     setDrawn( item, true );
00500 
00501 }
00502 
00503 void GanttView::modifySummaryTask( KDGanttViewItem *item, Task *task )
00504 {
00505     //kDebug()<<k_funcinfo<<endl;
00506     KLocale * locale = KGlobal::locale();
00507     //kDebug()<<k_funcinfo<<task->name()<<": "<<task->currentSchedule()<<", "<<task->notScheduled()<<", "<<(m_project ? m_project->notScheduled() : false)<<endl;
00508     if ( task->currentSchedule() == 0 ) {
00509         item->setShowNoInformation( m_showNoInformation );
00510         item->setStartTime( task->projectNode() ->startTime() );
00511         item->setEndTime( item->startTime().addDays( 1 ) );
00512     } else {
00513         bool noinf = m_showNoInformation && ( task->notScheduled() || ( m_project ? m_project->notScheduled() : false /*hmmm, no project?*/ ) );
00514         item->setShowNoInformation( noinf );
00515         item->setStartTime( task->startTime() );
00516         item->setEndTime( task->endTime() );
00517     }
00518     item->setListViewText( task->name() );
00519     item->setListViewText( 1, task->wbs() );
00520     //item->setOpen(true);
00521     if ( m_showTaskName ) {
00522         item->setText( task->name() );
00523     } else {
00524         item->setText( QString() );
00525     }
00526     QString w = i18n( "Name: %1", task->name() );
00527     if ( !task->notScheduled() ) {
00528         w += "\n" + i18n( "Start: %1", locale->formatDateTime( task->startTime() ) );
00529         w += "\n" + i18n( "End: %1", locale->formatDateTime( task->endTime() ) );
00530     }
00531     bool ok = true;
00532     if ( task->notScheduled() ) {
00533         w += "\n" + i18n( "Not scheduled" );
00534         ok = false;
00535     } else {
00536         if ( !m_showNoInformation && m_project && m_project->notScheduled() ) {
00537             ok = false;
00538         }
00539     }
00540     if ( ok ) {
00541         QColor c( Qt::cyan );
00542         item->setColors( c, c, c );
00543     } else {
00544         QColor c( Qt::yellow );
00545         item->setColors( c, c, c );
00546     }
00547     item->setTooltipText( w );
00548     setDrawn( item, true );
00549 }
00550 
00551 void GanttView::modifyTask( KDGanttViewItem *item, Task *task )
00552 {
00553     //kDebug()<<k_funcinfo<<endl;
00554     KLocale * locale = KGlobal::locale();
00555     //kDebug()<<k_funcinfo<<task->name()<<": "<<task->currentSchedule()<<", "<<task->notScheduled()<<", "<<(m_project ? m_project->notScheduled() : false)<<endl;
00556     item->setListViewText( task->name() );
00557     item->setListViewText( 1, task->wbs() );
00558     if ( task->currentSchedule() == 0 ) {
00559         item->setShowNoInformation( m_showNoInformation );
00560         item->setStartTime( task->projectNode() ->startTime() );
00561         item->setEndTime( item->startTime().addDays( 1 ) );
00562     } else {
00563         bool noinf = m_showNoInformation && ( task->notScheduled() || ( m_project ? m_project->notScheduled() : false /*hmmm, no project?*/ ) );
00564         item->setShowNoInformation( noinf );
00565         item->setStartTime( task->startTime() );
00566         item->setEndTime( task->endTime() );
00567     }
00568     //item->setOpen(true);
00569     QString text;
00570     if ( m_showTaskName ) {
00571         text = task->name();
00572     }
00573     if ( m_showResources && !task->notScheduled() ) {
00574         QList<Appointment*> lst = task->appointments();
00575         if ( lst.count() > 0 ) {
00576             if ( !text.isEmpty() )
00577                 text += ' ';
00578             text += '(';
00579             bool first = true;
00580             foreach ( Appointment * a, lst ) {
00581                 if ( !first )
00582                     text += ", ";
00583                 text += a->resource() ->resource() ->name();
00584                 first = false;
00585             }
00586             text += ')';
00587         }
00588     }
00589     item->setText( text );
00590     if ( m_showProgress ) {
00591         item->setProgress( task->progress().percentFinished );
00592     } else {
00593         item->setProgress( 0 );
00594     }
00595     if ( m_showPositiveFloat ) {
00596         QDateTime t = task->endTime() + task->positiveFloat();
00597         if ( t.isValid() && t > task->endTime() ) {
00598             item->setFloatEndTime( t );
00599         } else {
00600             item->setFloatEndTime( QDateTime() );
00601         }
00602     } else {
00603         item->setFloatStartTime( QDateTime() );
00604         item->setFloatEndTime( QDateTime() );
00605     }
00606     QString w = i18n( "Name: %1", task->name() );
00607     if ( !task->notScheduled() ) {
00608         w += "\n";
00609         w += i18n( "Start: %1", locale->formatDateTime( task->startTime() ) );
00610         w += "\n";
00611         w += i18n( "End: %1", locale->formatDateTime( task->endTime() ) );
00612         if ( m_showProgress ) {
00613             w += "\n";
00614             w += i18n( "Completion: %1%", task->progress().percentFinished );
00615         }
00616         if ( task->positiveFloat() > Duration::zeroDuration ) {
00617             w += "\n" + i18n( "Float: %1", task->positiveFloat().toString( Duration::Format_i18nDayTime ) );
00618         }
00619         if ( task->inCriticalPath() ) {
00620             w += "\n" + i18n( "Critical path" );
00621         } else if ( task->isCritical() ) {
00622             w += "\n" + i18n( "Critical" );
00623         }
00624     }
00625     QString sts;
00626     bool ok = true;
00627     if ( task->notScheduled() ) {
00628         sts += "\n" + i18n( "Not scheduled" );
00629         ok = false;
00630     } else {
00631         if ( task->resourceError() ) {
00632             sts += "\n" + i18n( "No resource assigned" );
00633             ok = false;
00634         }
00635         if ( task->resourceNotAvailable() ) {
00636             sts += "\n" + i18n( "Resource not available" );
00637             ok = false;
00638         }
00639         if ( task->schedulingError() ) {
00640             sts += "\n" + i18n( "Scheduling conflict" );
00641             ok = false;
00642         }
00643         if ( task->effortMetError() ) {
00644             sts += "\n" + i18n( "Requested effort could not be met" );
00645             ok = false;
00646         }
00647         if ( task->resourceOverbooked() ) {
00648             ok = false;
00649             QStringList rl = task->overbookedResources();
00650             sts += "\n" + i18nc( "arg: list of resources", "Resource overbooked: %1" ).arg( rl.join( "," ) );
00651 
00652         }
00653         if ( !m_showNoInformation && m_project && m_project->notScheduled() ) {
00654             ok = false;
00655         }
00656     }
00657     if ( ok ) {
00658         QColor c( Qt::green );
00659         item->setColors( c, c, c );
00660     } else {
00661         w += sts;
00662         QColor c( Qt::yellow );
00663         item->setColors( c, c, c );
00664     }
00665     item->setHighlight( false );
00666     if ( m_showCriticalTasks ) {
00667         item->setHighlight( task->isCritical() );
00668     } else if ( m_showCriticalPath ) {
00669         item->setHighlight( task->inCriticalPath() );
00670     }
00671 
00672     item->setTooltipText( w );
00673     setDrawn( item, true );
00674 }
00675 
00676 void GanttView::modifyMilestone( KDGanttViewItem *item, Task *task )
00677 {
00678     //kDebug()<<k_funcinfo<<endl;
00679     KLocale * locale = KGlobal::locale();
00680     //kDebug()<<k_funcinfo<<task->name()<<": "<<task->currentSchedule()<<", "<<task->notScheduled()<<", "<<(m_project ? m_project->notScheduled() : false)<<endl;
00681     if ( task->currentSchedule() == 0 ) {
00682         item->setShowNoInformation( m_showNoInformation );
00683         item->setStartTime( task->projectNode() ->startTime() );
00684     } else {
00685         bool noinf = m_showNoInformation && ( task->notScheduled() || ( m_project ? m_project->notScheduled() : false /*hmmm, no project?*/ ) );
00686         item->setShowNoInformation( noinf );
00687         item->setStartTime( task->startTime() );
00688     }
00689     item->setListViewText( task->name() );
00690     item->setListViewText( 1, task->wbs() );
00691     //item->setOpen(true);
00692     if ( m_showTaskName ) {
00693         item->setText( task->name() );
00694     } else {
00695         item->setText( QString() );
00696     }
00697     if ( m_showPositiveFloat ) {
00698         DateTime t = task->startTime() + task->positiveFloat();
00699         //kDebug()<<k_funcinfo<<task->name()<<" float: "<<t.toString()<<endl;
00700         if ( t.isValid() && t > task->startTime() ) {
00701             item->setFloatEndTime( t );
00702         } else {
00703             item->setFloatEndTime( QDateTime() );
00704         }
00705     } else {
00706         item->setFloatStartTime( QDateTime() );
00707         item->setFloatEndTime( QDateTime() );
00708     }
00709     //TODO: Show progress
00710 
00711     QString w = i18n( "Name: %1", task->name() );
00712     if ( !task->notScheduled() ) {
00713         w += "\n" + i18n( "Time: %1", locale->formatDateTime( task->startTime() ) );
00714 
00715         if ( task->positiveFloat() > Duration::zeroDuration ) {
00716             w += "\n" + i18n( "Float: %1", task->positiveFloat().toString( Duration::Format_i18nDayTime ) );
00717         }
00718         if ( task->inCriticalPath() ) {
00719             w += "\n" + i18n( "Critical path" );
00720         } else if ( task->isCritical() ) {
00721             w += "\n" + i18n( "Critical" );
00722         }
00723     }
00724     bool ok = true;
00725     if ( task->notScheduled() ) {
00726         w += "\n" + i18n( "Not scheduled" );
00727         ok = false;
00728     } else {
00729         if ( task->schedulingError() ) {
00730             w += "\n" + i18n( "Scheduling conflict" );
00731             ok = false;
00732         }
00733         if ( !m_showNoInformation && m_project && m_project->notScheduled() ) {
00734             ok = false;
00735         }
00736     }
00737     if ( ok ) {
00738         QColor c( Qt::blue );
00739         item->setColors( c, c, c );
00740     } else {
00741         QColor c( Qt::yellow );
00742         item->setColors( c, c, c );
00743     }
00744     item->setHighlight( false );
00745     if ( m_showCriticalTasks ) {
00746         item->setHighlight( task->isCritical() );
00747     } else if ( m_showCriticalPath ) {
00748         item->setHighlight( task->inCriticalPath() );
00749     }
00750 
00751     item->setTooltipText( w );
00752     setDrawn( item, true );
00753 }
00754 
00755 KDGanttViewItem *GanttView::addNode( KDGanttViewItem *parentItem, Node *node, KDGanttViewItem *after )
00756 {
00757     //kDebug()<<k_funcinfo<<endl;
00758     if ( node->type() == Node::Type_Project ) {
00759         return addProject( parentItem, node, after );
00760     }
00761     if ( node->type() == Node::Type_Subproject ) {
00762         return addSubProject( parentItem, node, after );
00763     }
00764     if ( node->type() == Node::Type_Summarytask ) {
00765         return addSummaryTask( parentItem, static_cast<Task *>( node ), after );
00766     }
00767     if ( node->type() == Node::Type_Task ) {
00768         return addTask( parentItem, static_cast<Task *>( node ), after );
00769     }
00770     if ( node->type() == Node::Type_Milestone ) {
00771         return addMilestone( parentItem, static_cast<Task *>( node ), after );
00772     }
00773     return 0;
00774 }
00775 
00776 KDGanttViewItem *GanttView::addProject( KDGanttViewItem *parentItem, Node *node, KDGanttViewItem *after )
00777 {
00778     //kDebug()<<k_funcinfo<<endl;
00779     GanttViewSummaryItem * item;
00780     if ( parentItem ) {
00781         item = new GanttViewSummaryItem( parentItem, node );
00782     } else {
00783         // we are on the top level
00784         item = new GanttViewSummaryItem( m_gantt, node );
00785     }
00786     if ( after )
00787         item->moveItem( after );
00788     modifyProject( item, node );
00789     return item;
00790 }
00791 
00792 KDGanttViewItem *GanttView::addSubProject( KDGanttViewItem *parentItem, Node *node, KDGanttViewItem *after )
00793 {
00794     //kDebug()<<k_funcinfo<<endl;
00795     return addProject( parentItem, node, after );
00796 }
00797 
00798 KDGanttViewItem *GanttView::addSummaryTask( KDGanttViewItem *parentItem, Task *task, KDGanttViewItem *after )
00799 {
00800     //kDebug()<<k_funcinfo<<endl;
00801     // display summary item
00802     GanttViewSummaryItem * item;
00803     if ( parentItem ) {
00804         item = new GanttViewSummaryItem( parentItem, task );
00805     } else {
00806         // we are on the top level
00807         item = new GanttViewSummaryItem( m_gantt, task );
00808     }
00809     if ( after )
00810         item->moveItem( after );
00811     modifySummaryTask( item, task );
00812     return item;
00813 }
00814 
00815 KDGanttViewItem *GanttView::addTask( KDGanttViewItem *parentItem, Task *task, KDGanttViewItem *after )
00816 {
00817     //kDebug()<<k_funcinfo<<endl;
00818     // display task item
00819     GanttViewTaskItem * item;
00820     if ( parentItem ) {
00821         item = new GanttViewTaskItem( parentItem, task );
00822     } else {
00823         // we are on the top level
00824         item = new GanttViewTaskItem( m_gantt, task );
00825     }
00826     if ( after )
00827         item->moveItem( after );
00828     modifyTask( item, task );
00829     return item;
00830 }
00831 
00832 KDGanttViewItem *GanttView::addMilestone( KDGanttViewItem *parentItem, Task *task, KDGanttViewItem *after )
00833 {
00834     //kDebug()<<k_funcinfo<<endl;
00835     GanttViewEventItem * item;
00836     if ( parentItem ) {
00837         item = new GanttViewEventItem( parentItem, task );
00838     } else {
00839         // we are on the top level
00840         item = new GanttViewEventItem( m_gantt, task );
00841     }
00842     if ( after )
00843         item->moveItem( after );
00844     modifyMilestone( item, task );
00845     return item;
00846 }
00847 
00848 void GanttView::drawChildren( KDGanttViewItem *parentItem, Node &parentNode )
00849 {
00850     //kDebug()<<k_funcinfo<<endl;
00851     foreach ( Node * n, parentNode.childNodeIterator() ) {
00852         if ( n->type() == Node::Type_Project )
00853             drawProject( parentItem, n );
00854         else if ( n->type() == Node::Type_Subproject )
00855             drawSubProject( parentItem, n );
00856         else if ( n->type() == Node::Type_Summarytask ) {
00857             Task * t = dynamic_cast<Task *>( n );
00858             Q_ASSERT( t );
00859             drawSummaryTask( parentItem, t );
00860         } else if ( n->type() == Node::Type_Task ) {
00861             Task * t = dynamic_cast<Task *>( n );
00862             Q_ASSERT( t );
00863             drawTask( parentItem, t );
00864         } else if ( n->type() == Node::Type_Milestone ) {
00865             Task * t = dynamic_cast<Task *>( n );
00866             Q_ASSERT( t );
00867             drawMilestone( parentItem, t );
00868         } else
00869             kDebug() << k_funcinfo << "Node type " << n->type() << " not implemented yet" << endl;
00870 
00871     }
00872 }
00873 
00874 
00875 void GanttView::drawProject( KDGanttViewItem *parentItem, Node *node )
00876 {
00877     //kDebug()<<k_funcinfo<<endl;
00878     GanttViewSummaryItem * item = dynamic_cast<GanttViewSummaryItem*>( addProject( parentItem, node ) );
00879     drawChildren( item, *node );
00880 }
00881 
00882 void GanttView::drawSubProject( KDGanttViewItem *parentItem, Node *node )
00883 {
00884     //kDebug()<<k_funcinfo<<endl;
00885     GanttViewSummaryItem * item = dynamic_cast<GanttViewSummaryItem*>( addSubProject( parentItem, node ) );
00886     drawChildren( item, *node );
00887 }
00888 
00889 void GanttView::drawSummaryTask( KDGanttViewItem *parentItem, Task *task )
00890 {
00891     //kDebug()<<k_funcinfo<<endl;
00892     GanttViewSummaryItem * item = dynamic_cast<GanttViewSummaryItem*>( addSummaryTask( parentItem, task ) );
00893     drawChildren( item, *task );
00894 }
00895 
00896 void GanttView::drawTask( KDGanttViewItem *parentItem, Task *task )
00897 {
00898     //kDebug()<<k_funcinfo<<endl;
00899     addTask( parentItem, task );
00900 }
00901 
00902 void GanttView::drawMilestone( KDGanttViewItem *parentItem, Task *task )
00903 {
00904     //kDebug()<<k_funcinfo<<endl;
00905     addMilestone( parentItem, task );
00906 }
00907 
00908 void GanttView::addTaskLink( KDGanttViewTaskLink *link )
00909 {
00910     //kDebug()<<k_funcinfo<<endl;
00911     m_taskLinks.append( link );
00912 }
00913 
00914 void GanttView::drawRelations()
00915 {
00916     if ( !m_showTaskLinks )
00917         return ;
00918     KDGanttViewItem *item = m_gantt->firstChild();
00919     //kDebug()<<k_funcinfo<<"First: "<<(item ? item->listViewText() : "nil")<<endl;
00920     for ( ; item; item = item->nextSibling() ) {
00921         drawRelations( item );
00922         drawChildRelations( item->firstChild() );
00923     }
00924 }
00925 
00926 void GanttView::drawChildRelations( KDGanttViewItem *item )
00927 {
00928     //kDebug()<<k_funcinfo<<"item: "<<(item ? item->listViewText() : "nil")<<endl;
00929     for ( ; item; item = item->nextSibling() ) {
00930         drawRelations( item );
00931         drawChildRelations( item->firstChild() );
00932     }
00933 }
00934 
00935 void GanttView::drawRelations( KDGanttViewItem *item )
00936 {
00937     //kDebug()<<k_funcinfo<<endl;
00938     if ( !item )
00939         return ;
00940 
00941     GanttViewSummaryItem *summaryItem = dynamic_cast<GanttViewSummaryItem *>( item );
00942     if ( summaryItem ) {
00943         //kDebug()<<k_funcinfo<<"Summary item: "<<summaryItem->listViewText()<<endl;
00944         summaryItem->insertRelations( this );
00945         return ;
00946     }
00947     GanttViewTaskItem *taskItem = dynamic_cast<GanttViewTaskItem *>( item );
00948     if ( taskItem ) {
00949         //kDebug()<<k_funcinfo<<"Task item: "<<taskItem->listViewText()<<endl;
00950         taskItem->insertRelations( this );
00951         return ;
00952     }
00953     GanttViewEventItem *milestoneItem = dynamic_cast<GanttViewEventItem *>( item );
00954     if ( milestoneItem ) {
00955         //kDebug()<<k_funcinfo<<"Milestone item: "<<milestoneItem->listViewText()<<endl;
00956         milestoneItem->insertRelations( this );
00957         return ;
00958     }
00959     kDebug() << k_funcinfo << "Unknown item type: " << item->listViewText() << endl;
00960 }
00961 
00962 void GanttView::currentItemChanged( KDGanttViewItem* item )
00963 {
00964     //kDebug()<<k_funcinfo<<(item ? item->listViewText() : "null")<<endl;
00965     m_taskView->clear();
00966     m_gantt->setSelected( m_currentItem, false );
00967     m_currentItem = item;
00968     if ( item ) {
00969         m_gantt->setSelected( item, true );
00970         if ( m_showAppointments ) {
00971             m_taskView->show();
00972             GanttViewTaskItem *taskItem = dynamic_cast<GanttViewTaskItem *>( item );
00973             if ( taskItem ) {
00974                 m_taskView->draw( taskItem->getTask() );
00975             } else {
00976                 GanttViewEventItem *msItem = dynamic_cast<GanttViewEventItem *>( item );
00977                 if ( msItem )
00978                     m_taskView->draw( msItem->getTask() );
00979             }
00980         } else {
00981             m_taskView->hide();
00982         }
00983     }
00984     emit enableActions( true );
00985 }
00986 
00987 Node *GanttView::currentNode() const
00988 {
00989     return getNode( m_currentItem );
00990 }
00991 
00992 void GanttView::popupMenuRequested( KDGanttViewItem * item, const QPoint & pos, int )
00993 {
00994     //kDebug()<<k_funcinfo<<(item?item->listViewText(0):"0")<<endl;
00995     if ( item == 0 ) {
00996         kDebug() << "No item selected" << endl;
00997         return ;
00998     }
00999     Node *n = getNode( item );
01000     if ( n == 0 ) {
01001         kDebug() << "No node selected" << endl;
01002         return ;
01003     }
01004     Task *t = dynamic_cast<Task*>( n );
01005     if ( t && ( t->type() == Node::Type_Task || t->type() == Node::Type_Milestone ) ) {
01006         emit requestPopupMenu( "task_popup", pos );
01007         //         QPopupMenu *menu = m_mainview->popupMenu("task_popup");
01008         //         if (menu)
01009         //         {
01010         //             /*int id =*/ menu->exec(pos);
01011         //kDebug()<<k_funcinfo<<"id="<<id<<endl;
01012         //         }
01013         return ;
01014     }
01015     if ( t && t->type() == Node::Type_Summarytask ) {
01016         emit requestPopupMenu( "summarytask_popup", pos );
01017         //         QPopupMenu *menu = m_mainview->popupMenu("summarytask_popup");
01018         //         if (menu)
01019         //         {
01020         //             /*int id =*/ menu->exec(pos);
01021         //kDebug()<<k_funcinfo<<"id="<<id<<endl;
01022         //         }
01023         return ;
01024     }
01025     //TODO: Other nodetypes
01026 }
01027 
01028 void GanttView::slotItemDoubleClicked( KDGanttViewItem* item )
01029 {
01030     //kDebug()<<k_funcinfo<<endl;
01031     emit itemDoubleClicked();
01032 }
01033 
01034 //TODO: 1) make it koffice compliant,
01035 //      2) allow printing on multiple pages
01036 void GanttView::print( KPrinter &prt )
01037 {
01038     //kDebug()<<k_funcinfo<<endl;
01039 
01040     KDGanttViewItem * selItem = m_gantt->selectedItem();
01041     if ( selItem )
01042         selItem->setSelected( false );
01043 
01044     //Comment from KWord
01045     //   We don't get valid metrics from the printer - and we want a better resolution
01046     //   anyway (it's the PS driver that takes care of the printer resolution).
01047     //But KSpread uses fixed 300 dpis, so we can use it.
01048 
01049     uint top, left, bottom, right;
01050     prt.margins( &top, &left, &bottom, &right );
01051     //kDebug()<<m.width()<<"x"<<m.height()<<" : "<<top<<", "<<left<<", "<<bottom<<", "<<right<<" : "<<size()<<endl;
01052 
01053     // get the size of the desired output for scaling.
01054     // here we want to print: ListView and TimeLine (default)
01055     // for this purpose, we call drawContents() with a 0 pointer as painter
01056     QSize size = m_gantt->drawContents( 0 );
01057 
01058     QPainter p;
01059     p.begin( &prt );
01060     p.setViewport( left, top, prt.width() - left - right, prt.height() - top - bottom );
01061     p.setClipRect( left, top, prt.width() - left - right, prt.height() - top - bottom );
01062 
01063     // Make a simple header
01064     p.drawRect( 0, 0, prt.width(), prt.height() );
01065     QString text;
01066     int hei = 0;
01067     text = KGlobal::locale() ->formatDateTime( QDateTime::currentDateTime() );
01068     QRect r = p.boundingRect( prt.width() - 1, 0, 0, 0, Qt::AlignRight, text );
01069     p.drawText( r, Qt::AlignRight, text );
01070     hei = r.height();
01071     //kDebug()<<"Date r="<<r.left()<<","<<r.top()<<" "<<r.width()<<"x"<<r.height()<<endl;
01072     if ( m_project ) {
01073         QRect re = p.boundingRect( 1, 0, 0, 0, Qt::AlignLeft, text );
01074         re.setWidth( prt.width() - r.width() - 5 ); // don't print on top of date
01075         p.drawText( re, Qt::AlignLeft, m_project->name() );
01076         hei = r.height();
01077         //kDebug()<<"Project r="<<re.left()<<","<<re.top()<<" "<<re.width()<<"x"<<re.height()<<": "<<endl;
01078         hei = qMax( hei, re.height() );
01079     }
01080 
01081     hei++;
01082     p.drawLine( 0, hei, prt.width(), hei );
01083     hei += 3;
01084     // compute the scale
01085     float dx = ( float ) ( prt.width() - 2 ) / ( float ) size.width();
01086     float dy = ( float ) ( prt.height() - hei ) / ( float ) size.height();
01087     float scale;
01088     // scale to fit the width or height of the paper
01089     if ( dx < dy )
01090         scale = dx;
01091     else
01092         scale = dy;
01093     // set the scale
01094     p.translate( 1, hei );
01095     p.scale( scale, scale );
01096     m_gantt->drawContents( &p );
01097     // the drawContents() has the side effect, that the painter translation is
01098     // after drawContents() set to the bottom of the painted stuff
01099     // for instance a
01100     // p.drawText(0, 0, "printend");
01101     // would be painted directly below the paintout of drawContents()
01102 
01103     p.end();
01104     if ( selItem )
01105         selItem->setSelected( true );
01106 }
01107 
01108 void GanttView::slotItemRenamed( KDGanttViewItem* item, int col, const QString& str )
01109 {
01110     //kDebug()<<k_funcinfo<<(item ? item->listViewText(col) : "null")<<": "<<str<<endl;
01111     if ( col == 0 ) {
01112         emit itemRenamed( getNode( item ), str );
01113     }
01114 }
01115 
01116 void GanttView::slotGvItemClicked( KDGanttViewItem * )
01117 {}
01118 
01119 // testing
01120 bool GanttView::exportGantt( QIODevice* device )
01121 {
01122     kDebug() << k_funcinfo << endl;
01123     return m_gantt->saveProject( device );
01124 }
01125 
01126 void GanttView::slotCreateTaskLink( KDGanttViewItem* from, KDGanttViewItem::Connector fc, KDGanttViewItem* to, KDGanttViewItem::Connector tc )
01127 {
01128     kDebug() << k_funcinfo << ( from ? from->listViewText() : "null" ) << " fc=" << fc << " to " << ( to ? to->listViewText() : "null" ) << " tc=" << tc << endl;
01129     Node *par = getNode( from );
01130     Node *child = getNode( to );
01131     if ( !par || !child || !( par->legalToLink( child ) ) ) {
01132         KMessageBox::sorry( this, i18n( "Cannot link these nodes" ) );
01133         return ;
01134     }
01135     int rt = linkTypeToRelation( fc, tc );
01136     if ( rt == Relation::None ) {
01137         KMessageBox::sorry( this, i18n( "Cannot link these nodes" ) );
01138         return ;
01139     }
01140     Relation *rel = child->findRelation( par );
01141     if ( rel )
01142         emit modifyRelation( rel, rt );
01143     else
01144         emit addRelation( par, child, rt );
01145 
01146     return ;
01147 }
01148 
01149 int GanttView::linkTypeToRelation( KDGanttViewItem::Connector fc, KDGanttViewItem::Connector tc )
01150 {
01151     if ( fc == KDGanttViewItem::TaskLinkStart ) {
01152         // TODO: support StartFinish
01153         //        if (tc == KDGanttViewItem::TaskLinkStart) {
01154         return Relation::StartStart;
01155         //        }
01156         //
01157         //        if (tc == KDGanttViewItem::TaskLinkEnd) {
01158         //            return Relation::StartFinish;
01159         //        }
01160 
01161     } else if ( fc == KDGanttViewItem::TaskLinkEnd ) {
01162         if ( tc == KDGanttViewItem::TaskLinkStart ) {
01163             return Relation::FinishStart;
01164         }
01165         if ( tc == KDGanttViewItem::TaskLinkEnd ) {
01166             return Relation::FinishFinish;
01167         }
01168     }
01169     return Relation::None;
01170 }
01171 
01172 void GanttView::slotModifyLink( KDGanttViewTaskLink* link )
01173 {
01174     //kDebug()<<k_funcinfo<<link<<endl;
01175     // we support only one from/to item in each link
01176     Node * par = getNode( link->from().first() );
01177     Relation *rel = par->findRelation( getNode( link->to().first() ) );
01178     if ( rel )
01179         emit modifyRelation( rel );
01180 }
01181 
01182 bool GanttView::setContext( Context::Ganttview &context, Project& /*project*/ )
01183 {
01184     //kDebug()<<k_funcinfo<<endl;
01185 
01186     Q3ValueList<int> list = m_splitter->sizes();
01187     list[ 0 ] = context.ganttviewsize;
01188     list[ 1 ] = context.taskviewsize;
01189     m_splitter->setSizes( list );
01190 
01191     //TODO this does not work yet!
01192     //     currentItemChanged(findItem(project.findNode(context.currentNode)));
01193 
01194     m_showResources = context.showResources ;
01195     m_showTaskName = context.showTaskName;
01196     m_showTaskLinks = context.showTaskLinks;
01197     m_showProgress = context.showProgress;
01198     m_showPositiveFloat = context.showPositiveFloat;
01199     m_showCriticalTasks = context.showCriticalTasks;
01200     m_showCriticalPath = context.showCriticalPath;
01201     m_showNoInformation = context.showNoInformation;
01202 
01203     //TODO this does not work yet!
01204     //     getContextClosedNodes(context, m_gantt->firstChild());
01205     //     for (QStringList::ConstIterator it = context.closedNodes.begin(); it != context.closedNodes.end(); ++it) {
01206     //         KDGanttViewItem *item = findItem(project.findNode(*it));
01207     //         if (item) {
01208     //             item->setOpen(false);
01209     //         }
01210     //     }
01211     return true;
01212 }
01213 
01214 void GanttView::getContext( Context::Ganttview &context ) const
01215 {
01216     //kDebug()<<k_funcinfo<<endl;
01217     context.ganttviewsize = m_splitter->sizes() [ 0 ];
01218     context.taskviewsize = m_splitter->sizes() [ 1 ];
01219     //kDebug()<<k_funcinfo<<"sizes="<<sizes()[0]<<","<<sizes()[1]<<endl;
01220     if ( currentNode() ) {
01221         context.currentNode = currentNode() ->id();
01222     }
01223     context.showResources = m_showResources;
01224     context.showTaskName = m_showTaskName;
01225     context.showTaskLinks = m_showTaskLinks;
01226     context.showProgress = m_showProgress;
01227     context.showPositiveFloat = m_showPositiveFloat;
01228     context.showCriticalTasks = m_showCriticalTasks;
01229     context.showCriticalPath = m_showCriticalPath;
01230     context.showNoInformation = m_showNoInformation;
01231     getContextClosedNodes( context, m_gantt->firstChild() );
01232 }
01233 
01234 void GanttView::getContextClosedNodes( Context::Ganttview &context, KDGanttViewItem *item ) const
01235 {
01236     if ( item == 0 )
01237         return ;
01238     for ( KDGanttViewItem * i = item; i; i = i->nextSibling() ) {
01239         if ( !i->isOpen() ) {
01240             context.closedNodes.append( getNode( i ) ->id() );
01241             //kDebug()<<k_funcinfo<<"add closed "<<i->listViewText()<<endl;
01242         }
01243         getContextClosedNodes( context, i->firstChild() );
01244     }
01245 }
01246 
01247 void GanttView::setReadWriteMode( bool on )
01248 {
01249     m_readWrite = on;
01250     disconnect( m_gantt, SIGNAL( gvCreateTaskLink( KDGanttViewItem*, KDGanttViewItem::Connector, KDGanttViewItem*, KDGanttViewItem::Connector ) ), this, SLOT( slotCreateTaskLink( KDGanttViewItem*, KDGanttViewItem::Connector, KDGanttViewItem*, KDGanttViewItem::Connector ) ) );
01251     disconnect( m_gantt, SIGNAL( taskLinkDoubleClicked( KDGanttViewTaskLink* ) ), this, SLOT( slotModifyLink( KDGanttViewTaskLink* ) ) );
01252 
01253     if ( on ) {
01254         connect( m_gantt, SIGNAL( gvCreateTaskLink( KDGanttViewItem*, KDGanttViewItem::Connector, KDGanttViewItem*, KDGanttViewItem::Connector ) ), this, SLOT( slotCreateTaskLink( KDGanttViewItem*, KDGanttViewItem::Connector, KDGanttViewItem*, KDGanttViewItem::Connector ) ) );
01255 
01256         connect( m_gantt, SIGNAL( taskLinkDoubleClicked( KDGanttViewTaskLink* ) ), SLOT( slotModifyLink( KDGanttViewTaskLink* ) ) );
01257     }
01258     setRenameEnabled( m_gantt->firstChild(), on );
01259 }
01260 
01261 void GanttView::setRenameEnabled( Q3ListViewItem *item, bool on )
01262 {
01263     if ( item == 0 )
01264         return ;
01265     for ( Q3ListViewItem * i = item; i; i = i->nextSibling() ) {
01266         i->setRenameEnabled( 0, on );
01267         setRenameEnabled( i->firstChild(), on );
01268     }
01269 }
01270 
01271 }  //KPlato namespace
01272 
01273 #include "kptganttview.moc"

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