kdgantt

KDGanttViewSubwidgets.cpp

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