kdgantt

KDGanttViewSubwidgets.cpp

00001 /* -*- Mode: C++ -*-
00002    $Id: KDGanttViewSubwidgets.cpp 516548 2006-03-07 14:58:04Z danders $
00003    KDGantt - a multi-platform charting engine
00004 */
00005 
00006 /****************************************************************************
00007  ** Copyright (C)  2002-2004 Klar�vdalens Datakonsult AB.  All rights reserved.
00008  **
00009  ** This file is part of the KDGantt library.
00010  **
00011  ** This file may be distributed and/or modified under the terms of the
00012  ** GNU General Public License version 2 as published by the Free Software
00013  ** Foundation and appearing in the file LICENSE.GPL included in the
00014  ** packaging of this file.
00015  **
00016  ** Licensees holding valid commercial KDGantt licenses may use this file in
00017  ** accordance with the KDGantt Commercial License Agreement provided with
00018  ** the Software.
00019  **
00020  ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00021  ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00022  **
00023  ** See http://www.klaralvdalens-datakonsult.se/Public/products/ for
00024  **   information about KDGantt Commercial License Agreements.
00025  **
00026  ** Contact info@klaralvdalens-datakonsult.se if any conditions of this
00027  ** licensing are not clear to you.
00028  **
00029  ** As a special exception, permission is given to link this program
00030  ** with any edition of Qt, and distribute the resulting executable,
00031  ** without including the source code for Qt in the source distribution.
00032  **
00033  **********************************************************************/
00034 
00035 
00036 #include "KDGanttViewSubwidgets.h"
00037 #include "KDGanttViewEventItem.h"
00038 #include "KDGanttViewSummaryItem.h"
00039 #include "KDGanttViewTaskItem.h"
00040 #ifndef KDGANTT_MASTER_CVS
00041 #include "KDGanttViewSubwidgets.moc"
00042 #endif
00043 
00044 #include <qlabel.h>
00045 #include <qheader.h>
00046 #include <qpainter.h>
00047 #include <qrect.h>
00048 #include <qtooltip.h>
00049 #include <qapplication.h>
00050 #include <qdrawutil.h>
00051 #include <qpalette.h>
00052 #include <qdragobject.h>
00053 #include <qptrlist.h>
00054 #include <qpen.h>
00055 
00056 #include <kglobal.h>
00057 #include <klocale.h>
00058 #include <kcalendarsystem.h>
00059 #include <kdebug.h>
00060 
00061 KDTimeTableWidget:: KDTimeTableWidget( QWidget* parent,KDGanttView* myGantt):QCanvas (parent)
00062 {
00063     myGanttView = myGantt;
00064     taskLinksVisible = true;
00065     flag_blockUpdating = false;
00066     int_blockUpdating = 0;
00067     gridPen.setStyle(Qt::DotLine);
00068     gridPen.setColor(QColor(100,100,100));
00069     maximumComputedGridHeight = 0;
00070     denseLineCount = 0;
00071     denseLineBrush = QBrush( QColor ( 240,240,240 ));
00072     noInfoLineBrush = QBrush(  QColor ( 100,100,100 ), Qt::FDiagPattern );
00073     pendingHeight = 0;
00074     pendingWidth = 0;
00075     retune(256);
00076     resize(1,1);
00077 }
00078 
00079 QPtrList<KDGanttViewTaskLink> KDTimeTableWidget::taskLinks()
00080 {
00081     return myTaskLinkList;
00082 }
00083 
00084 void KDTimeTableWidget::clearTaskLinks()
00085 {
00086     // cannot use clear() here, as tasklinks will remove themselves from my list when deleted!
00087     QPtrListIterator<KDGanttViewTaskLink> it(myTaskLinkList);
00088     while (it.current()) {
00089         delete it.current();
00090     }
00091         
00092 }
00093 
00094 void KDTimeTableWidget::resetWidth( int wid )
00095 {
00096     if ( wid == width() ) {
00097         if (pendingHeight)
00098             pendingWidth = wid;
00099         else
00100             pendingWidth = 0;
00101         return;
00102     }
00103     if ( ! pendingHeight )
00104         pendingHeight = height();
00105     pendingWidth = wid;
00106     updateMyContent();
00107 }
00108 
00109 void KDTimeTableWidget::checkHeight( int hei )
00110 {
00111     if( hei < height() )
00112         return;
00113     if ( pendingHeight < hei+100)
00114         pendingHeight = hei+100;
00115     if ( !  pendingWidth )
00116         pendingWidth = width();
00117     maximumComputedGridHeight = 0; //force recomputing all
00118     updateMyContent();
00119 }
00120 
00121 
00122 void KDTimeTableWidget::setNoInformationBrush( const QBrush& brush )
00123 {
00124     noInfoLineBrush = brush;
00125     updateMyContent();
00126 }
00127 QBrush KDTimeTableWidget::noInformationBrush() const
00128 {
00129     return noInfoLineBrush;
00130 }
00131 
00132 void KDTimeTableWidget::removeItemFromTasklinks( KDGanttViewItem* item)
00133 {
00134     QPtrListIterator<KDGanttViewTaskLink> it((myTaskLinkList));
00135     for ( ; it.current(); ++it ) {
00136         it.current()->removeItemFromList( item );
00137     }
00138 }
00139 
00140 void KDTimeTableWidget::expandItem( QListViewItem * item)
00141 {
00142     item->invalidateHeight () ;
00143     //qApp->processEvents();
00144     updateMyContent();
00145 }
00146 void KDTimeTableWidget::collapseItem( QListViewItem * item)
00147 {
00148     item->invalidateHeight () ;
00149     //qApp->processEvents();
00150     updateMyContent();
00151 }
00152 
00153 void KDTimeTableWidget::highlightItem( QListViewItem * item )
00154 {
00155     static bool itemwashighlighted;
00156     static KDGanttViewItem* highlightedItem = 0;
00157     if (highlightedItem)
00158         highlightedItem->setHighlight(itemwashighlighted);
00159     highlightedItem = ( KDGanttViewItem*)item;
00160     itemwashighlighted = highlightedItem->highlight();
00161     highlightedItem->setHighlight(true);
00162     item->invalidateHeight () ;
00163     myGanttView->myListView->contentsY();
00164     updateMyContent();
00165 }
00166 int  KDTimeTableWidget::computeHeight()
00167 {
00168     // compute height of ListView
00169     // show only items shown in ListView
00170     int hei = 0;
00171     KDGanttViewItem* temp;
00172     temp = myGanttView->firstChild();
00173     while (temp) {
00174         hei += temp->computeHeight();
00175         temp = temp->nextSibling();
00176     }
00177     // set hei  to 1 to avoid canavs to be a null pixmap
00178     if (hei == 0) {
00179         hei = 1;
00180     }
00181     //qDebug("COMPUTED HEI %d ", hei);
00182     emit heightComputed( hei );
00183     return hei;
00184 }
00185 void KDTimeTableWidget::computeVerticalGrid()
00186 {
00187     // recompute the vertical grid
00188     // compute the vertical grid
00189     // if we have too much lines, hide them
00190     //qDebug("computeVerticalGrid() ");
00191     int cw =  myGanttView->myTimeHeader->myGridMinorWidth;
00192     int i = 0;
00193     int h ;
00194     if (pendingHeight > height() )
00195         h = pendingHeight;
00196     else
00197         h = height();
00198     int wid;
00199     if ( pendingWidth )
00200         wid = pendingWidth;
00201     else
00202         wid = width();
00203     KDCanvasLine* templine;
00204     KDCanvasRectangle* temprect;
00205     QColor colcol;
00206     QPen colPen;
00207     bool colorIterator = true;
00208 
00209 
00210     if (myGanttView->showMinorTicks()){//minor
00211         colPen.setWidth(cw);
00212         QPtrListIterator<KDCanvasRectangle> itcol(columnColorList);
00213         QPtrListIterator<KDCanvasLine> itgrid(verGridList);
00214         for ( ; itgrid.current(); ++itgrid ) {
00215             if (i < wid) {
00216                 itgrid.current()->setPoints(i,0,i,h);
00217                 itgrid.current()->show();
00218 
00219                 if (myGanttView->myTimeHeader->getColumnColor(colcol,i,i+cw))
00220                     {
00221 
00222                         colPen.setColor(colcol);
00223                         if (colorIterator)
00224                             colorIterator = itcol.current();
00225                         if (colorIterator)
00226                             {/*
00227                                itcol.current()->setPen(colPen);
00228                                itcol.current()->setPoints(i+(cw/2),0,i+(cw/2),h);
00229                              */
00230 
00231                                 itcol.current()->setPen( QPen::NoPen );
00232                                 itcol.current()->setBrush( QBrush( colcol, SolidPattern) );
00233                                 itcol.current()->setSize(cw ,h );
00234                                 itcol.current()->move( i, 0 );
00235                                 itcol.current()->show();
00236                                 ++itcol;
00237                             } else {
00238 
00239                                 /*
00240                                   templine = new KDCanvasLine(this,0,Type_is_KDGanttGridItem);
00241                                   templine->setPen(colPen);
00242                                   templine->setPoints(i+(cw/2),0,i+(cw/2),h);
00243                                 */
00244                                 temprect = new KDCanvasRectangle(this,0,Type_is_KDGanttGridItem);
00245                                 temprect->setPen( QPen::NoPen );
00246                                 temprect->setBrush( QBrush( colcol, SolidPattern) );
00247                                 temprect->setSize(cw ,h );
00248                                 temprect->move( i, 0 );
00249                                 temprect->setZ(-20);
00250                                 temprect->show();
00251                                 columnColorList.append(temprect);
00252                             }
00253                     }
00254                 i += cw;
00255             } else {
00256                 itgrid.current()->hide();
00257             }
00258         }
00259         // create additional Lines for vertical grid
00260         for ( ;i < wid;i += cw) {
00261             templine = new KDCanvasLine(this,0,Type_is_KDGanttGridItem);
00262             templine->setPen(gridPen);
00263             templine->setPoints(i,0,i,h);
00264             templine->setZ(0);
00265             templine->show();
00266             verGridList.append(templine);
00267             if (myGanttView->myTimeHeader->getColumnColor(colcol,i,i+cw))
00268                 {
00269                     colPen.setColor(colcol);
00270                     if (colorIterator)
00271                         colorIterator = itcol.current();
00272                     if (colorIterator)
00273                         {/*
00274                            itcol.current()->setPen(colPen);
00275                            itcol.current()->setPoints(i+(cw/2),0,i+(cw/2),h);
00276                          */
00277                             itcol.current()->setPen( QPen::NoPen );
00278                             itcol.current()->setBrush( QBrush( colcol, SolidPattern) );
00279                             itcol.current()->setSize(cw ,h );
00280                             itcol.current()->move( i, 0 );
00281                             itcol.current()->show();
00282                             ++itcol;
00283                         } else {
00284                             temprect = new KDCanvasRectangle(this,0,Type_is_KDGanttGridItem);
00285                             temprect->setPen( QPen::NoPen );
00286                             temprect->setBrush( QBrush( colcol, SolidPattern) );
00287                             temprect->setSize(cw ,h );
00288                             temprect->move( i, 0 );
00289                             temprect->setZ(-20);
00290                             temprect->show();
00291                             columnColorList.append(temprect);
00292                             /*
00293                               templine = new KDCanvasLine(this,0,Type_is_KDGanttGridItem);
00294                               templine->setPen(colPen);
00295                               templine->setPoints(i+(cw/2),0,i+(cw/2),h);
00296                               templine->setZ(-20);
00297                               templine->show();
00298                               columnColorList.append(templine);
00299                             */
00300                         }
00301                 }
00302         }
00303         if (colorIterator)
00304             for ( ; itcol.current(); ++itcol )
00305                 itcol.current()->hide();
00306     } else {//major
00307         if (myGanttView->showMajorTicks()) {
00308             QValueList<int>::iterator intIt = myGanttView->myTimeHeader->majorTicks.begin();
00309             QValueList<int>::iterator intItEnd = myGanttView->myTimeHeader->majorTicks.end();
00310             QPtrListIterator<KDCanvasRectangle> itcol(columnColorList);
00311             QPtrListIterator<KDCanvasLine> itgrid(verGridList);
00312             int left = 0;
00313             for ( ; itgrid.current(); ++itgrid ) {
00314                 if (intIt != intItEnd) {
00315                     left = (*intIt);
00316                     ++intIt;
00317                     itgrid.current()->setPoints(left,0,left,h);
00318                     itgrid.current()->show();
00319                     //int right = (*intIt);
00320                     if ((*intIt))
00321                         if (myGanttView->myTimeHeader->getColumnColor(colcol,left,(*intIt) ))
00322                             {
00323                                 int mid = (-left+(*intIt));
00324                                 colPen.setColor(colcol);
00325                                 colPen.setWidth((*intIt)-left);
00326                                 if (colorIterator)
00327                                     colorIterator = itcol.current();
00328                                 if (colorIterator)
00329                                     {/*
00330                                        itcol.current()->setPen(colPen);
00331                                        itcol.current()->setPoints(i+mid,0,mid,h);
00332                                      */
00333                                         itcol.current()->setPen( QPen::NoPen );
00334                                         itcol.current()->setBrush( QBrush( colcol, SolidPattern) );
00335                                         itcol.current()->setSize(mid ,h );
00336                                         itcol.current()->move( left, 0 );
00337                                         itcol.current()->show();
00338                                         ++itcol;
00339                                     } else {
00340                                         temprect = new KDCanvasRectangle(this,0,Type_is_KDGanttGridItem);
00341                                         temprect->setPen( QPen::NoPen );
00342                                         temprect->setBrush( QBrush( colcol, SolidPattern) );
00343                                         temprect->setSize(mid,h );
00344                                         temprect->move( left, 0 );
00345                                         temprect->setZ(-20);
00346                                         temprect->show();
00347                                         columnColorList.append(temprect);
00348                                         /*
00349                                           templine = new KDCanvasLine(this,0,Type_is_KDGanttGridItem);
00350                                           templine->setPen(colPen);
00351                                           templine->setPoints(mid,0,i+mid,h);
00352                                           templine->setZ(-20);
00353                                           templine->show();
00354                                           columnColorList.append(templine);
00355                                         */
00356 
00357                                     }
00358                             }
00359 
00360                 } else {
00361                     itgrid.current()->hide();
00362                 }
00363             }
00364             KDCanvasLine* templine;
00365             // create additional Lines for vertical grid
00366             for ( ;intIt != intItEnd  ;++intIt) {
00367 
00368                 templine = new KDCanvasLine(this,0,Type_is_KDGanttGridItem);
00369                 templine->setPen(gridPen);
00370                 templine->setPoints((*intIt),0,(*intIt),h);
00371                 templine->setZ(0);
00372                 templine->show();
00373                 verGridList.append(templine);
00374                 if ((*intIt))
00375                     if (myGanttView->myTimeHeader->getColumnColor(colcol,left,(*intIt)))
00376                         {
00377                             int mid = (-left+(*intIt));
00378                             colPen.setColor(colcol);
00379                             colPen.setWidth((*intIt)-left);
00380                             if (colorIterator)
00381                                 colorIterator = itcol.current();
00382                             if (colorIterator)
00383                                 {/*
00384                                    itcol.current()->setPen(colPen);
00385                                    itcol.current()->setPoints(i+mid,0,mid,h);
00386                                  */
00387                                     itcol.current()->setPen( QPen::NoPen );
00388                                     itcol.current()->setBrush( QBrush( colcol, SolidPattern) );
00389                                     itcol.current()->setSize(mid ,h );
00390                                     itcol.current()->move( left, 0 );
00391                                     itcol.current()->show();
00392                                     ++itcol;
00393                                 } else {
00394                                     temprect = new KDCanvasRectangle(this,0,Type_is_KDGanttGridItem);
00395                                     temprect->setPen( QPen::NoPen );
00396                                     temprect->setBrush( QBrush( colcol, SolidPattern) );
00397                                     temprect->setSize(mid ,h );
00398                                     temprect->move( left, 0 );
00399                                     temprect->setZ(-20);
00400                                     temprect->show();
00401                                     columnColorList.append(temprect);
00402                                     /*
00403                                       templine = new KDCanvasLine(this,0,Type_is_KDGanttGridItem);
00404                                       templine->setPen(colPen);
00405                                       templine->setPoints(mid,0,i+mid,h);
00406                                       templine->setZ(-20);
00407                                       templine->show();
00408                                       columnColorList.append(templine);
00409                                     */
00410                                 }
00411                         }
00412                 left = (*intIt);
00413             }
00414             if (colorIterator)
00415                 for ( ; itcol.current(); ++itcol ) {
00416                     itcol.current()->hide();
00417                 }
00418 
00419         }
00420         else {
00421             //hideall
00422             QPtrListIterator<KDCanvasLine> itgrid(verGridList);
00423             for ( ; itgrid.current(); ++itgrid ) {
00424                 itgrid.current()->hide();
00425             }
00426             QPtrListIterator<KDCanvasRectangle> itcol(columnColorList);
00427             for ( ; itcol.current(); ++itcol ) {
00428                 itcol.current()->hide();
00429             }
00430         }
00431     }
00432 }
00433 void KDTimeTableWidget::computeHorizontalGrid()
00434 {
00435     // compute  horizontal grid
00436     //qDebug("computeHorizontalGrid() ");
00437     KDGanttViewItem* temp = myGanttView->firstChild();
00438     int wid;
00439     if ( pendingWidth )
00440         wid = pendingWidth;
00441     else
00442         wid = width();
00443     KDCanvasLine* templine;
00444     QPtrListIterator<KDCanvasLine> ithor(horGridList);
00445     if ( ithor.current() ) {
00446         templine = ithor.current();
00447         ++ithor;
00448     } else {
00449         templine = new KDCanvasLine(this,0,Type_is_KDGanttGridItem);
00450         templine->setPen(gridPen);
00451         templine->setZ(0);
00452         horGridList.append(templine);
00453     }
00454     templine->setPoints(0,0,wid,0);
00455     templine->show();
00456     int posY;
00457     while ( temp ) {
00458         posY = temp->itemPos() + temp->height();
00459         if ( ithor.current() ) {
00460             templine = ithor.current();
00461             ++ithor;
00462         } else {
00463             //new vertical grid line
00464             templine = new KDCanvasLine(this,0,Type_is_KDGanttGridItem);
00465             templine->setPen(gridPen);
00466             templine->setZ(0);
00467             horGridList.append(templine);
00468         }
00469         if ( templine->endPoint() != QPoint(wid,posY ))
00470             templine->setPoints(0,posY,wid,posY );
00471         if ( !templine->isVisible() )
00472             templine->show();
00473         //QString ts = "asGroup";
00474         //if (!temp->displaySubitemsAsGroup() )
00475         //  ts = " NOT asGroup";
00476         //qDebug("temp name %s %s", temp->listViewText(0).latin1(), ts.latin1());
00477 
00478         temp = temp->itemBelow ();
00479     }
00480     while ( ithor.current() ) {
00481         if ( ithor.current()->isVisible() )
00482             ithor.current()->hide();
00483         ++ithor;
00484     }
00485 }
00486 
00487 void KDTimeTableWidget::computeDenseLines()
00488 {
00489     KDGanttViewItem* temp = myGanttView->firstChild();
00490     int wid;
00491     if ( pendingWidth )
00492         wid = pendingWidth;
00493     else
00494         wid = width();
00495     QPtrListIterator<KDCanvasRectangle> ithordense(horDenseList);
00496     KDCanvasRectangle* denseLine;
00497     int tempDenseLineCount = 0;
00498     while ( temp ) {
00499         if ( temp->isVisible() ) {
00500             ++tempDenseLineCount;
00501             if ( tempDenseLineCount == denseLineCount ) {
00502                 tempDenseLineCount = 0;
00503                 if ( ithordense.current() ) {
00504                     denseLine = ithordense.current();
00505                     ++ithordense;
00506                 } else {
00507                     denseLine =new KDCanvasRectangle(this,0,Type_is_KDGanttGridItem);
00508                     denseLine->setZ(-2);
00509                     horDenseList.append( denseLine );
00510                 }
00511                 if ( denseLine->rect() != QRect(0, temp->itemPos(),wid, temp->height()) ) {
00512                     denseLine->move( 0, temp->itemPos() );
00513                     denseLine->setSize( wid, temp->height());
00514                 }
00515                 if (denseLine->brush() != denseLineBrush ) {
00516                     denseLine->setPen( QPen(  Qt::NoPen ) );
00517                     denseLine->setBrush( denseLineBrush);
00518                 }
00519                 if (!denseLine->isVisible() )
00520                     denseLine->show();
00521 
00522             } else {
00523                 ;
00524             }
00525         }
00526         temp = temp->itemBelow ();
00527     }
00528     while ( ithordense.current() ) {
00529         if ( ithordense.current()->isVisible() ) {
00530             ithordense.current()->hide();
00531         }
00532         ++ithordense;
00533     }
00534 }
00535 void KDTimeTableWidget::computeShowNoInformation()
00536 {
00537     KDGanttViewItem* temp = myGanttView->firstChild();
00538     int wid;
00539     if ( pendingWidth )
00540         wid = pendingWidth;
00541     else
00542         wid = width();
00543     QPtrListIterator<KDCanvasRectangle> itnoinfo(showNoInfoList);
00544     KDCanvasRectangle* noInfoLine;
00545     while ( temp ) {
00546         if ( temp->showNoInformation() ) {
00547             if ( itnoinfo.current() ) {
00548                 noInfoLine = itnoinfo.current();
00549                 ++itnoinfo;
00550             } else {
00551                 noInfoLine =new KDCanvasRectangle(this,0,Type_is_KDGanttGridItem);
00552                 showNoInfoList.append( noInfoLine );
00553                 noInfoLine->setZ(-1);
00554             }
00555             noInfoLine->move( 0, temp->itemPos() );
00556             noInfoLine->setSize( wid, temp->height());
00557             noInfoLine->setPen( QPen(  Qt::NoPen ) );
00558             noInfoLine->setBrush( noInfoLineBrush);
00559             noInfoLine->show();
00560         }
00561         temp = temp->itemBelow ();
00562     }
00563     while ( itnoinfo.current() ) {
00564         itnoinfo.current()->hide();
00565         ++itnoinfo;
00566     }
00567 
00568 }
00569 
00570 void KDTimeTableWidget::computeTaskLinks()
00571 {
00572     //compute and show tasklinks
00573     QPtrListIterator<KDGanttViewTaskLink> it((myTaskLinkList));
00574     for ( ; it.current(); ++it ) {
00575         if (it.current()->isVisible())
00576             it.current()->showMe(true);
00577         else
00578             it.current()->showMe(false);
00579     }
00580 }
00581 
00582 // updateMyContent() can be blocked by blockUpdating( true ) or inc_blockUpdating()
00583 // updateMyContent() is blocked, if the GanttView is hidden after startup
00584 
00585 void KDTimeTableWidget::updateMyContent()
00586 {
00587     if ( flag_blockUpdating || int_blockUpdating ) {
00588         // qDebug("KDTimeTableWidget::updateMyContent() blocked! ");
00589         return;
00590     }
00591     //qDebug("KDTimeTableWidget::updateMyContent() ********************************* ");
00592     /*
00593     // debug output
00594     KDGanttViewItem* temp =  myGanttView->firstChild();
00595     while (temp != 0) {
00596     temp->printinfo("  " );
00597     temp = temp->nextSibling();
00598     }
00599     */
00600     int hei = computeHeight();
00601     minimumHeight = hei;
00602     int viewport_hei = myGanttView->myCanvasView->viewport()->height();
00603     if ( viewport_hei > hei )
00604         hei = viewport_hei + 100;
00605     if ( myGanttView->myTimeHeader->registerStartTime() )
00606         return; // try again via timeheader computeTicks();
00607     if ( myGanttView->myTimeHeader->registerEndTime() )
00608         return; // try again via timeheader computeTicks();
00609     if ( hei > height() ) {
00610         if ( !  pendingWidth )
00611             pendingWidth = width();
00612         if ( pendingHeight < hei )
00613             pendingHeight = hei;
00614     }
00615     if (pendingHeight > hei )
00616         hei =  pendingHeight;
00617     if (hei > maximumComputedGridHeight)
00618         {
00619             maximumComputedGridHeight = hei;
00620             // compute the background interval lines
00621             myGanttView->myTimeHeader->computeIntervals( hei );
00622             //compute VerticalGrid and column color
00623             computeVerticalGrid();
00624         }
00625     computeTaskLinks();
00626     computeHorizontalGrid();
00627     computeDenseLines();
00628     computeShowNoInformation();
00629     //setAllChanged();
00630     update();
00631     if (pendingWidth && pendingHeight ) {
00632         resize( pendingWidth, pendingHeight );
00633         pendingWidth = 0;
00634         pendingHeight = 0;
00635         emit heightComputed( 0 );
00636 
00637     }
00638     pendingWidth = 0;
00639     pendingHeight = 0;
00640     //qDebug("KDTimeTableWidget::updateMyContent() -------------------------");
00641 }
00642 // used for blocking recursive methods
00643 // e.g. KDGanttViewItem::setHighlight() and  displaySubitemsAsGroup() == true
00644 
00645 void KDTimeTableWidget::inc_blockUpdating( )
00646 {
00647     ++ int_blockUpdating;
00648 }
00649 // used for blocking recursive methods
00650 void KDTimeTableWidget::dec_blockUpdating( )
00651 {
00652     -- int_blockUpdating;
00653 }
00654 // if false(i.e. unblock), sets int_blockUpdating to 0
00655 void KDTimeTableWidget::setBlockUpdating( bool block )
00656 {
00657     if ( !block )
00658         int_blockUpdating = 0;
00659     flag_blockUpdating = block;
00660 }
00661 bool KDTimeTableWidget::blockUpdating()
00662 {
00663     return flag_blockUpdating;
00664 }
00665 
00666 void KDTimeTableWidget::setShowTaskLinks( bool show )
00667 {
00668     taskLinksVisible = show;
00669     updateMyContent();
00670 }
00671 bool KDTimeTableWidget::showTaskLinks()
00672 {
00673     return taskLinksVisible;
00674 }
00675 void KDTimeTableWidget::setHorBackgroundLines( int count,  QBrush brush )
00676 {
00677     denseLineBrush = brush;
00678     denseLineCount = 0;
00679     if ( count > 1 )
00680         denseLineCount = count;
00681 }
00682 
00683 
00684 int KDTimeTableWidget::horBackgroundLines(  QBrush& brush )
00685 {
00686     brush =  denseLineBrush;
00687     return denseLineCount;
00688 }
00689 
00690 int KDTimeTableWidget::getCoordX( QDateTime dt ) {
00691     return myGanttView->myTimeHeader->getCoordX(dt);
00692 }
00693 
00694 /* ***************************************************************
00695    KDTimeHeaderWidget:: KDTimeHeaderWidget
00696    ***************************************************************** */
00697 KDTimeHeaderWidget:: KDTimeHeaderWidget( QWidget* parent,KDGanttView* gant )
00698     : QWidget (parent)
00699 {
00700     myToolTip = new KDTimeHeaderToolTip(this,this);
00701     mySizeHint = 0;
00702     myGanttView = gant;
00703     flagDoNotRecomputeAfterChange = true;
00704     QDateTime start = (QDateTime::currentDateTime ()).addSecs(-3600);
00705     setHorizonStart(start);
00706     setHorizonEnd( start.addSecs(3600*2));
00707     flagStartTimeSet = false;
00708     flagEndTimeSet = false;
00709     myCenterDateTime = QDateTime::currentDateTime ();
00710     setScale(KDGanttView::Auto);
00711     //setScale(KDGanttView::Hour);
00712     myMaxScale = KDGanttView::Month;
00713     myMinScale = KDGanttView::Minute;
00714     myAutoScaleMinorTickcount = 100;
00715     setMajorScaleCount( 1 );
00716     setMinorScaleCount( 1);
00717     setMinimumColumnWidth( 5 );
00718     setYearFormat(KDGanttView::FourDigit );
00719     setHourFormat( KDGanttView::Hour_12 );
00720     myZoomFactor = 1.0;
00721     setWeekendBackgroundColor(QColor(220,220,220) );
00722     setWeekendDays( 6, 7 );
00723     myGridMinorWidth = 0;
00724     myPopupMenu = new QPopupMenu(this);
00725     QPopupMenu * zoomPopupMenu = new QPopupMenu(this);
00726     myPopupMenu->insertItem (i18n("Zoom"),zoomPopupMenu, 1);
00727     zoomPopupMenu->insertItem( i18n("Zoom to 100%"),this, SLOT(setSettings(int)),0 ,21,21 );
00728     zoomPopupMenu->insertItem( i18n("Zoom to Fit"),this, SLOT(setSettings(int)),0 ,20,20 );
00729     zoomPopupMenu->insertItem( i18n("Zoom In (x 2)"),this, SLOT(setSettings(int)),0 ,22,22 );
00730     zoomPopupMenu->insertItem( i18n("Zoom In (x 6)"),this, SLOT(setSettings(int)),0 ,24,24 );
00731     zoomPopupMenu->insertItem( i18n("Zoom In (x 12)"),this, SLOT(setSettings(int)),0 ,26,26 );
00732     zoomPopupMenu->insertItem( i18n("Zoom Out (x 1/2)"),this, SLOT(setSettings(int)),0 ,23,23 );
00733     zoomPopupMenu->insertItem( i18n("Zoom Out (x 1/6)"),this, SLOT(setSettings(int)),0 ,25,25 );
00734     zoomPopupMenu->insertItem( i18n("Zoom Out (x 1/12)"),this, SLOT(setSettings(int)),0 ,27,27 );
00735     scalePopupMenu = new QPopupMenu(this);
00736     myPopupMenu->insertItem (i18n("Scale"),scalePopupMenu, 2);
00737     scalePopupMenu->insertItem( i18n("Minute"),this, SLOT(setSettings(int)),0 ,1,1 );
00738     scalePopupMenu->insertItem( i18n("Hour"),this, SLOT(setSettings(int)),0 ,2,2 );
00739     scalePopupMenu->insertItem( i18n("Day"),this, SLOT(setSettings(int)),0 ,3,3 );
00740     scalePopupMenu->insertItem( i18n("Week"),this, SLOT(setSettings(int)),0 ,4,4 );
00741     scalePopupMenu->insertItem( i18n("Month"),this, SLOT(setSettings(int)),0 ,5,5 );
00742     scalePopupMenu->insertItem( i18n("Auto"),this, SLOT(setSettings(int)),0 ,6,6 );
00743     scalePopupMenu->setCheckable ( true );
00744     timePopupMenu = new QPopupMenu(this);
00745     myPopupMenu->insertItem (i18n("Time Format"),timePopupMenu, 3);
00746     timePopupMenu->insertItem( i18n("24 Hour"),this, SLOT(setSettings(int)),0 ,40,40 );
00747     timePopupMenu->insertItem( i18n("12 PM Hour"),this, SLOT(setSettings(int)),0 ,41,41 );
00748     timePopupMenu->insertItem( i18n("24:00 Hour"),this, SLOT(setSettings(int)),0 ,42,42 );
00749     yearPopupMenu = new QPopupMenu(this);
00750     myPopupMenu->insertItem (i18n("Year Format"),yearPopupMenu, 4);
00751     yearPopupMenu->insertItem( i18n("Four Digit"),this, SLOT(setSettings(int)),0 ,50,50 );
00752     yearPopupMenu->insertItem( i18n("Two Digit"),this, SLOT(setSettings(int)),0 ,51,51 );
00753     yearPopupMenu->insertItem( i18n("Two Digit Apostrophe"),this, SLOT(setSettings(int)),0 ,52,52 );
00754     yearPopupMenu->insertItem( i18n("No Date on Minute/Hour Scale"),this, SLOT(setSettings(int)),0 ,53,53 );
00755 
00756     gridPopupMenu = new QPopupMenu(this);
00757     myPopupMenu->insertItem (i18n("Grid"),gridPopupMenu,5);
00758     gridPopupMenu->insertItem( i18n("Show Minor Grid"),this, SLOT(setSettings(int)),0 ,10,10 );
00759     gridPopupMenu->insertItem( i18n("Show Major Grid"),this, SLOT(setSettings(int)),0 ,11,11 );
00760     gridPopupMenu->insertItem( i18n("Show No Grid"),this, SLOT(setSettings(int)),0 ,12,12 );
00761     myPopupMenu->insertItem( i18n("Print"),this, SLOT(setSettings(int)),0 ,30,30 );
00762     connect(myPopupMenu, SIGNAL (  aboutToShow () ) , this, SLOT( preparePopupMenu() )) ;
00763     flagZoomToFit = false;
00764     setShowMinorTicks( true );
00765     myRealEnd =  myHorizonEnd;
00766     myRealStart = myHorizonStart;
00767     autoComputeTimeLine = true;
00768     flagDoNotRecomputeAfterChange = false;
00769     flagDoNotRepaintAfterChange = false;
00770     setShowPopupMenu(false,false,false,false,false,false,false);
00771     for (int j =1;j<8;++j)
00772         weekdayColor[j] = Qt::white;
00773     myMinimumWidth = 0;
00774     mouseDown = false;
00775     beginMouseDown = 0;
00776     endMouseDown = 0;
00777 }
00778 
00779 KDTimeHeaderWidget::~KDTimeHeaderWidget()
00780 {
00781     delete myToolTip;
00782 }
00783 void  KDTimeHeaderWidget::preparePopupMenu()
00784 {
00785     myPopupMenu->setItemVisible ( 1, flagShowZoom  );
00786     myPopupMenu->setItemVisible ( 2, flagShowScale );
00787     myPopupMenu->setItemVisible ( 3, flagShowTime );
00788     myPopupMenu->setItemVisible ( 4, flagShowYear );
00789     myPopupMenu->setItemVisible ( 5, flagShowGrid);
00790     myPopupMenu->setItemVisible ( 30, flagShowPrint );
00791     if (flagZoomToFit)
00792         myPopupMenu->changeItem( 1, i18n("Zoom (Fit)"));
00793     else
00794         myPopupMenu->changeItem( 1, i18n("Zoom (%1)").arg( QString::number( zoomFactor(), 'f',3) ) );
00795     int i = 0;
00796     int id;
00797     while ( ( id = scalePopupMenu->idAt( i++ )) >= 0 ) {
00798         scalePopupMenu->setItemChecked ( id, false );
00799     }
00800     scalePopupMenu->setItemChecked ( scalePopupMenu->idAt ( (int)( scale()) ), true );
00801     i = 0;
00802     while ( ( id = timePopupMenu->idAt( i++ )) >= 0 ) {
00803         timePopupMenu->setItemChecked ( id, false );
00804     }
00805     timePopupMenu->setItemChecked ( timePopupMenu->idAt ( (int)( hourFormat()) ), true );
00806     i = 0;
00807     while ( ( id = yearPopupMenu->idAt( i++ )) >= 0 ) {
00808         yearPopupMenu->setItemChecked ( id, false );
00809     }
00810     yearPopupMenu->setItemChecked ( yearPopupMenu->idAt ( (int)( yearFormat()) ), true );
00811     i = 0;
00812     while ( ( id = gridPopupMenu->idAt( i++ )) >= 0 ) {
00813         gridPopupMenu->setItemChecked ( id, false );
00814     }
00815 
00816     gridPopupMenu->setItemChecked ( gridPopupMenu->idAt ( 0 ), showMinorTicks() );
00817     gridPopupMenu->setItemChecked ( gridPopupMenu->idAt ( 1 ), showMajorTicks() );
00818     gridPopupMenu->setItemChecked ( gridPopupMenu->idAt ( 2 ),
00819                                     !(showMajorTicks() || showMinorTicks()) );
00820 
00821 
00822 }
00823 
00824 QString  KDTimeHeaderWidget::getToolTipText(QPoint p)
00825 {
00826     return KGlobal::locale()->formatDateTime(getDateTimeForIndex(p.x()));
00827 }
00828 void KDTimeHeaderWidget::addTickRight( int num )
00829 {
00830     int secs = ((num*getTickTime())-30);
00831     setHorizonEnd(getDateTimeForIndex(width()).addSecs(secs));
00832     //qApp->processEvents();
00833 }
00834 
00835 void KDTimeHeaderWidget::addTickLeft( int num )
00836 {
00837     int secs = ((num*getTickTime())-30);
00838     setHorizonStart(getDateTimeForIndex(0).addSecs(-secs));
00839     //qApp->processEvents();
00840 }
00841 // the time in secs of one minor grid tick
00842 int KDTimeHeaderWidget::getTickTime()
00843 {
00844     return getDateTimeForIndex(0).secsTo(getDateTimeForIndex(myGridMinorWidth));
00845 }
00846 
00847 
00848 void KDTimeHeaderWidget::checkWidth( int wid )
00849 {
00850     // we have to set the minimum width one pixel higher than the
00851     // viewport width of the canvas view in  order to
00852     // avoid that the horiz. scrollbar of the canvasview is hidden
00853     myMinimumWidth = wid + 1;
00854     if ( myMinimumWidth  > width() ||
00855          ( myMinimumWidth > mySizeHint &&
00856            myMinimumWidth < (width() - myGridMinorWidth  )) )
00857         computeTicks();
00858     
00859     // Update (horizontal) scrollbar, 
00860     // We probably come from an external resize and then we must
00861     // calculate on basis of myCanvasView.
00862     // (NOTE: we have disconnected the auto QScrollView scrollbar update)
00863     if (myGanttView && myGanttView->myCanvasView)
00864         myGanttView->myCanvasView->updateScrollBars();
00865 }
00866 
00867 bool KDTimeHeaderWidget::registerStartTime()
00868 {
00869 
00870     QListViewItemIterator it( myGanttView->myListView );
00871     if (!flagStartTimeSet) {
00872         QDateTime temp , time;
00873         KDGanttViewItem* item;
00874         bool setNewTime = false;
00875         item = (KDGanttViewItem*)myGanttView->myListView->firstChild();
00876         if ( item ) {
00877             temp = item->startTime();
00878             time = temp;
00879             //  while ( item != 0)
00880             for ( ; it.current(); ++it ) {
00881                 item = ( KDGanttViewItem* )it.current();
00882                 if (item->isVisibleInGanttView) {
00883                     if ( !setNewTime )
00884                         temp = item->startTime();
00885                     switch( item->type() ) {
00886                     case KDGanttViewItem::Event:
00887                         time = ((KDGanttViewEventItem*)item)->leadTime();
00888                         setNewTime = true;
00889                         break;
00890                     case KDGanttViewItem::Summary:
00891                     case KDGanttViewItem::Task:
00892                         time = item->startTime();
00893                         setNewTime = true;
00894                         break;
00895                     default:
00896                         time = temp;
00897                     }
00898                     if ( time < temp) {
00899                         temp = time ;
00900                     }
00901                 }
00902             }
00903             if ( setNewTime )
00904                 if ( myHorizonStart != temp) {
00905                     myHorizonStart = temp;
00906                     computeTicks();
00907                     return true;
00908                 }
00909         }
00910     }
00911     return false;
00912 }
00913 
00914 
00915 bool KDTimeHeaderWidget::registerEndTime()
00916 {
00917     if (!flagEndTimeSet) {
00918         QDateTime temp , time;
00919         KDGanttViewItem* item;
00920         bool setNewTime = false;
00921         item = (KDGanttViewItem*)myGanttView->myListView->firstChild();
00922         if ( item ) {
00923             temp = item->startTime();
00924             time = temp;
00925             QListViewItemIterator it( myGanttView->myListView );
00926             for ( ; it.current(); ++it ) {
00927                 item = ( KDGanttViewItem* )it.current();
00928                 if (item->isVisibleInGanttView) {
00929                     if ( !setNewTime )
00930                         temp = item->startTime();
00931                     switch( item->type() ) {
00932                     case KDGanttViewItem::Event:
00933                         time = ((KDGanttViewEventItem*)item)->startTime();
00934                         setNewTime = true;
00935                         break;
00936                     case KDGanttViewItem::Summary:
00937                         time = item->endTime();
00938                         if ( time < ((KDGanttViewSummaryItem*)item)->actualEndTime())
00939                             time = ((KDGanttViewSummaryItem*)item)->actualEndTime();
00940                         setNewTime = true;
00941                         break;
00942                     case KDGanttViewItem::Task:
00943                         time = item->endTime();
00944                         setNewTime = true;
00945                         break;
00946                     default:
00947                         time = temp;
00948                     }
00949                     if ( time > temp)
00950                         temp = time ;
00951                 }
00952             }
00953 
00954             if ( setNewTime )
00955                 if (myHorizonEnd != temp ) {
00956                     myHorizonEnd = temp;
00957                     computeTicks();
00958                     return true;
00959                 }
00960         }
00961     }
00962     return false;
00963 }
00964 
00965 
00966 void KDTimeHeaderWidget::setShowPopupMenu( bool show,
00967                                            bool showZoom,
00968                                            bool showScale,
00969                                            bool showTime,
00970                                            bool showYear,
00971                                            bool showGrid,
00972                                            bool showPrint)
00973 {
00974     flagShowPopupMenu = show;
00975     flagShowZoom = showZoom;
00976     flagShowScale  = showScale;
00977     flagShowTime  = showTime;
00978     flagShowYear = showYear;
00979     flagShowGrid  = showGrid;
00980     flagShowPrint = showPrint;
00981 }
00982 
00983 
00984 bool KDTimeHeaderWidget::showPopupMenu() const
00985 {
00986     return flagShowPopupMenu;
00987 }
00988 
00989 void KDTimeHeaderWidget::setSettings(int i)
00990 {
00991 
00992     switch (i) {
00993     case 1:
00994         setScale(KDGanttView::Minute );
00995         break;
00996     case 2:
00997         setScale(KDGanttView::Hour );
00998         break;
00999     case 3:
01000         setScale(KDGanttView::Day );
01001         break;
01002     case 4:
01003         setScale(KDGanttView::Week );
01004         break;
01005     case 5:
01006         setScale(KDGanttView::Month );
01007         break;
01008     case 6:
01009         setScale(KDGanttView::Auto );
01010         break;
01011     case 10:
01012         setShowMinorTicks( true );
01013         break;
01014     case 11:
01015         setShowMajorTicks( true );{
01016 
01017         }
01018         break;
01019     case 12:
01020         setShowMajorTicks( false );
01021         setShowMinorTicks( false);
01022         break;
01023     case 20:
01024         zoomToFit();
01025         break;
01026     case 21:
01027         zoom(1.0);
01028         break;
01029     case 22:
01030         zoom(2.0,false);
01031         break;
01032     case 23:
01033         zoom(0.5,false);
01034         break;
01035     case 24:
01036         zoom(6.0,false);
01037         break;
01038     case 25:
01039         zoom(0.16666,false);
01040         break;
01041     case 26:
01042         zoom(12.0,false);
01043         break;
01044     case 27:
01045         zoom(0.08333,false);
01046         break;
01047     case 30:
01048         myGanttView->print();
01049         break;
01050     case 40:
01051     case 41:
01052     case 42:
01053         setHourFormat( (KDGanttView::HourFormat) (i - 40) );
01054         break;
01055     case 50:
01056     case 51:
01057     case 52:
01058     case 53:
01059         setYearFormat( (KDGanttView::YearFormat) ( i - 50) );
01060         break;
01061 
01062     case 60:
01063 
01064         break;
01065 
01066     case 61:
01067 
01068         break;
01069 
01070     case 62:
01071 
01072         break;
01073 
01074     case 63:
01075 
01076         break;
01077 
01078     case 64:
01079 
01080         break;
01081     }
01082     // myGanttView->myTimeTable->updateMyContent();
01083 }
01084 void KDTimeHeaderWidget::zoomToFit()
01085 {
01086     flagZoomToFit = true;
01087     computeTicks();
01088     // Since we have disconnected autoupdate of scrollbars, we must do it ourselves
01089     if (myGanttView && myGanttView->myCanvasView)
01090         myGanttView->myCanvasView->updateScrollBars();
01091 }
01092 double KDTimeHeaderWidget::zoomFactor()
01093 {
01094     return myZoomFactor;
01095 }
01096 double KDTimeHeaderWidget::secsFromTo( QDateTime begin, QDateTime end )
01097 {
01098     QDateTime temp;
01099     double secs, days;
01100     days = begin.daysTo(end);
01101     temp = begin.addDays((int) days);
01102     secs = temp.secsTo(end);
01103     secs += days * 86400.0;
01104     return secs;
01105 }
01106 
01107 
01108 void KDTimeHeaderWidget::zoomToSelection( QDateTime start, QDateTime end)
01109 {
01110     if (start < myHorizonStart) {
01111         myHorizonStart = start;
01112         flagStartTimeSet = true;
01113         //qDebug("myHorizonStart reset");
01114     }
01115     if (end > myHorizonEnd) {
01116         myHorizonEnd = end;
01117         flagEndTimeSet = true;
01118         //qDebug("myHorizonEnd reset ");
01119     }
01120     flagDoNotRepaintAfterChange = true;//avoid flicker
01121     zoom(1.0); // set to 100%
01122     int viewWid = myGanttView->myCanvasView->viewport()->width();
01123     int timeWid =  getCoordX(end)-getCoordX(start);
01124     double fac;
01125     fac  = ( (double)viewWid)/((double) timeWid  );
01126     zoom (fac);
01127     timeWid =  getCoordX(end)-getCoordX(start);
01128     int count = 0;
01129     int lastScaleCount = 0;
01130     while (timeWid >viewWid || ( ( myRealMinorScaleCount != lastScaleCount)  && timeWid*2 < viewWid ) ) {
01131         lastScaleCount = myRealMinorScaleCount;
01132         fac = (fac * (double)viewWid)/(double)timeWid;
01133         zoom (fac);
01134         timeWid =  getCoordX(end)-getCoordX(start);
01135         if ( count++ > 10 ) {
01136             //qDebug("Exiting while loop in zoomToSelection ");
01137             break;
01138         }
01139     }
01140     flagDoNotRepaintAfterChange = false;
01141     updateTimeTable();
01142     repaint();
01143     moveTimeLineTo((getCoordX(start)-(viewWid-timeWid)/2));
01144     // Since we have disconnected autoupdate of scrollbars, we must do it ourselves
01145     if (myGanttView && myGanttView->myCanvasView)
01146         myGanttView->myCanvasView->updateScrollBars();
01147 }
01148 void KDTimeHeaderWidget::moveTimeLineTo(int X)
01149 {
01150     int Y = myGanttView->myCanvasView->contentsY ();
01151     myGanttView->myCanvasView->setContentsPos (X, Y );
01152 }
01153 
01154 void KDTimeHeaderWidget::zoom(double factor, bool absolute)
01155 {
01156     flagZoomToFit = false;
01157     if ( factor < 0.000001 ) {
01158         qDebug("KDGanttView::zoom() : Zoom factor to low. Nothing zoomed. ");
01159         return;
01160     }
01161     double newZoom;
01162     if (absolute)
01163         newZoom = factor;
01164     else
01165         newZoom = myZoomFactor * factor;
01166     double relativeZoom;
01167     relativeZoom = newZoom / myZoomFactor;
01168 
01169     //qDebug("zooming relative %f ", relativeZoom);
01170     //qDebug("zooming absolute %f ", newZoom);
01171     int viewWid = myGanttView->myCanvasView->viewport()->width();
01172     if ( width() * relativeZoom < viewWid && ( newZoom > 1.01 || newZoom < 0.99 ) ) {
01173         qDebug("KDGanttView::zoom() : Zoom factor to low for current horizon. ");
01174         // qDebug("zooming relative %f, zooming absolute %f, viewWidth %d width %d ", relativeZoom,  newZoom, viewWid, width() );
01175         return;
01176     }
01177     myZoomFactor = newZoom;
01178     computeTicks();
01179     // Since we have disconnected autoupdate of scrollbars, we must do it ourselves
01180     if (myGanttView && myGanttView->myCanvasView)
01181         myGanttView->myCanvasView->updateScrollBars();
01182 }
01183 
01191 void KDTimeHeaderWidget::setHorizonStart( const QDateTime& start )
01192 {
01193     myHorizonStart = start;
01194     flagStartTimeSet = true;
01195     computeTicks();
01196 }
01197 
01198 
01205 QDateTime KDTimeHeaderWidget::horizonStart() const
01206 {
01207     return myHorizonStart;
01208 }
01209 
01210 
01218 void KDTimeHeaderWidget::setHorizonEnd( const QDateTime& start )
01219 {
01220     myHorizonEnd = start;
01221     flagEndTimeSet = true;
01222     computeTicks();
01223 
01224 }
01225 
01226 
01233 QDateTime KDTimeHeaderWidget::horizonEnd() const
01234 {
01235     return myHorizonEnd;
01236 }
01237 
01238 
01247 void KDTimeHeaderWidget::setScale(Scale unit )
01248 {
01249     myScale = unit;
01250     myZoomFactor = 1.0;
01251     computeTicks();
01252     // Since we have disconnected autoupdate of scrollbars, we must do it ourselves
01253     if (myGanttView && myGanttView->myCanvasView)
01254         myGanttView->myCanvasView->updateScrollBars();
01255 }
01256 
01257 
01264 KDTimeHeaderWidget::Scale KDTimeHeaderWidget::scale() const
01265 {
01266     return myScale;
01267 }
01268 
01269 
01276 void KDTimeHeaderWidget::setMaximumScale( Scale unit )
01277 {
01278     myMaxScale = unit;
01279     computeTicks();
01280 }
01281 
01282 
01289 KDTimeHeaderWidget::Scale  KDTimeHeaderWidget::maximumScale() const
01290 {
01291     return myMaxScale;
01292 }
01293 
01294 
01301 void  KDTimeHeaderWidget::setMinimumScale( Scale unit )
01302 {
01303     myMinScale = unit;
01304     computeTicks();
01305 }
01306 
01307 
01314 KDTimeHeaderWidget::Scale  KDTimeHeaderWidget::minimumScale() const
01315 {
01316     return myMinScale;
01317 }
01318 
01319 
01328 void KDTimeHeaderWidget::setMinimumColumnWidth( int width )
01329 {
01330     myMinimumColumWidth =  width;
01331     computeTicks();
01332 }
01333 
01334 
01341 int KDTimeHeaderWidget::minimumColumnWidth() const
01342 {
01343     return myMinimumColumWidth;
01344 }
01345 
01346 
01354 void KDTimeHeaderWidget::setYearFormat( YearFormat format )
01355 {
01356     myYearFormat =  format;
01357     computeTicks();
01358 }
01359 
01360 
01367 KDTimeHeaderWidget::YearFormat KDTimeHeaderWidget::yearFormat() const
01368 {
01369     return  myYearFormat;
01370 }
01371 
01372 
01380 void KDTimeHeaderWidget::setHourFormat( HourFormat format )
01381 {
01382     myHourFormat = format;
01383     computeTicks();
01384 }
01385 
01386 
01393 KDTimeHeaderWidget::HourFormat KDTimeHeaderWidget::hourFormat() const
01394 {
01395     return myHourFormat;
01396 }
01397 
01398 
01405 void KDTimeHeaderWidget::setShowMajorTicks( bool show )
01406 {
01407     flagShowMajorTicks = show;
01408     if (show) {
01409         setShowMinorTicks(false);
01410     }
01411     updateTimeTable();
01412 }
01413 
01414 
01421 bool KDTimeHeaderWidget::showMajorTicks() const
01422 {
01423     return flagShowMajorTicks;
01424 }
01425 
01426 
01433 void KDTimeHeaderWidget::setShowMinorTicks( bool show )
01434 {
01435     flagShowMinorTicks = show;
01436     if (show)
01437         setShowMajorTicks(false );
01438     //repaintMe();
01439     updateTimeTable();
01440 }
01441 
01442 
01449 bool KDTimeHeaderWidget::showMinorTicks() const
01450 {
01451     return flagShowMinorTicks;
01452 }
01453 
01454 
01463 void KDTimeHeaderWidget::setColumnBackgroundColor( const QDateTime& column,
01464                                                    const QColor& color,
01465                                                    Scale mini, Scale maxi )
01466 {
01467     ColumnColorList::iterator it;
01468     for ( it = ccList.begin(); it != ccList.end(); ++it ) {
01469         if ((*it).datetime == column) {
01470             (*it).color = color;
01471             (*it).minScaleView = mini;
01472             (*it).maxScaleView = maxi;
01473             return;
01474         }
01475     }
01476     DateTimeColor newItem;
01477     newItem.datetime = column;
01478     newItem.color = color;
01479     newItem.minScaleView = mini;
01480     newItem.maxScaleView = maxi;
01481     ccList.append(newItem);
01482     updateTimeTable();
01483 }
01484 
01485 void KDTimeHeaderWidget::computeIntervals( int height )
01486 {
01487 
01488     IntervalColorList::iterator it;
01489     int left, right;
01490     for ( it = icList.begin(); it != icList.end(); ++it ) {
01491         if ( (*it).minScaleView <= myRealScale && (*it).maxScaleView >= myRealScale ) {
01492             left = getCoordX((*it).datetime);
01493             right = getCoordX((*it).end);
01494             if ( right == left )
01495                 ++right;
01496             (*it).canvasRect->setPen( QPen::NoPen );
01497             (*it).canvasRect->setBrush( QBrush( (*it).color, SolidPattern) );
01498             (*it).canvasRect->setSize( right - left ,height );
01499             (*it).canvasRect->move( left,0 );
01500             (*it).canvasRect->show();
01501         } else {
01502             (*it).canvasRect->hide();
01503             /*
01504               (*it).canvasLine->setPen( QPen( (*it).color, right - left ) );
01505               (*it).canvasLine->setPoints( mid ,0 ,mid ,height );
01506               (*it).canvasLine->show();
01507               } else {
01508               (*it).canvasLine->hide();
01509             */
01510         }
01511     }
01512 }
01513 bool KDTimeHeaderWidget::changeBackgroundInterval( const QDateTime& oldstart,
01514                                                    const QDateTime& oldend,
01515                                                    const QDateTime& newstart,
01516                                                    const QDateTime& newend )
01517 {
01518     IntervalColorList::iterator it;
01519     for ( it = icList.begin(); it != icList.end(); ++it ) {
01520         if ((*it).datetime == oldstart && (*it).end == oldend ) {
01521             IntervalColorList::iterator it2;
01522             for ( it2 = icList.begin(); it2 != icList.end(); ++it2 ) {
01523                 if ((*it2).datetime == newstart && (*it2).end == newend )
01524                     return false;
01525             }
01526             (*it).datetime = newstart;
01527             (*it).end = newend;
01528             updateTimeTable();
01529             return true;
01530         }
01531     }
01532     return false;
01533 }
01534 bool KDTimeHeaderWidget::deleteBackgroundInterval( const QDateTime& start,
01535                                                    const QDateTime& end)
01536 {
01537     IntervalColorList::iterator it;
01538     for ( it = icList.begin(); it != icList.end(); ++it ) {
01539         if ((*it).datetime == start && (*it).end == end ) {
01540             //delete  (*it).canvasLine;
01541             delete  (*it).canvasRect;
01542             icList.remove(it);
01543             updateTimeTable();
01544             return true;
01545         }
01546     }
01547     return false;
01548 }
01549 
01550 void KDTimeHeaderWidget::setIntervalBackgroundColor( const QDateTime& start,
01551                                                      const QDateTime& end,
01552                                                      const QColor& color,
01553                                                      Scale mini ,
01554                                                      Scale maxi )
01555 {
01556 
01557     IntervalColorList::iterator it;
01558     for ( it = icList.begin(); it != icList.end(); ++it ) {
01559         if ((*it).datetime == start && (*it).end == end ) {
01560             (*it).color = color;
01561             (*it).minScaleView = mini;
01562             (*it).maxScaleView = maxi;
01563             return;
01564         }
01565     }
01566     DateTimeColor newItem;
01567     if ( start <= end ) {
01568         newItem.datetime = start;
01569         newItem.end = end;
01570     } else {
01571         newItem.datetime = end;
01572         newItem.end = start;
01573     }
01574     newItem.color = color;
01575     newItem.minScaleView = mini;
01576     newItem.maxScaleView = maxi;
01577     //newItem.canvasLine = new KDCanvasLine(myGanttView->myTimeTable,0,Type_is_KDGanttGridItem);
01578     newItem.canvasRect = new KDCanvasRectangle(myGanttView->myTimeTable,0,Type_is_KDGanttGridItem);
01579     newItem.canvasRect->setZ(-19);
01580     icList.append(newItem);
01581     updateTimeTable();
01582 
01583 }
01584 void KDTimeHeaderWidget::clearBackgroundColor()
01585 {
01586 
01587     IntervalColorList::iterator itic;
01588     for ( itic = icList.begin(); itic != icList.end(); ++itic ) {
01589         delete  (*itic).canvasRect;
01590     }
01591     ccList.clear();
01592     icList.clear();
01593     updateTimeTable();
01594 }
01595 QDateTime KDTimeHeaderWidget::getDateTimeForIndex(int X, bool local )
01596 {
01597     int coordX = X;
01598     if ( !local ) {
01599         QPoint p = QPoint ( X, 1 );
01600         coordX = myGanttView->myTimeHeaderScroll->viewportToContents(myGanttView->myTimeHeaderScroll->mapFromGlobal( p )).x();
01601 
01602     }
01603     double secs = (secsFromTo( myRealStart, myRealEnd ) * ((double)coordX))/(double)width();
01604     double days = secs/86400.0;
01605     secs = secs - ( ((int) days) *86400.0 );
01606     return (myRealStart.addDays ( (int) days )).addSecs( (int) secs);
01607 }
01608 
01609 //FIXME: This doesn't work quite intuitively (imho) when scale is day
01610 //       and each column containes more than 1 day:
01611 //       1) If a column includes a weekend day, the whole column gets weekend color,
01612 //       2) If a column includes 7 days, either *all* columns get weekend color, or
01613 //          *none* get weekend color (haven't figured out why)
01614 //       Proposal: Only use weekend color if the whole column is a weekend.
01615 //       Alt: Color the area that actually is the weekend.
01616 bool KDTimeHeaderWidget::getColumnColor(QColor& col,int coordLow, int coordHigh)
01617 {
01618     if (!flagShowMajorTicks && !flagShowMinorTicks)
01619         return false;
01620     QDateTime start,end;
01621     start = getDateTimeForIndex(coordLow);
01622     end = getDateTimeForIndex(coordHigh).addSecs(-1);
01623     Scale tempScale = myRealScale;
01624     if (flagShowMajorTicks)
01625         switch (myRealScale)
01626             {
01627             case KDGanttView::Minute: tempScale = KDGanttView::Hour;  break;
01628             case KDGanttView::Hour: tempScale = KDGanttView::Day   ;  break;
01629             case KDGanttView::Day: tempScale = KDGanttView::Week   ;  break;
01630             case KDGanttView::Week: tempScale = KDGanttView::Month  ;  break;
01631             case KDGanttView::Month: return false   ;  break;
01632             case KDGanttView::Auto: return false   ;  break;
01633             }
01634     //check defined column color
01635     ColumnColorList::iterator it;
01636     for ( it = ccList.begin(); it != ccList.end(); ++it ) {
01637         if ((*it).datetime  >= start && (*it).datetime  <= end) {
01638             if (tempScale >= (*it).minScaleView &&   tempScale <= (*it).maxScaleView    ) {
01639                 col = (*it).color;
01640                 return true;
01641             }
01642         }
01643     }
01644 
01645     if (tempScale > KDGanttView::Day) return false;
01646 
01647     start = getDateTimeForIndex((coordLow+coordHigh)/2);
01648     int day = start.date().dayOfWeek ();
01649     //checkweekdaycolor
01650     if (weekdayColor[day] != Qt::white) {
01651         col = weekdayColor[day];
01652         return true;
01653     }
01654     //checkweekendcolor
01655     int endday = myWeekendDaysEnd;
01656     col = myWeekendBackgroundColor;
01657     if (myWeekendDaysStart > myWeekendDaysEnd)
01658         endday +=7;
01659     if (day >= myWeekendDaysStart && day <= endday) {
01660         return true;
01661     } else {
01662         if (day+7 >= myWeekendDaysStart && day+7 <= endday) {
01663             return true;
01664         }
01665     }
01666     return false;
01667 }
01668 
01677 QColor KDTimeHeaderWidget::columnBackgroundColor( const QDateTime& column ) const
01678 {
01679     QColor c;
01680     c = white;
01681     ColumnColorList::const_iterator ite;
01682     for ( ite = ccList.begin(); ite != ccList.end(); ++ite ) {
01683         if ((*ite).datetime == column) {
01684             c = (*ite).color;
01685         }
01686     }
01687     return c;
01688 }
01689 
01690 
01699 void KDTimeHeaderWidget::setWeekendBackgroundColor( const QColor& color )
01700 {
01701     myWeekendBackgroundColor = color ;
01702     updateTimeTable();
01703 }
01704 
01705 
01712 QColor KDTimeHeaderWidget::weekendBackgroundColor() const
01713 {
01714     return myWeekendBackgroundColor;
01715 }
01716 
01727 void KDTimeHeaderWidget::setWeekdayBackgroundColor( const QColor& color, int  weekday )
01728 {
01729     weekdayColor[weekday] = color;
01730     updateTimeTable();
01731 }
01732 
01733 
01741 QColor KDTimeHeaderWidget::weekdayBackgroundColor(int weekday) const
01742 {
01743     return weekdayColor[weekday];
01744 }
01745 
01746 
01757 void KDTimeHeaderWidget::setWeekendDays( int start, int end )
01758 {
01759     myWeekendDaysStart = start;
01760     myWeekendDaysEnd = end;
01761     updateTimeTable();
01762 }
01763 
01764 
01772 void KDTimeHeaderWidget::weekendDays( int& start, int& end ) const
01773 {
01774     start = myWeekendDaysStart;
01775     end = myWeekendDaysEnd ;
01776 }
01777 
01778 
01779 
01786 void KDTimeHeaderWidget::setMajorScaleCount( int count )
01787 {
01788     myMajorScaleCount=count;
01789     computeTicks();
01790 }
01791 
01792 
01799 int KDTimeHeaderWidget::majorScaleCount() const
01800 {
01801     return myMajorScaleCount;
01802 }
01803 
01804 
01811 void KDTimeHeaderWidget::setMinorScaleCount( int count )
01812 {
01813     myMinorScaleCount = count;
01814     computeTicks();
01815 }
01816 
01817 
01824 int KDTimeHeaderWidget::minorScaleCount() const
01825 {
01826     return myMinorScaleCount ;
01827 
01828 }
01829 
01830 
01831 void KDTimeHeaderWidget::resizeEvent ( QResizeEvent * )
01832 {
01833     // qDebug("KDTimeHeaderWidget:: resizeEvent ");
01834     paintPix.resize( 800, height () );
01835 }
01836 
01837 
01838 void KDTimeHeaderWidget::updateTimeTable()
01839 {
01840     //qDebug("KDTimeHeaderWidget::updateTimeTable() ");
01841     if (flagDoNotRecomputeAfterChange) return;
01842     // setting the scrolling steps
01843     int scrollLineStep = myGridMinorWidth;
01844     if (showMajorTicks()) {
01845         QValueList<int>::iterator intIt = majorTicks.begin();
01846         scrollLineStep = 5 * myGridMinorWidth;
01847         if (intIt != majorTicks.end()) {
01848             int left = *intIt;
01849             ++intIt;
01850             if (intIt != majorTicks.end()) {
01851                 scrollLineStep = *intIt-left;
01852             }
01853         }
01854     }
01855     myGanttView->myCanvasView->horizontalScrollBar()->setLineStep(scrollLineStep);
01856     myGanttView->myTimeTable->maximumComputedGridHeight = 0;
01857     myGanttView->myTimeTable->updateMyContent();
01858 }
01859 
01860 
01861 void KDTimeHeaderWidget::setAutoScaleMinorTickCount( int count )
01862 {
01863     myAutoScaleMinorTickcount = count;
01864     computeTicks();
01865 
01866 }
01867 
01868 
01869 int KDTimeHeaderWidget::autoScaleMinorTickCount()
01870 {
01871     return myAutoScaleMinorTickcount;
01872 }
01873 
01874 
01875 void KDTimeHeaderWidget::repaintMe(int left,int paintwid, QPainter* painter)
01876 {
01877     if (flagDoNotRecomputeAfterChange) return;
01878     QColorGroup qcg =QColorGroup( white, black,white, darkGray,black,gray,gray) ;
01879     QPainter* p;
01880     int offsetLeft = 0;
01881     if ( paintwid > paintPix.width()-100 )
01882         paintPix.resize( paintwid+100, height () );
01883     if ( painter )
01884         p = painter;
01885     else {
01886         p = new QPainter( &paintPix );
01887         offsetLeft = left-50;
01888     }
01889     if ( mouseDown ) {
01890         p->fillRect( left-offsetLeft, 0, paintwid, height(), QBrush(paletteBackgroundColor()) );
01891         int start ;
01892         int wid;
01893         if ( beginMouseDown < endMouseDown ) {
01894             start = beginMouseDown ;
01895             wid = endMouseDown - beginMouseDown ;
01896         } else {
01897             start = endMouseDown ;
01898             wid = -endMouseDown + beginMouseDown ;
01899         }
01900         p->fillRect( start-offsetLeft, 0, wid, height(), QBrush(paletteBackgroundColor().dark()) );
01901     } else {
01902         if (! painter )
01903             p->fillRect( left-offsetLeft, 0, paintwid, height(), QBrush(paletteBackgroundColor()) );
01904     }
01905     p->setPen(QColor(40,40,40));
01906     QFont tempFont = p->font();
01907     tempFont.setWeight(63);
01908     p->setFont(tempFont);
01909     int hei1 = myMajorGridHeight,
01910         hei2 = height(),
01911         wid1 = myGridMinorWidth;
01912     int xCoord;
01913     int lwid = 1;
01914 
01915     QValueList<QString>::iterator it;
01916     QValueList<int>::iterator intIt = majorTicks.begin();
01917     for ( it =  majorText.begin(); it !=  majorText.end(); ++it ) {
01918         xCoord  = (*intIt++);
01919         if (((*intIt)>= left && xCoord <= left+paintwid)) {
01920             qDrawShadeLine ( p,xCoord-offsetLeft ,hei1+1, xCoord-offsetLeft, -2, qcg, true, lwid, 1 );
01921             p->drawText(xCoord+4-offsetLeft,hei1-4,(*it));
01922         }
01923     }
01924     qDrawShadeLine ( p,left-offsetLeft  ,hei1, left+paintwid-offsetLeft, hei1, qcg, true, lwid, 1 );
01925     int i = 0;
01926     for ( it =  minorText.begin(); it !=  minorText.end(); ++it ) {
01927         if (i*wid1 >= left-wid1 && i*wid1 <= left+paintwid) {
01928             qDrawShadeLine ( p,i*wid1-offsetLeft ,hei1-1, i*wid1-offsetLeft, hei2, qcg, true, lwid, 1 );
01929             p->drawText(i*wid1+1-offsetLeft,hei1+1,wid1-1,hei2-hei1,Qt::AlignCenter,(*it));
01930         }
01931         ++i;
01932     }
01933     p->setPen(black);
01934     p->drawLine(left-offsetLeft,hei1,left+paintwid-offsetLeft,hei1);
01935     qDrawShadeLine ( p,left-offsetLeft  ,hei2-1, left+paintwid-offsetLeft, hei2-1, qcg, true, lwid, 1 );
01936     p->drawLine(left-offsetLeft,hei2-1,left+paintwid-offsetLeft,hei2-1);
01937     if ( !painter ) {
01938         p->end();
01939         delete p;
01940         bitBlt ( this, left, 0, &paintPix, 50, 0, paintwid, height() );
01941     }
01942 }
01943 
01944 // cuts the secs in the DateTime if scale is Minute ,
01945 // the minutes and secs if scale is Hour and so on
01946 
01947 QDateTime KDTimeHeaderWidget::getEvenTimeDate(QDateTime tempdatetime ,Scale sc)
01948 {
01949     QDate tempdate;
01950     int min, hour;
01951     int tempMinorScaleCount = myRealMinorScaleCount;
01952     switch (sc)
01953         {
01954         case KDGanttView::Month:
01955             tempdate = tempdatetime.date();
01956             while (tempdate.day ()!= 1 )
01957                 tempdate = tempdate.addDays(-1);
01958             //while (tempdate.month ()!= 1 )
01959             //tempdate = tempdate.addMonths(-1);
01960             tempdatetime = QDateTime (tempdate, QTime (0,0));
01961             break;
01962         case KDGanttView::Week:
01963             tempdate = tempdatetime.date();
01964             while (tempdate.dayOfWeek ()!= KGlobal::locale()->weekStartDay())
01965                 tempdate = tempdate.addDays(-1);
01966             //tempdate = tempdate.addDays(-7);
01967             tempdatetime = QDateTime (tempdate, QTime (0,0));
01968             break;
01969         case KDGanttView::Day:
01970             tempdatetime = QDateTime (tempdatetime.date(), QTime ( 0,0 ) );
01971             break;
01972         case KDGanttView::Hour:
01973             hour = tempdatetime.time().hour();
01974             while (24%tempMinorScaleCount > 0 && 24%tempMinorScaleCount < 24)
01975                 ++tempMinorScaleCount;
01976             hour = ( hour /tempMinorScaleCount)*tempMinorScaleCount;
01977             tempdatetime = QDateTime (tempdatetime.date(), QTime (hour, 0 ));
01978             break;
01979         case KDGanttView::Minute:
01980             min = tempdatetime.time().minute();
01981             while (60%tempMinorScaleCount > 0 && 60%tempMinorScaleCount < 60)
01982                 ++tempMinorScaleCount;
01983             // qDebug("myMinorScaleCount %d %d %d",myMinorScaleCount, myRealMinorScaleCount, tempMinorScaleCount);
01984             min = (min /tempMinorScaleCount)*tempMinorScaleCount;
01985             tempdatetime = QDateTime (tempdatetime.date(), QTime (tempdatetime.time().hour(),min ));
01986 
01987             break;
01988         case KDGanttView::Auto:
01989             break;
01990         }
01991     return tempdatetime;
01992 }
01993 
01994 
01995 void KDTimeHeaderWidget::computeRealScale(QDateTime start)
01996 {
01997 
01998     if (myScale ==KDGanttView::Auto) {
01999         //qDebug("Autoscale ");
02000         //double secsPerMinor = (((double)start.daysTo(myHorizonEnd))* 86400.00)/((double)myAutoScaleMinorTickcount);
02001         double secsPerMinor = (((double)start.secsTo(myHorizonEnd)))/((double)myAutoScaleMinorTickcount);
02002         secsPerMinor /= myZoomFactor;
02003         if (secsPerMinor <= 1800) {
02004             myRealScale =  KDGanttView::Minute;
02005             myRealMinorScaleCount = (int) secsPerMinor/60;
02006         } else {
02007             if (secsPerMinor <= 12*3600) {
02008                 myRealScale =  KDGanttView::Hour;
02009                 myRealMinorScaleCount = (int)  secsPerMinor/3600;
02010             } else {
02011                 if (secsPerMinor <= 24*3600*3) {
02012                     myRealScale =  KDGanttView::Day;
02013                     myRealMinorScaleCount = (int)  secsPerMinor/(3600*24);
02014                 } else {
02015                     if (secsPerMinor <= 24*3600*14) {
02016                         myRealScale =  KDGanttView::Week;
02017                         myRealMinorScaleCount =  (int) secsPerMinor/(3600*24*7);
02018                     } else {
02019                         myRealScale =  KDGanttView::Month;
02020                         myRealMinorScaleCount =  (int) secsPerMinor/(3600*24*30);
02021 
02022                     }
02023                 }
02024             }
02025         }
02026         if(myRealMinorScaleCount == 0)
02027             myRealMinorScaleCount = 1;
02028         myRealMajorScaleCount = 1;
02029     }
02030     else {
02031         //qDebug("Fixed scale ");
02032         myRealScale = myScale;
02033         if (myRealScale > myMaxScale)
02034             myRealScale = myMaxScale;
02035         if (myRealScale < myMinScale)
02036             myRealScale = myMinScale;
02037         myRealMinorScaleCount = (int) ( ((double)myMinorScaleCount) /myZoomFactor );
02038         double tempZoom = myZoomFactor;
02039         myRealMajorScaleCount =  myMajorScaleCount;
02040         while (myRealMinorScaleCount == 0) {
02041             if (myRealScale  == myMinScale) {
02042                 myRealMinorScaleCount = 1;
02043                 break;
02044             }
02045             switch (myRealScale)
02046                 {
02047                 case KDGanttView::Minute:
02048                     myRealMinorScaleCount = 1;
02049                     return;
02050                     break;
02051                 case KDGanttView::Hour:
02052                     myRealScale = KDGanttView::Minute;
02053                     tempZoom = tempZoom/60;
02054                     break;
02055                 case KDGanttView::Day:
02056                     myRealScale = KDGanttView::Hour;
02057                     tempZoom = tempZoom/24;
02058                     break;
02059                 case KDGanttView::Week:
02060                     myRealScale = KDGanttView::Day;
02061                     tempZoom = tempZoom/7;
02062                     break;
02063                 case KDGanttView::Month:
02064                     myRealScale =  KDGanttView::Week ;
02065                     tempZoom = tempZoom*7/30;
02066                     break;
02067                 case KDGanttView::Auto:
02068                     break;
02069                 }
02070             myRealMinorScaleCount =  (int) ( myMinorScaleCount /tempZoom );
02071         }
02072     }
02073 }
02074 
02075 
02076 void KDTimeHeaderWidget::computeTicks(bool doNotComputeRealScale)
02077 {
02078     if (flagDoNotRecomputeAfterChange) return;
02079     bool block = myGanttView->myTimeTable->blockUpdating();
02080     myGanttView->myTimeTable->setBlockUpdating( true );
02081     //qDebug("computeticks ");
02082     majorTicks.clear();
02083     minorText.clear();
02084     majorText.clear();
02085     if ( !doNotComputeRealScale )
02086         saveCenterDateTime();
02087     if (!doNotComputeRealScale)
02088         computeRealScale(myHorizonStart);
02089     myRealStart = getEvenTimeDate(myHorizonStart ,myRealScale);
02090     if (!doNotComputeRealScale)
02091         computeRealScale(myRealStart);
02092     int tempMinorScaleCount = myRealMinorScaleCount,
02093         tempMajorScaleCount = myRealMajorScaleCount;
02094     int minorItems,minorPerMajor = 1;
02095     minorItems = (int)  (secsFromTo( myRealStart, myHorizonEnd)/60.0);
02096     //qDebug("tempMinorScaleCount %d ", tempMinorScaleCount);
02097     QPainter p(this);
02098     int Width, Height;
02099     QString testTextMinor,testTextMajor, tempStr;
02100     QRect itemRectMinor, itemRectMajor;
02101     QDate tempDate = myRealStart.date();
02102     myRealEnd = myRealStart;
02103     // preparing the testtext for the differennt scales
02104     switch (myRealScale)
02105         {
02106             // the x in testTextMajor is added to reserve a little bit more space
02107         case KDGanttView::Minute:
02108             testTextMinor = "60";
02109             if (myHourFormat == KDGanttView::Hour_12)
02110                 testTextMajor = "Mon Aug 30, 12 AMx";
02111             else
02112                 testTextMajor = "Mon Aug 30, 24:00x";
02113             minorPerMajor = 6000;
02114             break;
02115         case KDGanttView::Hour:
02116             minorItems = minorItems/60;
02117             if (myHourFormat == KDGanttView::Hour_24)
02118                 testTextMinor = "24x";
02119             else
02120                 testTextMinor = "12 AM";
02121             testTextMajor = "Mon Aug 30, x";
02122             if ( yearFormat() != KDGanttView::NoDate )
02123                 testTextMajor += getYear(QDate::currentDate());
02124             minorPerMajor = 2400;
02125             break;
02126         case KDGanttView::Day:
02127             minorItems = minorItems/(60*24);
02128             testTextMinor = "88";
02129             testTextMajor = "Aug 30, x"+getYear(QDate::currentDate());
02130             minorPerMajor = 700;
02131             break;
02132         case KDGanttView::Week:
02133             minorItems = minorItems/(60*24*7);
02134             testTextMinor = "88";
02135             testTextMajor = "Aug x"+getYear(QDate::currentDate());
02136             minorPerMajor = 435; // 435 = 365days/12months/7days * 100
02137             break;
02138         case KDGanttView::Month:
02139             minorItems = (minorItems*12)/(60*24*365);
02140             testTextMinor = "M";
02141             testTextMajor = "x"+getYear(QDate::currentDate());
02142             minorPerMajor = 1200;
02143             break;
02144         case KDGanttView::Auto:
02145             qDebug("KDGanttView::Internal Error in KDTimeHeaderWidget::computeTicks() ");
02146             qDebug("             RealScale == Auto : This may not be! ");
02147             break;
02148         }
02149     itemRectMinor = p.boundingRect ( 10, 10, 2, 2, Qt::AlignLeft,testTextMinor);
02150     itemRectMajor = p.boundingRect ( 10, 10, 2, 2, Qt::AlignLeft,testTextMajor);
02151     p.end();
02152     //qDebug("     tempMinorScaleCount %d ", tempMinorScaleCount);
02153     Height = itemRectMinor.height()+itemRectMajor.height()+11;
02154     Width = (itemRectMinor.width()+5);
02155     if (Width < minimumColumnWidth()) Width = minimumColumnWidth();
02156     // if the desired width is greater than the maximum width of this widget
02157     // increase the minorscalecount
02158     int maxWid = myGanttView->myCanvasView->viewport()->width();
02159     if (!flagZoomToFit)
02160         maxWid = maximumWidth();
02161     while((minorItems/tempMinorScaleCount+1)*Width > maxWid)
02162         ++tempMinorScaleCount;
02163     //qDebug("             tempMinorScaleCount %d ", tempMinorScaleCount);
02164     mySizeHint = (minorItems/tempMinorScaleCount+1)*Width;
02165     switch (myRealScale)
02166         {
02167         case KDGanttView::Minute:
02168             if (tempMinorScaleCount < 60)
02169                 while (60%tempMinorScaleCount > 0 && 60%tempMinorScaleCount < 60)
02170                     ++tempMinorScaleCount;
02171             if (tempMinorScaleCount >= 60) {
02172                 myRealScale = KDGanttView::Hour;
02173                 myRealMinorScaleCount = tempMinorScaleCount/ 60;
02174                 // myRealMinorScaleCount = 1;
02175                 myRealMajorScaleCount = 1;
02176                 qDebug("KDGantt::Overzoom:Rescaling from Minute to Hour");
02177                 myGanttView->myTimeTable->setBlockUpdating( block );
02178                 emit myGanttView->rescaling( KDGanttView::Hour );
02179                 computeTicks(true);
02180                 return;
02181             }
02182             break;
02183         case KDGanttView::Hour:
02184             while (24%tempMinorScaleCount > 0 && 24%tempMinorScaleCount < 24)
02185                 ++tempMinorScaleCount;
02186             if (tempMinorScaleCount >= 24) {
02187                 myRealScale = KDGanttView::Day;
02188                 myRealMinorScaleCount = tempMinorScaleCount/ 24;
02189                 //myRealMinorScaleCount = 1;
02190                 myRealMajorScaleCount = 1;
02191                 qDebug("KDGantt::Overzoom:Rescaling from Hour to Day");
02192                 myGanttView->myTimeTable->setBlockUpdating( block );
02193                 emit myGanttView->rescaling( KDGanttView::Day );
02194                 computeTicks(true);
02195                 return;
02196             }
02197             break;
02198         default:
02199             break;
02200         }
02201     //flagZoomToFit = false;
02202     while((minorItems/tempMinorScaleCount+1)*Width < myMinimumWidth ) {
02203         ++minorItems;
02204     }
02205     minorItems = (minorItems/tempMinorScaleCount)+1;
02206     // if not enough space for the text of the major scale, increase majorscalecount
02207     minorPerMajor = (minorPerMajor*tempMajorScaleCount)/tempMinorScaleCount;
02208     // checking, if enough space for majorscale
02209     // if not, increasing MajorScaleCount
02210 
02211     while ((minorPerMajor*Width)/100 < itemRectMajor.width()) {
02212         minorPerMajor = minorPerMajor/tempMajorScaleCount;
02213         ++tempMajorScaleCount;
02214         minorPerMajor = minorPerMajor*tempMajorScaleCount;
02215 
02216     }
02217     // now we have the fixed  width of the minorscale computed
02218     myGridMinorWidth = Width;
02219     // the width of this widget is the gridwidth * the amount of items
02220     Width *= minorItems;
02221     // if size changed, reset geometry
02222     if (width() != Width   || height() != Height  )
02223         {
02224             resize( Width, Height );
02225             emit  sizeChanged( Width );
02226         }
02227     myMajorGridHeight = itemRectMajor.height()+5;
02228     QTime tempTime = myRealStart.time();
02229     QDateTime tempDateTime;
02230     int i;
02231     const KCalendarSystem * calendar = KGlobal::locale()->calendar();
02232     switch (myRealScale)
02233         {
02234         case KDGanttView::Minute:
02235             myRealEnd = myRealEnd.addSecs((minorItems)*tempMinorScaleCount*60);
02236             for ( i = 0; i < minorItems;++i) {
02237                 tempStr.setNum(tempTime.minute());
02238                 minorText.append(tempStr);
02239                 tempTime = tempTime.addSecs(60*tempMinorScaleCount);
02240             }
02241             tempDateTime = myRealStart;
02242             while (tempDateTime.time().minute() != 0)
02243                 tempDateTime = tempDateTime.addSecs(60);
02244             while (tempDateTime < myRealEnd) {
02245                 majorTicks.append( getCoordX(tempDateTime));
02246                 tempStr.setNum(tempDateTime.date().day());
02247                 if ( yearFormat() == KDGanttView::NoDate ) {
02248                     tempStr = calendar->weekDayName( tempDateTime.date() )+", "
02249                         +getHour(tempDateTime.time());
02250                 } else {
02251                     tempStr = calendar->weekDayName( tempDateTime.date(), true )+" "+
02252                         calendar->monthName( tempDateTime.date().month(), tempDateTime.date().year(), true)+ " "+
02253                         tempStr+", "+getHour(tempDateTime.time());
02254                 }
02255 
02256                 majorText.append(tempStr);
02257                 tempDateTime = tempDateTime.addSecs(3600*tempMajorScaleCount);
02258             }
02259             majorTicks.append( getCoordX(tempDateTime));
02260             break;
02261 
02262         case KDGanttView::Hour:
02263             myRealEnd = myRealEnd.addSecs(minorItems*tempMinorScaleCount*60*60);
02264 
02265             for ( i = 0; i < minorItems;++i) {
02266                 tempStr = getHour(tempTime);
02267                 minorText.append(tempStr);
02268                 tempTime = tempTime.addSecs(3600*tempMinorScaleCount);
02269             }
02270             tempDateTime = myRealStart;
02271             while (tempDateTime.time().hour() != 0)
02272                 tempDateTime = tempDateTime.addSecs(3600);
02273             while (tempDateTime < myRealEnd) {
02274                 majorTicks.append( getCoordX(tempDateTime));
02275                 tempStr.setNum(tempDateTime.date().day());
02276                 if ( yearFormat() == KDGanttView::NoDate ) {
02277                     tempStr = calendar->weekDayName( tempDateTime.date() );
02278                 } else {
02279                     tempStr = calendar->weekDayName( tempDateTime.date(), true )+" "+
02280                         calendar->monthName( tempDateTime.date().month(), tempDateTime.date().year(), true)+ " "+
02281                         tempStr+", "+getYear(tempDateTime.date());
02282                 }
02283                 majorText.append(tempStr);
02284                 tempDateTime = tempDateTime.addDays(tempMajorScaleCount);
02285             }
02286             majorTicks.append( getCoordX(tempDateTime));
02287             break;
02288         case KDGanttView::Day:
02289             myRealEnd = myRealEnd.addDays(minorItems*tempMinorScaleCount);
02290             for ( i = 0; i < minorItems;++i) {
02291                 if (tempMinorScaleCount == 1)
02292                     minorText.append((calendar->weekDayName(tempDate, true)).left(1)); //TODO: BIDI
02293                 else
02294                     minorText.append(QString::number(tempDate.day()));
02295                 tempDate = tempDate.addDays(tempMinorScaleCount);
02296             }
02297             tempDate = myRealStart.date();
02298             while (tempDate.dayOfWeek() != KGlobal::locale()->weekStartDay())
02299                 tempDate = tempDate.addDays(1);
02300             while (tempDate < myRealEnd.date()) {
02301                 majorTicks.append( getCoordX(tempDate));
02302                 tempStr.setNum(tempDate.day());
02303                 tempStr = calendar->monthName(tempDate.month(), tempDate.year(), true)+ " "+
02304                     tempStr+", "+getYear(tempDate);
02305                 majorText.append(tempStr);
02306                 tempDate = tempDate.addDays(7*tempMajorScaleCount);
02307             }
02308             majorTicks.append( getCoordX(tempDate));
02309             break;
02310         case KDGanttView::Week:
02311             myRealEnd = myRealEnd.addDays(minorItems*tempMinorScaleCount*7);
02312             for ( i = 0; i < minorItems;++i) {
02313                 tempStr.setNum(tempDate.day());
02314                 minorText.append(tempStr);
02315                 tempDate = tempDate.addDays(7*tempMinorScaleCount);
02316             }
02317             tempDate = myRealStart.date();
02318             while (tempDate.day() != KGlobal::locale()->weekStartDay())
02319                 tempDate = tempDate.addDays(1);
02320             while (tempDate < myRealEnd.date()) {
02321                 majorTicks.append( getCoordX(tempDate));
02322                 tempStr = calendar->monthName(tempDate.month(), tempDate.year(), true)+ " "+getYear(tempDate);
02323                 majorText.append(tempStr);
02324                 tempDate = tempDate.addMonths(tempMajorScaleCount);
02325             }
02326             majorTicks.append( getCoordX(tempDate));
02327             break;
02328         case KDGanttView::Month:
02329             myRealEnd = myRealEnd.addMonths(minorItems*tempMinorScaleCount);
02330             for ( i = 0; i < minorItems;++i) {
02331                 minorText.append((calendar->monthName(tempDate.month(), tempDate.year(), true)).left(1)); //TODO: BIDI
02332                 tempDate = tempDate.addMonths(tempMinorScaleCount);
02333             }
02334             tempDate = myRealStart.date();
02335             while (tempDate.month() != 1)
02336                 tempDate = tempDate.addMonths(1);
02337             while (tempDate < myRealEnd.date()) {
02338                 majorTicks.append( getCoordX(tempDate));
02339                 tempStr = getYear(tempDate);
02340                 majorText.append(tempStr);
02341                 tempDate = tempDate.addYears(tempMajorScaleCount);
02342             }
02343             majorTicks.append( getCoordX(tempDate));
02344             break;
02345         case KDGanttView::Auto:
02346             break;
02347         }
02348 
02349     if (flagDoNotRepaintAfterChange) {
02350         myGanttView->myTimeTable->setBlockUpdating( block );
02351         return;
02352     }
02353     //qDebug("KDTimeHeaderWidget width %d, viewport width %d  ",width (), myGanttView->myCanvasView->viewport()->width());
02354     myGanttView->myTimeTable->setBlockUpdating( block );
02355     updateTimeTable();
02356     centerDateTime(myCenterDateTime);
02357     repaint();
02358 }
02359 
02360 
02361 void KDTimeHeaderWidget::saveCenterDateTime()
02362 {
02363     double wid = width();
02364     double allsecs = secsFromTo( myRealStart, myRealEnd );
02365     double center = myGanttView->myCanvasView->viewport()->width();
02366     center = center / 2;
02367     center = center + myGanttView->myCanvasView->contentsX();
02368     double secs = (allsecs*center)/wid;
02369     double days = secs/86400.0;
02370     secs = secs - ( (int) days *86400.0 );
02371     myCenterDateTime =  (myRealStart.addDays ( (int) days )).addSecs( (int) secs);
02372 }
02373 
02374 
02375 void KDTimeHeaderWidget::centerDateTime( const QDateTime& center )
02376 {
02377      moveTimeLineTo(getCoordX( center )-(myGanttView->myCanvasView->viewport()->width() /2));
02378     //  qDebug("centerDateTime %s %d %d", center.toString().latin1(),getCoordX( center ),(myGanttView->myCanvasView->viewport()->width() /2) );
02379    
02380 }
02381 
02382 
02383 void KDTimeHeaderWidget::paintEvent(QPaintEvent *p)
02384 {
02385     repaintMe(p->rect().x(),p->rect().width());
02386 }
02387 
02388 
02389 int KDTimeHeaderWidget::getCoordX(QDate date)
02390 {
02391     int wid = width();
02392     int daysAll = myRealStart.daysTo(myRealEnd);
02393     if (daysAll == 0) return 0;
02394     int days = myRealStart.daysTo(QDateTime(date));
02395     return (wid *days) /daysAll;
02396 }
02397 
02398 
02399 int KDTimeHeaderWidget::getCoordX(QDateTime datetime)
02400 {
02401     double wid = width();
02402     double secsAll = secsFromTo( myRealStart, myRealEnd );
02403     if (secsAll == 0.0) return 0;
02404     double secs = secsFromTo( myRealStart, datetime);
02405     return ((int)((wid *(secs /secsAll))+0.5));
02406 }
02407 
02408 
02409 QString KDTimeHeaderWidget::getYear(QDate date)
02410 {
02411     QString ret;
02412     ret.setNum(date.year());
02413     switch (yearFormat()) {
02414     case KDGanttView::FourDigit:
02415         // nothing to do
02416         break;
02417     case KDGanttView::TwoDigit:
02418         ret = ret.right(2);
02419         break;
02420     case KDGanttView::TwoDigitApostrophe:
02421         ret = "'"+ret.right(2);
02422         break;
02423     case KDGanttView::NoDate:
02424         // nothing to do
02425         break;
02426     }
02427     return ret;
02428 }
02429 
02430 
02431 QString KDTimeHeaderWidget::getHour(QTime time)
02432 {
02433     QString ret;
02434     int hour = time.hour();
02435     if (myHourFormat == KDGanttView::Hour_12) {
02436         if (hour >= 12) {
02437             if (hour > 12) hour -=12;
02438             ret.setNum(hour);
02439             ret = ret +" PM";
02440         } else {
02441             if (hour == 0) hour = 12;
02442             ret.setNum(hour);
02443             ret = ret +" AM";
02444         }
02445     } else {
02446         if (myHourFormat == KDGanttView::Hour_24)
02447             ret.setNum(hour);
02448         else {
02449             ret.setNum(hour);
02450             ret += ":00";
02451         }
02452     }
02453     return ret;
02454 }
02455 
02456 
02457 void KDTimeHeaderWidget::mousePressEvent ( QMouseEvent * e )
02458 {
02459     mouseDown = false;
02460     switch ( e->button() ) {
02461     case LeftButton:
02462         mouseDown = true;
02463         beginMouseDown = e->pos().x();
02464         endMouseDown = e->pos().x();
02465         break;
02466     case RightButton:
02467         if (flagShowPopupMenu)
02468             myPopupMenu->popup(e->globalPos());
02469         break;
02470     case MidButton:
02471         break;
02472     default:
02473         break;
02474     }
02475 
02476 }
02477 
02478 
02479 void KDTimeHeaderWidget::mouseReleaseEvent ( QMouseEvent *  )
02480 {
02481     if ( mouseDown ) {
02482         mouseDown = false;
02483         // zoom to selection getDateTimeForIndex(
02484         int start, end;
02485         if ( beginMouseDown < endMouseDown ) {
02486             start = beginMouseDown;
02487             end = endMouseDown;
02488         } else {
02489             start = endMouseDown;
02490             end = beginMouseDown;
02491         }
02492         if (start < 0 )
02493             start = 0;
02494         if ( end > width() )
02495             end = width();
02496         //qDebug("start %s ",getDateTimeForIndex(start).toString().latin1() );
02497         //qDebug("end %s ",getDateTimeForIndex(end).toString().latin1() );
02498         emit myGanttView->timeIntervalSelected( getDateTimeForIndex(start),getDateTimeForIndex(end) );
02499         emit myGanttView->timeIntervallSelected( getDateTimeForIndex(start),getDateTimeForIndex(end) );
02500         //zoomToSelection( getDateTimeForIndex(start),getDateTimeForIndex(end) );
02501     }
02502     mouseDown = false;
02503     repaint();
02504 }
02505 
02506 
02507 void KDTimeHeaderWidget::mouseDoubleClickEvent ( QMouseEvent *  )
02508 {
02509 
02510 }
02511 
02512 
02513 void KDTimeHeaderWidget::mouseMoveEvent ( QMouseEvent * e )
02514 {
02515     if ( mouseDown ) {
02516         if ( e->pos().y() < -height() || e->pos().y() > 2* height() ) {
02517             mouseDown = false;
02518             repaint();
02519             return;
02520         }
02521         endMouseDown = e->pos().x();
02522         //repaint;
02523         int val = -1;
02524         if (endMouseDown <  -x() ) {
02525             val = myGanttView->myCanvasView->horizontalScrollBar()->value() -
02526                 myGanttView->myCanvasView->horizontalScrollBar()->lineStep();
02527             if ( val < 0 ) {
02528                 val = 0;
02529             }
02530         }
02531         if (endMouseDown >  -x() +parentWidget()->width() ) {
02532             val = myGanttView->myCanvasView->horizontalScrollBar()->value() +
02533                 myGanttView->myCanvasView->horizontalScrollBar()->lineStep();
02534 
02535         }
02536         repaintMe(-x(),parentWidget()->width());
02537         if ( val > -1 ) {
02538             if ( val > myGanttView->myCanvasView->horizontalScrollBar()->maxValue() ) {
02539                 val = myGanttView->myCanvasView->horizontalScrollBar()->maxValue();
02540             }
02541             myGanttView->myCanvasView->horizontalScrollBar()->setValue( val );
02542         }
02543         //qDebug("mousemove %d %d %d %d",endMouseDown, -x(),parentWidget()->width() , e->pos().y());
02544     }
02545 }
02546 
02547 
02548 /* ***************************************************************
02549    KDLegendWidget:: KDLegendWidget
02550    ***************************************************************** */
02551 KDLegendWidget:: KDLegendWidget( QWidget* parent,
02552                                  KDGanttMinimizeSplitter* legendParent ) :
02553     KDGanttSemiSizingControl ( KDGanttSemiSizingControl::Before, Vertical,
02554                                parent)
02555 {
02556     myLegendParent = legendParent;
02557     dock = 0;
02558     scroll = new QScrollView( legendParent );
02559     setMaximizedWidget( scroll );
02560 
02561     setMinimizedWidget( myLabel = new QLabel( i18n( " Legend is hidden" ), this) );
02562     setGeometry( 0, 0, 50, 50 );
02563     myLegend = 0;
02564     clearLegend();
02565     showMe ( false );
02566 }
02567 void KDLegendWidget::setAsDockwindow( bool dockwin )
02568 {
02569     if ( (dock == 0 && !dockwin) || ( dock && dockwin  ) )
02570         return;
02571     if ( dockwin )
02572         {
02573             setMaximizedWidget( 0 );
02574             showMe ( false );
02575             if ( dock ) delete dock;
02576             dock = new QDockWindow(QDockWindow:: OutsideDock,0 );
02577             dock->resize( 200, 100 );
02578             dock->setHorizontallyStretchable( true );
02579             dock->setVerticallyStretchable( true );
02580             dock->setCaption(i18n("Legend: ") );
02581             dock->setResizeEnabled (true );
02582             delete myLegend;
02583             myLegend = 0;
02584             delete scroll;
02585             scroll = new QScrollView( dock );
02586             clearLegend();
02587             dock->setWidget(scroll);
02588             setMaximizedWidget( dock );
02589             showMe ( false );
02590 
02591         } else {
02592             setMaximizedWidget( 0 );
02593             showMe ( false );
02594             delete myLegend;
02595             myLegend = 0;
02596             delete scroll;
02597             delete dock;
02598             dock = 0;
02599             scroll = new QScrollView( myLegendParent );
02600             clearLegend();
02601             setMaximizedWidget( scroll );
02602             showMe ( false );
02603         }
02604 
02605 }
02606 
02607 
02608 bool KDLegendWidget::asDockwindow( )
02609 {
02610     if ( dock )
02611         return true;
02612     return false;
02613 }
02614 
02615 
02616 QDockWindow* KDLegendWidget::dockwindow( )
02617 {
02618     return dock;
02619 }
02620 
02621 
02622 void KDLegendWidget::setFont( QFont font)
02623 {
02624     myLegend->setFont( font);
02625     myLabel->setFont( font);
02626     QWidget::setFont( font );
02627 }
02628 
02629 
02630 void KDLegendWidget::drawToPainter( QPainter *p )
02631 {
02632     p->drawPixmap( 0, 0, QPixmap::grabWidget( myLegend ) );
02633 }
02634 
02635 
02636 QSize KDLegendWidget::legendSize()
02637 {
02638     return myLegend->size();
02639 }
02640 
02641 
02642 QSize KDLegendWidget::legendSizeHint()
02643 {
02644     QApplication::sendPostedEvents( 0, QEvent::LayoutHint );
02645     return QSize( myLegend->sizeHint().width(), myLegend->sizeHint().height()+scroll->horizontalScrollBar()->height());
02646 }
02647 
02648 
02649 void KDLegendWidget::showMe ( bool show )
02650 {
02651     minimize( !show );
02652 }
02653 
02654 
02655 void KDLegendWidget::clearLegend ( )
02656 {
02657     if ( myLegend ) delete myLegend;
02658     if ( dock )
02659         myLegend = new QGroupBox( 1, Qt::Horizontal, scroll->viewport() );
02660     else
02661         myLegend = new QGroupBox( 1, Qt::Horizontal, i18n( "Legend" ), scroll->viewport() );
02662     myLegend->setBackgroundColor( Qt::white );
02663     myLegend->setFont( font() );
02664     scroll->addChild(  myLegend );
02665     scroll->setResizePolicy( QScrollView::AutoOneFit );
02666     myLegend->layout()->setMargin( 11 );
02667     myLegend->setFrameStyle( QFrame::NoFrame );
02668     if ( dock )
02669         scroll->setMaximumHeight( 32000 );
02670     else
02671         scroll->setMaximumHeight( legendSizeHint().height() );
02672 }
02673 
02674 
02675 void KDLegendWidget::addLegendItem( KDGanttViewItem::Shape shape, const QColor& shapeColor, const QString& text )
02676 {
02677     QLabel * temp;
02678     QPixmap p = KDGanttView::getPixmap( shape,  shapeColor, Qt::white, 10);
02679     QWidget *w = new QWidget( myLegend );
02680     w->setBackgroundColor( Qt::white );
02681     QHBoxLayout *lay = new QHBoxLayout( w ,0, 6);
02682     temp = new QLabel ( w );
02683     lay->addWidget( temp, 0, Qt:: AlignRight);
02684     temp->setPixmap(p);
02685     temp = new QLabel ( text, w );
02686     temp->setBackgroundColor( Qt::white );
02687     lay->addWidget( temp, 0, Qt:: AlignLeft);
02688     lay->addStretch();
02689     if ( dock )
02690         scroll->setMaximumHeight( 32000 );
02691     else
02692         scroll->setMaximumHeight( legendSizeHint().height() );
02693 }
02694 
02695 
02696 bool KDLegendWidget::isShown ( )
02697 {
02698     return !isMinimized();
02699 }
02700 
02701 
02702 KDListView::KDListView(QWidget* parent, KDGanttView* gantView):QListView (parent)
02703 {
02704     myGanttView = gantView;
02705     setAcceptDrops(true);
02706     new KDListViewWhatsThis(viewport(),this);
02707     setRootIsDecorated( true );
02708     setAllColumnsShowFocus( true );
02709     addColumn( i18n( "Task Name" ) );
02710     setSorting( -1 );
02711     //setVScrollBarMode (QScrollView::AlwaysOn );
02712     setHScrollBarMode (QScrollView::AlwaysOn );
02713     setDefaultRenameAction(QListView::Accept);
02714     setColumnWidthMode ( 0,Maximum  );
02715     _calendarMode = false;
02716     // QObject::connect(this, SIGNAL (  pressed ( QListViewItem * )) , this, SLOT( dragItem( QListViewItem *))) ;
02717 }
02718 
02719 
02720 void  KDListView::dragItem( QListViewItem *  )
02721 {
02722     // qDebug("drag ");
02723     // startDrag();
02724 }
02725 QString KDListView::getWhatsThisText(QPoint p)
02726 {
02727     KDGanttViewItem* item = ( KDGanttViewItem* ) itemAt( p );
02728     if ( item )
02729         return item->whatsThisText();
02730     return i18n( "No item Found" );
02731 }
02732 
02733 void  KDListView::setCalendarMode( bool mode )
02734 {
02735     _calendarMode = mode;
02736     // setRootIsDecorated ( ! mode );
02737 }
02738 
02739 void  KDListView::setOpen(QListViewItem * item, bool open )
02740 {
02741     if (! _calendarMode || ! open ) {
02742         (( KDGanttViewItem*)item)->setCallListViewOnSetOpen( false );
02743         QListView::setOpen ( item, open );
02744         (( KDGanttViewItem*)item)->setCallListViewOnSetOpen( true );
02745         return;
02746     }
02747     // we are in calendarmode
02748     // in calendarmode only items can be opened which have subitems which have subitems
02749 
02750     QListViewItem* temp;
02751     temp = item->firstChild();
02752     bool openItem = false;
02753     while (temp) {
02754         if ( (( KDGanttViewItem*)temp)->displaySubitemsAsGroup() ) {
02755             temp->setVisible( true );
02756             openItem = true;
02757         }
02758         else {
02759             temp->setVisible( false );
02760             //qDebug(" temp->setVisible( false );");
02761         }
02762         temp = temp->nextSibling();
02763     }
02764     if ( openItem ) {
02765         (( KDGanttViewItem*)item)->setCallListViewOnSetOpen( false );
02766         QListView::setOpen ( item, open );
02767         (( KDGanttViewItem*)item)->setCallListViewOnSetOpen( true );
02768     }
02769 }
02770 
02771 
02772 void  KDListView::contentsMouseDoubleClickEvent ( QMouseEvent * e )
02773 {
02774     QListView::contentsMouseDoubleClickEvent ( e );
02775     //if ( ! _calendarMode )
02776     // QListView::contentsMouseDoubleClickEvent ( e );
02777     // else
02778     {
02779 
02780         emit myGanttView->lvItemDoubleClicked ( (KDGanttViewItem*) itemAt(e->pos() ) );
02781         emit myGanttView->itemDoubleClicked ( (KDGanttViewItem*) itemAt(e->pos() ) );
02782     }
02783 
02784 }
02785 
02786 
02787 void  KDListView::drawToPainter ( QPainter * p, bool drawHeader )
02788 {
02789     // Draw list
02790     drawAllContents ( p, 0, 0, contentsWidth(), contentsHeight() );
02791     if (!drawHeader) {
02792         return;
02793     }
02794     // Draw headers
02795     QPen pen = QPen(Qt::lightGray, 1);
02796     p->save();
02797     QHeader *h = header();
02798     for (int s = 0; s < h->count(); ++s) {
02799         QRect r = h->sectionRect(s);
02800         if (s==0) {
02801             p->translate(0, -r.height());
02802         }
02803         //kdDebug()<<s<<": "<<h->label(s)<<" "<<r<<endl;
02804         p->drawText(r.x()+2, r.y(), r.width()-2, r.height(), columnAlignment(s)|Qt::AlignVCenter, h->label(s), -1);
02805         p->save();
02806         p->setPen(pen);
02807         p->drawRect(r.x(), r.y()+1, r.width(), r.height()-2);
02808         p->restore();
02809 
02810     }
02811     p->restore();
02812 }
02813 
02814 int KDListView::buildDrawables(QPtrList<KDListView::DrawableItem> &lst, int level, int ypos, QListViewItem *item, int ymin, int ymax) const {
02815     int y = ypos;
02816     int ih = item->height();
02817     if (y < ymin && y+ih > ymin) {
02818         y = ymin; // include partial item at top
02819     }
02820     if (y >= ymin && y < ymax) { // include partial item at bottom
02821         KDListView::DrawableItem *dr = new KDListView::DrawableItem(level, y, item);
02822         lst.append(dr);
02823         //kdDebug()<<k_funcinfo<<level<<", "<<y<<" : "<<item->text(0)<<endl;
02824     }
02825     y += ih;
02826     if (item->isOpen()) {
02827         QListViewItem *child = item->firstChild();
02828         for (; child; child = child->nextSibling()) {
02829             y = buildDrawables(lst, level+1, y, child, ymin, ymax);
02830         }
02831     }
02832     return y;
02833 }
02834 // This is a copy of QListView::drawContentsOffset(), with a few changes
02835 // because drawContentsOffset() only draws *visible* items,
02836 // we want to draw *all* items.
02837 // FIXME: Haven't got paintBraches() to work, atm live without it.
02838 void KDListView::drawAllContents(QPainter * p, int cx, int cy, int cw, int ch) {
02839     if ( columns() == 0 ) {
02840         paintEmptyArea( p, QRect( cx, cy, cw, ch ) );
02841         return;
02842     }
02843     //kdDebug()<<k_funcinfo<<QRect(cx, cy, cw, ch)<<endl;
02844     QPtrList<KDListView::DrawableItem> drawables;
02845     drawables.setAutoDelete(true);
02846     QListViewItem *child = firstChild();
02847     int level = 0;
02848     int ypos = 0;
02849     for (; child; child = child->nextSibling()) {
02850         ypos = buildDrawables(drawables, level, ypos, child, cy, cy+ch);
02851     }
02852     
02853     p->setFont( font() );
02854 
02855     QPtrListIterator<KDListView::DrawableItem> it(drawables);
02856 
02857     QRect r;
02858     int fx = -1, x, fc = 0, lc = 0;
02859     int tx = -1;
02860     KDListView::DrawableItem * current;
02861 
02862     while ( (current = it.current()) != 0 ) {
02863         ++it;
02864         int ih = current->i->height();
02865         int ith = current->i->totalHeight();
02866         int c;
02867         int cs;
02868 
02869         // need to paint current?
02870         if ( ih > 0 && current->y < cy+ch && current->y+ih > cy ) {
02871             //kdDebug()<<k_funcinfo<<"Paint: "<<current->i->text(0)<<" y="<<current->y<<endl;
02872             if ( fx < 0 ) {
02873                 // find first interesting column, once
02874                 x = 0;
02875                 c = 0;
02876                 cs = header()->cellSize( 0 );
02877                 while ( x + cs <= cx && c < header()->count() ) {
02878                     x += cs;
02879                     c++;
02880                     if ( c < header()->count() )
02881                         cs = header()->cellSize( c );
02882                 }
02883                 fx = x;
02884                 fc = c;
02885                 while( x < cx + cw && c < header()->count() ) {
02886                     x += cs;
02887                     c++;
02888                     if ( c < header()->count() )
02889                         cs = header()->cellSize( c );
02890                 }
02891                 lc = c;
02892             }
02893 
02894             x = fx;
02895             c = fc;
02896             // draw to last interesting column
02897 
02898             const QColorGroup &cg = ( palette().inactive() );
02899 
02900             while ( c < lc && !drawables.isEmpty() ) {
02901                 int i = header()->mapToLogical( c );
02902                 cs = header()->cellSize( c );
02903                 r.setRect( x, current->y-cy, cs, ih );
02904                 if ( i == 0 )
02905                     r.setLeft( r.left() + current->l * treeStepSize() );
02906 
02907                 p->save();
02908                 // No need to paint if the cell isn't technically visible
02909                 if ( !( r.width() == 0 || r.height() == 0 ) ) {
02910                     p->translate( r.left(), r.top() );
02911                     int ac = header()->mapToLogical( c );
02912                     // map to Left currently. This should change once we
02913                     // can really reverse the listview.
02914                     int align = columnAlignment( ac );
02915                     if ( align == AlignAuto ) align = AlignLeft;
02916                     bool sel = current->i->isSelected();
02917                     if (sel)
02918                         current->i->setSelected(false);
02919                     current->i->paintCell( p, cg, ac, r.width(), align );
02920                     if (sel)
02921                         current->i->setSelected(sel);
02922                 }
02923                 p->restore();
02924                 x += cs;
02925                 c++;
02926             }
02927 
02928         }
02929 
02930         const int cell = header()->mapToActual( 0 );
02931 
02932         if ( tx < 0 )
02933             tx = header()->cellPos( cell );
02934 
02935         // do any children of current need to be painted?
02936 /* FIXME: painting branches doesn't work for some reason...
02937         if ( ih != ith && 
02938             rootIsDecorated() &&
02939             current->y + ith > cy &&
02940             current->y + ih < cy + ch &&
02941             tx + current->l * treeStepSize() < cx + cw &&
02942             tx + (current->l+1) * treeStepSize() > cx ) {
02943             // compute the clip rectangle the safe way
02944 
02945             int rtop = current->y + ih;
02946             int rbottom = current->y + ith;
02947             int rleft = tx + current->l*treeStepSize();
02948             int rright = rleft + treeStepSize();
02949 
02950             int crtop = QMAX( rtop, cy );
02951             int crbottom = QMIN( rbottom, cy+ch );
02952             int crleft = QMAX( rleft, cx );
02953             int crright = QMIN( rright, cx+cw );
02954 
02955             r.setRect( crleft, crtop,
02956                     crright-crleft, crbottom-crtop );
02957 
02958             if ( r.isValid() ) {
02959                 p->save();
02960                 p->translate( rleft, crtop );
02961                 //kdDebug()<<k_funcinfo<<"paintBranches: "<<current->i->text(0)<<endl;
02962 
02963                 current->i->paintBranches( p, colorGroup(), treeStepSize(),
02964                                         rtop - crtop, r.height() );
02965                 p->restore();
02966             }
02967         }*/
02968     }
02969 }
02970 
02971 void KDListView::resizeEvent(QResizeEvent *)
02972 {
02973     triggerUpdate ();
02974 }
02975 void KDListView::dragEnterEvent ( QDragEnterEvent * e)
02976 {
02977     if ( !myGanttView->dropEnabled() ) {
02978         e->accept( false );
02979         return;
02980     }
02981     myGanttView->lvDragEnterEvent(e);
02982     //e->accept(KDGanttViewItemDrag::canDecode(e) );
02983 }
02984 
02985 void KDListView::dragMoveEvent ( QDragMoveEvent * e)
02986 {
02987     if ( !myGanttView->dropEnabled() ) {
02988         e->accept( false );
02989         return;
02990     }
02991     KDGanttViewItem* draggedItem = 0;
02992     KDGanttViewItem* gItem = (KDGanttViewItem*)itemAt( e->pos()) ;
02993     setCurrentItem( gItem );
02994     if (  e->source() == myGanttView )
02995         draggedItem = myGanttView->myCanvasView->lastClickedItem;
02996     // execute user defined dragMoveEvent handling
02997     if (myGanttView->lvDragMoveEvent ( e , draggedItem, gItem ) )
02998         return;
02999     if ( !KDGanttViewItemDrag::canDecode(e) ) {
03000         e->accept( false );
03001         return;
03002     }
03003     if ( e->source() == myGanttView && gItem ){
03004         // internal drag - do not allow to drag the item to a subitem of itself
03005         KDGanttViewItem* pItem = gItem->parent();
03006         while ( pItem ) {
03007             if ( pItem == myGanttView->myCanvasView->lastClickedItem ) {
03008                 e->accept( false );
03009                 return;
03010             }
03011             pItem = pItem->parent();
03012         }
03013         if ( gItem == myGanttView->myCanvasView->lastClickedItem ) {
03014             e->accept( false );
03015             return;
03016         }
03017     }
03018     e->accept( true );
03019 }
03020 
03021 void KDListView::dragLeaveEvent ( QDragLeaveEvent * )
03022 {
03023     //qDebug("contentsDragLeaveEvent ");
03024 }
03025 void KDListView::dropEvent ( QDropEvent *e )
03026 {
03027     if ( !myGanttView->dropEnabled() ) {
03028         e->accept( false );
03029         return;
03030     }
03031     KDGanttViewItem* gItem = (KDGanttViewItem*)itemAt( e->pos()) ;
03032     KDGanttViewItem* draggedItem = 0;
03033     if (  e->source() == myGanttView )
03034         draggedItem = myGanttView->myCanvasView->lastClickedItem;
03035     if (myGanttView->lvDropEvent ( e, draggedItem, gItem ))
03036         return;
03037     QString string;
03038     KDGanttViewItemDrag::decode( e, string );
03039     KDGanttViewItem* newItem = 0;
03040 
03041     if ( gItem == myGanttView->myCanvasView->lastClickedItem && gItem != 0 ) {
03042         qDebug("KDGanttView::Possible bug in drag&drop code ");
03043         return;
03044     }
03045 
03046     QDomDocument doc( "GanttView" );
03047     doc.setContent( string );
03048     QDomElement docRoot = doc.documentElement(); // ChartParams element
03049     QDomNode node = docRoot.firstChild();
03050     bool enable = myGanttView->myTimeTable->blockUpdating( );
03051     myGanttView->myTimeTable->setBlockUpdating( true );
03052     while( !node.isNull() ) {
03053         QDomElement element = node.toElement();
03054         if( !element.isNull() ) { // was really an element
03055             QString tagName = element.tagName();
03056             if( tagName == "Items" ) {
03057                 QDomNode node = element.firstChild();
03058                 while( !node.isNull() ) {
03059                     QDomElement element = node.toElement();
03060                     if( !element.isNull() ) { // was really an element
03061                         QString tagName = element.tagName();
03062                         if( tagName == "Item" ) {
03063                             if (  gItem )
03064                                 newItem = KDGanttViewItem::createFromDomElement( gItem,
03065                                                                                  element );
03066                             else
03067                                 newItem = KDGanttViewItem::createFromDomElement( myGanttView,
03068                                                                                  element );
03069                         } else {
03070                             qDebug( "Unrecognized tag name: %s", tagName.latin1() );
03071                             Q_ASSERT( false );
03072                         }
03073                     }
03074                     //qDebug("next node1 ");
03075                     node = node.nextSibling();
03076                 }
03077             }
03078         }
03079         //qDebug("next node2 ");
03080         node = node.nextSibling();
03081     }
03082     newItem->setDisplaySubitemsAsGroup(myGanttView->displaySubitemsAsGroup());
03083     newItem->resetSubitemVisibility();
03084     myGanttView->slot_lvDropped(e, draggedItem, gItem);
03085     myGanttView->myTimeTable->setBlockUpdating( enable );
03086     myGanttView->myTimeTable->updateMyContent();
03087     return;
03088 }
03089 
03090 QDragObject * KDListView::dragObject ()
03091 {
03092     return QListView::dragObject ();
03093 }
03094 
03095 void KDListView::startDrag ()
03096 {
03097     if ( ! myGanttView->dragEnabled() )
03098         return;
03099     KDGanttViewItem* cItem = (KDGanttViewItem*) currentItem ();
03100     myGanttView->myCanvasView->lastClickedItem = cItem;
03101     myGanttView->lvStartDrag (cItem);
03102 }
03103 
03104 KDCanvasText::KDCanvasText( KDTimeTableWidget* canvas,
03105                             void* parentItem,
03106                             int type ) :
03107     QCanvasText(canvas)
03108 {
03109     myParentType = type;
03110     myParentItem = parentItem;
03111 }
03112 
03113 
03114 KDCanvasLine::KDCanvasLine( KDTimeTableWidget* canvas,
03115                             void* parentItem,
03116                             int type ) :
03117     QCanvasLine(canvas)
03118 {
03119     myParentType = type;
03120     myParentItem = parentItem;
03121 }
03122 
03123 
03124 KDCanvasPolygonItem::KDCanvasPolygonItem( KDTimeTableWidget* canvas,
03125                                           void* parentItem,
03126                                           int type ) :
03127     QCanvasPolygonalItem( canvas )
03128 {
03129     myParentType = type;
03130     myParentItem = parentItem;
03131 }
03132 
03133 
03134 KDCanvasPolygon::KDCanvasPolygon( KDTimeTableWidget* canvas,
03135                                   void* parentItem,
03136                                   int type ) :
03137     QCanvasPolygon( canvas )
03138 {
03139     myParentType = type;
03140     myParentItem = parentItem;
03141 }
03142 
03143 
03144 KDCanvasEllipse::KDCanvasEllipse( KDTimeTableWidget* canvas,
03145                                   void* parentItem,
03146                                   int type ) :
03147     QCanvasEllipse( canvas )
03148 {
03149     myParentType = type;
03150     myParentItem = parentItem;
03151 }
03152 
03153 
03154 KDCanvasRectangle::KDCanvasRectangle( KDTimeTableWidget* canvas,
03155                                       void* parentItem,
03156                                       int type ) :
03157     QCanvasRectangle( canvas )
03158 {
03159     myParentType = type;
03160     myParentItem = parentItem;
03161 }
03162 
03163 
03164 
03165 
03166 KDGanttCanvasView::KDGanttCanvasView( KDGanttView* sender,QCanvas* canvas, QWidget* parent,  const char* name ) : QCanvasView ( canvas, parent, name )
03167 {
03168     setHScrollBarMode (QScrollView::AlwaysOn );
03169     setVScrollBarMode( QScrollView::AlwaysOn );
03170     myToolTip = new KDCanvasToolTip(viewport(),this);
03171     mySignalSender =  sender;
03172     currentItem = 0;
03173     currentLink = 0;
03174     cuttedItem = 0;
03175     fromItem = 0;
03176     fromArea = 0;
03177     linkItemsEnabled = false;
03178     linkLine = new QCanvasLine(canvas);
03179     linkLine->hide();
03180     linkLine->setZ(1000);
03181     //set_Mouse_Tracking(true);
03182     new KDCanvasWhatsThis(viewport(),this);
03183     onItem = new QPopupMenu( this );
03184     QPopupMenu * newMenu = new QPopupMenu( this );
03185     QPopupMenu * onView = new QPopupMenu( this );
03186     onView->insertItem( i18n( "Summary" ), this,
03187                         SLOT ( newRootItem( int ) ), 0, 0 );
03188     onView->insertItem( i18n( "Event" ), this,
03189                         SLOT ( newRootItem( int ) ), 0, 1);
03190     onView->insertItem( i18n( "Task" ), this,
03191                         SLOT ( newRootItem( int ) ), 0, 2 );
03192 
03193     onItem->insertItem( i18n( "New Root" ), onView );
03194     newMenu->insertItem( i18n( "Summary" ),
03195                          this, SLOT ( newChildItem(  int) ), 0, 0 );
03196     newMenu->insertItem( i18n( "Event" ),
03197                          this, SLOT ( newChildItem( int ) ), 0, 1 );
03198     newMenu->insertItem( i18n( "Task" ),
03199                          this, SLOT ( newChildItem( int ) ), 0, 2 );
03200 
03201     onItem->insertItem( i18n( "New Child" ), newMenu );
03202     QPopupMenu * afterMenu = new QPopupMenu( this );
03203     afterMenu->insertItem( i18n( "Summary" ),
03204                            this, SLOT ( newChildItem(  int) ), 0, 0+4 );
03205     afterMenu->insertItem( i18n( "Event" ),
03206                            this, SLOT ( newChildItem( int ) ), 0, 1+4 );
03207     afterMenu->insertItem( i18n( "Task" ),
03208                            this, SLOT ( newChildItem( int ) ), 0, 2+4 );
03209     onItem->insertItem( i18n( "New After" ), afterMenu );
03210     QPopupMenu *pasteMenu = new QPopupMenu( this );
03211     pasteMenu->insertItem( i18n( "As Root" ),
03212                            this, SLOT ( pasteItem( int ) ), 0, 0 );
03213     pasteMenu->insertItem( i18n( "As Child" ),
03214                            this, SLOT ( pasteItem( int ) ), 0, 1 );
03215     pasteMenu->insertItem( i18n( "After" ),
03216                            this, SLOT ( pasteItem( int ) ), 0, 2 );
03217     onItem->insertItem( i18n( "Paste" ), pasteMenu, 3 );
03218     onItem->insertItem( i18n( "Cut Item" ), this, SLOT ( cutItem() ) );
03219     onItem->setItemEnabled( 3, false );
03220     myMyContentsHeight = 0;
03221     _showItemAddPopupMenu = false;
03222     
03223     QObject *scrollViewTimer = child( "scrollview scrollbar timer", "QTimer", false );
03224     Q_ASSERT( scrollViewTimer );
03225     if ( scrollViewTimer ) {
03226         disconnect( scrollViewTimer, SIGNAL(timeout()), this, SLOT(updateScrollBars() ) );
03227     }
03228     // If they needed a scrollbar timer in scrollview...
03229     connect( &scrollBarTimer, SIGNAL(timeout()), this, SLOT(myUpdateScrollBars() ) );
03230     
03231     myScrollTimer = new QTimer( this );
03232     connect( myScrollTimer, SIGNAL( timeout() ), SLOT( slotScrollTimer() ) );
03233     autoScrollEnabled = false;
03234 }
03235 
03236 
03237 KDGanttCanvasView::~KDGanttCanvasView()
03238 {
03239     delete myToolTip;
03240 }
03241 
03242 
03243 void KDGanttCanvasView::setShowPopupMenu( bool show )
03244 {
03245     _showItemAddPopupMenu = show;
03246 }
03247 bool KDGanttCanvasView::showPopupMenu()
03248 {
03249     return _showItemAddPopupMenu;
03250 }
03251 
03252 
03253 void KDGanttCanvasView::moveMyContent( int, int y)
03254 {
03255     setContentsPos(contentsX(), y);
03256 }
03257 
03258 void KDGanttCanvasView::resizeEvent ( QResizeEvent * e )
03259 {
03260     int ho = e->oldSize().height();
03261     int wo = e->oldSize().width();
03262     int hi = height();
03263     int wi = width();
03264     //QScrollView::blockSignals( true );
03265 
03266     verticalScrollBar()->setUpdatesEnabled( false );
03267     QScrollView::resizeEvent ( e ) ;
03268     if ( ho != hi )
03269         emit heightResized( viewport()->height());
03270     if ( wo != wi )
03271         emit widthResized( viewport()->width() );
03272     //setMyContentsHeight( 0 ); // via timer
03273     //QScrollView::blockSignals( false );
03274     scrollBarTimer.start(0, true);
03275 }
03276 
03277 void KDGanttCanvasView::myUpdateScrollBars()
03278 {
03279     setMyContentsHeight( 0 );
03280 }
03281 void KDGanttCanvasView::setMyContentsHeight( int hei )
03282 {
03283     //qDebug("setMyContentsHeight %d %d ", hei,  myMyContentsHeight);
03284     if ( hei > 0 )
03285         myMyContentsHeight = hei;
03286     verticalScrollBar()->setUpdatesEnabled( true ); // set false in resizeEvent()
03287     if ( viewport()->height() <= myMyContentsHeight )
03288         verticalScrollBar()->setRange( 0, myMyContentsHeight- viewport()->height()+1);
03289     else
03290         verticalScrollBar()->setRange( 0,0 );
03291     // testing for unmatching ScrollBar values of timeheader and timetable
03292     // may happen after external resizing
03293     if ( horizontalScrollBar()->value() != mySignalSender->myTimeHeaderScroll->horizontalScrollBar()->value() ) {
03294         // I am the Boss!
03295         mySignalSender->myTimeHeaderScroll->horizontalScrollBar()->setValue(horizontalScrollBar()->value()  );
03296 
03297     }
03298 
03299 }
03300 
03301 // Call after *internal* resizing (like addTickRight())
03302 // Then the new scrollbar maxValue is in myTimeHeader.
03303 void KDGanttCanvasView::updateHorScrollBar() {
03304     //qDebug("horizontalScrollBar max=%d, myTimeHeaderScroll=%d", horizontalScrollBar()->maxValue(), mySignalSender->myTimeHeaderScroll->horizontalScrollBar()->value());
03305     
03306     horizontalScrollBar()->setRange(mySignalSender->myTimeHeaderScroll->horizontalScrollBar()->minValue(), mySignalSender->myTimeHeaderScroll->horizontalScrollBar()->maxValue());
03307     
03308 }
03309 
03310 void  KDGanttCanvasView::cutItem( KDGanttViewItem* item )
03311 {
03312     lastClickedItem = item;
03313     cutItem();
03314 }
03315 void  KDGanttCanvasView::insertItemAsRoot( KDGanttViewItem* item )
03316 {
03317     mySignalSender->myListView->insertItem( item  );
03318     if ( item == cuttedItem )
03319         cuttedItem = 0;
03320 }
03321 void  KDGanttCanvasView::insertItemAsChild( KDGanttViewItem* parent, KDGanttViewItem* item )
03322 {
03323     parent->insertItem( cuttedItem );
03324     if ( item == cuttedItem )
03325         cuttedItem = 0;
03326 }
03327 void  KDGanttCanvasView::insertItemAfter( KDGanttViewItem* parent , KDGanttViewItem* item )
03328 {
03329     if ( parent->parent() ) {
03330         parent->parent()->insertItem( item );
03331     }
03332     else
03333         mySignalSender->myListView->insertItem( item );
03334     item->moveItem( parent );
03335     if ( item == cuttedItem )
03336         cuttedItem = 0;
03337 }
03338 
03339 void  KDGanttCanvasView::cutItem()
03340 {
03341     lastClickedItem->hideSubtree();
03342     //qDebug("last clicked %d parent %d ", lastClickedItem  , lastClickedItem->parent());
03343     if ( lastClickedItem->parent() )
03344         lastClickedItem->parent()->takeItem(lastClickedItem);
03345     else
03346         mySignalSender->myListView->takeItem( lastClickedItem );
03347     mySignalSender->myTimeTable->updateMyContent();
03348     if ( cuttedItem )
03349         delete cuttedItem;
03350     cuttedItem = lastClickedItem;
03351     onItem->setItemEnabled( 3, true );
03352 
03353 }
03354 // called from the destructor in KDGanttViewItem or KDGanttView
03355 
03356 void  KDGanttCanvasView::resetCutPaste( KDGanttViewItem* item )
03357 {
03358     if ( item == 0 && cuttedItem ) {
03359         delete cuttedItem;
03360         cuttedItem = 0;
03361     }
03362     if (item == cuttedItem) {
03363         onItem->setItemEnabled( 3, false );
03364         cuttedItem = 0;
03365     }
03366 }
03367 
03368 void  KDGanttCanvasView::pasteItem( int type )
03369 {
03370     if ( !cuttedItem )
03371         return;
03372     switch( type ) {
03373     case 0://root
03374         mySignalSender->myListView->insertItem( cuttedItem );
03375         break;
03376     case 1://child
03377         lastClickedItem->insertItem( cuttedItem );
03378         break;
03379     case 2://after
03380         if ( lastClickedItem->parent() ) {
03381             lastClickedItem->parent()->insertItem( cuttedItem );
03382         }
03383         else
03384             mySignalSender->myListView->insertItem( cuttedItem );
03385         cuttedItem->moveItem( lastClickedItem );
03386         break;
03387     default:
03388         ;
03389     }
03390     cuttedItem = 0;
03391     onItem->setItemEnabled( 3, false );
03392     mySignalSender->myTimeTable->updateMyContent();
03393 }
03394 void  KDGanttCanvasView::newRootItem(int type)
03395 {
03396     KDGanttViewItem* temp = 0;
03397     switch( type ) {
03398     case 1:
03399         temp = new KDGanttViewEventItem( mySignalSender, i18n( "New Event" ) );
03400         break;
03401     case 0:
03402         temp = new KDGanttViewSummaryItem( mySignalSender, i18n( "New Summary" ) );
03403         break;
03404     case 2:
03405         temp = new KDGanttViewTaskItem( mySignalSender, i18n( "New Task" ) );
03406         break;
03407     default:
03408         ;
03409     }
03410     if ( temp )
03411         mySignalSender->editItem( temp );
03412 }
03413 
03414 void  KDGanttCanvasView::newChildItem( int type )
03415 {
03416     KDGanttViewItem* temp = 0;
03417     switch( type ) {
03418     case 1:
03419         temp = new KDGanttViewEventItem( lastClickedItem, i18n( "New Event" ) );
03420         break;
03421     case 0:
03422         temp = new KDGanttViewSummaryItem( lastClickedItem, i18n( "New Summary" ) );
03423         break;
03424     case 2:
03425         temp = new KDGanttViewTaskItem( lastClickedItem, i18n( "New Task" ) );
03426         break;
03427     case 5:
03428         if ( lastClickedItem->parent() )
03429             temp = new KDGanttViewEventItem( lastClickedItem->parent(), lastClickedItem, i18n( "New Event" ) );
03430         else
03431             temp = new KDGanttViewEventItem( mySignalSender, lastClickedItem, i18n( "New Event" ) );
03432         break;
03433     case 4:
03434         if ( lastClickedItem->parent() )
03435             temp = new KDGanttViewSummaryItem( lastClickedItem->parent(), lastClickedItem, i18n( "New Summary" ) );
03436         else
03437             temp = new KDGanttViewSummaryItem( mySignalSender, lastClickedItem, i18n( "New Summary" ) );
03438         break;
03439     case 6:
03440         if ( lastClickedItem->parent() )
03441             temp = new KDGanttViewTaskItem( lastClickedItem->parent(), lastClickedItem, i18n( "New Task" ) );
03442         else
03443             temp = new KDGanttViewTaskItem( mySignalSender, lastClickedItem, i18n( "New Task" ) );
03444         break;
03445 
03446 
03447     default:
03448         ;
03449     }
03450     if ( temp )
03451         mySignalSender->editItem( temp );
03452 }
03453 
03454 void  KDGanttCanvasView::drawToPainter ( QPainter * p )
03455 {
03456     drawContents ( p, 0, 0, canvas()->width(), canvas()->height() );
03457 }
03458 QString  KDGanttCanvasView::getToolTipText(QPoint p)
03459 {
03460     QCanvasItemList il = canvas()->collisions ( viewportToContents( p ));
03461     QCanvasItemList::Iterator it;
03462     for ( it = il.begin(); it != il.end(); ++it ) {
03463         switch (getType(*it)) {
03464         case Type_is_KDGanttViewItem:
03465             return (getItem(*it))->tooltipText();
03466             break;
03467         case Type_is_KDGanttTaskLink:
03468             return (getLink(*it))->tooltipText();
03469             break;
03470         default:
03471             break;
03472         }
03473     }
03474     return "";
03475 }
03476 
03477 QString  KDGanttCanvasView::getWhatsThisText(QPoint p)
03478 {
03479     QCanvasItemList il = canvas() ->collisions (viewportToContents( p ));
03480     QCanvasItemList::Iterator it;
03481     for ( it = il.begin(); it != il.end(); ++it ) {
03482         switch (getType(*it)) {
03483         case Type_is_KDGanttViewItem:
03484             return (getItem(*it))->whatsThisText();
03485             break;
03486         case Type_is_KDGanttTaskLink:
03487             return (getLink(*it))->whatsThisText();
03488             break;
03489         default:
03490             break;
03491         }
03492     }
03493     return "";
03494 }
03495 
03496 
03504 void KDGanttCanvasView::contentsMousePressEvent ( QMouseEvent * e )
03505 {
03506     //qDebug("mousepress! %d ", this);
03507     //qDebug("focus %d ",qApp->focusWidget());
03508     setFocus();
03509     currentLink = 0;
03510     currentItem = 0;
03511     if (e->button() == RightButton && mySignalSender->editable()) {
03512         lastClickedItem = (KDGanttViewItem*) mySignalSender->myListView->itemAt( QPoint(2,e->pos().y()));
03513         if ( lastClickedItem ) {
03514             if ( lastClickedItem->displaySubitemsAsGroup() && ! lastClickedItem->isOpen() ) {
03515                 // findSub subitem
03516                 QCanvasItemList il = canvas() ->collisions ( e->pos() );
03517                 QCanvasItemList::Iterator it;
03518                 for ( it = il.begin(); it != il.end(); ++it ) {
03519                     if ( getType(*it) == Type_is_KDGanttViewItem ) {
03520                         lastClickedItem = getItem(*it);
03521                     }
03522                 }
03523             }
03524             if ( _showItemAddPopupMenu  )
03525                 onItem->popup(e->globalPos());
03526         }
03527     }
03528     QCanvasItemList il = canvas() ->collisions ( e->pos() );
03529     QCanvasItemList::Iterator it;
03530     for ( it = il.begin(); it != il.end(); ++it ) {
03531         switch ( e->button() ) {
03532         case LeftButton:
03533             switch (getType(*it)) {
03534             case Type_is_KDGanttViewItem:
03535                 currentItem = getItem(*it);
03536                 if (! currentItem->enabled() ) {
03537                     currentItem = 0;
03538                 } else if (linkItemsEnabled && 
03539                            !currentItem->isMyTextCanvas(*it)) {
03540                     fromArea = getItemArea(currentItem, e->pos().x());
03541                     if (fromArea > 0) {
03542                         fromItem = currentItem;
03543                         linkLine->setPoints(e->pos().x(), e->pos().y(), e->pos().x(), e->pos().y());
03544                         linkLine->show();
03545                     }
03546                 }
03547                 break;
03548             case Type_is_KDGanttTaskLink:
03549                 currentLink = getLink(*it);
03550                 break;
03551             default:
03552                 break;
03553             }
03554             break;
03555         case RightButton:
03556             switch (getType(*it)) {
03557             case Type_is_KDGanttViewItem:
03558                 currentItem = getItem(*it);
03559                 if (! currentItem->enabled() )
03560                     currentItem = 0;
03561                 break;
03562             case Type_is_KDGanttTaskLink:
03563                 currentLink = getLink(*it);
03564                 break;
03565             }
03566             break;
03567         case MidButton:
03568             switch (getType(*it)) {
03569             case Type_is_KDGanttViewItem:
03570                 currentItem = getItem(*it);
03571                 if (! currentItem->enabled() )
03572                     currentItem = 0;
03573                 break;
03574             case Type_is_KDGanttTaskLink:
03575                 currentLink = getLink(*it);
03576                 break;
03577             }
03578             break;
03579         default:
03580             break;
03581         }
03582     }
03583     if (e->button() == RightButton ) {
03584         mySignalSender->gvContextMenuRequested( currentItem, e->globalPos() );
03585     }
03586     if (autoScrollEnabled && e->button() == LeftButton) {
03587         myScrollTimer->start(50);
03588     }
03589 }
03597 void KDGanttCanvasView::contentsMouseReleaseEvent ( QMouseEvent * e )
03598 {
03599     static KDGanttViewItem* lastClicked = 0;
03600     mySignalSender->gvMouseButtonClicked( e->button(), currentItem ,  e->globalPos() );
03601     //qDebug("datetime %s ",mySignalSender->getDateTimeForCoordX(e->globalPos().x(), true ).toString().latin1() );
03602     //qDebug("mousepos %d %d ",e->pos().x(),e->pos().y() );
03603     //qDebug("mouseup ");
03604     // if ( currentLink || currentItem )
03605     {
03606         switch ( e->button() ) {
03607         case LeftButton:
03608             myScrollTimer->stop();
03609             {
03610                 mySignalSender->itemLeftClicked( currentItem );
03611                 mySignalSender->gvItemLeftClicked( currentItem );
03612             }
03613             if ( currentLink )
03614                 mySignalSender->taskLinkLeftClicked( currentLink );
03615             if (linkItemsEnabled && fromItem) {
03616                 linkLine->hide();
03617                 canvas()->update();
03618                 QCanvasItemList il = canvas() ->collisions ( e->pos() );
03619                 QCanvasItemList::Iterator it;
03620                 for ( it = il.begin(); it != il.end(); ++it ) {
03621                     if (getType(*it) == Type_is_KDGanttViewItem) {
03622                         KDGanttViewItem *toItem = getItem(*it);
03623                         if (!toItem->isMyTextCanvas(*it)) {
03624                             int toArea = getItemArea(toItem, e->pos().x());
03625                             if (toArea > 0 && toItem && fromItem != toItem) {
03626                                 mySignalSender->linkItems(fromItem, toItem, getLinkType(fromArea, toArea));
03627                             }
03628                         }
03629                         break;
03630                     }
03631                 }
03632             }
03633             fromItem = 0;
03634             break;
03635         case RightButton:
03636             {
03637                 mySignalSender->itemRightClicked( currentItem );
03638                 mySignalSender->gvItemRightClicked( currentItem );
03639 
03640             }
03641             if ( currentLink )
03642                 mySignalSender->taskLinkRightClicked( currentLink );
03643             break;
03644         case MidButton:
03645             {
03646                 mySignalSender->itemMidClicked( currentItem );
03647                 mySignalSender->gvItemMidClicked( currentItem );
03648             }
03649             if ( currentLink )
03650                 mySignalSender->taskLinkRightClicked( currentLink );
03651             break;
03652         default:
03653             break;
03654         }
03655     }
03656     if ( lastClicked != currentItem )
03657         mySignalSender->gvCurrentChanged( currentItem );
03658     lastClicked = currentItem;
03659     currentLink = 0;
03660     currentItem = 0;
03661 }
03669 void KDGanttCanvasView::contentsMouseDoubleClickEvent ( QMouseEvent * e )
03670 {
03671     QCanvasItemList il = canvas() ->collisions ( e->pos() );
03672     QCanvasItemList::Iterator it;
03673     for ( it = il.begin(); it != il.end(); ++it ) {
03674         switch ( e->button() ) {
03675         case LeftButton:
03676             switch (getType(*it)) {
03677             case Type_is_KDGanttViewItem:
03678                 if ( getItem(*it)->enabled() )
03679                     mySignalSender->itemDoubleClicked(getItem(*it));
03680                 mySignalSender->gvItemDoubleClicked(getItem(*it));
03681                 return;
03682                 break;
03683             case Type_is_KDGanttTaskLink:
03684                 mySignalSender->taskLinkDoubleClicked(getLink(*it));
03685                 return;
03686                 break;
03687             default:
03688                 break;
03689             }
03690             break;
03691             /*
03692               case RightButton:
03693               switch (getType(*it)) {
03694               case Type_is_KDGanttViewItem:
03695               mySignalSender->itemRightClicked(getItem(*it));
03696               return;
03697               break;
03698               case Type_is_KDGanttTaskLink:
03699               mySignalSender->taskLinkRightClicked(getLink(*it));
03700               return;
03701               break;
03702               }
03703               break;
03704               case MidButton:
03705               switch (getType(*it)) {
03706               case Type_is_KDGanttViewItem:
03707               mySignalSender->itemMidClicked(getItem(*it));
03708               return;
03709               break;
03710               case Type_is_KDGanttTaskLink:
03711               mySignalSender->taskLinkMidClicked(getLink(*it));
03712               return;
03713               break;
03714               }
03715               break;
03716             */
03717         default:
03718             break;
03719         }
03720     }
03721 }
03729 void KDGanttCanvasView::contentsMouseMoveEvent ( QMouseEvent *e )
03730 {
03731     //qDebug("mousemove! ");
03732     static int moves = 0;
03733     if ( (currentLink || currentItem) && (moves < 3) ) {
03734         ++moves;
03735 
03736     } else {
03737         moves = 0;
03738         currentLink = 0;
03739         currentItem = 0;
03740     }
03741     if (autoScrollEnabled)
03742         mousePos = e->pos()- QPoint(contentsX(),contentsY()); // make mousePos relative 0
03743     if (fromItem) {
03744         //qDebug("mousemove: linking %s: %d,%d ",fromItem->listViewText().latin1(), e->pos().x(), e->pos().y());
03745         linkLine->setPoints(linkLine->startPoint().x(), linkLine->startPoint().y(), e->pos().x(), e->pos().y());
03746         canvas()->update();
03747     }
03748     // no action implemented
03749     //qDebug("mousemove ");
03750     //QToolTip::setGloballyEnabled (false);
03751     //QToolTip::remove(viewport());
03752     // QToolTip::add(viewport(), "hello");
03753     // QToolTip::setGloballyEnabled (true);
03754     /*
03755       QCanvasItemList il = canvas() ->collisions ( e->pos() );
03756 
03757       QCanvasItemList::Iterator it;
03758       KDGanttItem* mouseover = 0;
03759       for ( it = il.begin(); it != il.end(); ++it ) {
03760 
03761       }
03762 
03763     */
03764 }
03765 void KDGanttCanvasView::viewportPaintEvent ( QPaintEvent * pe )
03766 {
03767     QCanvasView::viewportPaintEvent ( pe );
03768 }
03769 void KDGanttCanvasView::set_Mouse_Tracking(bool on)
03770 {
03771     viewport()->setMouseTracking(on);
03772 }
03773 int  KDGanttCanvasView::getType(QCanvasItem* it)
03774 {
03775     switch (it->rtti()) {
03776     case QCanvasItem::Rtti_Line: return ((KDCanvasLine*)it)->myParentType;
03777     case QCanvasItem::Rtti_Ellipse: return ((KDCanvasEllipse *)it)->myParentType;
03778     case QCanvasItem::Rtti_Text: return ((KDCanvasText *)it)->myParentType;
03779     case QCanvasItem::Rtti_Polygon: return ((KDCanvasPolygon *)it)->myParentType;
03780     case QCanvasItem::Rtti_Rectangle: return ((KDCanvasRectangle *)it)->myParentType;
03781     }
03782     return -1;
03783 }
03784 KDGanttViewItem*  KDGanttCanvasView::getItem(QCanvasItem* it)
03785 {
03786     switch (it->rtti()) {
03787     case QCanvasItem::Rtti_Line: return (KDGanttViewItem*)  ((KDCanvasLine*)it)->myParentItem;
03788     case QCanvasItem::Rtti_Ellipse: return (KDGanttViewItem*)  ((KDCanvasEllipse *)it)->myParentItem;
03789     case QCanvasItem::Rtti_Text: return (KDGanttViewItem*) ((KDCanvasText *)it)->myParentItem;
03790     case QCanvasItem::Rtti_Polygon: return (KDGanttViewItem*) ((KDCanvasPolygon *)it)->myParentItem;
03791     case QCanvasItem::Rtti_Rectangle: return (KDGanttViewItem*) ((KDCanvasRectangle *)it)->myParentItem;
03792 
03793     }
03794     return 0;
03795 }
03796 KDGanttViewTaskLink*  KDGanttCanvasView::getLink(QCanvasItem* it)
03797 {
03798     switch (it->rtti()) {
03799     case QCanvasItem::Rtti_Line: return (KDGanttViewTaskLink*)  ((KDCanvasLine*)it)->myParentItem;
03800     case QCanvasItem::Rtti_Ellipse: return (KDGanttViewTaskLink*)  ((KDCanvasEllipse *)it)->myParentItem;
03801     case QCanvasItem::Rtti_Text: return (KDGanttViewTaskLink*) ((KDCanvasText *)it)->myParentItem;
03802     case QCanvasItem::Rtti_Polygon: return (KDGanttViewTaskLink*) ((KDCanvasPolygon *)it)->myParentItem;
03803     }
03804     return 0;
03805 }
03806 
03807 void KDGanttCanvasView::slotScrollTimer() {
03808     int mx = mousePos.x(); 
03809     int my = mousePos.y();
03810     int dx = 0;
03811     int dy = 0;
03812     if (mx < 0)
03813         dx = -5;
03814     else if (mx > visibleWidth())
03815         dx = 5;
03816     if (my < 0)
03817         dy = -5;
03818     else if (my > visibleHeight())
03819         dy = QMIN(5, verticalScrollBar()->maxValue()-verticalScrollBar()->value());
03820     
03821     if (dx != 0 || dy != 0)
03822         scrollBy(dx, dy);
03823 }
03824 
03825 int KDGanttCanvasView::getItemArea(KDGanttViewItem *item, int x) {
03826     // area can be: no area = 0, Start = 1, Finish = 2
03827     // TODO: middle (move, dnd), front, back (resize)
03828     KDTimeTableWidget *tt = dynamic_cast<KDTimeTableWidget *>(canvas());
03829     if (!tt) {
03830         qWarning("Cannot cast canvas to KDTimeTableWidget");
03831         return 0;
03832     }
03833     int area = 0;
03834     int start = tt->getCoordX(item->startTime());
03835     int end = start;
03836     if (item->type() == KDGanttViewItem::Event) {
03837         x > start ? area = 2 : area = 1;
03838     } else {
03839         end = tt->getCoordX(item->endTime());
03840         if ((end - start)/2 > (x - start))
03841             area = 1;
03842         else
03843             area = 2;
03844     }
03845     return area;
03846 }
03847 
03848 int KDGanttCanvasView::getLinkType(int from, int to) {
03849     // from, to should be Start = 1 or Finish = 2
03850     if ((from == 1) && (to == 1)) {
03851         return KDGanttViewTaskLink::StartStart;
03852     }
03853     if ((from == 1) && (to == 2)) {
03854         return KDGanttViewTaskLink::StartFinish;
03855     }
03856     if ((from == 2) && (to == 1)) {
03857         return KDGanttViewTaskLink::FinishStart;
03858     }
03859     if ((from == 2) && (to == 2)) {
03860         return KDGanttViewTaskLink::FinishFinish;
03861     }
03862     return KDGanttViewTaskLink::None;
03863 }
KDE Home | KDE Accessibility Home | Description of Access Keys