• Skip to content
  • Skip to link menu
KDE 4.2 API Reference
  • KDE API Reference
  • kdepim
  • Sitemap
  • Contact Us
 

kdgantt1

KDGanttView.cpp

Go to the documentation of this file.
00001 /* -*- Mode: C++ -*-
00002    $Id: KDGanttView.cpp 836291 2008-07-22 04:34:42Z pradeepto $
00003    KDGantt - a multi-platform charting engine
00004 */
00005 
00006 /****************************************************************************
00007  ** Copyright (C)  2002-2004 Klarälvdalens Datakonsult AB.  All rights reserved.
00008  **
00009  ** This file is part of the KDGantt library.
00010  **
00011  ** This file may be used under the terms of the GNU General Public
00012  ** License versions 2.0 or 3.0 as published by the Free Software
00013  ** Foundation and appearing in the files LICENSE.GPL2 and LICENSE.GPL3
00014  ** included in the packaging of this file.  Alternatively you may (at
00015  ** your option) use any later version of the GNU General Public
00016  ** License if such license has been publicly approved by
00017  ** Klarälvdalens Datakonsult AB (or its successors, if any).
00018  ** 
00019  ** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
00020  ** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
00021  ** A PARTICULAR PURPOSE. Klarälvdalens Datakonsult AB reserves all rights
00022  ** not expressly granted herein.
00023  ** 
00024  ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00025  ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00026  **
00027  ** As a special exception, permission is given to link this program
00028  ** with any edition of Qt, and distribute the resulting executable,
00029  ** without including the source code for Qt in the source distribution.
00030  **
00031  **********************************************************************/
00032 
00033 // we need the protected QHeader method
00034 // QHeader::paintSection ( QPainter * p, int index, const QRect & fr )
00035 // in order to print the header of the list view
00036 // because we cannot reimplement QHeader to access this method we
00037 // have to get access to the protected QHeader methods
00038 
00039 #include "KDGanttView.h"
00040 #include "KDGanttViewSubwidgets.h"
00041 #include "KDGanttMinimizeSplitter.h"
00042 #include "KDGanttViewItem.h"
00043 #include "KDGanttViewTaskItem.h"
00044 #include "KDGanttViewEventItem.h"
00045 #include "KDGanttViewSummaryItem.h"
00046 #include "KDGanttXMLTools.h"
00047 #if QT_VERSION < 0x040000
00048 #include "itemAttributeDialog.h"
00049 #endif
00050 #include <QPrinter>
00051 #include <QPainter>
00052 #include <QLayout>
00053 #include <QFile>
00054 #include <QApplication>
00055 #include <QtDebug>
00056 #include <QPrintDialog>
00057 #include <QDragEnterEvent>
00058 
00059 #include <QMessageBox>
00060 #include <QFileInfo>
00061 #include <QTextStream>
00062 
00063 
00064 
00065 #if defined KDAB_EVAL
00066 #include "../evaldialog/evaldialog.h"
00067 #endif
00068 
00089 KDGanttView::KDGanttView( QWidget* parent, const char* name  )
00090     : KDGanttMinimizeSplitter( Qt::Vertical, parent ),
00091       myCanvasView(0),
00092       myTimeHeaderScroll(0),
00093       mFixedHorizon( false )
00094 {
00095   setObjectName( name );
00096 
00097 #if defined KDAB_EVAL
00098     EvalDialog::checkEvalLicense( "KD Gantt" );
00099 #endif
00100   myCurrentItem = 0;
00101   mUserHorizonChangeEnabled = true;
00102 #if QT_VERSION < 0x040000
00103     setMinimizeDirection ( KDGanttMinimizeSplitter::Down );
00104 #endif
00105     mySplitter = new KDGanttMinimizeSplitter( this );
00106 #if QT_VERSION < 0x040000
00107     mySplitter->setMinimizeDirection ( KDGanttMinimizeSplitter::Left );
00108 #endif
00109     leftWidget = new QVBox( mySplitter );
00110     rightWidget = new QVBox( mySplitter );
00111     //leftWidget->setMinimumSize( 20, 20 );
00112     //rightWidget->setMinimumSize( 20, 20 );
00113     myLegend = new KDLegendWidget( leftWidget, this );
00114     spacerLeft = new QWidget( leftWidget );
00115     spacerLeftLayout = new QHBoxLayout( spacerLeft );
00116     spacerLeftLayout->setMargin( 0 );
00117     spacerLeftLayout->setSpacing( 0 );
00118 
00119     myListView = new KDListView(leftWidget, this);
00120     myListView->setVScrollBarMode (QScrollView::AlwaysOff );
00121 #if QT_VERSION < 0x040000
00122     connect( myListView, SIGNAL( selectionChanged( QListViewItem* ) ),
00123              this, SLOT( slotSelectionChanged( QListViewItem* ) ) );
00124     connect( myListView, SIGNAL( mouseButtonClicked ( int, QListViewItem * , const QPoint &, int ) ),
00125              this, SLOT( slotmouseButtonClicked ( int , QListViewItem * , const QPoint &, int ) ) );
00126     connect( myListView, SIGNAL( contextMenuRequested ( QListViewItem * , const QPoint &, int  ) ),
00127              this, SLOT( slotcontextMenuRequested ( QListViewItem * , const QPoint & , int ) ) );
00128     connect( myListView, SIGNAL(expanded ( QListViewItem *  ) ),
00129              this, SLOT(slotItemExpanded ( QListViewItem * ) ) );
00130     connect( myListView, SIGNAL(collapsed ( QListViewItem *  ) ),
00131              this, SLOT(slotItemCollapsed( QListViewItem * ) ) );
00132     connect( myListView, SIGNAL(currentChanged( QListViewItem *  ) ),
00133              this, SLOT(slotCurrentChanged ( QListViewItem * ) ) );
00134     connect( myListView, SIGNAL(itemRenamed ( QListViewItem * , int , const QString &  ) ),
00135              this, SLOT(slotItemRenamed ( QListViewItem *, int , const QString &  ) ) );
00136     connect( myListView, SIGNAL(mouseButtonPressed(  int, QListViewItem * , const QPoint &, int ) ),
00137              this, SLOT(slotMouseButtonPressed (  int , QListViewItem * , const QPoint & , int ) ) );
00138 #else
00139     connect( myListView, SIGNAL( selectionChanged( Q3ListViewItem* ) ),
00140              this, SLOT( slotSelectionChanged( Q3ListViewItem* ) ) );
00141     connect( myListView, SIGNAL( mouseButtonClicked ( int, Q3ListViewItem * , const QPoint &, int ) ),
00142              this, SLOT( slotmouseButtonClicked ( int , Q3ListViewItem * , const QPoint &, int ) ) );
00143     connect( myListView, SIGNAL( contextMenuRequested ( Q3ListViewItem * , const QPoint &, int  ) ),
00144              this, SLOT( slotcontextMenuRequested ( Q3ListViewItem * , const QPoint & , int ) ) );
00145     connect( myListView, SIGNAL(expanded ( Q3ListViewItem *  ) ),
00146              this, SLOT(slotItemExpanded ( Q3ListViewItem * ) ) );
00147     connect( myListView, SIGNAL(collapsed ( Q3ListViewItem *  ) ),
00148              this, SLOT(slotItemCollapsed( Q3ListViewItem * ) ) );
00149     connect( myListView, SIGNAL(currentChanged( Q3ListViewItem *  ) ),
00150              this, SLOT(slotCurrentChanged ( Q3ListViewItem * ) ) );
00151     connect( myListView, SIGNAL(itemRenamed ( Q3ListViewItem * , int , const QString &  ) ),
00152              this, SLOT(slotItemRenamed ( Q3ListViewItem *, int , const QString &  ) ) );
00153     connect( myListView, SIGNAL(mouseButtonPressed(  int, Q3ListViewItem * , const QPoint &, int ) ),
00154              this, SLOT(slotMouseButtonPressed (  int , Q3ListViewItem * , const QPoint & , int ) ) );
00155 #endif
00156     //connect( myListView, SIGNAL( ), this, SLOT( ) );
00157     myTimeTable = new KDTimeTableWidget (0,this);
00158 
00159     spacerRight = new QWidget(  rightWidget );
00160 
00161     myTimeHeaderContainer = new QHBox( rightWidget );
00162     myTimeHeaderContainer->setFrameStyle( QFrame::NoFrame  );
00163     myTimeHeaderContainer->setMargin( 0 );
00164     myTimeHeaderScroll = new QScrollView ( myTimeHeaderContainer );
00165     myTimeHeaderScroll->setHScrollBarMode( QScrollView::AlwaysOff );
00166     myTimeHeaderScroll->setVScrollBarMode( QScrollView::AlwaysOff );
00167     timeHeaderSpacerWidget = new QWidget( myTimeHeaderContainer );
00168 
00169 
00170     /*
00171     myTimeHeaderScroll = new QScrollView ( rightWidget );
00172     myTimeHeaderScroll->setHScrollBarMode( QScrollView::AlwaysOff );
00173     myTimeHeaderScroll->setVScrollBarMode( QScrollView::AlwaysOn );
00174     */
00175     //myTimeHeader = new KDTimeHeaderWidget (rightWidget,this);
00176     myTimeHeader = new KDTimeHeaderWidget (myTimeHeaderScroll->viewport(),this);
00177     myTimeHeaderScroll->addChild( myTimeHeader );
00178     QPalette pal = myTimeHeader->palette();
00179     myTimeHeaderScroll->viewport()->setPalette( pal );
00180     timeHeaderSpacerWidget->setPalette( pal );
00181     myCanvasView = new KDGanttCanvasView( this, myTimeTable, rightWidget);
00182     myTimeHeaderScroll->setFrameStyle( QFrame::NoFrame  );
00183     //
00184     myCanvasView->setFrameStyle( QFrame::NoFrame  );
00185     myCanvasView->setMargin( 0 );
00186     //
00187     myTimeHeaderScroll->setMargin( 0 );//myCanvasView->frameWidth() );
00188     setFrameStyle(myListView->frameStyle());
00189     setLineWidth( 2 );
00190     myListView->setFrameStyle( QFrame::NoFrame  );
00191     myListView->setMargin( 0 );
00192 #if QT_VERSION < 0x040000
00193     QObject::connect(myListView, SIGNAL (  expanded ( QListViewItem * ) ) ,
00194                      myTimeTable , SLOT( expandItem(QListViewItem * ))) ;
00195     QObject::connect(myListView, SIGNAL (collapsed ( QListViewItem * ) ) ,
00196                      myTimeTable , SLOT(collapseItem(QListViewItem * ))) ;
00197 #else
00198     QObject::connect(myListView, SIGNAL (  expanded ( Q3ListViewItem * ) ) ,
00199                      myTimeTable , SLOT( expandItem(Q3ListViewItem * ))) ;
00200     QObject::connect(myListView, SIGNAL (collapsed ( Q3ListViewItem * ) ) ,
00201                      myTimeTable , SLOT(collapseItem(Q3ListViewItem * ))) ;
00202 #endif
00203     timeHeaderSpacerWidget->setFixedWidth(myCanvasView->verticalScrollBar()->width() );
00204     listViewIsVisible = true;
00205     chartIsEditable = true;
00206     editorIsEnabled = true;
00207     _displaySubitemsAsGroup = false;
00208     initDefaults();
00209     _showHeader = false;
00210 
00211     myTextColor = Qt::black;
00212     //QObject::connect( this, SIGNAL (itemDoubleClicked( KDGanttViewItem* ) ) , this, SLOT( editItem( KDGanttViewItem*  ))) ;
00213 #if QT_VERSION < 0x040000
00214     myItemAttributeDialog = 0;
00215 #endif
00216     setRepaintMode( KDGanttView::Medium );
00217     setShowLegendButton( true );
00218     setHeaderVisible( false );
00219 
00220     // now connecting the widgets
00221     connect(myCanvasView->horizontalScrollBar(), SIGNAL (  valueChanged ( int )) ,myTimeHeaderScroll->horizontalScrollBar(), SLOT( setValue ( int))) ;
00222     connect(myCanvasView, SIGNAL (  heightResized( int )) ,myTimeTable, SLOT( checkHeight ( int))) ;
00223     connect(myCanvasView, SIGNAL (  widthResized( int )) ,myTimeHeader, SLOT( checkWidth ( int))) ;
00224 
00225     QObject::connect(myCanvasView->verticalScrollBar(), SIGNAL ( valueChanged ( int ) ) ,myListView->verticalScrollBar(), SLOT( setValue ( int ))) ;
00226     connect(myTimeHeader, SIGNAL ( sizeChanged( int ) ) ,this, SLOT(slotHeaderSizeChanged()  )) ;
00227     connect(myTimeHeader, SIGNAL ( sizeChanged( int ) ) ,myTimeTable, SLOT(resetWidth( int ) )) ;
00228     connect(myListView, SIGNAL ( contentsMoving ( int, int ) ) ,myCanvasView, SLOT(  moveMyContent( int, int ))) ;
00229     connect(myTimeTable, SIGNAL ( heightComputed ( int ) ) ,myCanvasView, SLOT(  setMyContentsHeight( int ))) ;
00230    // the next three are for adding new ticks at left/right
00231 #if QT_VERSION < 0x040000
00232     //connect( myCanvasView->horizontalScrollBar(), SIGNAL( prevLine () ) ,this, SLOT( addTickLeft()));
00233     //connect( myCanvasView->horizontalScrollBar(), SIGNAL( nextLine () ) ,this, SLOT( addTickRight()));
00234 #else
00235     connect( myCanvasView->horizontalScrollBar(), SIGNAL( actionTriggered ( int ) ) ,this, SLOT( hScrollBarAction( int )));
00236     connect( myCanvasView->verticalScrollBar(), SIGNAL( actionTriggered ( int ) ) ,this, SLOT( vScrollBarAction( int )));
00237 #endif
00238    // now initing
00239     fCenterTimeLineAfterShow = false;
00240     fDragEnabled = false;
00241     fDropEnabled = false;
00242     closingBlocked = false;
00243    myTimeHeader->computeTicks();
00244    centerTimelineAfterShow( QDateTime::currentDateTime () );
00245    setDisplayEmptyTasksAsLine( false );
00246    //QValueList<int> list;
00247    //list.append(240);
00248    //list.append(530);
00249    //mySplitter->setSizes( list );
00250    myTimeTable->setBlockUpdating();// block updating until this->show() is called
00251    mAddTickcountForTimeline = 1;
00252    myListView->setDefaultRenameAction( QListView::Reject );
00253 }
00254 
00255 KDGanttView::~KDGanttView()
00256 {
00257     // Don't call clearAll, it recreates widgets inside KDLegendWidget
00258   QPtrList<KDGanttViewTaskLink>  tll = taskLinks();
00259   tll.setAutoDelete( true );
00260   tll.clear();
00261   QPtrList<KDGanttViewTaskLinkGroup> tlg = myTaskLinkGroupList;
00262   tlg.setAutoDelete( true );
00263   tlg.clear();
00264   clear();
00265 
00266   // delete cut item, if there is any
00267     myCanvasView->resetCutPaste( 0 );
00268     delete myTimeTable;
00269 }
00288 void KDGanttView::vScrollBarAction( int action )
00289 {
00290     //qDebug() << "vScrollBarAction " << action ;
00291     switch ( mRepaintMode ) {
00292     case  No:
00293 
00294         break;
00295     case Medium:
00296         if ( action == 2 || action == 1 )
00297             forceRepaint();
00298         break;
00299     case Always:
00300         if ( action != 0 )
00301             forceRepaint();
00302         break;
00303     }
00304 
00305 }
00306 void KDGanttView::hScrollBarAction( int action )
00307 {
00308     //qDebug() << "hScrollBarAction " << action;
00309     if (  action == 2 ) { // left
00310         addTickLeft();
00311     } else if ( action == 1 ) {
00312         addTickRight();
00313     }
00314     switch ( mRepaintMode ) {
00315     case  No:
00316 
00317         break;
00318     case Medium:
00319         if ( action == 2 || action == 1 )
00320             forceRepaint();
00321         break;
00322     case Always:
00323         if ( action != 0 )
00324             forceRepaint();
00325         break;
00326     }
00327 }
00328 
00329 KDGanttViewItem* KDGanttView::createUserDefinedItem( QString kdGanttViewItemTypeAsString,
00330                                                      KDGanttViewItem* parent,
00331                                                      KDGanttViewItem* after,
00332                                                      const QString& lvtext,
00333                                                      const QString& name )
00334 {
00335     Q_UNUSED( kdGanttViewItemTypeAsString )
00336     Q_UNUSED( parent )
00337     Q_UNUSED( after )
00338     Q_UNUSED( lvtext )
00339     Q_UNUSED( name )
00340     qDebug() << "KDGanttView::createUserDefinedItem: Unknown type " << kdGanttViewItemTypeAsString;
00341     return 0;
00342 }
00387 KDGanttViewItem* KDGanttView::createNewItem( QString KDGanttViewItemTypeAsString,
00388                                              KDGanttViewItem* parent,
00389                                              KDGanttViewItem* after,
00390                                              const QString& lvtext,
00391                                              const QString& name )
00392 {
00393     KDGanttViewItem* retItem = 0;
00394     KDGanttViewItem::Type type = KDGanttViewItem::stringToType( KDGanttViewItemTypeAsString );
00395    switch( type ) {
00396     case KDGanttViewItem::Event:
00397         if ( parent ) {
00398             if ( after )
00399                 retItem = new KDGanttViewEventItem( parent, after, lvtext, name);
00400             else
00401                 retItem = new KDGanttViewEventItem( parent, lvtext, name);
00402         } else {
00403             if ( after )
00404                 retItem = new KDGanttViewEventItem( this, after, lvtext, name);
00405             else
00406                 retItem = new KDGanttViewEventItem( this, lvtext, name);
00407         }
00408         break;
00409     case KDGanttViewItem::Summary:
00410         if ( parent ) {
00411             if ( after )
00412                 retItem = new KDGanttViewSummaryItem( parent, after, lvtext, name);
00413             else
00414                 retItem = new KDGanttViewSummaryItem( parent, lvtext, name);
00415         } else {
00416             if ( after )
00417                 retItem = new KDGanttViewSummaryItem( this, after, lvtext, name);
00418             else
00419                 retItem = new KDGanttViewSummaryItem( this, lvtext, name);
00420         }
00421         break;
00422     case KDGanttViewItem::Task:
00423         if ( parent ) {
00424             if ( after )
00425                 retItem = new KDGanttViewTaskItem( parent, after, lvtext, name);
00426             else
00427                 retItem = new KDGanttViewTaskItem( parent, lvtext, name);
00428         } else {
00429             if ( after )
00430                 retItem = new KDGanttViewTaskItem( this, after, lvtext, name);
00431             else
00432                 retItem = new KDGanttViewTaskItem( this, lvtext, name);
00433         }
00434         break;
00435     case KDGanttViewItem::UnknownType:
00436         retItem = createUserDefinedItem( KDGanttViewItemTypeAsString,parent,after,lvtext,name );
00437         break;
00438     default:
00439         qDebug() << "Unknown type in KDGanttView::createNewItem()";
00440     }
00441    return retItem;
00442 }
00449 void KDGanttView::setListViewColumnWidth ( int col, int w )
00450 {
00451     myListView->setColumnWidth ( col, w );
00452 }
00453 
00463 QHeader * KDGanttView::listViewHeader () const
00464 {
00465     return myListView->header();
00466 }
00467 
00474 void KDGanttView::setAllOpen()
00475 {
00476 
00477     KDGanttViewItem* curItem = (KDGanttViewItem*) myListView->itemAt( QPoint (  myListView->width() - 10 , 5 ));
00478     bool block = myTimeTable->blockUpdating();
00479     myTimeTable->setBlockUpdating( true );
00480     KDGanttViewItem* temp = firstChild();
00481     while (temp != 0) {
00482       temp->setAllSubitemsExpanded( true );
00483       temp = temp->nextSibling();
00484     }
00485     myTimeTable->setBlockUpdating( block );
00486     myTimeTable->updateMyContent();
00487     if ( curItem && ! block ) {
00488         myListView->ensureItemVisible( curItem );
00489     }
00490 
00491 }
00498 void KDGanttView::setAllClose()
00499 {
00500     KDGanttViewItem* curItem = (KDGanttViewItem*) myListView->itemAt( QPoint (  myListView->width() - 10 , 5 ));
00501     bool block = myTimeTable->blockUpdating();
00502     myTimeTable->setBlockUpdating( true );
00503     KDGanttViewItem* temp = firstChild();
00504     while (temp != 0) {
00505         temp->setAllSubitemsExpanded( false );
00506         temp = temp->nextSibling();
00507     }
00508     myTimeTable->setBlockUpdating( block );
00509     myTimeTable->updateMyContent();
00510     if ( curItem && !block ) {
00511         myListView->ensureItemVisible( curItem );
00512     }
00513 }
00514 
00515 
00539 void KDGanttView::setUpdateEnabled( bool enable )
00540 {
00541   myTimeTable->setBlockUpdating( !enable );
00542   if ( enable ) {
00543       QTimer::singleShot( 0, this, SLOT ( updateGanttContent() ) );
00544       //updateGanttContent();
00545   }
00546 }
00547 void KDGanttView::updateGanttContent()
00548 {
00549     myTimeTable->updateMyContent();
00550     myCanvasView->setMyContentsHeight( 0 );
00551 }
00552 
00560 bool KDGanttView::getUpdateEnabled() const
00561 {
00562   return !myTimeTable->blockUpdating();
00563 }
00564 
00573 void KDGanttView::setGanttMaximumWidth( int w )
00574 {
00575   myTimeHeader->setMaximumWidth ( w );
00576 }
00584 int  KDGanttView::ganttMaximumWidth() const
00585 {
00586   return myTimeHeader->maximumWidth();
00587 }
00588 
00595 void KDGanttView::showEvent( QShowEvent * event )
00596 {
00597   if ( event->spontaneous() ) {
00598     KDGanttMinimizeSplitter::showEvent( event );
00599     return;
00600   }
00601 
00602   myTimeTable->setBlockUpdating( false );
00603   if (myCanvasView->horizontalScrollBar()->value() > 0 )
00604     myCanvasView->horizontalScrollBar()->setValue(myCanvasView->horizontalScrollBar()->value()-1  );
00605   else
00606     myCanvasView->horizontalScrollBar()->setValue(1 );
00607   myTimeTable->updateMyContent();
00608 
00609   KDGanttMinimizeSplitter::showEvent( event );
00610 
00611   myCanvasView->setMyContentsHeight( 0 );
00612   if ( fCenterTimeLineAfterShow ) {
00613     fCenterTimeLineAfterShow = false;
00614     centerTimeline (dtCenterTimeLineAfterShow);
00615   }
00616 }
00624 void KDGanttView::closeEvent( QCloseEvent * event )
00625 {
00626   //qDebug() << "close ";
00627   if ( closingBlocked ) {
00628     event->ignore();
00629     return;
00630   }
00631   KDGanttMinimizeSplitter::closeEvent( event );
00632 }
00633 
00634 
00643 QSize KDGanttView::sizeHint() const
00644 {
00645   bool block = myTimeTable->blockUpdating();
00646   myTimeTable->setBlockUpdating( false );
00647   myTimeTable->updateMyContent();
00648   /* The below causes recursive calls to various size updating methods, which
00649    * cause QCanvas to hide and show items like mad, which is very slow. If
00650    * there is a legitimate gui updating issue here somewhere, it will need
00651    * to be solved differently.
00652    */
00653   //qApp->processEvents();
00654   int hintHeight = myTimeHeader->height();
00655   int legendHeight = 0;
00656   if ( showLegendButton() )
00657     legendHeight = myLegend->height();
00658   int listViewHeaderHeight = 0;
00659   if ( headerVisible() )
00660     listViewHeaderHeight = myListView->header()->height();
00661   if ( hintHeight < legendHeight+listViewHeaderHeight )
00662     hintHeight = legendHeight + listViewHeaderHeight;
00663   hintHeight += myListView->horizontalScrollBar()->height();
00664   if ( myLegend->isShown() )
00665     hintHeight += myLegend->legendSizeHint().height() +10;
00666   hintHeight += myTimeTable->minimumHeight()+myListView->frameWidth()*2+2;
00667   int hintWid = myListView->sizeHint().width();
00668   //hintWid += myTimeHeader->mySizeHint+myCanvasView->verticalScrollBar()->width();
00669   hintWid += myCanvasView->sizeHint().width();
00670   // add 10 for the splitter-bars
00671   // qDebug() << "sizehint " << hintWid+10 << " " << hintHeight;
00672   myTimeTable->setBlockUpdating( block );
00673   return QSize( hintWid+10, hintHeight );
00674 }
00675 
00676 
00684 void KDGanttView::setShowLegendButton( bool show )
00685 {
00686   _showLegendButton = show;
00687      if ( show )
00688          myLegend->show();
00689     else
00690          myLegend->hide();
00691      slotHeaderSizeChanged();
00692 }
00693 
00694 
00701 bool KDGanttView::showLegendButton() const
00702 {
00703     return _showLegendButton;
00704 }
00705 
00706 
00714 void KDGanttView::setHeaderVisible( bool visible )
00715 {
00716     if( visible )
00717         myListView->header()->show();
00718     else
00719         myListView->header()->hide();
00720     _showHeader = visible;
00721     slotHeaderSizeChanged();
00722 }
00723 
00724 
00731 bool KDGanttView::headerVisible() const
00732 {
00733   return _showHeader;
00734 }
00735 
00736 
00745 QDateTime KDGanttView::getDateTimeForCoordX(int coordX, bool global ) const
00746 {
00747   // default for myTimeHeader->getDateTimeForIndex() is local
00748    return myTimeHeader->getDateTimeForIndex(coordX, !global );
00749 }
00750 
00751 
00755 void KDGanttView::slotSelectionChanged( QListViewItem* item )
00756 {
00757     KDGanttViewItem* gItem = static_cast<KDGanttViewItem*>( item );
00758     Q_ASSERT( gItem );
00759     emit lvSelectionChanged( gItem );
00760 }
00761 
00762 
00763 /*
00764   Implements a casted pass-through of the mouseButtonClicked() signal.
00765   Signals itemLeftClicked() , itemMidClicked() are emitted as well.
00766 */
00767 void KDGanttView::slotmouseButtonClicked ( int button, QListViewItem * item,
00768                                            const QPoint & pos, int c )
00769 {
00770   KDGanttViewItem* gItem = static_cast<KDGanttViewItem*>( item );
00771   emit lvMouseButtonClicked ( button , gItem,  pos,  c );
00772   if (gItem == 0 && myCurrentItem != 0 ) {
00773     myCurrentItem = 0;
00774     emit lvCurrentChanged( gItem );
00775   }
00776   if (gItem != 0 && myCurrentItem == 0 ) {
00777     myCurrentItem = gItem;
00778     emit lvCurrentChanged( gItem );
00779   }
00780 
00781   // removed - makes no sense!
00782   //emit mouseButtonClicked ( button , gItem,  pos,  c );
00783    {
00784     switch ( button ) {
00785     case  Qt::LeftButton:
00786       emit lvItemLeftClicked( gItem );
00787       emit itemLeftClicked( gItem );
00788       break;
00789     case  Qt::MidButton:
00790       emit lvItemMidClicked( gItem );
00791       emit itemMidClicked( gItem );
00792       break;
00793     }
00794   }
00795 }
00796 
00797 
00798 /*
00799   Implements a casted pass-through of the contextMenuRequested() signal.
00800   The signal itemRightClicked() is emitted as well;
00801   the position is the global position.
00802 */
00803 void KDGanttView::slotcontextMenuRequested ( QListViewItem * item, const QPoint & pos, int col )
00804 {
00805     KDGanttViewItem* gItem = static_cast<KDGanttViewItem*>( item );
00806     emit lvContextMenuRequested ( gItem,  pos,  col );
00807     emit lvItemRightClicked( gItem );
00808     emit itemRightClicked( gItem );
00809 }
00810 
00811 /*
00812   Implements a casted pass-through of the collapsed() signal.
00813 */
00814 void KDGanttView::slotItemCollapsed ( QListViewItem * item )
00815 {
00816    {
00817     KDGanttViewItem* gItem = static_cast<KDGanttViewItem*>( item );
00818     emit itemCollapsed ( gItem );
00819   }
00820 }
00821 
00822 
00823 /*
00824   Implements a casted pass-through of the  expanded() signal.
00825 */
00826 void KDGanttView::slotItemExpanded ( QListViewItem * item )
00827 {
00828    {
00829        KDGanttViewItem* gItem = static_cast<KDGanttViewItem*>( item );
00830        emit itemExpanded( gItem );
00831    }
00832 }
00833 
00834 
00835 
00836 
00837 void KDGanttView::emptySpaceDoubleClicked( QMouseEvent * e )
00838 {
00839     emit dateTimeDoubleClicked( getDateTimeForCoordX( e->x(), false ) );
00840 }
00841 
00842 
00843 /*
00844   Implements a casted pass-through of the currentChanged() signal.
00845 */
00846 void KDGanttView::slotCurrentChanged ( QListViewItem * item )
00847 {
00848     KDGanttViewItem* gItem = static_cast<KDGanttViewItem*>( item );
00849     myCurrentItem = gItem;
00850     emit lvCurrentChanged( gItem );
00851 }
00852 
00853 
00854 /*
00855   Implements a casted pass-through of the itemRenamed() signal.
00856 */
00857 void KDGanttView::slotItemRenamed ( QListViewItem * item , int col,
00858                                     const QString & text )
00859 {
00860     KDGanttViewItem* gItem = static_cast<KDGanttViewItem*>( item );
00861     emit lvItemRenamed( gItem,  col, text );
00862 }
00863 
00864 
00865 /*
00866   Implements a casted pass-through of the mouseButtonPressed() signal.
00867 */
00868 void KDGanttView::slotMouseButtonPressed ( int button, QListViewItem * item,
00869                                            const QPoint & pos, int c )
00870 {
00871     KDGanttViewItem* gItem = static_cast<KDGanttViewItem*>( item );
00872     emit lvMouseButtonPressed( button, gItem,  pos,  c  );
00873 }
00874 
00875 
00890 void KDGanttView::setRepaintMode( RepaintMode mode )
00891 {
00892 
00893   QScrollBar  *cvh, *cvv;
00894   cvh = myCanvasView->horizontalScrollBar();
00895   cvv = myCanvasView->verticalScrollBar();
00896   // first disconnect
00897   mRepaintMode = mode;
00898   cvh->disconnect( this );
00899   cvv->disconnect( this );
00900 
00901 #if QT_VERSION < 0x040000
00902   connect( myCanvasView->horizontalScrollBar(), SIGNAL( prevLine () ) ,this, SLOT( addTickLeft()));
00903   connect( myCanvasView->horizontalScrollBar(), SIGNAL( nextLine () ) ,this, SLOT( addTickRight()));
00904 #endif
00905   switch ( mode ) {
00906   case  No:
00907 
00908     break;
00909   case Medium:
00910     connect( cvv, SIGNAL (sliderReleased () ) ,this, SLOT(forceRepaint()));
00911     connect( cvh, SIGNAL (sliderReleased () ) ,this, SLOT(forceRepaint()));
00912 #if QT_VERSION < 0x040000
00913     connect( cvv, SIGNAL (nextLine () ) ,this, SLOT(forceRepaint()));
00914     connect( cvh, SIGNAL (nextLine () ) ,this, SLOT(forceRepaint()));
00915     connect( cvv, SIGNAL (prevLine () ) ,this, SLOT(forceRepaint()));
00916     connect( cvh, SIGNAL (prevLine () ) ,this, SLOT(forceRepaint()));
00917 #endif
00918     break;
00919   case Always:
00920 #if QT_VERSION < 0x040000
00921     connect( cvv, SIGNAL (valueChanged ( int ) ) ,this, SLOT(forceRepaint( int )));
00922     connect( cvh, SIGNAL (valueChanged ( int ) ) ,this, SLOT(forceRepaint( int )));
00923 #endif
00924     connect( cvv, SIGNAL (sliderReleased () ) ,this, SLOT(forceRepaint()));
00925     connect( cvh, SIGNAL (sliderReleased () ) ,this, SLOT(forceRepaint()));
00926     break;
00927   }
00928 }
00929 
00930 
00931 void KDGanttView::forceRepaint( int )
00932 {
00933   if ( myTimeTable->blockUpdating() )
00934     return;
00935   // qDebug() << "forceRepaint( int ) ";
00936   myTimeTable->setAllChanged();
00937   myTimeTable->update();
00938 }
00939 
00940 
00941 void KDGanttView::slotHeaderSizeChanged()
00942 {
00943   int legendHeight = 0;
00944   if ( showLegendButton() )
00945     legendHeight = 24;
00946   int listViewHeaderHeight = 0;
00947   if ( headerVisible() )
00948     listViewHeaderHeight = myListView->header()->height();
00949   int timeHeaderHeight = myTimeHeader->height()+myTimeHeaderScroll->frameWidth()*2;;
00950   int diffY = timeHeaderHeight-legendHeight-listViewHeaderHeight;
00951   if ( diffY < 0 ) {
00952     spacerLeft->setFixedHeight( 0 );
00953     spacerRight->setFixedHeight(-diffY);
00954   } else {
00955     spacerRight->setFixedHeight( 0 );
00956     spacerLeft->setFixedHeight( diffY );
00957   }
00958   myLegend->setFixedHeight( legendHeight );
00959   myTimeHeaderContainer->setFixedHeight( timeHeaderHeight );
00960 }
00961 
00962 void KDGanttView::setLegendIsDockwindow( bool show )
00969 {
00970   bool isdock = myLegend->asDockwindow();
00971   if ( show != isdock ) {
00972     myLegend->setAsDockwindow(show);
00973     // legend is cleared - reinit legend with list
00974     legendItem* li;
00975     for ( li = myLegendItems.first(); li; li = myLegendItems.next() ) {
00976         if ( li->has2 )
00977             myLegend->addLegendItem(li->shape, li->color, li->text,li->shape2, li->color2, li->text2 );
00978         else
00979             myLegend->addLegendItem(li->shape, li->color, li->text );
00980     }
00981   }
00982 }
00983 
00984 bool KDGanttView::legendIsDockwindow() const
00991 {
00992     return myLegend->asDockwindow();
00993 }
00994 
00995 
01008 QDockWindow* KDGanttView::legendDockwindow() const
01009 {
01010   return myLegend->dockwindow();
01011 }
01012 
01013 
01022 void KDGanttView::setShowLegend( bool show )
01023 {
01024     myLegend->showMe(show);
01025 }
01026 
01027 
01036 bool KDGanttView::showLegend() const
01037 {
01038     return myLegend->isShown();
01039 }
01040 
01041 
01050 void KDGanttView::setShowListView( bool show )
01051 {
01052     if(listViewIsVisible == show) return;
01053     listViewIsVisible = show;
01054     if (listViewIsVisible)
01055         myListView->parentWidget()->show();
01056     else
01057         myListView->parentWidget()->hide();
01058 }
01059 
01060 
01067 bool KDGanttView::showListView() const
01068 {
01069     return listViewIsVisible;
01070 }
01071 
01072 
01082 void KDGanttView::setEditorEnabled( bool enable )
01083 {
01084   editorIsEnabled =  enable;
01085 }
01086 
01087 
01096 bool KDGanttView::editorEnabled() const
01097 {
01098     return editorIsEnabled;
01099 }
01100 
01101 
01110 void KDGanttView::setEditable( bool editable )
01111 {
01112   chartIsEditable =  editable;
01113 }
01114 
01115 
01123 bool KDGanttView::editable() const
01124 {
01125     return chartIsEditable;
01126 }
01127 
01128 
01140 bool KDGanttView::saveProject( QIODevice* device )
01141 {
01142     Q_ASSERT( device );
01143 
01144     QDomDocument doc = saveXML();
01145     if( device->isOpen() )
01146         device->close();
01147     if( device->open( IO_WriteOnly ) ) {
01148         QTextStream ts( device );
01149         ts << doc.toString();
01150         return true;
01151     } else
01152         return false;
01153 }
01154 
01155 
01167 bool KDGanttView::loadProject( QIODevice* device )
01168 {
01169     Q_ASSERT( device );
01170 
01171     if( device->isOpen() )
01172         device->close();
01173     if( device->open( IO_ReadOnly ) ) {
01174         QDomDocument doc( "GanttView" );
01175     QString err;
01176     int errline, errcol;
01177     if ( !doc.setContent( device, &err, &errline, &errcol ) ) {
01178       qDebug() << "KDGantt::Error parsing XML data at line " << errline << ". Message is: ";
01179       qDebug() << err;
01180       device->close();
01181       return false;
01182     }
01183         device->close();
01184         clearAll();
01185         return loadXML( doc );
01186     } else
01187         return false;
01188 }
01189 
01190 // slot, can be connected to menu action
01191 // Note: This should possibly have a setup dialog so the user can print
01192 //       something other than the default
01193 void KDGanttView::print()
01194 {
01195     print(0);
01196 }
01197 
01216 void KDGanttView::print( QPrinter* printer ,
01217                          bool printListView, bool printTimeLine,
01218                          bool printLegend )
01219 {
01220   bool deletePrinter = false;
01221   if (! printer ) {
01222     printer = new QPrinter();
01223     deletePrinter = true;
01224     QPrintDialog dialog(printer);
01225     if ( !dialog.exec() ) {
01226       delete printer;
01227       return;
01228     }
01229   }
01230   // now we have a printer to print on
01231   QPainter p( printer );
01232   // get the paper metrics
01233   float dx, dy;
01234   // get the size of the desired output for scaling.
01235   // here we want to print all: ListView, TimeLine, and Legend
01236   // for this purpose, we call drawContents() with a 0 pointer as painter
01237   QSize size = drawContents( 0, printListView, printTimeLine, printLegend );
01238 
01239   // at the top, we want to print current time/date
01240   QString date = "Printing Time: " + QDateTime::currentDateTime().toString();
01241   int hei = p.boundingRect(0,0, 5, 5, Qt::AlignLeft, date ).height();
01242   p.drawText( 0, 0, date );
01243 
01244   // compute the scale
01245 #if QT_VERSION >= 0x040000
01246   dx = (float) printer->width()  / (float)size.width();
01247   dy  = (float)(printer->height() - ( 2 * hei )) / (float)size.height();
01248 #else
01249   QPaintDeviceMetrics m = QPaintDeviceMetrics ( printer );
01250   dx = (float) m.width()  / (float)size.width();
01251   dy  = (float)(m.height() - ( 2 * hei )) / (float)size.height();
01252 #endif
01253   float scale;
01254   // scale to fit the width or height of the paper
01255   if ( dx < dy )
01256     scale = dx;
01257   else
01258     scale = dy;
01259   // set the scale
01260   p.scale( scale, scale );
01261   // now printing with y offset:  2 hei
01262   p.translate( 0, 2*hei );
01263   drawContents( &p, printListView, printTimeLine, printLegend );
01264   // the drawContents() has the side effect, that the painter translation is
01265   // after drawContents() set to the bottom of the painted stuff
01266   // for instance a
01267   // p.drawText(0, 0, "printend");
01268   // would be painted directly below the paintout of drawContents()
01269   p.end();
01270   if ( deletePrinter )
01271     delete printer;
01272 }
01273 
01274 
01314 QSize KDGanttView::drawContents( QPainter* p,
01315               bool drawListView , bool drawTimeLine, bool drawLegend )
01316 {
01317     QSize size;
01318     int lvX, lvY, thX, thY, tlX, tlY, lwX, lwY, allX, allY;
01319     lvX = myListView->contentsWidth();
01320     lvY = myTimeTable->minimumHeight() + 2;
01321     thX = myTimeHeader->width();
01322     thY = myTimeHeader->height();
01323     tlX = myCanvasView->canvas()->width();
01324     tlY = lvY;
01325     lwX = myLegend->legendSize().width();
01326     lwY = myLegend->legendSize().height();
01327     allX = 0;
01328     allY = 0;
01329     if ( drawListView ) {
01330         allX += lvX;
01331         allY += tlY;
01332     }
01333     if ( drawTimeLine ) {
01334         allX += thX;
01335         allY += thY;
01336     }
01337     if ( drawLegend ) {
01338         allY += lwY;
01339         if ( allX < lwX )
01340             allX = lwX ;
01341     }
01342     size = QSize( allX, allY );
01343     int temp = 0;
01344     if ( p ) {
01345         if ( drawListView ) {
01346             if ( drawTimeLine )
01347                 temp =  thY;
01348             p->translate( 0, temp );
01349             if ( headerVisible() ) {
01350                 p->translate( 0,  -myListView->header()->height());
01351                 int cou = myListView->header()->count();
01352                 int iii;
01353                 QRect rect ( 0,0,0, myListView->header()->height());
01354                 for ( iii = 0; iii < cou; ++iii ) {
01355                     rect.setLeft ( myListView->header()->sectionPos( iii ) );
01356                     rect.setRight ( myListView->header()->sectionPos( iii ) + myListView->header()->sectionSize (iii));
01357                     myListView->header()->paintSection ( p,  myListView->header()->mapToIndex (iii),  rect );
01358                 }
01359                 p->translate( 0,  myListView->header()->height());
01360             }
01361             myListView->drawToPainter( p );
01362             p->translate( lvX, -temp);
01363         }
01364         if ( drawTimeLine ) {
01365             p->translate( myCanvasView->frameWidth(), 0);
01366             myTimeHeader->repaintMe( 0, myTimeHeader->width(), p );
01367             p->translate( -myCanvasView->frameWidth(), thY);
01368             myCanvasView->drawToPainter( p );
01369             if ( drawListView )
01370                 p->translate( -lvX, tlY);
01371             else
01372                 p->translate( 0, tlY);
01373         } else {
01374             if ( drawListView )
01375                 p->translate( -lvX, 0 );
01376         }
01377         if ( drawLegend ) {
01378             myLegend->drawToPainter( p );
01379             p->translate( 0, lwY );
01380         }
01381     }
01382     return size;
01383 }
01384 
01398 void KDGanttView::setZoomFactor( double factor, bool absolute )
01399 {
01400     myTimeHeader->zoom(factor,absolute);
01401 }
01402 
01403 
01411 double KDGanttView::zoomFactor() const
01412 {
01413     return myTimeHeader->zoomFactor();
01414 }
01415 
01416 
01425 void KDGanttView::zoomToFit()
01426 {
01427   myTimeHeader->zoomToFit();
01428 }
01429 
01430 
01443 void KDGanttView::zoomToSelection( const QDateTime& start,  const QDateTime&  end )
01444 {
01445 
01446   myTimeHeader->zoomToSelection( start, end);
01447 
01448 }
01462 void KDGanttView::zoomToSelectionAndSetStartEnd( const QDateTime& start,  const QDateTime&  end )
01463 {
01464     /*
01465     myTimeHeader->setHorizonStart(start);
01466     myTimeHeader->setHorizonEnd(start);
01467     myTimeHeader->zoomToSelection( start, end);
01468     */
01469     myTimeHeader->zoomToSelectionAndSetStartEnd( start, end);
01470 }
01471 
01472 
01479 void KDGanttView::ensureVisible( KDGanttViewItem* item )
01480 {
01481     if ( item == 0 ) return;
01482     myListView->ensureItemVisible (item);
01483 }
01484 
01485 
01506 void KDGanttView::centerTimeline( const QDateTime& center )
01507 {
01508     myTimeHeader->centerDateTime( center, mUserHorizonChangeEnabled );
01509 }
01510 
01511 
01525 void KDGanttView::centerTimelineAfterShow( const QDateTime& center )
01526 {
01527   myTimeHeader->centerDateTime( center );
01528   if ( isVisible() ) return;
01529   dtCenterTimeLineAfterShow = center;
01530   fCenterTimeLineAfterShow = true;
01531 }
01532 
01537 void KDGanttView::setTimelineToStart()
01538 {
01539   myCanvasView->horizontalScrollBar()->setValue( 0 );
01540 }
01541 
01542 
01546 void KDGanttView::setTimelineToEnd()
01547 {
01548  myCanvasView->horizontalScrollBar()->setValue(myCanvasView->horizontalScrollBar()->maximum());
01549 }
01550 
01551 
01562 void KDGanttView::addTicksLeft( int num )
01563 {
01564   myTimeHeader->addTickLeft( num  );
01565 }
01566 
01567 
01577 void KDGanttView::addTicksRight( int num )
01578 {
01579   myTimeHeader->addTickRight( num );
01580 }
01581 
01582 
01587 void KDGanttView::center( KDGanttViewItem* item )
01588 {
01589     ensureVisible(item);
01590     int x =  myListView->contentsWidth()/2;
01591     int y = myListView->itemPos (item );
01592     myListView->center(x,y);
01593 }
01594 
01595 
01602 void KDGanttView::setShowTaskLinks( bool show )
01603 {
01604     myTimeTable->setShowTaskLinks(show);
01605 
01606 }
01607 
01608 
01615 bool KDGanttView::showTaskLinks() const
01616 {
01617     return  myTimeTable->showTaskLinks();
01618 }
01619 
01620 
01628 void KDGanttView::setFont(const QFont& font)
01629 {
01630     myListView->setFont(font);
01631     myListView->repaint();
01632     myTimeHeader->setFont(font);
01633     myLegend->setFont( font );
01634     QWidget::setFont( font );
01635     setScale(scale());
01636     QTimer::singleShot( 0, this, SLOT( slotHeaderSizeChanged() ) );
01637 }
01638 
01639 
01664 void KDGanttView::setShowHeaderPopupMenu( bool show,
01665                                           bool showZoom,
01666                                           bool showScale,
01667                                           bool showTime,
01668                                           bool showYear,
01669                                           bool showGrid,
01670                                           bool showPrint)
01671 {
01672     if ( show && myTimeHeader->showPopupMenu() ) return;
01673     myTimeHeader->setShowPopupMenu( show,showZoom,showScale,showTime,
01674                                     showYear,showGrid,showPrint );
01675 }
01676 
01677 
01684 bool KDGanttView::showHeaderPopupMenu() const
01685 {
01686     return myTimeHeader->