You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
4049 lines
133 KiB
4049 lines
133 KiB
/* -*- Mode: C++ -*-
|
|
$Id$
|
|
KDGantt - a multi-platform charting engine
|
|
*/
|
|
|
|
/****************************************************************************
|
|
** Copyright (C) 2002-2004 Klarälvdalens Datakonsult AB. All rights reserved.
|
|
**
|
|
** This file is part of the KDGantt library.
|
|
**
|
|
** This file may be distributed and/or modified under the terms of the
|
|
** GNU General Public License version 2 as published by the Free Software
|
|
** Foundation and appearing in the file LICENSE.GPL included in the
|
|
** packaging of this file.
|
|
**
|
|
** Licensees holding valid commercial KDGantt licenses may use this file in
|
|
** accordance with the KDGantt Commercial License Agreement provided with
|
|
** the Software.
|
|
**
|
|
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
|
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
|
**
|
|
** See http://www.klaralvdalens-datakonsult.se/Public/products/ for
|
|
** information about KDGantt Commercial License Agreements.
|
|
**
|
|
** Contact info@klaralvdalens-datakonsult.se if any conditions of this
|
|
** licensing are not clear to you.
|
|
**
|
|
** As a special exception, permission is given to link this program
|
|
** with any edition of Qt, and distribute the resulting executable,
|
|
** without including the source code for Qt in the source distribution.
|
|
**
|
|
**********************************************************************/
|
|
|
|
|
|
#include "KDGanttViewSubwidgets.h"
|
|
#include "KDGanttViewEventItem.h"
|
|
#include "KDGanttViewSummaryItem.h"
|
|
#include "KDGanttViewTaskItem.h"
|
|
#ifndef KDGANTT_MASTER_CVS
|
|
#include "KDGanttViewSubwidgets.moc"
|
|
#endif
|
|
|
|
#include <tqlabel.h>
|
|
#include <tqheader.h>
|
|
#include <tqpainter.h>
|
|
#include <tqrect.h>
|
|
#include <tqtooltip.h>
|
|
#include <tqapplication.h>
|
|
#include <tqdrawutil.h>
|
|
#include <tqpalette.h>
|
|
#include <tqdragobject.h>
|
|
#include <tqptrlist.h>
|
|
#include <tqpen.h>
|
|
|
|
#include <kglobal.h>
|
|
#include <klocale.h>
|
|
#include <kcalendarsystem.h>
|
|
#include <kdebug.h>
|
|
|
|
KDTimeTableWidget:: KDTimeTableWidget( TQWidget* parent,KDGanttView* myGantt)
|
|
: TQCanvas (parent)
|
|
{
|
|
myGanttView = myGantt;
|
|
taskLinksVisible = true;
|
|
flag_blockUpdating = false;
|
|
int_blockUpdating = 0;
|
|
gridPen.setStyle(Qt::DotLine);
|
|
gridPen.setColor(TQColor(100,100,100));
|
|
maximumComputedGridHeight = 0;
|
|
denseLineCount = 0;
|
|
denseLineBrush = TQBrush( TQColor ( 240,240,240 ));
|
|
noInfoLineBrush = TQBrush( TQColor ( 100,100,100 ), Qt::FDiagPattern );
|
|
pendingHeight = 0;
|
|
pendingWidth = 0;
|
|
retune(256);
|
|
resize(1,1);
|
|
}
|
|
|
|
TQPtrList<KDGanttViewTaskLink> KDTimeTableWidget::taskLinks()
|
|
{
|
|
return myTaskLinkList;
|
|
}
|
|
|
|
void KDTimeTableWidget::clearTaskLinks()
|
|
{
|
|
// cannot use clear() here, as tasklinks will remove themselves from my list when deleted!
|
|
TQPtrListIterator<KDGanttViewTaskLink> it(myTaskLinkList);
|
|
while (it.current()) {
|
|
delete it.current();
|
|
}
|
|
|
|
}
|
|
|
|
void KDTimeTableWidget::resetWidth( int wid )
|
|
{
|
|
if ( wid == width() ) {
|
|
if (pendingHeight)
|
|
pendingWidth = wid;
|
|
else
|
|
pendingWidth = 0;
|
|
return;
|
|
}
|
|
if ( ! pendingHeight )
|
|
pendingHeight = height();
|
|
pendingWidth = wid;
|
|
updateMyContent();
|
|
}
|
|
|
|
void KDTimeTableWidget::checkHeight( int hei )
|
|
{
|
|
if( hei < height() )
|
|
return;
|
|
if ( pendingHeight < hei+100)
|
|
pendingHeight = hei+100;
|
|
if ( ! pendingWidth )
|
|
pendingWidth = width();
|
|
maximumComputedGridHeight = 0; //force recomputing all
|
|
updateMyContent();
|
|
}
|
|
|
|
|
|
void KDTimeTableWidget::setNoInformationBrush( const TQBrush& brush )
|
|
{
|
|
noInfoLineBrush = brush;
|
|
updateMyContent();
|
|
}
|
|
TQBrush KDTimeTableWidget::noInformationBrush() const
|
|
{
|
|
return noInfoLineBrush;
|
|
}
|
|
|
|
void KDTimeTableWidget::removeItemFromTasklinks( KDGanttViewItem* item)
|
|
{
|
|
TQPtrListIterator<KDGanttViewTaskLink> it((myTaskLinkList));
|
|
for ( ; it.current(); ++it ) {
|
|
it.current()->removeItemFromList( item );
|
|
}
|
|
}
|
|
|
|
void KDTimeTableWidget::expandItem( TQListViewItem * item)
|
|
{
|
|
item->tqinvalidateHeight () ;
|
|
//tqApp->processEvents();
|
|
updateMyContent();
|
|
}
|
|
void KDTimeTableWidget::collapseItem( TQListViewItem * item)
|
|
{
|
|
item->tqinvalidateHeight () ;
|
|
//tqApp->processEvents();
|
|
updateMyContent();
|
|
}
|
|
|
|
void KDTimeTableWidget::highlightItem( TQListViewItem * item )
|
|
{
|
|
static bool itemwashighlighted;
|
|
static KDGanttViewItem* highlightedItem = 0;
|
|
if (highlightedItem)
|
|
highlightedItem->setHighlight(itemwashighlighted);
|
|
highlightedItem = ( KDGanttViewItem*)item;
|
|
itemwashighlighted = highlightedItem->highlight();
|
|
highlightedItem->setHighlight(true);
|
|
item->tqinvalidateHeight () ;
|
|
myGanttView->myListView->contentsY();
|
|
updateMyContent();
|
|
}
|
|
int KDTimeTableWidget::computeHeight()
|
|
{
|
|
// compute height of ListView
|
|
// show only items shown in ListView
|
|
int hei = 0;
|
|
KDGanttViewItem* temp;
|
|
temp = myGanttView->firstChild();
|
|
while (temp) {
|
|
hei += temp->computeHeight();
|
|
temp = temp->nextSibling();
|
|
}
|
|
// set hei to 1 to avoid canavs to be a null pixmap
|
|
if (hei == 0) {
|
|
hei = 1;
|
|
}
|
|
//qDebug("COMPUTED HEI %d ", hei);
|
|
emit heightComputed( hei );
|
|
return hei;
|
|
}
|
|
void KDTimeTableWidget::computeVerticalGrid()
|
|
{
|
|
// recompute the vertical grid
|
|
// compute the vertical grid
|
|
// if we have too much lines, hide them
|
|
//qDebug("computeVerticalGrid() ");
|
|
int cw = myGanttView->myTimeHeader->myGridMinorWidth;
|
|
int i = 0;
|
|
int h ;
|
|
if (pendingHeight > height() )
|
|
h = pendingHeight;
|
|
else
|
|
h = height();
|
|
int wid;
|
|
if ( pendingWidth )
|
|
wid = pendingWidth;
|
|
else
|
|
wid = width();
|
|
KDCanvasLine* templine;
|
|
KDCanvasRectangle* temprect;
|
|
TQColor colcol;
|
|
TQPen colPen;
|
|
bool colorIterator = true;
|
|
|
|
|
|
if (myGanttView->showMinorTicks()){//minor
|
|
colPen.setWidth(cw);
|
|
TQPtrListIterator<KDCanvasRectangle> itcol(columnColorList);
|
|
TQPtrListIterator<KDCanvasLine> itgrid(verGridList);
|
|
for ( ; itgrid.current(); ++itgrid ) {
|
|
if (i < wid) {
|
|
itgrid.current()->setPoints(i,0,i,h);
|
|
itgrid.current()->show();
|
|
|
|
if (myGanttView->myTimeHeader->getColumnColor(colcol,i,i+cw))
|
|
{
|
|
|
|
colPen.setColor(colcol);
|
|
if (colorIterator)
|
|
colorIterator = itcol.current();
|
|
if (colorIterator)
|
|
{/*
|
|
itcol.current()->setPen(colPen);
|
|
itcol.current()->setPoints(i+(cw/2),0,i+(cw/2),h);
|
|
*/
|
|
|
|
itcol.current()->setPen( TQPen::NoPen );
|
|
itcol.current()->setBrush( TQBrush( colcol, SolidPattern) );
|
|
itcol.current()->setSize(cw ,h );
|
|
itcol.current()->move( i, 0 );
|
|
itcol.current()->show();
|
|
++itcol;
|
|
} else {
|
|
|
|
/*
|
|
templine = new KDCanvasLine(this,0,Type_is_KDGanttGridItem);
|
|
templine->setPen(colPen);
|
|
templine->setPoints(i+(cw/2),0,i+(cw/2),h);
|
|
*/
|
|
temprect = new KDCanvasRectangle(this,0,Type_is_KDGanttGridItem);
|
|
temprect->setPen( TQPen::NoPen );
|
|
temprect->setBrush( TQBrush( colcol, SolidPattern) );
|
|
temprect->setSize(cw ,h );
|
|
temprect->move( i, 0 );
|
|
temprect->setZ(-20);
|
|
temprect->show();
|
|
columnColorList.append(temprect);
|
|
}
|
|
}
|
|
i += cw;
|
|
} else {
|
|
itgrid.current()->hide();
|
|
}
|
|
}
|
|
// create additional Lines for vertical grid
|
|
for ( ;i < wid;i += cw) {
|
|
templine = new KDCanvasLine(this,0,Type_is_KDGanttGridItem);
|
|
templine->setPen(gridPen);
|
|
templine->setPoints(i,0,i,h);
|
|
templine->setZ(0);
|
|
templine->show();
|
|
verGridList.append(templine);
|
|
if (myGanttView->myTimeHeader->getColumnColor(colcol,i,i+cw))
|
|
{
|
|
colPen.setColor(colcol);
|
|
if (colorIterator)
|
|
colorIterator = itcol.current();
|
|
if (colorIterator)
|
|
{/*
|
|
itcol.current()->setPen(colPen);
|
|
itcol.current()->setPoints(i+(cw/2),0,i+(cw/2),h);
|
|
*/
|
|
itcol.current()->setPen( TQPen::NoPen );
|
|
itcol.current()->setBrush( TQBrush( colcol, SolidPattern) );
|
|
itcol.current()->setSize(cw ,h );
|
|
itcol.current()->move( i, 0 );
|
|
itcol.current()->show();
|
|
++itcol;
|
|
} else {
|
|
temprect = new KDCanvasRectangle(this,0,Type_is_KDGanttGridItem);
|
|
temprect->setPen( TQPen::NoPen );
|
|
temprect->setBrush( TQBrush( colcol, SolidPattern) );
|
|
temprect->setSize(cw ,h );
|
|
temprect->move( i, 0 );
|
|
temprect->setZ(-20);
|
|
temprect->show();
|
|
columnColorList.append(temprect);
|
|
/*
|
|
templine = new KDCanvasLine(this,0,Type_is_KDGanttGridItem);
|
|
templine->setPen(colPen);
|
|
templine->setPoints(i+(cw/2),0,i+(cw/2),h);
|
|
templine->setZ(-20);
|
|
templine->show();
|
|
columnColorList.append(templine);
|
|
*/
|
|
}
|
|
}
|
|
}
|
|
if (colorIterator)
|
|
for ( ; itcol.current(); ++itcol )
|
|
itcol.current()->hide();
|
|
} else {//major
|
|
if (myGanttView->showMajorTicks()) {
|
|
TQValueList<int>::iterator intIt = myGanttView->myTimeHeader->majorTicks.begin();
|
|
TQValueList<int>::iterator intItEnd = myGanttView->myTimeHeader->majorTicks.end();
|
|
TQPtrListIterator<KDCanvasRectangle> itcol(columnColorList);
|
|
TQPtrListIterator<KDCanvasLine> itgrid(verGridList);
|
|
int left = 0;
|
|
for ( ; itgrid.current(); ++itgrid ) {
|
|
if (intIt != intItEnd) {
|
|
left = (*intIt);
|
|
++intIt;
|
|
itgrid.current()->setPoints(left,0,left,h);
|
|
itgrid.current()->show();
|
|
//int right = (*intIt);
|
|
if ((*intIt))
|
|
if (myGanttView->myTimeHeader->getColumnColor(colcol,left,(*intIt) ))
|
|
{
|
|
int mid = (-left+(*intIt));
|
|
colPen.setColor(colcol);
|
|
colPen.setWidth((*intIt)-left);
|
|
if (colorIterator)
|
|
colorIterator = itcol.current();
|
|
if (colorIterator)
|
|
{/*
|
|
itcol.current()->setPen(colPen);
|
|
itcol.current()->setPoints(i+mid,0,mid,h);
|
|
*/
|
|
itcol.current()->setPen( TQPen::NoPen );
|
|
itcol.current()->setBrush( TQBrush( colcol, SolidPattern) );
|
|
itcol.current()->setSize(mid ,h );
|
|
itcol.current()->move( left, 0 );
|
|
itcol.current()->show();
|
|
++itcol;
|
|
} else {
|
|
temprect = new KDCanvasRectangle(this,0,Type_is_KDGanttGridItem);
|
|
temprect->setPen( TQPen::NoPen );
|
|
temprect->setBrush( TQBrush( colcol, SolidPattern) );
|
|
temprect->setSize(mid,h );
|
|
temprect->move( left, 0 );
|
|
temprect->setZ(-20);
|
|
temprect->show();
|
|
columnColorList.append(temprect);
|
|
/*
|
|
templine = new KDCanvasLine(this,0,Type_is_KDGanttGridItem);
|
|
templine->setPen(colPen);
|
|
templine->setPoints(mid,0,i+mid,h);
|
|
templine->setZ(-20);
|
|
templine->show();
|
|
columnColorList.append(templine);
|
|
*/
|
|
|
|
}
|
|
}
|
|
|
|
} else {
|
|
itgrid.current()->hide();
|
|
}
|
|
}
|
|
KDCanvasLine* templine;
|
|
// create additional Lines for vertical grid
|
|
for ( ;intIt != intItEnd ;++intIt) {
|
|
|
|
templine = new KDCanvasLine(this,0,Type_is_KDGanttGridItem);
|
|
templine->setPen(gridPen);
|
|
templine->setPoints((*intIt),0,(*intIt),h);
|
|
templine->setZ(0);
|
|
templine->show();
|
|
verGridList.append(templine);
|
|
if ((*intIt))
|
|
if (myGanttView->myTimeHeader->getColumnColor(colcol,left,(*intIt)))
|
|
{
|
|
int mid = (-left+(*intIt));
|
|
colPen.setColor(colcol);
|
|
colPen.setWidth((*intIt)-left);
|
|
if (colorIterator)
|
|
colorIterator = itcol.current();
|
|
if (colorIterator)
|
|
{/*
|
|
itcol.current()->setPen(colPen);
|
|
itcol.current()->setPoints(i+mid,0,mid,h);
|
|
*/
|
|
itcol.current()->setPen( TQPen::NoPen );
|
|
itcol.current()->setBrush( TQBrush( colcol, SolidPattern) );
|
|
itcol.current()->setSize(mid ,h );
|
|
itcol.current()->move( left, 0 );
|
|
itcol.current()->show();
|
|
++itcol;
|
|
} else {
|
|
temprect = new KDCanvasRectangle(this,0,Type_is_KDGanttGridItem);
|
|
temprect->setPen( TQPen::NoPen );
|
|
temprect->setBrush( TQBrush( colcol, SolidPattern) );
|
|
temprect->setSize(mid ,h );
|
|
temprect->move( left, 0 );
|
|
temprect->setZ(-20);
|
|
temprect->show();
|
|
columnColorList.append(temprect);
|
|
/*
|
|
templine = new KDCanvasLine(this,0,Type_is_KDGanttGridItem);
|
|
templine->setPen(colPen);
|
|
templine->setPoints(mid,0,i+mid,h);
|
|
templine->setZ(-20);
|
|
templine->show();
|
|
columnColorList.append(templine);
|
|
*/
|
|
}
|
|
}
|
|
left = (*intIt);
|
|
}
|
|
if (colorIterator)
|
|
for ( ; itcol.current(); ++itcol ) {
|
|
itcol.current()->hide();
|
|
}
|
|
|
|
}
|
|
else {
|
|
//hideall
|
|
TQPtrListIterator<KDCanvasLine> itgrid(verGridList);
|
|
for ( ; itgrid.current(); ++itgrid ) {
|
|
itgrid.current()->hide();
|
|
}
|
|
TQPtrListIterator<KDCanvasRectangle> itcol(columnColorList);
|
|
for ( ; itcol.current(); ++itcol ) {
|
|
itcol.current()->hide();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
void KDTimeTableWidget::computeHorizontalGrid()
|
|
{
|
|
// compute horizontal grid
|
|
//qDebug("computeHorizontalGrid() ");
|
|
KDGanttViewItem* temp = myGanttView->firstChild();
|
|
int wid;
|
|
if ( pendingWidth )
|
|
wid = pendingWidth;
|
|
else
|
|
wid = width();
|
|
KDCanvasLine* templine;
|
|
TQPtrListIterator<KDCanvasLine> ithor(horGridList);
|
|
if ( ithor.current() ) {
|
|
templine = ithor.current();
|
|
++ithor;
|
|
} else {
|
|
templine = new KDCanvasLine(this,0,Type_is_KDGanttGridItem);
|
|
templine->setPen(gridPen);
|
|
templine->setZ(0);
|
|
horGridList.append(templine);
|
|
}
|
|
templine->setPoints(0,0,wid,0);
|
|
templine->show();
|
|
int posY;
|
|
while ( temp ) {
|
|
posY = temp->itemPos() + temp->height();
|
|
if ( ithor.current() ) {
|
|
templine = ithor.current();
|
|
++ithor;
|
|
} else {
|
|
//new vertical grid line
|
|
templine = new KDCanvasLine(this,0,Type_is_KDGanttGridItem);
|
|
templine->setPen(gridPen);
|
|
templine->setZ(0);
|
|
horGridList.append(templine);
|
|
}
|
|
if ( templine->endPoint() != TQPoint(wid,posY ))
|
|
templine->setPoints(0,posY,wid,posY );
|
|
if ( !templine->isVisible() )
|
|
templine->show();
|
|
//TQString ts = "asGroup";
|
|
//if (!temp->displaySubitemsAsGroup() )
|
|
// ts = " NOT asGroup";
|
|
//qDebug("temp name %s %s", temp->listViewText(0).latin1(), ts.latin1());
|
|
|
|
temp = temp->itemBelow ();
|
|
}
|
|
while ( ithor.current() ) {
|
|
if ( ithor.current()->isVisible() )
|
|
ithor.current()->hide();
|
|
++ithor;
|
|
}
|
|
}
|
|
|
|
void KDTimeTableWidget::computeDenseLines()
|
|
{
|
|
KDGanttViewItem* temp = myGanttView->firstChild();
|
|
int wid;
|
|
if ( pendingWidth )
|
|
wid = pendingWidth;
|
|
else
|
|
wid = width();
|
|
TQPtrListIterator<KDCanvasRectangle> ithordense(horDenseList);
|
|
KDCanvasRectangle* denseLine;
|
|
int tempDenseLineCount = 0;
|
|
while ( temp ) {
|
|
if ( temp->isVisible() ) {
|
|
++tempDenseLineCount;
|
|
if ( tempDenseLineCount == denseLineCount ) {
|
|
tempDenseLineCount = 0;
|
|
if ( ithordense.current() ) {
|
|
denseLine = ithordense.current();
|
|
++ithordense;
|
|
} else {
|
|
denseLine =new KDCanvasRectangle(this,0,Type_is_KDGanttGridItem);
|
|
denseLine->setZ(-2);
|
|
horDenseList.append( denseLine );
|
|
}
|
|
if ( denseLine->rect() != TQRect(0, temp->itemPos(),wid, temp->height()) ) {
|
|
denseLine->move( 0, temp->itemPos() );
|
|
denseLine->setSize( wid, temp->height());
|
|
}
|
|
if (denseLine->brush() != denseLineBrush ) {
|
|
denseLine->setPen( TQPen( Qt::NoPen ) );
|
|
denseLine->setBrush( denseLineBrush);
|
|
}
|
|
if (!denseLine->isVisible() )
|
|
denseLine->show();
|
|
|
|
} else {
|
|
;
|
|
}
|
|
}
|
|
temp = temp->itemBelow ();
|
|
}
|
|
while ( ithordense.current() ) {
|
|
if ( ithordense.current()->isVisible() ) {
|
|
ithordense.current()->hide();
|
|
}
|
|
++ithordense;
|
|
}
|
|
}
|
|
void KDTimeTableWidget::computeShowNoInformation()
|
|
{
|
|
KDGanttViewItem* temp = myGanttView->firstChild();
|
|
int wid;
|
|
if ( pendingWidth )
|
|
wid = pendingWidth;
|
|
else
|
|
wid = width();
|
|
TQPtrListIterator<KDCanvasRectangle> itnoinfo(showNoInfoList);
|
|
KDCanvasRectangle* noInfoLine;
|
|
while ( temp ) {
|
|
if ( temp->showNoInformation() ) {
|
|
if ( itnoinfo.current() ) {
|
|
noInfoLine = itnoinfo.current();
|
|
++itnoinfo;
|
|
} else {
|
|
noInfoLine =new KDCanvasRectangle(this,0,Type_is_KDGanttGridItem);
|
|
showNoInfoList.append( noInfoLine );
|
|
noInfoLine->setZ(-1);
|
|
}
|
|
noInfoLine->move( 0, temp->itemPos() );
|
|
noInfoLine->setSize( wid, temp->height());
|
|
noInfoLine->setPen( TQPen( Qt::NoPen ) );
|
|
noInfoLine->setBrush( noInfoLineBrush);
|
|
noInfoLine->show();
|
|
}
|
|
temp = temp->itemBelow ();
|
|
}
|
|
while ( itnoinfo.current() ) {
|
|
itnoinfo.current()->hide();
|
|
++itnoinfo;
|
|
}
|
|
|
|
}
|
|
|
|
void KDTimeTableWidget::computeTaskLinks()
|
|
{
|
|
//compute and show tasklinks
|
|
TQPtrListIterator<KDGanttViewTaskLink> it((myTaskLinkList));
|
|
for ( ; it.current(); ++it ) {
|
|
if (it.current()->isVisible())
|
|
it.current()->showMe(true);
|
|
else
|
|
it.current()->showMe(false);
|
|
}
|
|
}
|
|
|
|
// updateMyContent() can be blocked by blockUpdating( true ) or inc_blockUpdating()
|
|
// updateMyContent() is blocked, if the GanttView is hidden after startup
|
|
|
|
void KDTimeTableWidget::updateMyContent()
|
|
{
|
|
if ( flag_blockUpdating || int_blockUpdating ) {
|
|
// qDebug("KDTimeTableWidget::updateMyContent() blocked! ");
|
|
return;
|
|
}
|
|
//qDebug("KDTimeTableWidget::updateMyContent() ********************************* ");
|
|
/*
|
|
// debug output
|
|
KDGanttViewItem* temp = myGanttView->firstChild();
|
|
while (temp != 0) {
|
|
temp->printinfo(" " );
|
|
temp = temp->nextSibling();
|
|
}
|
|
*/
|
|
int hei = computeHeight();
|
|
minimumHeight = hei;
|
|
int viewport_hei = myGanttView->myCanvasView->viewport()->height();
|
|
if ( viewport_hei > hei )
|
|
hei = viewport_hei + 100;
|
|
if ( myGanttView->myTimeHeader->registerStartTime() )
|
|
return; // try again via timeheader computeTicks();
|
|
if ( myGanttView->myTimeHeader->registerEndTime() )
|
|
return; // try again via timeheader computeTicks();
|
|
if ( hei > height() ) {
|
|
if ( ! pendingWidth )
|
|
pendingWidth = width();
|
|
if ( pendingHeight < hei )
|
|
pendingHeight = hei;
|
|
}
|
|
if (pendingHeight > hei )
|
|
hei = pendingHeight;
|
|
if (hei > maximumComputedGridHeight)
|
|
{
|
|
maximumComputedGridHeight = hei;
|
|
// compute the background interval lines
|
|
myGanttView->myTimeHeader->computeIntervals( hei );
|
|
//compute VerticalGrid and column color
|
|
computeVerticalGrid();
|
|
}
|
|
computeTaskLinks();
|
|
computeHorizontalGrid();
|
|
computeDenseLines();
|
|
computeShowNoInformation();
|
|
//setAllChanged();
|
|
update();
|
|
if (pendingWidth && pendingHeight ) {
|
|
resize( pendingWidth, pendingHeight );
|
|
pendingWidth = 0;
|
|
pendingHeight = 0;
|
|
emit heightComputed( 0 );
|
|
|
|
}
|
|
pendingWidth = 0;
|
|
pendingHeight = 0;
|
|
//qDebug("KDTimeTableWidget::updateMyContent() -------------------------");
|
|
}
|
|
// used for blocking recursive methods
|
|
// e.g. KDGanttViewItem::setHighlight() and displaySubitemsAsGroup() == true
|
|
|
|
void KDTimeTableWidget::inc_blockUpdating( )
|
|
{
|
|
++ int_blockUpdating;
|
|
}
|
|
// used for blocking recursive methods
|
|
void KDTimeTableWidget::dec_blockUpdating( )
|
|
{
|
|
-- int_blockUpdating;
|
|
}
|
|
// if false(i.e. unblock), sets int_blockUpdating to 0
|
|
void KDTimeTableWidget::setBlockUpdating( bool block )
|
|
{
|
|
if ( !block )
|
|
int_blockUpdating = 0;
|
|
flag_blockUpdating = block;
|
|
}
|
|
bool KDTimeTableWidget::blockUpdating()
|
|
{
|
|
return flag_blockUpdating;
|
|
}
|
|
|
|
void KDTimeTableWidget::setShowTaskLinks( bool show )
|
|
{
|
|
taskLinksVisible = show;
|
|
updateMyContent();
|
|
}
|
|
bool KDTimeTableWidget::showTaskLinks()
|
|
{
|
|
return taskLinksVisible;
|
|
}
|
|
void KDTimeTableWidget::setHorBackgroundLines( int count, TQBrush brush )
|
|
{
|
|
denseLineBrush = brush;
|
|
denseLineCount = 0;
|
|
if ( count > 1 )
|
|
denseLineCount = count;
|
|
}
|
|
|
|
|
|
int KDTimeTableWidget::horBackgroundLines( TQBrush& brush )
|
|
{
|
|
brush = denseLineBrush;
|
|
return denseLineCount;
|
|
}
|
|
|
|
int KDTimeTableWidget::getCoordX( TQDateTime dt ) {
|
|
return myGanttView->myTimeHeader->getCoordX(dt);
|
|
}
|
|
|
|
/* ***************************************************************
|
|
KDTimeHeaderWidget:: KDTimeHeaderWidget
|
|
***************************************************************** */
|
|
KDTimeHeaderWidget:: KDTimeHeaderWidget( TQWidget* parent,KDGanttView* gant )
|
|
: TQWidget (parent)
|
|
{
|
|
myToolTip = new KDTimeHeaderToolTip(this,this);
|
|
mySizeHint = 0;
|
|
myGanttView = gant;
|
|
flagDoNotRecomputeAfterChange = true;
|
|
TQDateTime start = (TQDateTime::tqcurrentDateTime ()).addSecs(-3600);
|
|
setHorizonStart(start);
|
|
setHorizonEnd( start.addSecs(3600*2));
|
|
flagStartTimeSet = false;
|
|
flagEndTimeSet = false;
|
|
myCenterDateTime = TQDateTime::tqcurrentDateTime ();
|
|
setScale(KDGanttView::Auto);
|
|
//setScale(KDGanttView::Hour);
|
|
myMaxScale = KDGanttView::Month;
|
|
myMinScale = KDGanttView::Minute;
|
|
myAutoScaleMinorTickcount = 100;
|
|
setMajorScaleCount( 1 );
|
|
setMinorScaleCount( 1);
|
|
setMinimumColumnWidth( 5 );
|
|
setYearFormat(KDGanttView::FourDigit );
|
|
setHourFormat( KDGanttView::Hour_12 );
|
|
myZoomFactor = 1.0;
|
|
setWeekendBackgroundColor(TQColor(220,220,220) );
|
|
setWeekendDays( 6, 7 );
|
|
myGridMinorWidth = 0;
|
|
myPopupMenu = new TQPopupMenu(this);
|
|
TQPopupMenu * zoomPopupMenu = new TQPopupMenu(this);
|
|
myPopupMenu->insertItem (i18n("Zoom"),zoomPopupMenu, 1);
|
|
zoomPopupMenu->insertItem( i18n("Zoom to 100%"),this, TQT_SLOT(setSettings(int)),0 ,21,21 );
|
|
zoomPopupMenu->insertItem( i18n("Zoom to Fit"),this, TQT_SLOT(setSettings(int)),0 ,20,20 );
|
|
zoomPopupMenu->insertItem( i18n("Zoom In (x 2)"),this, TQT_SLOT(setSettings(int)),0 ,22,22 );
|
|
zoomPopupMenu->insertItem( i18n("Zoom In (x 6)"),this, TQT_SLOT(setSettings(int)),0 ,24,24 );
|
|
zoomPopupMenu->insertItem( i18n("Zoom In (x 12)"),this, TQT_SLOT(setSettings(int)),0 ,26,26 );
|
|
zoomPopupMenu->insertItem( i18n("Zoom Out (x 1/2)"),this, TQT_SLOT(setSettings(int)),0 ,23,23 );
|
|
zoomPopupMenu->insertItem( i18n("Zoom Out (x 1/6)"),this, TQT_SLOT(setSettings(int)),0 ,25,25 );
|
|
zoomPopupMenu->insertItem( i18n("Zoom Out (x 1/12)"),this, TQT_SLOT(setSettings(int)),0 ,27,27 );
|
|
scalePopupMenu = new TQPopupMenu(this);
|
|
myPopupMenu->insertItem (i18n("Scale"),scalePopupMenu, 2);
|
|
scalePopupMenu->insertItem( i18n("Minute"),this, TQT_SLOT(setSettings(int)),0 ,1,1 );
|
|
scalePopupMenu->insertItem( i18n("Hour"),this, TQT_SLOT(setSettings(int)),0 ,2,2 );
|
|
scalePopupMenu->insertItem( i18n("Day"),this, TQT_SLOT(setSettings(int)),0 ,3,3 );
|
|
scalePopupMenu->insertItem( i18n("Week"),this, TQT_SLOT(setSettings(int)),0 ,4,4 );
|
|
scalePopupMenu->insertItem( i18n("Month"),this, TQT_SLOT(setSettings(int)),0 ,5,5 );
|
|
scalePopupMenu->insertItem( i18n("Auto"),this, TQT_SLOT(setSettings(int)),0 ,6,6 );
|
|
scalePopupMenu->setCheckable ( true );
|
|
timePopupMenu = new TQPopupMenu(this);
|
|
myPopupMenu->insertItem (i18n("Time Format"),timePopupMenu, 3);
|
|
timePopupMenu->insertItem( i18n("24 Hour"),this, TQT_SLOT(setSettings(int)),0 ,40,40 );
|
|
timePopupMenu->insertItem( i18n("12 PM Hour"),this, TQT_SLOT(setSettings(int)),0 ,41,41 );
|
|
timePopupMenu->insertItem( i18n("24:00 Hour"),this, TQT_SLOT(setSettings(int)),0 ,42,42 );
|
|
yearPopupMenu = new TQPopupMenu(this);
|
|
myPopupMenu->insertItem (i18n("Year Format"),yearPopupMenu, 4);
|
|
yearPopupMenu->insertItem( i18n("Four Digit"),this, TQT_SLOT(setSettings(int)),0 ,50,50 );
|
|
yearPopupMenu->insertItem( i18n("Two Digit"),this, TQT_SLOT(setSettings(int)),0 ,51,51 );
|
|
yearPopupMenu->insertItem( i18n("Two Digit Apostrophe"),this, TQT_SLOT(setSettings(int)),0 ,52,52 );
|
|
yearPopupMenu->insertItem( i18n("No Date on Minute/Hour Scale"),this, TQT_SLOT(setSettings(int)),0 ,53,53 );
|
|
|
|
gridPopupMenu = new TQPopupMenu(this);
|
|
myPopupMenu->insertItem (i18n("Grid"),gridPopupMenu,5);
|
|
gridPopupMenu->insertItem( i18n("Show Minor Grid"),this, TQT_SLOT(setSettings(int)),0 ,10,10 );
|
|
gridPopupMenu->insertItem( i18n("Show Major Grid"),this, TQT_SLOT(setSettings(int)),0 ,11,11 );
|
|
gridPopupMenu->insertItem( i18n("Show No Grid"),this, TQT_SLOT(setSettings(int)),0 ,12,12 );
|
|
myPopupMenu->insertItem( i18n("Print"),this, TQT_SLOT(setSettings(int)),0 ,30,30 );
|
|
connect(myPopupMenu, TQT_SIGNAL ( aboutToShow () ) , this, TQT_SLOT( preparePopupMenu() )) ;
|
|
flagZoomToFit = false;
|
|
setShowMinorTicks( true );
|
|
myRealEnd = myHorizonEnd;
|
|
myRealStart = myHorizonStart;
|
|
autoComputeTimeLine = true;
|
|
flagDoNotRecomputeAfterChange = false;
|
|
flagDoNotRepaintAfterChange = false;
|
|
setShowPopupMenu(false,false,false,false,false,false,false);
|
|
for (int j =1;j<8;++j)
|
|
weekdayColor[j] = Qt::white;
|
|
myMinimumWidth = 0;
|
|
mouseDown = false;
|
|
beginMouseDown = 0;
|
|
endMouseDown = 0;
|
|
}
|
|
|
|
KDTimeHeaderWidget::~KDTimeHeaderWidget()
|
|
{
|
|
delete myToolTip;
|
|
}
|
|
void KDTimeHeaderWidget::preparePopupMenu()
|
|
{
|
|
myPopupMenu->setItemVisible ( 1, flagShowZoom );
|
|
myPopupMenu->setItemVisible ( 2, flagShowScale );
|
|
myPopupMenu->setItemVisible ( 3, flagShowTime );
|
|
myPopupMenu->setItemVisible ( 4, flagShowYear );
|
|
myPopupMenu->setItemVisible ( 5, flagShowGrid);
|
|
myPopupMenu->setItemVisible ( 30, flagShowPrint );
|
|
if (flagZoomToFit)
|
|
myPopupMenu->changeItem( 1, i18n("Zoom (Fit)"));
|
|
else
|
|
myPopupMenu->changeItem( 1, i18n("Zoom (%1)").arg( TQString::number( zoomFactor(), 'f',3) ) );
|
|
int i = 0;
|
|
int id;
|
|
while ( ( id = scalePopupMenu->idAt( i++ )) >= 0 ) {
|
|
scalePopupMenu->setItemChecked ( id, false );
|
|
}
|
|
scalePopupMenu->setItemChecked ( scalePopupMenu->idAt ( (int)( scale()) ), true );
|
|
i = 0;
|
|
while ( ( id = timePopupMenu->idAt( i++ )) >= 0 ) {
|
|
timePopupMenu->setItemChecked ( id, false );
|
|
}
|
|
timePopupMenu->setItemChecked ( timePopupMenu->idAt ( (int)( hourFormat()) ), true );
|
|
i = 0;
|
|
while ( ( id = yearPopupMenu->idAt( i++ )) >= 0 ) {
|
|
yearPopupMenu->setItemChecked ( id, false );
|
|
}
|
|
yearPopupMenu->setItemChecked ( yearPopupMenu->idAt ( (int)( yearFormat()) ), true );
|
|
i = 0;
|
|
while ( ( id = gridPopupMenu->idAt( i++ )) >= 0 ) {
|
|
gridPopupMenu->setItemChecked ( id, false );
|
|
}
|
|
|
|
gridPopupMenu->setItemChecked ( gridPopupMenu->idAt ( 0 ), showMinorTicks() );
|
|
gridPopupMenu->setItemChecked ( gridPopupMenu->idAt ( 1 ), showMajorTicks() );
|
|
gridPopupMenu->setItemChecked ( gridPopupMenu->idAt ( 2 ),
|
|
!(showMajorTicks() || showMinorTicks()) );
|
|
|
|
|
|
}
|
|
|
|
TQString KDTimeHeaderWidget::getToolTipText(TQPoint p)
|
|
{
|
|
return KGlobal::locale()->formatDateTime(getDateTimeForIndex(p.x()));
|
|
}
|
|
void KDTimeHeaderWidget::addTickRight( int num )
|
|
{
|
|
int secs = ((num*getTickTime())-30);
|
|
setHorizonEnd(getDateTimeForIndex(width()).addSecs(secs));
|
|
//tqApp->processEvents();
|
|
}
|
|
|
|
void KDTimeHeaderWidget::addTickLeft( int num )
|
|
{
|
|
int secs = ((num*getTickTime())-30);
|
|
setHorizonStart(getDateTimeForIndex(0).addSecs(-secs));
|
|
//tqApp->processEvents();
|
|
}
|
|
// the time in secs of one minor grid tick
|
|
int KDTimeHeaderWidget::getTickTime()
|
|
{
|
|
return getDateTimeForIndex(0).secsTo(getDateTimeForIndex(myGridMinorWidth));
|
|
}
|
|
|
|
|
|
void KDTimeHeaderWidget::checkWidth( int wid )
|
|
{
|
|
// we have to set the minimum width one pixel higher than the
|
|
// viewport width of the canvas view in order to
|
|
// avoid that the horiz. scrollbar of the canvasview is hidden
|
|
myMinimumWidth = wid + 1;
|
|
if ( myMinimumWidth > width() ||
|
|
( myMinimumWidth > mySizeHint &&
|
|
myMinimumWidth < (width() - myGridMinorWidth )) )
|
|
computeTicks();
|
|
|
|
// Update (horizontal) scrollbar,
|
|
// We probably come from an external resize and then we must
|
|
// calculate on basis of myCanvasView.
|
|
// (NOTE: we have disconnected the auto TQScrollView scrollbar update)
|
|
if (myGanttView && myGanttView->myCanvasView)
|
|
myGanttView->myCanvasView->updateScrollBars();
|
|
}
|
|
|
|
bool KDTimeHeaderWidget::registerStartTime()
|
|
{
|
|
|
|
TQListViewItemIterator it( myGanttView->myListView );
|
|
if (!flagStartTimeSet) {
|
|
TQDateTime temp , time;
|
|
KDGanttViewItem* item;
|
|
bool setNewTime = false;
|
|
item = (KDGanttViewItem*)myGanttView->myListView->firstChild();
|
|
if ( item ) {
|
|
temp = item->startTime();
|
|
time = temp;
|
|
// while ( item != 0)
|
|
for ( ; it.current(); ++it ) {
|
|
item = ( KDGanttViewItem* )it.current();
|
|
if (item->isVisibleInGanttView) {
|
|
if ( !setNewTime )
|
|
temp = item->startTime();
|
|
switch( item->type() ) {
|
|
case KDGanttViewItem::Event:
|
|
time = ((KDGanttViewEventItem*)item)->leadTime();
|
|
setNewTime = true;
|
|
break;
|
|
case KDGanttViewItem::Summary:
|
|
case KDGanttViewItem::Task:
|
|
time = item->startTime();
|
|
setNewTime = true;
|
|
break;
|
|
default:
|
|
time = temp;
|
|
}
|
|
if ( time < temp) {
|
|
temp = time ;
|
|
}
|
|
}
|
|
}
|
|
if ( setNewTime )
|
|
if ( myHorizonStart != temp) {
|
|
myHorizonStart = temp;
|
|
computeTicks();
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
|
|
bool KDTimeHeaderWidget::registerEndTime()
|
|
{
|
|
if (!flagEndTimeSet) {
|
|
TQDateTime temp , time;
|
|
KDGanttViewItem* item;
|
|
bool setNewTime = false;
|
|
item = (KDGanttViewItem*)myGanttView->myListView->firstChild();
|
|
if ( item ) {
|
|
temp = item->startTime();
|
|
time = temp;
|
|
TQListViewItemIterator it( myGanttView->myListView );
|
|
for ( ; it.current(); ++it ) {
|
|
item = ( KDGanttViewItem* )it.current();
|
|
if (item->isVisibleInGanttView) {
|
|
if ( !setNewTime )
|
|
temp = item->startTime();
|
|
switch( item->type() ) {
|
|
case KDGanttViewItem::Event:
|
|
time = ((KDGanttViewEventItem*)item)->startTime();
|
|
setNewTime = true;
|
|
break;
|
|
case KDGanttViewItem::Summary:
|
|
time = item->endTime();
|
|
if ( time < ((KDGanttViewSummaryItem*)item)->actualEndTime())
|
|
time = ((KDGanttViewSummaryItem*)item)->actualEndTime();
|
|
setNewTime = true;
|
|
break;
|
|
case KDGanttViewItem::Task:
|
|
time = item->endTime();
|
|
setNewTime = true;
|
|
break;
|
|
default:
|
|
time = temp;
|
|
}
|
|
if ( time > temp)
|
|
temp = time ;
|
|
}
|
|
}
|
|
|
|
if ( setNewTime )
|
|
if (myHorizonEnd != temp ) {
|
|
myHorizonEnd = temp;
|
|
computeTicks();
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
|
|
void KDTimeHeaderWidget::setShowPopupMenu( bool show,
|
|
bool showZoom,
|
|
bool showScale,
|
|
bool showTime,
|
|
bool showYear,
|
|
bool showGrid,
|
|
bool showPrint)
|
|
{
|
|
flagShowPopupMenu = show;
|
|
flagShowZoom = showZoom;
|
|
flagShowScale = showScale;
|
|
flagShowTime = showTime;
|
|
flagShowYear = showYear;
|
|
flagShowGrid = showGrid;
|
|
flagShowPrint = showPrint;
|
|
}
|
|
|
|
|
|
bool KDTimeHeaderWidget::showPopupMenu() const
|
|
{
|
|
return flagShowPopupMenu;
|
|
}
|
|
|
|
void KDTimeHeaderWidget::setSettings(int i)
|
|
{
|
|
|
|
switch (i) {
|
|
case 1:
|
|
setScale(KDGanttView::Minute );
|
|
break;
|
|
case 2:
|
|
setScale(KDGanttView::Hour );
|
|
break;
|
|
case 3:
|
|
setScale(KDGanttView::Day );
|
|
break;
|
|
case 4:
|
|
setScale(KDGanttView::Week );
|
|
break;
|
|
case 5:
|
|
setScale(KDGanttView::Month );
|
|
break;
|
|
case 6:
|
|
setScale(KDGanttView::Auto );
|
|
break;
|
|
case 10:
|
|
setShowMinorTicks( true );
|
|
break;
|
|
case 11:
|
|
setShowMajorTicks( true );{
|
|
|
|
}
|
|
break;
|
|
case 12:
|
|
setShowMajorTicks( false );
|
|
setShowMinorTicks( false);
|
|
break;
|
|
case 20:
|
|
zoomToFit();
|
|
break;
|
|
case 21:
|
|
zoom(1.0);
|
|
break;
|
|
case 22:
|
|
zoom(2.0,false);
|
|
break;
|
|
case 23:
|
|
zoom(0.5,false);
|
|
break;
|
|
case 24:
|
|
zoom(6.0,false);
|
|
break;
|
|
case 25:
|
|
zoom(0.16666,false);
|
|
break;
|
|
case 26:
|
|
zoom(12.0,false);
|
|
break;
|
|
case 27:
|
|
zoom(0.08333,false);
|
|
break;
|
|
case 30:
|
|
myGanttView->print();
|
|
break;
|
|
case 40:
|
|
case 41:
|
|
case 42:
|
|
setHourFormat( (KDGanttView::HourFormat) (i - 40) );
|
|
break;
|
|
case 50:
|
|
case 51:
|
|
case 52:
|
|
case 53:
|
|
setYearFormat( (KDGanttView::YearFormat) ( i - 50) );
|
|
break;
|
|
|
|
case 60:
|
|
|
|
break;
|
|
|
|
case 61:
|
|
|
|
break;
|
|
|
|
case 62:
|
|
|
|
break;
|
|
|
|
case 63:
|
|
|
|
break;
|
|
|
|
case 64:
|
|
|
|
break;
|
|
}
|
|
// myGanttView->myTimeTable->updateMyContent();
|
|
}
|
|
void KDTimeHeaderWidget::zoomToFit()
|
|
{
|
|
flagZoomToFit = true;
|
|
computeTicks();
|
|
// Since we have disconnected autoupdate of scrollbars, we must do it ourselves
|
|
if (myGanttView && myGanttView->myCanvasView)
|
|
myGanttView->myCanvasView->updateScrollBars();
|
|
}
|
|
double KDTimeHeaderWidget::zoomFactor()
|
|
{
|
|
return myZoomFactor;
|
|
}
|
|
double KDTimeHeaderWidget::secsFromTo( TQDateTime begin, TQDateTime end )
|
|
{
|
|
TQDateTime temp;
|
|
double secs, days;
|
|
days = begin.daysTo(end);
|
|
temp = begin.addDays((int) days);
|
|
secs = temp.secsTo(end);
|
|
secs += days * 86400.0;
|
|
return secs;
|
|
}
|
|
|
|
|
|
void KDTimeHeaderWidget::zoomToSelection( TQDateTime start, TQDateTime end)
|
|
{
|
|
if (start < myHorizonStart) {
|
|
myHorizonStart = start;
|
|
flagStartTimeSet = true;
|
|
//qDebug("myHorizonStart reset");
|
|
}
|
|
if (end > myHorizonEnd) {
|
|
myHorizonEnd = end;
|
|
flagEndTimeSet = true;
|
|
//qDebug("myHorizonEnd reset ");
|
|
}
|
|
flagDoNotRepaintAfterChange = true;//avoid flicker
|
|
zoom(1.0); // set to 100%
|
|
int viewWid = myGanttView->myCanvasView->viewport()->width();
|
|
int timeWid = getCoordX(end)-getCoordX(start);
|
|
double fac;
|
|
fac = ( (double)viewWid)/((double) timeWid );
|
|
zoom (fac);
|
|
timeWid = getCoordX(end)-getCoordX(start);
|
|
int count = 0;
|
|
int lastScaleCount = 0;
|
|
while (timeWid >viewWid || ( ( myRealMinorScaleCount != lastScaleCount) && timeWid*2 < viewWid ) ) {
|
|
lastScaleCount = myRealMinorScaleCount;
|
|
fac = (fac * (double)viewWid)/(double)timeWid;
|
|
zoom (fac);
|
|
timeWid = getCoordX(end)-getCoordX(start);
|
|
if ( count++ > 10 ) {
|
|
//qDebug("Exiting while loop in zoomToSelection ");
|
|
break;
|
|
}
|
|
}
|
|
flagDoNotRepaintAfterChange = false;
|
|
updateTimeTable();
|
|
tqrepaint();
|
|
moveTimeLineTo((getCoordX(start)-(viewWid-timeWid)/2));
|
|
// Since we have disconnected autoupdate of scrollbars, we must do it ourselves
|
|
if (myGanttView && myGanttView->myCanvasView)
|
|
myGanttView->myCanvasView->updateScrollBars();
|
|
}
|
|
void KDTimeHeaderWidget::moveTimeLineTo(int X)
|
|
{
|
|
int Y = myGanttView->myCanvasView->contentsY ();
|
|
myGanttView->myCanvasView->setContentsPos (X, Y );
|
|
}
|
|
|
|
void KDTimeHeaderWidget::zoom(double factor, bool absolute)
|
|
{
|
|
flagZoomToFit = false;
|
|
if ( factor < 0.000001 ) {
|
|
qDebug("KDGanttView::zoom() : Zoom factor to low. Nothing zoomed. ");
|
|
return;
|
|
}
|
|
double newZoom;
|
|
if (absolute)
|
|
newZoom = factor;
|
|
else
|
|
newZoom = myZoomFactor * factor;
|
|
double relativeZoom;
|
|
relativeZoom = newZoom / myZoomFactor;
|
|
|
|
//qDebug("zooming relative %f ", relativeZoom);
|
|
//qDebug("zooming absolute %f ", newZoom);
|
|
int viewWid = myGanttView->myCanvasView->viewport()->width();
|
|
if ( width() * relativeZoom < viewWid && ( newZoom > 1.01 || newZoom < 0.99 ) ) {
|
|
qDebug("KDGanttView::zoom() : Zoom factor to low for current horizon. ");
|
|
// qDebug("zooming relative %f, zooming absolute %f, viewWidth %d width %d ", relativeZoom, newZoom, viewWid, width() );
|
|
return;
|
|
}
|
|
myZoomFactor = newZoom;
|
|
computeTicks();
|
|
// Since we have disconnected autoupdate of scrollbars, we must do it ourselves
|
|
if (myGanttView && myGanttView->myCanvasView)
|
|
myGanttView->myCanvasView->updateScrollBars();
|
|
}
|
|
|
|
/*!
|
|
Sets the start of the horizon of the Gantt chart. If \a start is
|
|
null, the horizon start is computed automatically.
|
|
|
|
\param start the start of the horizon
|
|
\sa horizonStart()
|
|
*/
|
|
void KDTimeHeaderWidget::setHorizonStart( const TQDateTime& start )
|
|
{
|
|
myHorizonStart = start;
|
|
flagStartTimeSet = true;
|
|
computeTicks();
|
|
}
|
|
|
|
|
|
/*!
|
|
Returns the start of the horizon of the Gantt chart.
|
|
|
|
\return the start of the horizon of the Gantt chart
|
|
\sa setHorizonStart()
|
|
*/
|
|
TQDateTime KDTimeHeaderWidget::horizonStart() const
|
|
{
|
|
return myHorizonStart;
|
|
}
|
|
|
|
|
|
/*!
|
|
Sets the end of the horizon of the Gantt chart. If \a end is
|
|
null, the horizon end is computed automatically.
|
|
|
|
\param end the end of the horizon
|
|
\sa setHorizonEnd()
|
|
*/
|
|
void KDTimeHeaderWidget::setHorizonEnd( const TQDateTime& start )
|
|
{
|
|
myHorizonEnd = start;
|
|
flagEndTimeSet = true;
|
|
computeTicks();
|
|
|
|
}
|
|
|
|
|
|
/*!
|
|
Returns the end of the horizon of the Gantt chart.
|
|
|
|
\return the end of the horizon of the Gantt chart
|
|
\sa setHorizonEnd()
|
|
*/
|
|
TQDateTime KDTimeHeaderWidget::horizonEnd() const
|
|
{
|
|
return myHorizonEnd;
|
|
}
|
|
|
|
|
|
/*!
|
|
Configures the unit of the lower scale of the header. The higher
|
|
unit is computed automatically.
|
|
Resets the zoomng factor to 1 (i.e. 100%).
|
|
|
|
\param unit the unit of the lower scale of the header.
|
|
\sa scale()
|
|
*/
|
|
void KDTimeHeaderWidget::setScale(Scale unit )
|
|
{
|
|
myScale = unit;
|
|
myZoomFactor = 1.0;
|
|
computeTicks();
|
|
// Since we have disconnected autoupdate of scrollbars, we must do it ourselves
|
|
if (myGanttView && myGanttView->myCanvasView)
|
|
myGanttView->myCanvasView->updateHorScrollBar();
|
|
}
|
|
|
|
|
|
/*!
|
|
Returns the unit of the lower scale of the header.
|
|
|
|
\return the unit of the lower scale of the header.
|
|
\sa setScale()
|
|
*/
|
|
KDTimeHeaderWidget::Scale KDTimeHeaderWidget::scale() const
|
|
{
|
|
return myScale;
|
|
}
|
|
|
|
|
|
/*!
|
|
Sets the maximal allowed time scale of the lower scale of the header.
|
|
|
|
\param unit the unit of the lower scale of the header.
|
|
\sa scale()
|
|
*/
|
|
void KDTimeHeaderWidget::setMaximumScale( Scale unit )
|
|
{
|
|
myMaxScale = unit;
|
|
computeTicks();
|
|
}
|
|
|
|
|
|
/*!
|
|
Returns the maximal allowed time scale of the lower scale of the header.
|
|
|
|
\return the unit of the lower scale of the header.
|
|
\sa setScale()
|
|
*/
|
|
KDTimeHeaderWidget::Scale KDTimeHeaderWidget::maximumScale() const
|
|
{
|
|
return myMaxScale;
|
|
}
|
|
|
|
|
|
/*!
|
|
Sets the minimal allowed time scale of the lower scale of the header.
|
|
|
|
\param unit the unit of the lower scale of the header.
|
|
\sa scale()
|
|
*/
|
|
void KDTimeHeaderWidget::setMinimumScale( Scale unit )
|
|
{
|
|
myMinScale = unit;
|
|
computeTicks();
|
|
}
|
|
|
|
|
|
/*!
|
|
Returns the minimal allowed time scale of the lower scale of the header.
|
|
|
|
\return the unit of the lower scale of the header.
|
|
\sa setScale()
|
|
*/
|
|
KDTimeHeaderWidget::Scale KDTimeHeaderWidget::minimumScale() const
|
|
{
|
|
return myMinScale;
|
|
}
|
|
|
|
|
|
/*!
|
|
Sets the minimum width a column needs to have. If the size of the
|
|
Gantt chart and the scale would make it necessary to go below this
|
|
limit otherwise, the chart will automatically be made less exact.
|
|
|
|
\param width the minimum column width
|
|
\sa minimumColumnWidth()
|
|
*/
|
|
void KDTimeHeaderWidget::setMinimumColumnWidth( int width )
|
|
{
|
|
myMinimumColumWidth = width;
|
|
computeTicks();
|
|
}
|
|
|
|
|
|
/*!
|
|
Returns the minimum width a column needs to have.
|
|
|
|
\return the column minimum width
|
|
\sa setMinimumColumnWidth()
|
|
*/
|
|
int KDTimeHeaderWidget::minimumColumnWidth() const
|
|
{
|
|
return myMinimumColumWidth;
|
|
}
|
|
|
|
|
|
/*!
|
|
Specifies the format in which to display years. If no years are
|
|
shown, this method has no effect.
|
|
|
|
\param format the year format
|
|
\sa yearFormat(), setHourFormat(), hourFormat()
|
|
*/
|
|
void KDTimeHeaderWidget::setYearFormat( YearFormat format )
|
|
{
|
|
myYearFormat = format;
|
|
computeTicks();
|
|
}
|
|
|
|
|
|
/*!
|
|
Returns the format in which to display years.
|
|
|
|
\return the year format
|
|
\sa setYearFormat(), setHourFormat(), hourFormat()
|
|
*/
|
|
KDTimeHeaderWidget::YearFormat KDTimeHeaderWidget::yearFormat() const
|
|
{
|
|
return myYearFormat;
|
|
}
|
|
|
|
|
|
/*!
|
|
Specifies the format in which to display hours. If no hours are
|
|
shown, this method has no effect.
|
|
|
|
\param format the hour format
|
|
\sa hourFormat(), setYearFormat(), yearFormat()
|
|
*/
|
|
void KDTimeHeaderWidget::setHourFormat( HourFormat format )
|
|
{
|
|
myHourFormat = format;
|
|
computeTicks();
|
|
}
|
|
|
|
|
|
/*!
|
|
Returns the format in which to display hours.
|
|
|
|
\return the hour format
|
|
\sa setHourFormat(), setYearFormat(), yearFormat()
|
|
*/
|
|
KDTimeHeaderWidget::HourFormat KDTimeHeaderWidget::hourFormat() const
|
|
{
|
|
return myHourFormat;
|
|
}
|
|
|
|
|
|
/*!
|
|
Specifies whether ticks should be shown on the major scale.
|
|
|
|
\param show true in order to show ticks, false in order to hide them
|
|
\sa showMajorTicks(), setShowMinorTicks(), showMinorTicks()
|
|
*/
|
|
void KDTimeHeaderWidget::setShowMajorTicks( bool show )
|
|
{
|
|
flagShowMajorTicks = show;
|
|
if (show) {
|
|
setShowMinorTicks(false);
|
|
}
|
|
updateTimeTable();
|
|
}
|
|
|
|
|
|
/*!
|
|
Returns whether ticks are shown on the major scale.
|
|
|
|
\return true if ticks are shown on the major scale
|
|
\sa setShowMajorTicks(), setShowMinorTicks(), showMinorTicks()
|
|
*/
|
|
bool KDTimeHeaderWidget::showMajorTicks() const
|
|
{
|
|
return flagShowMajorTicks;
|
|
}
|
|
|
|
|
|
/*!
|
|
Specifies whether ticks should be shown on the minor scale.
|
|
|
|
\param show true in order to show ticks, false in order to hide them
|
|
\sa showMinorTicks(), setShowMajorTicks(), showMajorTicks()
|
|
*/
|
|
void KDTimeHeaderWidget::setShowMinorTicks( bool show )
|
|
{
|
|
flagShowMinorTicks = show;
|
|
if (show)
|
|
setShowMajorTicks(false );
|
|
//tqrepaintMe();
|
|
updateTimeTable();
|
|
}
|
|
|
|
|
|
/*!
|
|
Returns whether ticks are shown on the minor scale.
|
|
|
|
\return true if ticks are shown on the minor scale
|
|
\sa setShowMinorTicks(), setShowMajorTicks(), showMajorTicks()
|
|
*/
|
|
bool KDTimeHeaderWidget::showMinorTicks() const
|
|
{
|
|
return flagShowMinorTicks;
|
|
}
|
|
|
|
|
|
/*!
|
|
Sets the background color for the column closest to \a column.
|
|
|
|
\param column the column to set the background color for
|
|
\param color the background color
|
|
\sa columnBackgroundColor(), setWeekendBackgroundColor(),
|
|
weekendBackgroundColor()
|
|
*/
|
|
void KDTimeHeaderWidget::setColumnBackgroundColor( const TQDateTime& column,
|
|
const TQColor& color,
|
|
Scale mini, Scale maxi )
|
|
{
|
|
ColumnColorList::iterator it;
|
|
for ( it = ccList.begin(); it != ccList.end(); ++it ) {
|
|
if ((*it).datetime == column) {
|
|
(*it).color = color;
|
|
(*it).minScaleView = mini;
|
|
(*it).maxScaleView = maxi;
|
|
return;
|
|
}
|
|
}
|
|
DateTimeColor newItem;
|
|
newItem.datetime = column;
|
|
newItem.color = color;
|
|
newItem.minScaleView = mini;
|
|
newItem.maxScaleView = maxi;
|
|
ccList.append(newItem);
|
|
updateTimeTable();
|
|
}
|
|
|
|
void KDTimeHeaderWidget::computeIntervals( int height )
|
|
{
|
|
IntervalColorList::const_iterator it;
|
|
for ( it = icList.begin(); it != icList.end(); ++it ) {
|
|
(*it)->tqlayout( this, height );
|
|
}
|
|
}
|
|
|
|
void KDTimeHeaderWidget::addIntervalBackgroundColor( KDIntervalColorRectangle* newItem )
|
|
{
|
|
icList.append(newItem);
|
|
updateTimeTable();
|
|
}
|
|
|
|
#if 0
|
|
bool KDTimeHeaderWidget::changeBackgroundInterval( const TQDateTime& oldstart,
|
|
const TQDateTime& oldend,
|
|
const TQDateTime& newstart,
|
|
const TQDateTime& newend )
|
|
{
|
|
IntervalColorList::iterator it;
|
|
for ( it = icList.begin(); it != icList.end(); ++it ) {
|
|
if ((*it).datetime == oldstart && (*it).end == oldend ) {
|
|
IntervalColorList::iterator it2;
|
|
for ( it2 = icList.begin(); it2 != icList.end(); ++it2 ) {
|
|
if ((*it2).datetime == newstart && (*it2).end == newend )
|
|
return false;
|
|
}
|
|
(*it).datetime = newstart;
|
|
(*it).end = newend;
|
|
updateTimeTable();
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
bool KDTimeHeaderWidget::deleteBackgroundInterval( const TQDateTime& start,
|
|
const TQDateTime& end)
|
|
{
|
|
IntervalColorList::iterator it;
|
|
for ( it = icList.begin(); it != icList.end(); ++it ) {
|
|
if ((*it).datetime == start && (*it).end == end ) {
|
|
//delete (*it).canvasLine;
|
|
delete (*it).canvasRect;
|
|
icList.remove(it);
|
|
updateTimeTable();
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void KDTimeHeaderWidget::setIntervalBackgroundColor( const TQDateTime& start,
|
|
const TQDateTime& end,
|
|
const TQColor& color,
|
|
Scale mini ,
|
|
Scale maxi )
|
|
{
|
|
|
|
IntervalColorList::iterator it;
|
|
for ( it = icList.begin(); it != icList.end(); ++it ) {
|
|
if ((*it).datetime == start && (*it).end == end ) {
|
|
(*it).color = color;
|
|
(*it).minScaleView = mini;
|
|
(*it).maxScaleView = maxi;
|
|
return;
|
|
}
|
|
}
|
|
DateTimeColor newItem;
|
|
if ( start <= end ) {
|
|
newItem.datetime = start;
|
|
newItem.end = end;
|
|
} else {
|
|
newItem.datetime = end;
|
|
newItem.end = start;
|
|
}
|
|
newItem.color = color;
|
|
newItem.minScaleView = mini;
|
|
newItem.maxScaleView = maxi;
|
|
//newItem.canvasLine = new KDCanvasLine(myGanttView->myTimeTable,0,Type_is_KDGanttGridItem);
|
|
newItem.canvasRect = new KDCanvasRectangle(myGanttView->myTimeTable,0,Type_is_KDGanttGridItem);
|
|
newItem.canvasRect->setZ(-19);
|
|
icList.append(newItem);
|
|
updateTimeTable();
|
|
}
|
|
#endif
|
|
|
|
void KDTimeHeaderWidget::clearBackgroundColor()
|
|
{
|
|
|
|
IntervalColorList::iterator itic;
|
|
for ( itic = icList.begin(); itic != icList.end(); ++itic ) {
|
|
delete (*itic);
|
|
}
|
|
ccList.clear();
|
|
icList.clear();
|
|
updateTimeTable();
|
|
}
|
|
TQDateTime KDTimeHeaderWidget::getDateTimeForIndex(int X, bool local )
|
|
{
|
|
int coordX = X;
|
|
if ( !local ) {
|
|
TQPoint p = TQPoint ( X, 1 );
|
|
coordX = myGanttView->myTimeHeaderScroll->viewportToContents(myGanttView->myTimeHeaderScroll->mapFromGlobal( p )).x();
|
|
|
|
}
|
|
double secs = (secsFromTo( myRealStart, myRealEnd ) * ((double)coordX))/(double)width();
|
|
double days = secs/86400.0;
|
|
secs = secs - ( ((int) days) *86400.0 );
|
|
return (myRealStart.addDays ( (int) days )).addSecs( (int) secs);
|
|
}
|
|
|
|
//FIXME: This doesn't work quite intuitively (imho) when scale is day
|
|
// and each column containes more than 1 day:
|
|
// 1) If a column includes a weekend day, the whole column gets weekend color,
|
|
// 2) If a column includes 7 days, either *all* columns get weekend color, or
|
|
// *none* get weekend color (haven't figured out why)
|
|
// Proposal: Only use weekend color if the whole column is a weekend.
|
|
// Alt: Color the area that actually is the weekend.
|
|
bool KDTimeHeaderWidget::getColumnColor(TQColor& col,int coordLow, int coordHigh)
|
|
{
|
|
if (!flagShowMajorTicks && !flagShowMinorTicks)
|
|
return false;
|
|
TQDateTime start,end;
|
|
start = getDateTimeForIndex(coordLow);
|
|
end = getDateTimeForIndex(coordHigh).addSecs(-1);
|
|
Scale tempScale = myRealScale;
|
|
if (flagShowMajorTicks)
|
|
switch (myRealScale)
|
|
{
|
|
case KDGanttView::Minute: tempScale = KDGanttView::Hour; break;
|
|
case KDGanttView::Hour: tempScale = KDGanttView::Day ; break;
|
|
case KDGanttView::Day: tempScale = KDGanttView::Week ; break;
|
|
case KDGanttView::Week: tempScale = KDGanttView::Month ; break;
|
|
case KDGanttView::Month: return false ; break;
|
|
case KDGanttView::Auto: return false ; break;
|
|
}
|
|
//check defined column color
|
|
ColumnColorList::iterator it;
|
|
for ( it = ccList.begin(); it != ccList.end(); ++it ) {
|
|
if ((*it).datetime >= start && (*it).datetime <= end) {
|
|
if (tempScale >= (*it).minScaleView && tempScale <= (*it).maxScaleView ) {
|
|
col = (*it).color;
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (tempScale > KDGanttView::Day) return false;
|
|
|
|
start = getDateTimeForIndex((coordLow+coordHigh)/2);
|
|
int day = start.date().dayOfWeek ();
|
|
//checkweekdaycolor
|
|
if (weekdayColor[day] != Qt::white) {
|
|
col = weekdayColor[day];
|
|
return true;
|
|
}
|
|
//checkweekendcolor
|
|
int endday = myWeekendDaysEnd;
|
|
col = myWeekendBackgroundColor;
|
|
if (myWeekendDaysStart > myWeekendDaysEnd)
|
|
endday +=7;
|
|
if (day >= myWeekendDaysStart && day <= endday) {
|
|
return true;
|
|
} else {
|
|
if (day+7 >= myWeekendDaysStart && day+7 <= endday) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/*!
|
|
Returns the background color for the column closes to \a column.
|
|
|
|
\param column the column to query the background color for
|
|
\return the background color of the specified column
|
|
\sa setColumnBackgroundColor(), setWeekendBackgroundColor(),
|
|
weekendBackgroundColor()
|
|
*/
|
|
TQColor KDTimeHeaderWidget::columnBackgroundColor( const TQDateTime& column ) const
|
|
{
|
|
TQColor c;
|
|
c = white;
|
|
ColumnColorList::const_iterator ite;
|
|
for ( ite = ccList.begin(); ite != ccList.end(); ++ite ) {
|
|
if ((*ite).datetime == column) {
|
|
c = (*ite).color;
|
|
}
|
|
}
|
|
return c;
|
|
}
|
|
|
|
|
|
/*!
|
|
Specifies the background color for weekend days. If no individual
|
|
days are visible on the Gantt chart, this method has no visible
|
|
effect.
|
|
|
|
\param color the background color to use for weekend days.
|
|
\sa weekendBackgroundColor(), setWeekendDays(), weekendDays()
|
|
*/
|
|
void KDTimeHeaderWidget::setWeekendBackgroundColor( const TQColor& color )
|
|
{
|
|
myWeekendBackgroundColor = color ;
|
|
updateTimeTable();
|
|
}
|
|
|
|
|
|
/*!
|
|
Returns the background color for weekend days.
|
|
|
|
\return the background color for weekend days
|
|
\sa setWeekendBackgroundColor(), setWeekendDays(), weekendDays()
|
|
*/
|
|
TQColor KDTimeHeaderWidget::weekendBackgroundColor() const
|
|
{
|
|
return myWeekendBackgroundColor;
|
|
}
|
|
|
|
/*!
|
|
Specifies the background color for week days. If no individual
|
|
days are visible on the Gantt chart, this method has no visible
|
|
effect. The days are specified as an interval of integer values
|
|
where 1 means Monday and 7 means Sunday.
|
|
|
|
\param color the background color to use for weekend days.
|
|
\param weekday the day of the week (Monday = 1, Sunday = 7)
|
|
\sa weekendBackgroundColor(), setWeekendDays(), weekendDays()
|
|
*/
|
|
void KDTimeHeaderWidget::setWeekdayBackgroundColor( const TQColor& color, int weekday )
|
|
{
|
|
weekdayColor[weekday] = color;
|
|
updateTimeTable();
|
|
}
|
|
|
|
|
|
/*!
|
|
Returns the background color for weekday days.
|
|
|
|
\param the day of the week (Monday = 1, Sunday = 7)
|
|
\return the background color for weekend days
|
|
\sa setWeekendBackgroundColor(), setWeekendDays(), weekendDays()
|
|
*/
|
|
TQColor KDTimeHeaderWidget::weekdayBackgroundColor(int weekday) const
|
|
{
|
|
return weekdayColor[weekday];
|
|
}
|
|
|
|
|
|
/*!
|
|
Defines which days are considered weekends. The days are specified
|
|
as an interval of integer values where 1 means Monday and 7 means
|
|
Sunday. In order to define a weekend from Sunday to Monday, specify
|
|
(7,1).
|
|
|
|
\param start the first day of the weekend
|
|
\param end the last day of the weekend
|
|
\sa weekendDays(), setWeekendBackgroundColor(), weekendBackgroundColor()
|
|
*/
|
|
void KDTimeHeaderWidget::setWeekendDays( int start, int end )
|
|
{
|
|
myWeekendDaysStart = start;
|
|
myWeekendDaysEnd = end;
|
|
updateTimeTable();
|
|
}
|
|
|
|
|
|
/*!
|
|
Returns which days are considered weekends.
|
|
|
|
\param start in this parameter, the first day of the weekend is returned
|
|
\param end in this parameter, the end day of the weekend is returned
|
|
\sa setWeekendDays(), setWeekendBackgroundColor(), weekendBackgroundColor()
|
|
*/
|
|
void KDTimeHeaderWidget::weekendDays( int& start, int& end ) const
|
|
{
|
|
start = myWeekendDaysStart;
|
|
end = myWeekendDaysEnd ;
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
Sets the number of ticks in the major scale.
|
|
|
|
\param count the number of ticks in the major scale
|
|
\sa majorScaleCount(), setMinorScaleCount(), minorScaleCount()
|
|
*/
|
|
void KDTimeHeaderWidget::setMajorScaleCount( int count )
|
|
{
|
|
myMajorScaleCount=count;
|
|
computeTicks();
|
|
}
|
|
|
|
|
|
/*!
|
|
Returns the number of ticks per unit in the major scale.
|
|
|
|
\return the number of ticks in the major scale
|
|
\sa setMajorScaleCount(), setMinorScaleCount(), minorScaleCount()
|
|
*/
|
|
int KDTimeHeaderWidget::majorScaleCount() const
|
|
{
|
|
return myMajorScaleCount;
|
|
}
|
|
|
|
|
|
/*!
|
|
Sets the number of ticks in the minor scale.
|
|
|
|
\param count the number of ticks in the minor scale
|
|
\sa minorScaleCount, setMajorScaleCount, majorScaleCount()
|
|
*/
|
|
void KDTimeHeaderWidget::setMinorScaleCount( int count )
|
|
{
|
|
myMinorScaleCount = count;
|
|
computeTicks();
|
|
}
|
|
|
|
|
|
/*!
|
|
Returns the number of ticks per unit in the minor scale.
|
|
|
|
\return the number of ticks in the minor scale
|
|
\sa setMinorScaleCount(), setMajorScaleCount(), majorScaleCount()
|
|
*/
|
|
int KDTimeHeaderWidget::minorScaleCount() const
|
|
{
|
|
return myMinorScaleCount ;
|
|
|
|
}
|
|
|
|
|
|
void KDTimeHeaderWidget::resizeEvent ( TQResizeEvent * )
|
|
{
|
|
// qDebug("KDTimeHeaderWidget:: resizeEvent ");
|
|
paintPix.resize( 800, height () );
|
|
}
|
|
|
|
|
|
void KDTimeHeaderWidget::updateTimeTable()
|
|
{
|
|
//qDebug("KDTimeHeaderWidget::updateTimeTable() ");
|
|
if (flagDoNotRecomputeAfterChange) return;
|
|
// setting the scrolling steps
|
|
int scrollLineStep = myGridMinorWidth;
|
|
if (showMajorTicks()) {
|
|
TQValueList<int>::iterator intIt = majorTicks.begin();
|
|
scrollLineStep = 5 * myGridMinorWidth;
|
|
if (intIt != majorTicks.end()) {
|
|
int left = *intIt;
|
|
++intIt;
|
|
if (intIt != majorTicks.end()) {
|
|
scrollLineStep = *intIt-left;
|
|
}
|
|
}
|
|
}
|
|
myGanttView->myCanvasView->horizontalScrollBar()->setLineStep(scrollLineStep);
|
|
myGanttView->myTimeTable->maximumComputedGridHeight = 0;
|
|
myGanttView->myTimeTable->updateMyContent();
|
|
}
|
|
|
|
|
|
void KDTimeHeaderWidget::setAutoScaleMinorTickCount( int count )
|
|
{
|
|
myAutoScaleMinorTickcount = count;
|
|
computeTicks();
|
|
|
|
}
|
|
|
|
|
|
int KDTimeHeaderWidget::autoScaleMinorTickCount()
|
|
{
|
|
return myAutoScaleMinorTickcount;
|
|
}
|
|
|
|
|
|
void KDTimeHeaderWidget::tqrepaintMe(int left,int paintwid, TQPainter* painter)
|
|
{
|
|
if (flagDoNotRecomputeAfterChange) return;
|
|
TQColorGroup qcg =TQColorGroup( white, black,white, darkGray,black,gray,gray) ;
|
|
TQPainter* p;
|
|
int offsetLeft = 0;
|
|
if ( paintwid > paintPix.width()-100 )
|
|
paintPix.resize( paintwid+100, height () );
|
|
if ( painter )
|
|
p = painter;
|
|
else {
|
|
p = new TQPainter( &paintPix );
|
|
offsetLeft = left-50;
|
|
}
|
|
if ( mouseDown ) {
|
|
p->fillRect( left-offsetLeft, 0, paintwid, height(), TQBrush(paletteBackgroundColor()) );
|
|
int start ;
|
|
int wid;
|
|
if ( beginMouseDown < endMouseDown ) {
|
|
start = beginMouseDown ;
|
|
wid = endMouseDown - beginMouseDown ;
|
|
} else {
|
|
start = endMouseDown ;
|
|
wid = -endMouseDown + beginMouseDown ;
|
|
}
|
|
p->fillRect( start-offsetLeft, 0, wid, height(), TQBrush(paletteBackgroundColor().dark()) );
|
|
} else {
|
|
if (! painter )
|
|
p->fillRect( left-offsetLeft, 0, paintwid, height(), TQBrush(paletteBackgroundColor()) );
|
|
}
|
|
p->setPen(TQColor(40,40,40));
|
|
TQFont tempFont = p->font();
|
|
tempFont.setWeight(63);
|
|
p->setFont(tempFont);
|
|
int hei1 = myMajorGridHeight,
|
|
hei2 = height(),
|
|
wid1 = myGridMinorWidth;
|
|
int xCoord;
|
|
int lwid = 1;
|
|
|
|
TQValueList<TQString>::iterator it;
|
|
TQValueList<int>::iterator intIt = majorTicks.begin();
|
|
for ( it = majorText.begin(); it != majorText.end(); ++it ) {
|
|
xCoord = (*intIt++);
|
|
if (((*intIt)>= left && xCoord <= left+paintwid)) {
|
|
qDrawShadeLine ( p,xCoord-offsetLeft ,hei1+1, xCoord-offsetLeft, -2, qcg, true, lwid, 1 );
|
|
p->drawText(xCoord+4-offsetLeft,hei1-4,(*it));
|
|
}
|
|
}
|
|
qDrawShadeLine ( p,left-offsetLeft ,hei1, left+paintwid-offsetLeft, hei1, qcg, true, lwid, 1 );
|
|
int i = 0;
|
|
for ( it = minorText.begin(); it != minorText.end(); ++it ) {
|
|
if (i*wid1 >= left-wid1 && i*wid1 <= left+paintwid) {
|
|
qDrawShadeLine ( p,i*wid1-offsetLeft ,hei1-1, i*wid1-offsetLeft, hei2, qcg, true, lwid, 1 );
|
|
p->drawText(i*wid1+1-offsetLeft,hei1+1,wid1-1,hei2-hei1,Qt::AlignCenter,(*it));
|
|
}
|
|
++i;
|
|
}
|
|
p->setPen(black);
|
|
p->drawLine(left-offsetLeft,hei1,left+paintwid-offsetLeft,hei1);
|
|
qDrawShadeLine ( p,left-offsetLeft ,hei2-1, left+paintwid-offsetLeft, hei2-1, qcg, true, lwid, 1 );
|
|
p->drawLine(left-offsetLeft,hei2-1,left+paintwid-offsetLeft,hei2-1);
|
|
if ( !painter ) {
|
|
p->end();
|
|
delete p;
|
|
bitBlt ( this, left, 0, &paintPix, 50, 0, paintwid, height() );
|
|
}
|
|
}
|
|
|
|
// cuts the secs in the DateTime if scale is Minute ,
|
|
// the minutes and secs if scale is Hour and so on
|
|
|
|
TQDateTime KDTimeHeaderWidget::getEvenTimeDate(TQDateTime tempdatetime ,Scale sc)
|
|
{
|
|
TQDate tempdate;
|
|
int min, hour;
|
|
int tempMinorScaleCount = myRealMinorScaleCount;
|
|
switch (sc)
|
|
{
|
|
case KDGanttView::Month:
|
|
tempdate = tempdatetime.date();
|
|
while (tempdate.day ()!= 1 )
|
|
tempdate = tempdate.addDays(-1);
|
|
//while (tempdate.month ()!= 1 )
|
|
//tempdate = tempdate.addMonths(-1);
|
|
tempdatetime = TQDateTime (tempdate, TQTime (0,0));
|
|
break;
|
|
case KDGanttView::Week:
|
|
tempdate = tempdatetime.date();
|
|
while (tempdate.dayOfWeek ()!= KGlobal::locale()->weekStartDay())
|
|
tempdate = tempdate.addDays(-1);
|
|
//tempdate = tempdate.addDays(-7);
|
|
tempdatetime = TQDateTime (tempdate, TQTime (0,0));
|
|
break;
|
|
case KDGanttView::Day:
|
|
tempdatetime = TQDateTime (tempdatetime.date(), TQTime ( 0,0 ) );
|
|
break;
|
|
case KDGanttView::Hour:
|
|
hour = tempdatetime.time().hour();
|
|
while (24%tempMinorScaleCount > 0 && 24%tempMinorScaleCount < 24)
|
|
++tempMinorScaleCount;
|
|
hour = ( hour /tempMinorScaleCount)*tempMinorScaleCount;
|
|
tempdatetime = TQDateTime (tempdatetime.date(), TQTime (hour, 0 ));
|
|
break;
|
|
case KDGanttView::Minute:
|
|
min = tempdatetime.time().minute();
|
|
while (60%tempMinorScaleCount > 0 && 60%tempMinorScaleCount < 60)
|
|
++tempMinorScaleCount;
|
|
// qDebug("myMinorScaleCount %d %d %d",myMinorScaleCount, myRealMinorScaleCount, tempMinorScaleCount);
|
|
min = (min /tempMinorScaleCount)*tempMinorScaleCount;
|
|
tempdatetime = TQDateTime (tempdatetime.date(), TQTime (tempdatetime.time().hour(),min ));
|
|
|
|
break;
|
|
case KDGanttView::Auto:
|
|
break;
|
|
}
|
|
return tempdatetime;
|
|
}
|
|
|
|
|
|
void KDTimeHeaderWidget::computeRealScale(TQDateTime start)
|
|
{
|
|
|
|
if (myScale ==KDGanttView::Auto) {
|
|
//qDebug("Autoscale ");
|
|
//double secsPerMinor = (((double)start.daysTo(myHorizonEnd))* 86400.00)/((double)myAutoScaleMinorTickcount);
|
|
double secsPerMinor = (((double)start.secsTo(myHorizonEnd)))/((double)myAutoScaleMinorTickcount);
|
|
secsPerMinor /= myZoomFactor;
|
|
if (secsPerMinor <= 1800) {
|
|
myRealScale = KDGanttView::Minute;
|
|
myRealMinorScaleCount = (int) secsPerMinor/60;
|
|
} else {
|
|
if (secsPerMinor <= 12*3600) {
|
|
myRealScale = KDGanttView::Hour;
|
|
myRealMinorScaleCount = (int) secsPerMinor/3600;
|
|
} else {
|
|
if (secsPerMinor <= 24*3600*3) {
|
|
myRealScale = KDGanttView::Day;
|
|
myRealMinorScaleCount = (int) secsPerMinor/(3600*24);
|
|
} else {
|
|
if (secsPerMinor <= 24*3600*14) {
|
|
myRealScale = KDGanttView::Week;
|
|
myRealMinorScaleCount = (int) secsPerMinor/(3600*24*7);
|
|
} else {
|
|
myRealScale = KDGanttView::Month;
|
|
myRealMinorScaleCount = (int) secsPerMinor/(3600*24*30);
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if(myRealMinorScaleCount == 0)
|
|
myRealMinorScaleCount = 1;
|
|
myRealMajorScaleCount = 1;
|
|
}
|
|
else {
|
|
//qDebug("Fixed scale ");
|
|
myRealScale = myScale;
|
|
if (myRealScale > myMaxScale)
|
|
myRealScale = myMaxScale;
|
|
if (myRealScale < myMinScale)
|
|
myRealScale = myMinScale;
|
|
myRealMinorScaleCount = (int) ( ((double)myMinorScaleCount) /myZoomFactor );
|
|
double tempZoom = myZoomFactor;
|
|
myRealMajorScaleCount = myMajorScaleCount;
|
|
while (myRealMinorScaleCount == 0) {
|
|
if (myRealScale == myMinScale) {
|
|
myRealMinorScaleCount = 1;
|
|
break;
|
|
}
|
|
switch (myRealScale)
|
|
{
|
|
case KDGanttView::Minute:
|
|
myRealMinorScaleCount = 1;
|
|
return;
|
|
break;
|
|
case KDGanttView::Hour:
|
|
myRealScale = KDGanttView::Minute;
|
|
tempZoom = tempZoom/60;
|
|
break;
|
|
case KDGanttView::Day:
|
|
myRealScale = KDGanttView::Hour;
|
|
tempZoom = tempZoom/24;
|
|
break;
|
|
case KDGanttView::Week:
|
|
myRealScale = KDGanttView::Day;
|
|
tempZoom = tempZoom/7;
|
|
break;
|
|
case KDGanttView::Month:
|
|
myRealScale = KDGanttView::Week ;
|
|
tempZoom = tempZoom*7/30;
|
|
break;
|
|
case KDGanttView::Auto:
|
|
break;
|
|
}
|
|
myRealMinorScaleCount = (int) ( myMinorScaleCount /tempZoom );
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void KDTimeHeaderWidget::computeTicks(bool doNotComputeRealScale)
|
|
{
|
|
if (flagDoNotRecomputeAfterChange) return;
|
|
bool block = myGanttView->myTimeTable->blockUpdating();
|
|
myGanttView->myTimeTable->setBlockUpdating( true );
|
|
//qDebug("computeticks ");
|
|
majorTicks.clear();
|
|
minorText.clear();
|
|
majorText.clear();
|
|
if ( !doNotComputeRealScale )
|
|
saveCenterDateTime();
|
|
if (!doNotComputeRealScale)
|
|
computeRealScale(myHorizonStart);
|
|
myRealStart = getEvenTimeDate(myHorizonStart ,myRealScale);
|
|
if (!doNotComputeRealScale)
|
|
computeRealScale(myRealStart);
|
|
int tempMinorScaleCount = myRealMinorScaleCount,
|
|
tempMajorScaleCount = myRealMajorScaleCount;
|
|
int minorItems,minorPerMajor = 1;
|
|
minorItems = (int) (secsFromTo( myRealStart, myHorizonEnd)/60.0);
|
|
//qDebug("tempMinorScaleCount %d ", tempMinorScaleCount);
|
|
TQPainter p(this);
|
|
int Width, Height;
|
|
TQString testTextMinor,testTextMajor, tempStr;
|
|
TQRect tqitemRectMinor, tqitemRectMajor;
|
|
TQDate tempDate = myRealStart.date();
|
|
myRealEnd = myRealStart;
|
|
// preparing the testtext for the differennt scales
|
|
switch (myRealScale)
|
|
{
|
|
// the x in testTextMajor is added to reserve a little bit more space
|
|
case KDGanttView::Minute:
|
|
testTextMinor = "60";
|
|
if (myHourFormat == KDGanttView::Hour_12)
|
|
testTextMajor = "Mon Aug 30, 12 AMx";
|
|
else
|
|
testTextMajor = "Mon Aug 30, 24:00x";
|
|
minorPerMajor = 6000;
|
|
break;
|
|
case KDGanttView::Hour:
|
|
minorItems = minorItems/60;
|
|
if (myHourFormat == KDGanttView::Hour_24)
|
|
testTextMinor = "24x";
|
|
else
|
|
testTextMinor = "12 AM";
|
|
testTextMajor = "Mon Aug 30, x";
|
|
if ( yearFormat() != KDGanttView::NoDate )
|
|
testTextMajor += getYear(TQDate::tqcurrentDate());
|
|
minorPerMajor = 2400;
|
|
break;
|
|
case KDGanttView::Day:
|
|
minorItems = minorItems/(60*24);
|
|
testTextMinor = "88";
|
|
testTextMajor = "Aug 30, x"+getYear(TQDate::tqcurrentDate());
|
|
minorPerMajor = 700;
|
|
break;
|
|
case KDGanttView::Week:
|
|
minorItems = minorItems/(60*24*7);
|
|
testTextMinor = "88";
|
|
testTextMajor = "Aug x"+getYear(TQDate::tqcurrentDate());
|
|
minorPerMajor = 435; // 435 = 365days/12months/7days * 100
|
|
break;
|
|
case KDGanttView::Month:
|
|
minorItems = (minorItems*12)/(60*24*365);
|
|
testTextMinor = "M";
|
|
testTextMajor = "x"+getYear(TQDate::tqcurrentDate());
|
|
minorPerMajor = 1200;
|
|
break;
|
|
case KDGanttView::Auto:
|
|
qDebug("KDGanttView::Internal Error in KDTimeHeaderWidget::computeTicks() ");
|
|
qDebug(" RealScale == Auto : This may not be! ");
|
|
break;
|
|
}
|
|
tqitemRectMinor = p.boundingRect ( 10, 10, 2, 2, Qt::AlignLeft,testTextMinor);
|
|
tqitemRectMajor = p.boundingRect ( 10, 10, 2, 2, Qt::AlignLeft,testTextMajor);
|
|
p.end();
|
|
//qDebug(" tempMinorScaleCount %d ", tempMinorScaleCount);
|
|
Height = tqitemRectMinor.height()+tqitemRectMajor.height()+11;
|
|
Width = (tqitemRectMinor.width()+5);
|
|
if (Width < minimumColumnWidth()) Width = minimumColumnWidth();
|
|
// if the desired width is greater than the maximum width of this widget
|
|
// increase the minorscalecount
|
|
int maxWid = myGanttView->myCanvasView->viewport()->width();
|
|
if (!flagZoomToFit)
|
|
maxWid = maximumWidth();
|
|
while((minorItems/tempMinorScaleCount+1)*Width > maxWid)
|
|
++tempMinorScaleCount;
|
|
//qDebug(" tempMinorScaleCount %d ", tempMinorScaleCount);
|
|
mySizeHint = (minorItems/tempMinorScaleCount+1)*Width;
|
|
switch (myRealScale)
|
|
{
|
|
case KDGanttView::Minute:
|
|
if (tempMinorScaleCount < 60)
|
|
while (60%tempMinorScaleCount > 0 && 60%tempMinorScaleCount < 60)
|
|
++tempMinorScaleCount;
|
|
if (tempMinorScaleCount >= 60) {
|
|
myRealScale = KDGanttView::Hour;
|
|
myRealMinorScaleCount = tempMinorScaleCount/ 60;
|
|
// myRealMinorScaleCount = 1;
|
|
myRealMajorScaleCount = 1;
|
|
qDebug("KDGantt::Overzoom:Rescaling from Minute to Hour");
|
|
myGanttView->myTimeTable->setBlockUpdating( block );
|
|
emit myGanttView->rescaling( KDGanttView::Hour );
|
|
computeTicks(true);
|
|
return;
|
|
}
|
|
break;
|
|
case KDGanttView::Hour:
|
|
while (24%tempMinorScaleCount > 0 && 24%tempMinorScaleCount < 24)
|
|
++tempMinorScaleCount;
|
|
if (tempMinorScaleCount >= 24) {
|
|
myRealScale = KDGanttView::Day;
|
|
myRealMinorScaleCount = tempMinorScaleCount/ 24;
|
|
//myRealMinorScaleCount = 1;
|
|
myRealMajorScaleCount = 1;
|
|
qDebug("KDGantt::Overzoom:Rescaling from Hour to Day");
|
|
myGanttView->myTimeTable->setBlockUpdating( block );
|
|
emit myGanttView->rescaling( KDGanttView::Day );
|
|
computeTicks(true);
|
|
return;
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
//flagZoomToFit = false;
|
|
while((minorItems/tempMinorScaleCount+1)*Width < myMinimumWidth ) {
|
|
++minorItems;
|
|
}
|
|
minorItems = (minorItems/tempMinorScaleCount)+1;
|
|
// if not enough space for the text of the major scale, increase majorscalecount
|
|
minorPerMajor = (minorPerMajor*tempMajorScaleCount)/tempMinorScaleCount;
|
|
// checking, if enough space for majorscale
|
|
// if not, increasing MajorScaleCount
|
|
|
|
while ((minorPerMajor*Width)/100 < tqitemRectMajor.width()) {
|
|
minorPerMajor = minorPerMajor/tempMajorScaleCount;
|
|
++tempMajorScaleCount;
|
|
minorPerMajor = minorPerMajor*tempMajorScaleCount;
|
|
|
|
}
|
|
// now we have the fixed width of the minorscale computed
|
|
myGridMinorWidth = Width;
|
|
// the width of this widget is the gridwidth * the amount of items
|
|
Width *= minorItems;
|
|
// if size changed, reset tqgeometry
|
|
if (width() != Width || height() != Height )
|
|
{
|
|
resize( Width, Height );
|
|
emit sizeChanged( Width );
|
|
}
|
|
myMajorGridHeight = tqitemRectMajor.height()+5;
|
|
TQTime tempTime = myRealStart.time();
|
|
TQDateTime tempDateTime;
|
|
int i;
|
|
const KCalendarSystem * calendar = KGlobal::locale()->calendar();
|
|
switch (myRealScale)
|
|
{
|
|
case KDGanttView::Minute:
|
|
myRealEnd = myRealEnd.addSecs((minorItems)*tempMinorScaleCount*60);
|
|
for ( i = 0; i < minorItems;++i) {
|
|
tempStr.setNum(tempTime.minute());
|
|
minorText.append(tempStr);
|
|
tempTime = tempTime.addSecs(60*tempMinorScaleCount);
|
|
}
|
|
tempDateTime = myRealStart;
|
|
while (tempDateTime.time().minute() != 0)
|
|
tempDateTime = tempDateTime.addSecs(60);
|
|
while (tempDateTime < myRealEnd) {
|
|
majorTicks.append( getCoordX(tempDateTime));
|
|
tempStr.setNum(tempDateTime.date().day());
|
|
if ( yearFormat() == KDGanttView::NoDate ) {
|
|
tempStr = calendar->weekDayName( tempDateTime.date() )+", "
|
|
+getHour(tempDateTime.time());
|
|
} else {
|
|
tempStr = calendar->weekDayName( tempDateTime.date(), true )+" "+
|
|
calendar->monthName( tempDateTime.date().month(), tempDateTime.date().year(), true)+ " "+
|
|
tempStr+", "+getHour(tempDateTime.time());
|
|
}
|
|
|
|
majorText.append(tempStr);
|
|
tempDateTime = tempDateTime.addSecs(3600*tempMajorScaleCount);
|
|
}
|
|
majorTicks.append( getCoordX(tempDateTime));
|
|
break;
|
|
|
|
case KDGanttView::Hour:
|
|
myRealEnd = myRealEnd.addSecs(minorItems*tempMinorScaleCount*60*60);
|
|
|
|
for ( i = 0; i < minorItems;++i) {
|
|
tempStr = getHour(tempTime);
|
|
minorText.append(tempStr);
|
|
tempTime = tempTime.addSecs(3600*tempMinorScaleCount);
|
|
}
|
|
tempDateTime = myRealStart;
|
|
while (tempDateTime.time().hour() != 0)
|
|
tempDateTime = tempDateTime.addSecs(3600);
|
|
while (tempDateTime < myRealEnd) {
|
|
majorTicks.append( getCoordX(tempDateTime));
|
|
tempStr.setNum(tempDateTime.date().day());
|
|
if ( yearFormat() == KDGanttView::NoDate ) {
|
|
tempStr = calendar->weekDayName( tempDateTime.date() );
|
|
} else {
|
|
tempStr = calendar->weekDayName( tempDateTime.date(), true )+" "+
|
|
calendar->monthName( tempDateTime.date().month(), tempDateTime.date().year(), true)+ " "+
|
|
tempStr+", "+getYear(tempDateTime.date());
|
|
}
|
|
majorText.append(tempStr);
|
|
tempDateTime = tempDateTime.addDays(tempMajorScaleCount);
|
|
}
|
|
majorTicks.append( getCoordX(tempDateTime));
|
|
break;
|
|
case KDGanttView::Day:
|
|
myRealEnd = myRealEnd.addDays(minorItems*tempMinorScaleCount);
|
|
for ( i = 0; i < minorItems;++i) {
|
|
if (tempMinorScaleCount == 1)
|
|
minorText.append((calendar->weekDayName(tempDate, true)).left(1)); //TODO: BIDI
|
|
else
|
|
minorText.append(TQString::number(tempDate.day()));
|
|
tempDate = tempDate.addDays(tempMinorScaleCount);
|
|
}
|
|
tempDate = myRealStart.date();
|
|
while (tempDate.dayOfWeek() != KGlobal::locale()->weekStartDay())
|
|
tempDate = tempDate.addDays(1);
|
|
while (tempDate < myRealEnd.date()) {
|
|
majorTicks.append( getCoordX(tempDate));
|
|
tempStr.setNum(tempDate.day());
|
|
tempStr = calendar->monthName(tempDate.month(), tempDate.year(), true)+ " "+
|
|
tempStr+", "+getYear(tempDate);
|
|
majorText.append(tempStr);
|
|
tempDate = tempDate.addDays(7*tempMajorScaleCount);
|
|
}
|
|
majorTicks.append( getCoordX(tempDate));
|
|
break;
|
|
case KDGanttView::Week:
|
|
myRealEnd = myRealEnd.addDays(minorItems*tempMinorScaleCount*7);
|
|
for ( i = 0; i < minorItems;++i) {
|
|
tempStr.setNum(tempDate.day());
|
|
minorText.append(tempStr);
|
|
tempDate = tempDate.addDays(7*tempMinorScaleCount);
|
|
}
|
|
tempDate = myRealStart.date();
|
|
while (tempDate.day() != KGlobal::locale()->weekStartDay())
|
|
tempDate = tempDate.addDays(1);
|
|
while (tempDate < myRealEnd.date()) {
|
|
majorTicks.append( getCoordX(tempDate));
|
|
tempStr = calendar->monthName(tempDate.month(), tempDate.year(), true)+ " "+getYear(tempDate);
|
|
majorText.append(tempStr);
|
|
tempDate = tempDate.addMonths(tempMajorScaleCount);
|
|
}
|
|
majorTicks.append( getCoordX(tempDate));
|
|
break;
|
|
case KDGanttView::Month:
|
|
myRealEnd = myRealEnd.addMonths(minorItems*tempMinorScaleCount);
|
|
for ( i = 0; i < minorItems;++i) {
|
|
minorText.append((calendar->monthName(tempDate.month(), tempDate.year(), true)).left(1)); //TODO: BIDI
|
|
tempDate = tempDate.addMonths(tempMinorScaleCount);
|
|
}
|
|
tempDate = myRealStart.date();
|
|
while (tempDate.month() != 1)
|
|
tempDate = tempDate.addMonths(1);
|
|
while (tempDate < myRealEnd.date()) {
|
|
majorTicks.append( getCoordX(tempDate));
|
|
tempStr = getYear(tempDate);
|
|
majorText.append(tempStr);
|
|
tempDate = tempDate.addYears(tempMajorScaleCount);
|
|
}
|
|
majorTicks.append( getCoordX(tempDate));
|
|
break;
|
|
case KDGanttView::Auto:
|
|
break;
|
|
}
|
|
|
|
if (flagDoNotRepaintAfterChange) {
|
|
myGanttView->myTimeTable->setBlockUpdating( block );
|
|
return;
|
|
}
|
|
//qDebug("KDTimeHeaderWidget width %d, viewport width %d ",width (), myGanttView->myCanvasView->viewport()->width());
|
|
myGanttView->myTimeTable->setBlockUpdating( block );
|
|
updateTimeTable();
|
|
centerDateTime(myCenterDateTime);
|
|
tqrepaint();
|
|
}
|
|
|
|
|
|
void KDTimeHeaderWidget::saveCenterDateTime()
|
|
{
|
|
double wid = width();
|
|
double allsecs = secsFromTo( myRealStart, myRealEnd );
|
|
double center = myGanttView->myCanvasView->viewport()->width();
|
|
center = center / 2;
|
|
center = center + myGanttView->myCanvasView->contentsX();
|
|
double secs = (allsecs*center)/wid;
|
|
double days = secs/86400.0;
|
|
secs = secs - ( (int) days *86400.0 );
|
|
myCenterDateTime = (myRealStart.addDays ( (int) days )).addSecs( (int) secs);
|
|
}
|
|
|
|
|
|
void KDTimeHeaderWidget::centerDateTime( const TQDateTime& center )
|
|
{
|
|
moveTimeLineTo(getCoordX( center )-(myGanttView->myCanvasView->viewport()->width() /2));
|
|
// qDebug("centerDateTime %s %d %d", center.toString().latin1(),getCoordX( center ),(myGanttView->myCanvasView->viewport()->width() /2) );
|
|
|
|
}
|
|
|
|
|
|
void KDTimeHeaderWidget::paintEvent(TQPaintEvent *p)
|
|
{
|
|
tqrepaintMe(p->rect().x(),p->rect().width());
|
|
}
|
|
|
|
|
|
int KDTimeHeaderWidget::getCoordX(TQDate date)
|
|
{
|
|
int wid = width();
|
|
int daysAll = myRealStart.daysTo(myRealEnd);
|
|
if (daysAll == 0) return 0;
|
|
int days = myRealStart.daysTo(TQDateTime(date));
|
|
return (wid *days) /daysAll;
|
|
}
|
|
|
|
|
|
int KDTimeHeaderWidget::getCoordX(TQDateTime datetime)
|
|
{
|
|
double wid = width();
|
|
double secsAll = secsFromTo( myRealStart, myRealEnd );
|
|
if (secsAll == 0.0) return 0;
|
|
double secs = secsFromTo( myRealStart, datetime);
|
|
return ((int)((wid *(secs /secsAll))+0.5));
|
|
}
|
|
|
|
|
|
TQString KDTimeHeaderWidget::getYear(TQDate date)
|
|
{
|
|
TQString ret;
|
|
ret.setNum(date.year());
|
|
switch (yearFormat()) {
|
|
case KDGanttView::FourDigit:
|
|
// nothing to do
|
|
break;
|
|
case KDGanttView::TwoDigit:
|
|
ret = ret.right(2);
|
|
break;
|
|
case KDGanttView::TwoDigitApostrophe:
|
|
ret = "'"+ret.right(2);
|
|
break;
|
|
case KDGanttView::NoDate:
|
|
// nothing to do
|
|
break;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
|
|
TQString KDTimeHeaderWidget::getHour(TQTime time)
|
|
{
|
|
TQString ret;
|
|
int hour = time.hour();
|
|
if (myHourFormat == KDGanttView::Hour_12) {
|
|
if (hour >= 12) {
|
|
if (hour > 12) hour -=12;
|
|
ret.setNum(hour);
|
|
ret = ret +" PM";
|
|
} else {
|
|
if (hour == 0) hour = 12;
|
|
ret.setNum(hour);
|
|
ret = ret +" AM";
|
|
}
|
|
} else {
|
|
if (myHourFormat == KDGanttView::Hour_24)
|
|
ret.setNum(hour);
|
|
else {
|
|
ret.setNum(hour);
|
|
ret += ":00";
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
|
|
void KDTimeHeaderWidget::mousePressEvent ( TQMouseEvent * e )
|
|
{
|
|
mouseDown = false;
|
|
switch ( e->button() ) {
|
|
case LeftButton:
|
|
mouseDown = true;
|
|
beginMouseDown = e->pos().x();
|
|
endMouseDown = e->pos().x();
|
|
break;
|
|
case RightButton:
|
|
if (flagShowPopupMenu)
|
|
myPopupMenu->popup(e->globalPos());
|
|
break;
|
|
case MidButton:
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
void KDTimeHeaderWidget::mouseReleaseEvent ( TQMouseEvent * )
|
|
{
|
|
if ( mouseDown ) {
|
|
mouseDown = false;
|
|
// zoom to selection getDateTimeForIndex(
|
|
int start, end;
|
|
if ( beginMouseDown < endMouseDown ) {
|
|
start = beginMouseDown;
|
|
end = endMouseDown;
|
|
} else {
|
|
start = endMouseDown;
|
|
end = beginMouseDown;
|
|
}
|
|
if (start < 0 )
|
|
start = 0;
|
|
if ( end > width() )
|
|
end = width();
|
|
//qDebug("start %s ",getDateTimeForIndex(start).toString().latin1() );
|
|
//qDebug("end %s ",getDateTimeForIndex(end).toString().latin1() );
|
|
emit myGanttView->timeIntervalSelected( getDateTimeForIndex(start),getDateTimeForIndex(end) );
|
|
emit myGanttView->timeIntervallSelected( getDateTimeForIndex(start),getDateTimeForIndex(end) );
|
|
//zoomToSelection( getDateTimeForIndex(start),getDateTimeForIndex(end) );
|
|
}
|
|
mouseDown = false;
|
|
tqrepaint();
|
|
}
|
|
|
|
|
|
void KDTimeHeaderWidget::mouseDoubleClickEvent ( TQMouseEvent * )
|
|
{
|
|
|
|
}
|
|
|
|
|
|
void KDTimeHeaderWidget::mouseMoveEvent ( TQMouseEvent * e )
|
|
{
|
|
if ( mouseDown ) {
|
|
if ( e->pos().y() < -height() || e->pos().y() > 2* height() ) {
|
|
mouseDown = false;
|
|
tqrepaint();
|
|
return;
|
|
}
|
|
endMouseDown = e->pos().x();
|
|
//tqrepaint;
|
|
int val = -1;
|
|
if (endMouseDown < -x() ) {
|
|
val = myGanttView->myCanvasView->horizontalScrollBar()->value() -
|
|
myGanttView->myCanvasView->horizontalScrollBar()->lineStep();
|
|
if ( val < 0 ) {
|
|
val = 0;
|
|
}
|
|
}
|
|
if (endMouseDown > -x() +tqparentWidget()->width() ) {
|
|
val = myGanttView->myCanvasView->horizontalScrollBar()->value() +
|
|
myGanttView->myCanvasView->horizontalScrollBar()->lineStep();
|
|
|
|
}
|
|
tqrepaintMe(-x(),tqparentWidget()->width());
|
|
if ( val > -1 ) {
|
|
if ( val > myGanttView->myCanvasView->horizontalScrollBar()->maxValue() ) {
|
|
val = myGanttView->myCanvasView->horizontalScrollBar()->maxValue();
|
|
}
|
|
myGanttView->myCanvasView->horizontalScrollBar()->setValue( val );
|
|
}
|
|
//qDebug("mousemove %d %d %d %d",endMouseDown, -x(),tqparentWidget()->width() , e->pos().y());
|
|
}
|
|
}
|
|
|
|
|
|
/* ***************************************************************
|
|
KDLegendWidget:: KDLegendWidget
|
|
***************************************************************** */
|
|
KDLegendWidget:: KDLegendWidget( TQWidget* parent,
|
|
KDGanttMinimizeSplitter* legendParent ) :
|
|
KDGanttSemiSizingControl ( KDGanttSemiSizingControl::Before, Vertical,
|
|
parent)
|
|
{
|
|
myLegendParent = legendParent;
|
|
dock = 0;
|
|
scroll = new TQScrollView( legendParent );
|
|
setMaximizedWidget( scroll );
|
|
|
|
setMinimizedWidget( myLabel = new TQLabel( i18n( " Legend is hidden" ), this) );
|
|
setGeometry( 0, 0, 50, 50 );
|
|
myLegend = 0;
|
|
clearLegend();
|
|
showMe ( false );
|
|
}
|
|
void KDLegendWidget::setAsDockwindow( bool dockwin )
|
|
{
|
|
if ( (dock == 0 && !dockwin) || ( dock && dockwin ) )
|
|
return;
|
|
if ( dockwin )
|
|
{
|
|
setMaximizedWidget( 0 );
|
|
showMe ( false );
|
|
if ( dock ) delete dock;
|
|
dock = new TQDockWindow(TQDockWindow:: OutsideDock,0 );
|
|
dock->resize( 200, 100 );
|
|
dock->setHorizontallyStretchable( true );
|
|
dock->setVerticallyStretchable( true );
|
|
dock->setCaption(i18n("Legend: ") );
|
|
dock->setResizeEnabled (true );
|
|
delete myLegend;
|
|
myLegend = 0;
|
|
delete scroll;
|
|
scroll = new TQScrollView( dock );
|
|
clearLegend();
|
|
dock->setWidget(scroll);
|
|
setMaximizedWidget( dock );
|
|
showMe ( false );
|
|
|
|
} else {
|
|
setMaximizedWidget( 0 );
|
|
showMe ( false );
|
|
delete myLegend;
|
|
myLegend = 0;
|
|
delete scroll;
|
|
delete dock;
|
|
dock = 0;
|
|
scroll = new TQScrollView( myLegendParent );
|
|
clearLegend();
|
|
setMaximizedWidget( scroll );
|
|
showMe ( false );
|
|
}
|
|
|
|
}
|
|
|
|
|
|
bool KDLegendWidget::asDockwindow( )
|
|
{
|
|
if ( dock )
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
|
|
TQDockWindow* KDLegendWidget::dockwindow( )
|
|
{
|
|
return dock;
|
|
}
|
|
|
|
|
|
void KDLegendWidget::setFont( TQFont font)
|
|
{
|
|
myLegend->setFont( font);
|
|
myLabel->setFont( font);
|
|
TQWidget::setFont( font );
|
|
}
|
|
|
|
|
|
void KDLegendWidget::drawToPainter( TQPainter *p )
|
|
{
|
|
p->drawPixmap( 0, 0, TQPixmap::grabWidget( myLegend ) );
|
|
}
|
|
|
|
|
|
TQSize KDLegendWidget::legendSize()
|
|
{
|
|
return myLegend->size();
|
|
}
|
|
|
|
|
|
TQSize KDLegendWidget::legendSizeHint()
|
|
{
|
|
TQApplication::sendPostedEvents( 0, TQEvent::LayoutHint );
|
|
return TQSize( myLegend->tqsizeHint().width(), myLegend->tqsizeHint().height()+scroll->horizontalScrollBar()->height());
|
|
}
|
|
|
|
|
|
void KDLegendWidget::showMe ( bool show )
|
|
{
|
|
minimize( !show );
|
|
}
|
|
|
|
|
|
void KDLegendWidget::clearLegend ( )
|
|
{
|
|
if ( myLegend ) delete myLegend;
|
|
if ( dock )
|
|
myLegend = new TQGroupBox( 1, Qt::Horizontal, scroll->viewport() );
|
|
else
|
|
myLegend = new TQGroupBox( 1, Qt::Horizontal, i18n( "Legend" ), scroll->viewport() );
|
|
myLegend->setBackgroundColor( Qt::white );
|
|
myLegend->setFont( font() );
|
|
scroll->addChild( myLegend );
|
|
scroll->setResizePolicy( TQScrollView::AutoOneFit );
|
|
myLegend->tqlayout()->setMargin( 11 );
|
|
myLegend->setFrameStyle( TQFrame::NoFrame );
|
|
if ( dock )
|
|
scroll->setMaximumHeight( 32000 );
|
|
else
|
|
scroll->setMaximumHeight( legendSizeHint().height() );
|
|
}
|
|
|
|
|
|
void KDLegendWidget::addLegendItem( KDGanttViewItem::Shape tqshape, const TQColor& tqshapeColor, const TQString& text )
|
|
{
|
|
TQLabel * temp;
|
|
TQPixmap p = KDGanttView::getPixmap( tqshape, tqshapeColor, Qt::white, 10);
|
|
TQWidget *w = new TQWidget( myLegend );
|
|
w->setBackgroundColor( Qt::white );
|
|
TQHBoxLayout *lay = new TQHBoxLayout( w ,0, 6);
|
|
temp = new TQLabel ( w );
|
|
lay->addWidget( temp, 0, Qt:: AlignRight);
|
|
temp->setPixmap(p);
|
|
temp = new TQLabel ( text, w );
|
|
temp->setBackgroundColor( Qt::white );
|
|
lay->addWidget( temp, 0, Qt:: AlignLeft);
|
|
lay->addStretch();
|
|
if ( dock )
|
|
scroll->setMaximumHeight( 32000 );
|
|
else
|
|
scroll->setMaximumHeight( legendSizeHint().height() );
|
|
}
|
|
|
|
|
|
bool KDLegendWidget::isShown ( )
|
|
{
|
|
return !isMinimized();
|
|
}
|
|
|
|
|
|
KDListView::KDListView(TQWidget* parent, KDGanttView* gantView):TQListView (parent)
|
|
{
|
|
myGanttView = gantView;
|
|
setAcceptDrops(true);
|
|
new KDListViewWhatsThis(viewport(),this);
|
|
setRootIsDecorated( true );
|
|
setAllColumnsShowFocus( true );
|
|
addColumn( i18n( "Task Name" ) );
|
|
setSorting( -1 );
|
|
//setVScrollBarMode (TQScrollView::AlwaysOn );
|
|
setHScrollBarMode (TQScrollView::AlwaysOn );
|
|
setDefaultRenameAction(TQListView::Accept);
|
|
setColumnWidthMode ( 0,Maximum );
|
|
_calendarMode = false;
|
|
// TQObject::connect(this, TQT_SIGNAL ( pressed ( TQListViewItem * )) , this, TQT_SLOT( dragItem( TQListViewItem *))) ;
|
|
}
|
|
|
|
|
|
void KDListView::dragItem( TQListViewItem * )
|
|
{
|
|
// qDebug("drag ");
|
|
// startDrag();
|
|
}
|
|
TQString KDListView::getWhatsThisText(TQPoint p)
|
|
{
|
|
KDGanttViewItem* item = ( KDGanttViewItem* ) itemAt( p );
|
|
if ( item )
|
|
return item->whatsThisText();
|
|
return i18n( "No item Found" );
|
|
}
|
|
|
|
void KDListView::setCalendarMode( bool mode )
|
|
{
|
|
_calendarMode = mode;
|
|
// setRootIsDecorated ( ! mode );
|
|
}
|
|
|
|
void KDListView::setOpen(TQListViewItem * item, bool open )
|
|
{
|
|
if (! _calendarMode || ! open ) {
|
|
(( KDGanttViewItem*)item)->setCallListViewOnSetOpen( false );
|
|
TQListView::setOpen ( item, open );
|
|
(( KDGanttViewItem*)item)->setCallListViewOnSetOpen( true );
|
|
return;
|
|
}
|
|
// we are in calendarmode
|
|
// in calendarmode only items can be opened which have subitems which have subitems
|
|
|
|
TQListViewItem* temp;
|
|
temp = item->firstChild();
|
|
bool openItem = false;
|
|
while (temp) {
|
|
if ( (( KDGanttViewItem*)temp)->displaySubitemsAsGroup() ) {
|
|
temp->setVisible( true );
|
|
openItem = true;
|
|
}
|
|
else {
|
|
temp->setVisible( false );
|
|
//qDebug(" temp->setVisible( false );");
|
|
}
|
|
temp = temp->nextSibling();
|
|
}
|
|
if ( openItem ) {
|
|
(( KDGanttViewItem*)item)->setCallListViewOnSetOpen( false );
|
|
TQListView::setOpen ( item, open );
|
|
(( KDGanttViewItem*)item)->setCallListViewOnSetOpen( true );
|
|
}
|
|
}
|
|
|
|
|
|
void KDListView::contentsMouseDoubleClickEvent ( TQMouseEvent * e )
|
|
{
|
|
TQListView::contentsMouseDoubleClickEvent ( e );
|
|
//if ( ! _calendarMode )
|
|
// TQListView::contentsMouseDoubleClickEvent ( e );
|
|
// else
|
|
{
|
|
|
|
emit myGanttView->lvItemDoubleClicked ( (KDGanttViewItem*) itemAt(e->pos() ) );
|
|
emit myGanttView->itemDoubleClicked ( (KDGanttViewItem*) itemAt(e->pos() ) );
|
|
}
|
|
|
|
}
|
|
|
|
|
|
void KDListView::drawToPainter ( TQPainter * p, bool drawHeader )
|
|
{
|
|
// Draw list
|
|
drawAllContents ( p, 0, 0, contentsWidth(), contentsHeight() );
|
|
if (!drawHeader) {
|
|
return;
|
|
}
|
|
// Draw headers
|
|
TQPen pen = TQPen(Qt::lightGray, 1);
|
|
p->save();
|
|
TQHeader *h = header();
|
|
for (int s = 0; s < h->count(); ++s) {
|
|
TQRect r = h->sectionRect(s);
|
|
if (s==0) {
|
|
p->translate(0, -r.height());
|
|
}
|
|
//kdDebug()<<s<<": "<<h->label(s)<<" "<<r<<endl;
|
|
p->drawText(r.x()+2, r.y(), r.width()-2, r.height(), columnAlignment(s)|Qt::AlignVCenter, h->label(s), -1);
|
|
p->save();
|
|
p->setPen(pen);
|
|
p->drawRect(r.x(), r.y()+1, r.width(), r.height()-2);
|
|
p->restore();
|
|
|
|
}
|
|
p->restore();
|
|
}
|
|
|
|
int KDListView::buildDrawables(TQPtrList<KDListView::DrawableItem> &lst, int level, int ypos, TQListViewItem *item, int ymin, int ymax) const {
|
|
int y = ypos;
|
|
int ih = item->height();
|
|
if (y < ymin && y+ih > ymin) {
|
|
y = ymin; // include partial item at top
|
|
}
|
|
if (y >= ymin && y < ymax) { // include partial item at bottom
|
|
KDListView::DrawableItem *dr = new KDListView::DrawableItem(level, y, item);
|
|
lst.append(dr);
|
|
//kdDebug()<<k_funcinfo<<level<<", "<<y<<" : "<<item->text(0)<<endl;
|
|
}
|
|
y += ih;
|
|
if (item->isOpen()) {
|
|
TQListViewItem *child = item->firstChild();
|
|
for (; child; child = child->nextSibling()) {
|
|
y = buildDrawables(lst, level+1, y, child, ymin, ymax);
|
|
}
|
|
}
|
|
return y;
|
|
}
|
|
// This is a copy of TQListView::drawContentsOffset(), with a few changes
|
|
// because drawContentsOffset() only draws *visible* items,
|
|
// we want to draw *all* items.
|
|
// FIXME: Haven't got paintBraches() to work, atm live without it.
|
|
void KDListView::drawAllContents(TQPainter * p, int cx, int cy, int cw, int ch) {
|
|
if ( columns() == 0 ) {
|
|
paintEmptyArea( p, TQRect( cx, cy, cw, ch ) );
|
|
return;
|
|
}
|
|
//kdDebug()<<k_funcinfo<<TQRect(cx, cy, cw, ch)<<endl;
|
|
TQPtrList<KDListView::DrawableItem> drawables;
|
|
drawables.setAutoDelete(true);
|
|
TQListViewItem *child = firstChild();
|
|
int level = 0;
|
|
int ypos = 0;
|
|
for (; child; child = child->nextSibling()) {
|
|
ypos = buildDrawables(drawables, level, ypos, child, cy, cy+ch);
|
|
}
|
|
|
|
p->setFont( font() );
|
|
|
|
TQPtrListIterator<KDListView::DrawableItem> it(drawables);
|
|
|
|
TQRect r;
|
|
int fx = -1, x, fc = 0, lc = 0;
|
|
int tx = -1;
|
|
KDListView::DrawableItem * current;
|
|
|
|
while ( (current = it.current()) != 0 ) {
|
|
++it;
|
|
int ih = current->i->height();
|
|
int ith = current->i->totalHeight();
|
|
int c;
|
|
int cs;
|
|
|
|
// need to paint current?
|
|
if ( ih > 0 && current->y < cy+ch && current->y+ih > cy ) {
|
|
//kdDebug()<<k_funcinfo<<"Paint: "<<current->i->text(0)<<" y="<<current->y<<endl;
|
|
if ( fx < 0 ) {
|
|
// find first interesting column, once
|
|
x = 0;
|
|
c = 0;
|
|
cs = header()->cellSize( 0 );
|
|
while ( x + cs <= cx && c < header()->count() ) {
|
|
x += cs;
|
|
c++;
|
|
if ( c < header()->count() )
|
|
cs = header()->cellSize( c );
|
|
}
|
|
fx = x;
|
|
fc = c;
|
|
while( x < cx + cw && c < header()->count() ) {
|
|
x += cs;
|
|
c++;
|
|
if ( c < header()->count() )
|
|
cs = header()->cellSize( c );
|
|
}
|
|
lc = c;
|
|
}
|
|
|
|
x = fx;
|
|
c = fc;
|
|
// draw to last interesting column
|
|
|
|
const TQColorGroup &cg = ( palette().inactive() );
|
|
|
|
while ( c < lc && !drawables.isEmpty() ) {
|
|
int i = header()->mapToLogical( c );
|
|
cs = header()->cellSize( c );
|
|
r.setRect( x, current->y-cy, cs, ih );
|
|
if ( i == 0 )
|
|
r.setLeft( r.left() + current->l * treeStepSize() );
|
|
|
|
p->save();
|
|
// No need to paint if the cell isn't technically visible
|
|
if ( !( r.width() == 0 || r.height() == 0 ) ) {
|
|
p->translate( r.left(), r.top() );
|
|
int ac = header()->mapToLogical( c );
|
|
// map to Left currently. This should change once we
|
|
// can really reverse the listview.
|
|
int align = columnAlignment( ac );
|
|
if ( align == AlignAuto ) align = AlignLeft;
|
|
bool sel = current->i->isSelected();
|
|
if (sel)
|
|
current->i->setSelected(false);
|
|
current->i->paintCell( p, cg, ac, r.width(), align );
|
|
if (sel)
|
|
current->i->setSelected(sel);
|
|
}
|
|
p->restore();
|
|
x += cs;
|
|
c++;
|
|
}
|
|
|
|
}
|
|
|
|
const int cell = header()->mapToActual( 0 );
|
|
|
|
if ( tx < 0 )
|
|
tx = header()->cellPos( cell );
|
|
|
|
// do any children of current need to be painted?
|
|
/* FIXME: painting branches doesn't work for some reason...
|
|
if ( ih != ith &&
|
|
rootIsDecorated() &&
|
|
current->y + ith > cy &&
|
|
current->y + ih < cy + ch &&
|
|
tx + current->l * treeStepSize() < cx + cw &&
|
|
tx + (current->l+1) * treeStepSize() > cx ) {
|
|
// compute the clip rectangle the safe way
|
|
|
|
int rtop = current->y + ih;
|
|
int rbottom = current->y + ith;
|
|
int rleft = tx + current->l*treeStepSize();
|
|
int rright = rleft + treeStepSize();
|
|
|
|
int crtop = QMAX( rtop, cy );
|
|
int crbottom = QMIN( rbottom, cy+ch );
|
|
int crleft = QMAX( rleft, cx );
|
|
int crright = QMIN( rright, cx+cw );
|
|
|
|
r.setRect( crleft, crtop,
|
|
crright-crleft, crbottom-crtop );
|
|
|
|
if ( r.isValid() ) {
|
|
p->save();
|
|
p->translate( rleft, crtop );
|
|
//kdDebug()<<k_funcinfo<<"paintBranches: "<<current->i->text(0)<<endl;
|
|
|
|
current->i->paintBranches( p, tqcolorGroup(), treeStepSize(),
|
|
rtop - crtop, r.height() );
|
|
p->restore();
|
|
}
|
|
}*/
|
|
}
|
|
}
|
|
|
|
void KDListView::resizeEvent(TQResizeEvent *)
|
|
{
|
|
triggerUpdate ();
|
|
}
|
|
void KDListView::dragEnterEvent ( TQDragEnterEvent * e)
|
|
{
|
|
if ( !myGanttView->dropEnabled() ) {
|
|
e->accept( false );
|
|
return;
|
|
}
|
|
myGanttView->lvDragEnterEvent(e);
|
|
//e->accept(KDGanttViewItemDrag::canDecode(e) );
|
|
}
|
|
|
|
void KDListView::dragMoveEvent ( TQDragMoveEvent * e)
|
|
{
|
|
if ( !myGanttView->dropEnabled() ) {
|
|
e->accept( false );
|
|
return;
|
|
}
|
|
KDGanttViewItem* draggedItem = 0;
|
|
KDGanttViewItem* gItem = (KDGanttViewItem*)itemAt( e->pos()) ;
|
|
setCurrentItem( gItem );
|
|
if ( e->source() == myGanttView )
|
|
draggedItem = myGanttView->myCanvasView->lastClickedItem;
|
|
// execute user defined dragMoveEvent handling
|
|
if (myGanttView->lvDragMoveEvent ( e , draggedItem, gItem ) )
|
|
return;
|
|
if ( !KDGanttViewItemDrag::canDecode(e) ) {
|
|
e->accept( false );
|
|
return;
|
|
}
|
|
if ( e->source() == myGanttView && gItem ){
|
|
// internal drag - do not allow to drag the item to a subitem of itself
|
|
KDGanttViewItem* pItem = gItem->parent();
|
|
while ( pItem ) {
|
|
if ( pItem == myGanttView->myCanvasView->lastClickedItem ) {
|
|
e->accept( false );
|
|
return;
|
|
}
|
|
pItem = pItem->parent();
|
|
}
|
|
if ( gItem == myGanttView->myCanvasView->lastClickedItem ) {
|
|
e->accept( false );
|
|
return;
|
|
}
|
|
}
|
|
e->accept( true );
|
|
}
|
|
|
|
void KDListView::dragLeaveEvent ( TQDragLeaveEvent * )
|
|
{
|
|
//qDebug("contentsDragLeaveEvent ");
|
|
}
|
|
void KDListView::dropEvent ( TQDropEvent *e )
|
|
{
|
|
if ( !myGanttView->dropEnabled() ) {
|
|
e->accept( false );
|
|
return;
|
|
}
|
|
KDGanttViewItem* gItem = (KDGanttViewItem*)itemAt( e->pos()) ;
|
|
KDGanttViewItem* draggedItem = 0;
|
|
if ( e->source() == myGanttView )
|
|
draggedItem = myGanttView->myCanvasView->lastClickedItem;
|
|
if (myGanttView->lvDropEvent ( e, draggedItem, gItem ))
|
|
return;
|
|
TQString string;
|
|
KDGanttViewItemDrag::decode( e, string );
|
|
KDGanttViewItem* newItem = 0;
|
|
|
|
if ( gItem == myGanttView->myCanvasView->lastClickedItem && gItem != 0 ) {
|
|
qDebug("KDGanttView::Possible bug in drag&drop code ");
|
|
return;
|
|
}
|
|
|
|
TQDomDocument doc( "GanttView" );
|
|
doc.setContent( string );
|
|
TQDomElement docRoot = doc.documentElement(); // ChartParams element
|
|
TQDomNode node = docRoot.firstChild();
|
|
bool enable = myGanttView->myTimeTable->blockUpdating( );
|
|
myGanttView->myTimeTable->setBlockUpdating( true );
|
|
while( !node.isNull() ) {
|
|
TQDomElement element = node.toElement();
|
|
if( !element.isNull() ) { // was really an element
|
|
TQString tagName = element.tagName();
|
|
if( tagName == "Items" ) {
|
|
TQDomNode node = element.firstChild();
|
|
while( !node.isNull() ) {
|
|
TQDomElement element = node.toElement();
|
|
if( !element.isNull() ) { // was really an element
|
|
TQString tagName = element.tagName();
|
|
if( tagName == "Item" ) {
|
|
if ( gItem )
|
|
newItem = KDGanttViewItem::createFromDomElement( gItem,
|
|
element );
|
|
else
|
|
newItem = KDGanttViewItem::createFromDomElement( myGanttView,
|
|
element );
|
|
} else {
|
|
qDebug( "Unrecognized tag name: %s", tagName.latin1() );
|
|
Q_ASSERT( false );
|
|
}
|
|
}
|
|
//qDebug("next node1 ");
|
|
node = node.nextSibling();
|
|
}
|
|
}
|
|
}
|
|
//qDebug("next node2 ");
|
|
node = node.nextSibling();
|
|
}
|
|
newItem->setDisplaySubitemsAsGroup(myGanttView->displaySubitemsAsGroup());
|
|
newItem->resetSubitemVisibility();
|
|
myGanttView->slot_lvDropped(e, draggedItem, gItem);
|
|
myGanttView->myTimeTable->setBlockUpdating( enable );
|
|
myGanttView->myTimeTable->updateMyContent();
|
|
return;
|
|
}
|
|
|
|
TQDragObject * KDListView::dragObject ()
|
|
{
|
|
return TQListView::dragObject ();
|
|
}
|
|
|
|
void KDListView::startDrag ()
|
|
{
|
|
if ( ! myGanttView->dragEnabled() )
|
|
return;
|
|
KDGanttViewItem* cItem = (KDGanttViewItem*) currentItem ();
|
|
myGanttView->myCanvasView->lastClickedItem = cItem;
|
|
myGanttView->lvStartDrag (cItem);
|
|
}
|
|
|
|
KDCanvasText::KDCanvasText( KDTimeTableWidget* canvas,
|
|
void* parentItem,
|
|
int type ) :
|
|
TQCanvasText(canvas)
|
|
{
|
|
myParentType = type;
|
|
myParentItem = parentItem;
|
|
}
|
|
|
|
|
|
KDCanvasLine::KDCanvasLine( KDTimeTableWidget* canvas,
|
|
void* parentItem,
|
|
int type ) :
|
|
TQCanvasLine(canvas)
|
|
{
|
|
myParentType = type;
|
|
myParentItem = parentItem;
|
|
}
|
|
|
|
|
|
KDCanvasPolygonItem::KDCanvasPolygonItem( KDTimeTableWidget* canvas,
|
|
void* parentItem,
|
|
int type ) :
|
|
TQCanvasPolygonalItem( canvas )
|
|
{
|
|
myParentType = type;
|
|
myParentItem = parentItem;
|
|
}
|
|
|
|
|
|
KDCanvasPolygon::KDCanvasPolygon( KDTimeTableWidget* canvas,
|
|
void* parentItem,
|
|
int type ) :
|
|
TQCanvasPolygon( canvas )
|
|
{
|
|
myParentType = type;
|
|
myParentItem = parentItem;
|
|
}
|
|
|
|
|
|
KDCanvasEllipse::KDCanvasEllipse( KDTimeTableWidget* canvas,
|
|
void* parentItem,
|
|
int type ) :
|
|
TQCanvasEllipse( canvas )
|
|
{
|
|
myParentType = type;
|
|
myParentItem = parentItem;
|
|
}
|
|
|
|
|
|
KDCanvasRectangle::KDCanvasRectangle( KDTimeTableWidget* canvas,
|
|
void* parentItem,
|
|
int type ) :
|
|
TQCanvasRectangle( canvas )
|
|
{
|
|
myParentType = type;
|
|
myParentItem = parentItem;
|
|
}
|
|
|
|
|
|
|
|
|
|
KDGanttCanvasView::KDGanttCanvasView( KDGanttView* sender,TQCanvas* canvas, TQWidget* parent, const
|
|
char* name ) : TQCanvasView ( canvas, parent, name ),
|
|
movingGVItem( 0 ),
|
|
scrollBarTimer( 0, "scrollBarTimer" )
|
|
{
|
|
setHScrollBarMode (TQScrollView::AlwaysOn );
|
|
setVScrollBarMode( TQScrollView::AlwaysOn );
|
|
myToolTip = new KDCanvasToolTip(viewport(),this);
|
|
mySignalSender = sender;
|
|
currentItem = 0;
|
|
currentLink = 0;
|
|
cuttedItem = 0;
|
|
fromItem = 0;
|
|
fromArea = 0;
|
|
linkItemsEnabled = false;
|
|
mouseDown = false;
|
|
linkLine = new TQCanvasLine(canvas);
|
|
linkLine->hide();
|
|
linkLine->setZ(1000);
|
|
set_Mouse_Tracking(true); // mouse cursor changes over KDIntervalColorRectangle borders
|
|
new KDCanvasWhatsThis(viewport(),this);
|
|
onItem = new TQPopupMenu( this );
|
|
TQPopupMenu * newMenu = new TQPopupMenu( this );
|
|
TQPopupMenu * onView = new TQPopupMenu( this );
|
|
onView->insertItem( i18n( "Summary" ), this,
|
|
TQT_SLOT ( newRootItem( int ) ), 0, 0 );
|
|
onView->insertItem( i18n( "Event" ), this,
|
|
TQT_SLOT ( newRootItem( int ) ), 0, 1);
|
|
onView->insertItem( i18n( "Task" ), this,
|
|
TQT_SLOT ( newRootItem( int ) ), 0, 2 );
|
|
|
|
onItem->insertItem( i18n( "New Root" ), onView );
|
|
newMenu->insertItem( i18n( "Summary" ),
|
|
this, TQT_SLOT ( newChildItem( int) ), 0, 0 );
|
|
newMenu->insertItem( i18n( "Event" ),
|
|
this, TQT_SLOT ( newChildItem( int ) ), 0, 1 );
|
|
newMenu->insertItem( i18n( "Task" ),
|
|
this, TQT_SLOT ( newChildItem( int ) ), 0, 2 );
|
|
|
|
onItem->insertItem( i18n( "New Child" ), newMenu );
|
|
TQPopupMenu * afterMenu = new TQPopupMenu( this );
|
|
afterMenu->insertItem( i18n( "Summary" ),
|
|
this, TQT_SLOT ( newChildItem( int) ), 0, 0+4 );
|
|
afterMenu->insertItem( i18n( "Event" ),
|
|
this, TQT_SLOT ( newChildItem( int ) ), 0, 1+4 );
|
|
afterMenu->insertItem( i18n( "Task" ),
|
|
this, TQT_SLOT ( newChildItem( int ) ), 0, 2+4 );
|
|
onItem->insertItem( i18n( "New After" ), afterMenu );
|
|
TQPopupMenu *pasteMenu = new TQPopupMenu( this );
|
|
pasteMenu->insertItem( i18n( "As Root" ),
|
|
this, TQT_SLOT ( pasteItem( int ) ), 0, 0 );
|
|
pasteMenu->insertItem( i18n( "As Child" ),
|
|
this, TQT_SLOT ( pasteItem( int ) ), 0, 1 );
|
|
pasteMenu->insertItem( i18n( "After" ),
|
|
this, TQT_SLOT ( pasteItem( int ) ), 0, 2 );
|
|
onItem->insertItem( i18n( "Paste" ), pasteMenu, 3 );
|
|
onItem->insertItem( i18n( "Cut Item" ), this, TQT_SLOT ( cutItem() ) );
|
|
onItem->setItemEnabled( 3, false );
|
|
myMyContentsHeight = 0;
|
|
_showItemAddPopupMenu = false;
|
|
|
|
TQObject *scrollViewTimer = child( "scrollview scrollbar timer", TQTIMER_OBJECT_NAME_STRING, false );
|
|
Q_ASSERT( scrollViewTimer );
|
|
if ( scrollViewTimer ) {
|
|
disconnect( scrollViewTimer, TQT_SIGNAL(timeout()), this, TQT_SLOT(updateScrollBars() ) );
|
|
}
|
|
// If they needed a scrollbar timer in scrollview...
|
|
connect( &scrollBarTimer, TQT_SIGNAL(timeout()), this, TQT_SLOT(myUpdateScrollBars() ) );
|
|
|
|
myScrollTimer = new TQTimer( this, "myScrollTimer" );
|
|
connect( myScrollTimer, TQT_SIGNAL( timeout() ), TQT_SLOT( slotScrollTimer() ) );
|
|
autoScrollEnabled = false;
|
|
}
|
|
|
|
|
|
KDGanttCanvasView::~KDGanttCanvasView()
|
|
{
|
|
delete myToolTip;
|
|
}
|
|
|
|
|
|
void KDGanttCanvasView::setShowPopupMenu( bool show )
|
|
{
|
|
_showItemAddPopupMenu = show;
|
|
}
|
|
bool KDGanttCanvasView::showPopupMenu()
|
|
{
|
|
return _showItemAddPopupMenu;
|
|
}
|
|
|
|
|
|
void KDGanttCanvasView::moveMyContent( int, int y)
|
|
{
|
|
setContentsPos(contentsX(), y);
|
|
}
|
|
|
|
void KDGanttCanvasView::resizeEvent ( TQResizeEvent * e )
|
|
{
|
|
int ho = e->oldSize().height();
|
|
int wo = e->oldSize().width();
|
|
int hi = height();
|
|
int wi = width();
|
|
//TQScrollView::blockSignals( true );
|
|
|
|
verticalScrollBar()->setUpdatesEnabled( false );
|
|
TQScrollView::resizeEvent ( e ) ;
|
|
if ( ho != hi )
|
|
emit heightResized( viewport()->height());
|
|
if ( wo != wi )
|
|
emit widthResized( viewport()->width() );
|
|
//setMyContentsHeight( 0 ); // via timer
|
|
//TQScrollView::blockSignals( false );
|
|
scrollBarTimer.start(0, true);
|
|
}
|
|
|
|
void KDGanttCanvasView::myUpdateScrollBars()
|
|
{
|
|
setMyContentsHeight( 0 );
|
|
}
|
|
void KDGanttCanvasView::setMyContentsHeight( int hei )
|
|
{
|
|
//qDebug("setMyContentsHeight %d %d ", hei, myMyContentsHeight);
|
|
if ( hei > 0 )
|
|
myMyContentsHeight = hei;
|
|
verticalScrollBar()->setUpdatesEnabled( true ); // set false in resizeEvent()
|
|
if ( viewport()->height() <= myMyContentsHeight )
|
|
verticalScrollBar()->setRange( 0, myMyContentsHeight- viewport()->height()+1);
|
|
else
|
|
verticalScrollBar()->setRange( 0,0 );
|
|
// testing for unmatching ScrollBar values of timeheader and timetable
|
|
// may happen after external resizing
|
|
if ( horizontalScrollBar()->value() != mySignalSender->myTimeHeaderScroll->horizontalScrollBar()->value() ) {
|
|
// I am the Boss!
|
|
mySignalSender->myTimeHeaderScroll->horizontalScrollBar()->setValue(horizontalScrollBar()->value() );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Call after *internal* resizing (like addTickRight())
|
|
// Then the new scrollbar maxValue is in myTimeHeader.
|
|
void KDGanttCanvasView::updateHorScrollBar() {
|
|
//qDebug("horizontalScrollBar max=%d, myTimeHeaderScroll=%d", horizontalScrollBar()->maxValue(), mySignalSender->myTimeHeaderScroll->horizontalScrollBar()->value());
|
|
|
|
horizontalScrollBar()->setRange(mySignalSender->myTimeHeaderScroll->horizontalScrollBar()->minValue(), mySignalSender->myTimeHeaderScroll->horizontalScrollBar()->maxValue());
|
|
|
|
}
|
|
|
|
void KDGanttCanvasView::cutItem( KDGanttViewItem* item )
|
|
{
|
|
lastClickedItem = item;
|
|
cutItem();
|
|
}
|
|
void KDGanttCanvasView::insertItemAsRoot( KDGanttViewItem* item )
|
|
{
|
|
mySignalSender->myListView->insertItem( item );
|
|
if ( item == cuttedItem )
|
|
cuttedItem = 0;
|
|
}
|
|
void KDGanttCanvasView::insertItemAsChild( KDGanttViewItem* parent, KDGanttViewItem* item )
|
|
{
|
|
parent->insertItem( cuttedItem );
|
|
if ( item == cuttedItem )
|
|
cuttedItem = 0;
|
|
}
|
|
void KDGanttCanvasView::insertItemAfter( KDGanttViewItem* parent , KDGanttViewItem* item )
|
|
{
|
|
if ( parent->parent() ) {
|
|
parent->parent()->insertItem( item );
|
|
}
|
|
else
|
|
mySignalSender->myListView->insertItem( item );
|
|
item->moveItem( parent );
|
|
if ( item == cuttedItem )
|
|
cuttedItem = 0;
|
|
}
|
|
|
|
void KDGanttCanvasView::cutItem()
|
|
{
|
|
lastClickedItem->hideSubtree();
|
|
//qDebug("last clicked %d parent %d ", lastClickedItem , lastClickedItem->parent());
|
|
if ( lastClickedItem->parent() )
|
|
lastClickedItem->parent()->takeItem(lastClickedItem);
|
|
else
|
|
mySignalSender->myListView->takeItem( lastClickedItem );
|
|
mySignalSender->myTimeTable->updateMyContent();
|
|
if ( cuttedItem )
|
|
delete cuttedItem;
|
|
cuttedItem = lastClickedItem;
|
|
onItem->setItemEnabled( 3, true );
|
|
|
|
}
|
|
// called from the destructor in KDGanttViewItem or KDGanttView
|
|
|
|
void KDGanttCanvasView::resetCutPaste( KDGanttViewItem* item )
|
|
{
|
|
if ( item == 0 && cuttedItem ) {
|
|
delete cuttedItem;
|
|
cuttedItem = 0;
|
|
}
|
|
if (item == cuttedItem) {
|
|
onItem->setItemEnabled( 3, false );
|
|
cuttedItem = 0;
|
|
}
|
|
}
|
|
|
|
void KDGanttCanvasView::pasteItem( int type )
|
|
{
|
|
if ( !cuttedItem )
|
|
return;
|
|
switch( type ) {
|
|
case 0://root
|
|
mySignalSender->myListView->insertItem( cuttedItem );
|
|
break;
|
|
case 1://child
|
|
lastClickedItem->insertItem( cuttedItem );
|
|
break;
|
|
case 2://after
|
|
if ( lastClickedItem->parent() ) {
|
|
lastClickedItem->parent()->insertItem( cuttedItem );
|
|
}
|
|
else
|
|
mySignalSender->myListView->insertItem( cuttedItem );
|
|
cuttedItem->moveItem( lastClickedItem );
|
|
break;
|
|
default:
|
|
;
|
|
}
|
|
cuttedItem = 0;
|
|
onItem->setItemEnabled( 3, false );
|
|
mySignalSender->myTimeTable->updateMyContent();
|
|
}
|
|
void KDGanttCanvasView::newRootItem(int type)
|
|
{
|
|
KDGanttViewItem* temp = 0;
|
|
switch( type ) {
|
|
case 1:
|
|
temp = new KDGanttViewEventItem( mySignalSender, i18n( "New Event" ) );
|
|
break;
|
|
case 0:
|
|
temp = new KDGanttViewSummaryItem( mySignalSender, i18n( "New Summary" ) );
|
|
break;
|
|
case 2:
|
|
temp = new KDGanttViewTaskItem( mySignalSender, i18n( "New Task" ) );
|
|
break;
|
|
default:
|
|
;
|
|
}
|
|
if ( temp )
|
|
mySignalSender->editItem( temp );
|
|
}
|
|
|
|
void KDGanttCanvasView::newChildItem( int type )
|
|
{
|
|
KDGanttViewItem* temp = 0;
|
|
switch( type ) {
|
|
case 1:
|
|
temp = new KDGanttViewEventItem( lastClickedItem, i18n( "New Event" ) );
|
|
break;
|
|
case 0:
|
|
temp = new KDGanttViewSummaryItem( lastClickedItem, i18n( "New Summary" ) );
|
|
break;
|
|
case 2:
|
|
temp = new KDGanttViewTaskItem( lastClickedItem, i18n( "New Task" ) );
|
|
break;
|
|
case 5:
|
|
if ( lastClickedItem->parent() )
|
|
temp = new KDGanttViewEventItem( lastClickedItem->parent(), lastClickedItem, i18n( "New Event" ) );
|
|
else
|
|
temp = new KDGanttViewEventItem( mySignalSender, lastClickedItem, i18n( "New Event" ) );
|
|
break;
|
|
case 4:
|
|
if ( lastClickedItem->parent() )
|
|
temp = new KDGanttViewSummaryItem( lastClickedItem->parent(), lastClickedItem, i18n( "New Summary" ) );
|
|
else
|
|
temp = new KDGanttViewSummaryItem( mySignalSender, lastClickedItem, i18n( "New Summary" ) );
|
|
break;
|
|
case 6:
|
|
if ( lastClickedItem->parent() )
|
|
temp = new KDGanttViewTaskItem( lastClickedItem->parent(), lastClickedItem, i18n( "New Task" ) );
|
|
else
|
|
temp = new KDGanttViewTaskItem( mySignalSender, lastClickedItem, i18n( "New Task" ) );
|
|
break;
|
|
|
|
|
|
default:
|
|
;
|
|
}
|
|
if ( temp )
|
|
mySignalSender->editItem( temp );
|
|
}
|
|
|
|
void KDGanttCanvasView::drawToPainter ( TQPainter * p )
|
|
{
|
|
drawContents ( p, 0, 0, canvas()->width(), canvas()->height() );
|
|
}
|
|
TQString KDGanttCanvasView::getToolTipText(TQPoint p)
|
|
{
|
|
TQCanvasItemList il = canvas()->collisions ( viewportToContents( p ));
|
|
TQCanvasItemList::Iterator it;
|
|
for ( it = il.begin(); it != il.end(); ++it ) {
|
|
switch (getType(*it)) {
|
|
case Type_is_KDGanttViewItem:
|
|
return (getItem(*it))->tooltipText();
|
|
break;
|
|
case Type_is_KDGanttTaskLink:
|
|
return (getLink(*it))->tooltipText();
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
return "";
|
|
}
|
|
|
|
TQString KDGanttCanvasView::getWhatsThisText(TQPoint p)
|
|
{
|
|
TQCanvasItemList il = canvas() ->collisions (viewportToContents( p ));
|
|
TQCanvasItemList::Iterator it;
|
|
for ( it = il.begin(); it != il.end(); ++it ) {
|
|
switch (getType(*it)) {
|
|
case Type_is_KDGanttViewItem:
|
|
return (getItem(*it))->whatsThisText();
|
|
break;
|
|
case Type_is_KDGanttTaskLink:
|
|
return (getLink(*it))->whatsThisText();
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
return "";
|
|
}
|
|
|
|
|
|
KDGanttCanvasView::MovingOperation KDGanttCanvasView::gvItemHitTest( KDGanttViewItem *item, KDTimeHeaderWidget* timeHeader, const TQPoint &pos )
|
|
{
|
|
const int left = timeHeader->getCoordX( item->startTime() );
|
|
const int right = timeHeader->getCoordX( item->endTime() );
|
|
const int width = right - left + 1;
|
|
const int x = pos.x();
|
|
if ( x < left + width / 10 )
|
|
return KDGanttCanvasView::ResizingLeft;
|
|
if ( x > right - width / 10 )
|
|
return KDGanttCanvasView::ResizingRight;
|
|
return KDGanttCanvasView::Moving;
|
|
}
|
|
|
|
/**
|
|
Handles the mouseevent if a mousekey is pressed
|
|
|
|
\param e the mouseevent
|
|
|
|
*/
|
|
|
|
void KDGanttCanvasView::contentsMousePressEvent ( TQMouseEvent * e )
|
|
{
|
|
//qDebug("mousepress! %d ", this);
|
|
//qDebug("focus %d ",tqApp->tqfocusWidget());
|
|
setFocus();
|
|
currentLink = 0;
|
|
currentItem = 0;
|
|
movingItem = 0;
|
|
mouseDown = true;
|
|
if (e->button() == RightButton && mySignalSender->editable()) {
|
|
lastClickedItem = (KDGanttViewItem*) mySignalSender->myListView->itemAt( TQPoint(2,e->pos().y()));
|
|
if ( lastClickedItem ) {
|
|
if ( lastClickedItem->displaySubitemsAsGroup() && ! lastClickedItem->isOpen() ) {
|
|
// findSub subitem
|
|
TQCanvasItemList il = canvas() ->collisions ( e->pos() );
|
|
TQCanvasItemList::Iterator it;
|
|
for ( it = il.begin(); it != il.end(); ++it ) {
|
|
if ( getType(*it) == Type_is_KDGanttViewItem ) {
|
|
lastClickedItem = getItem(*it);
|
|
}
|
|
}
|
|
}
|
|
if ( _showItemAddPopupMenu )
|
|
onItem->popup(e->globalPos());
|
|
}
|
|
}
|
|
TQCanvasItemList il = canvas() ->collisions ( e->pos() );
|
|
TQCanvasItemList::Iterator it;
|
|
for ( it = il.begin(); it != il.end(); ++it ) {
|
|
switch ( e->button() ) {
|
|
case LeftButton:
|
|
switch (getType(*it)) {
|
|
case Type_is_KDGanttViewItem:
|
|
currentItem = getItem(*it);
|
|
if (! currentItem->enabled() ) {
|
|
currentItem = 0;
|
|
} else if (linkItemsEnabled &&
|
|
!currentItem->isMyTextCanvas(*it)) {
|
|
fromArea = getItemArea(currentItem, e->pos().x());
|
|
if (fromArea > 0) {
|
|
fromItem = currentItem;
|
|
linkLine->setPoints(e->pos().x(), e->pos().y(), e->pos().x(), e->pos().y());
|
|
linkLine->show();
|
|
}
|
|
}
|
|
{
|
|
KDCanvasRectangle *rect = dynamic_cast<KDCanvasRectangle*>( *it );
|
|
if ( rect ) {
|
|
movingGVItem = dynamic_cast<KDGanttViewTaskItem*>( getItem( rect ) );
|
|
if ( movingGVItem ) {
|
|
movingStart = e->pos();
|
|
movingStartDate = movingGVItem->startTime();
|
|
movingOperation = gvItemHitTest( movingGVItem, mySignalSender->myTimeHeader, e->pos() );
|
|
if ( movingOperation == Moving && !movingGVItem->isMoveable() )
|
|
movingGVItem = 0;
|
|
else if ( movingOperation != Moving && !movingGVItem->isResizeable() )
|
|
movingOperation = Moving;
|
|
} else {
|
|
movingGVItem = 0;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case Type_is_KDGanttTaskLink:
|
|
currentLink = getLink(*it);
|
|
break;
|
|
case Type_is_KDGanttGridItem:
|
|
if ( (*it)->rtti() == KDIntervalColorRectangle::RTTI ) {
|
|
// Cleaner would be isMovable()/isResizeable() in an interface
|
|
// implemented by all movable objects...
|
|
movingItem = static_cast<TQCanvasRectangle *>(*it);
|
|
movingStart = e->pos();
|
|
KDIntervalColorRectangle* icr = static_cast<KDIntervalColorRectangle *>( movingItem );
|
|
KDIntervalColorRectangle::HitTest hitTest = icr->hitTest( mySignalSender->myTimeHeader, movingStart );
|
|
movingOperation = hitTest == KDIntervalColorRectangle::Start ? ResizingLeft :
|
|
hitTest == KDIntervalColorRectangle::End ? ResizingRight :
|
|
Moving;
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
break;
|
|
case RightButton:
|
|
switch (getType(*it)) {
|
|
case Type_is_KDGanttViewItem:
|
|
currentItem = getItem(*it);
|
|
if (! currentItem->enabled() )
|
|
currentItem = 0;
|
|
break;
|
|
case Type_is_KDGanttTaskLink:
|
|
currentLink = getLink(*it);
|
|
break;
|
|
}
|
|
break;
|
|
case MidButton:
|
|
switch (getType(*it)) {
|
|
case Type_is_KDGanttViewItem:
|
|
currentItem = getItem(*it);
|
|
if (! currentItem->enabled() )
|
|
currentItem = 0;
|
|
break;
|
|
case Type_is_KDGanttTaskLink:
|
|
currentLink = getLink(*it);
|
|
break;
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
if (e->button() == RightButton ) {
|
|
mySignalSender->gvContextMenuRequested( currentItem, e->globalPos() );
|
|
}
|
|
if (autoScrollEnabled && e->button() == LeftButton) {
|
|
myScrollTimer->start(50);
|
|
}
|
|
}
|
|
/**
|
|
Handles the mouseevent if a mousekey is released
|
|
|
|
\param e the mouseevent
|
|
|
|
*/
|
|
|
|
void KDGanttCanvasView::contentsMouseReleaseEvent ( TQMouseEvent * e )
|
|
{
|
|
mouseDown = false;
|
|
static KDGanttViewItem* lastClicked = 0;
|
|
mySignalSender->gvMouseButtonClicked( e->button(), currentItem , e->globalPos() );
|
|
//qDebug("datetime %s ",mySignalSender->getDateTimeForCoordX(e->globalPos().x(), true ).toString().latin1() );
|
|
//qDebug("mousepos %d %d ",e->pos().x(),e->pos().y() );
|
|
//qDebug("mouseup ");
|
|
// if ( currentLink || currentItem )
|
|
{
|
|
switch ( e->button() ) {
|
|
case LeftButton:
|
|
myScrollTimer->stop();
|
|
{
|
|
mySignalSender->itemLeftClicked( currentItem );
|
|
mySignalSender->gvItemLeftClicked( currentItem );
|
|
}
|
|
if ( currentLink )
|
|
mySignalSender->taskLinkLeftClicked( currentLink );
|
|
if (linkItemsEnabled && fromItem) {
|
|
linkLine->hide();
|
|
canvas()->update();
|
|
TQCanvasItemList il = canvas() ->collisions ( e->pos() );
|
|
TQCanvasItemList::Iterator it;
|
|
for ( it = il.begin(); it != il.end(); ++it ) {
|
|
if (getType(*it) == Type_is_KDGanttViewItem) {
|
|
KDGanttViewItem *toItem = getItem(*it);
|
|
if (!toItem->isMyTextCanvas(*it)) {
|
|
int toArea = getItemArea(toItem, e->pos().x());
|
|
if (toArea > 0 && toItem && fromItem != toItem) {
|
|
mySignalSender->linkItems(fromItem, toItem, getLinkType(fromArea, toArea));
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
fromItem = 0;
|
|
if ( movingGVItem ) {
|
|
mySignalSender->gvItemMoved( movingGVItem );
|
|
movingGVItem = 0;
|
|
}
|
|
break;
|
|
case RightButton:
|
|
{
|
|
mySignalSender->itemRightClicked( currentItem );
|
|
mySignalSender->gvItemRightClicked( currentItem );
|
|
|
|
}
|
|
if ( currentLink )
|
|
mySignalSender->taskLinkRightClicked( currentLink );
|
|
break;
|
|
case MidButton:
|
|
{
|
|
mySignalSender->itemMidClicked( currentItem );
|
|
mySignalSender->gvItemMidClicked( currentItem );
|
|
}
|
|
if ( currentLink )
|
|
mySignalSender->taskLinkRightClicked( currentLink );
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
if ( lastClicked != currentItem )
|
|
mySignalSender->gvCurrentChanged( currentItem );
|
|
lastClicked = currentItem;
|
|
currentLink = 0;
|
|
currentItem = 0;
|
|
}
|
|
/**
|
|
Handles the mouseevent if a mousekey is doubleclicked
|
|
|
|
\param e the mouseevent
|
|
|
|
*/
|
|
|
|
void KDGanttCanvasView::contentsMouseDoubleClickEvent ( TQMouseEvent * e )
|
|
{
|
|
TQCanvasItemList il = canvas() ->collisions ( e->pos() );
|
|
|
|
if ( il.isEmpty() && e->button() == LeftButton ) {
|
|
//not directly sending a signal here (encapsulation and whatnot)
|
|
mySignalSender->emptySpaceDoubleClicked(e);
|
|
return;
|
|
}
|
|
|
|
TQCanvasItemList::Iterator it;
|
|
for ( it = il.begin(); it != il.end(); ++it ) {
|
|
switch ( e->button() ) {
|
|
case LeftButton:
|
|
switch (getType(*it)) {
|
|
case Type_is_KDGanttViewItem:
|
|
if ( getItem(*it)->enabled() )
|
|
mySignalSender->itemDoubleClicked(getItem(*it));
|
|
mySignalSender->gvItemDoubleClicked(getItem(*it));
|
|
return;
|
|
break;
|
|
case Type_is_KDGanttTaskLink:
|
|
mySignalSender->taskLinkDoubleClicked(getLink(*it));
|
|
return;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
break;
|
|
/*
|
|
case RightButton:
|
|
switch (getType(*it)) {
|
|
case Type_is_KDGanttViewItem:
|
|
mySignalSender->itemRightClicked(getItem(*it));
|
|
return;
|
|
break;
|
|
case Type_is_KDGanttTaskLink:
|
|
mySignalSender->taskLinkRightClicked(getLink(*it));
|
|
return;
|
|
break;
|
|
}
|
|
break;
|
|
case MidButton:
|
|
switch (getType(*it)) {
|
|
case Type_is_KDGanttViewItem:
|
|
mySignalSender->itemMidClicked(getItem(*it));
|
|
return;
|
|
break;
|
|
case Type_is_KDGanttTaskLink:
|
|
mySignalSender->taskLinkMidClicked(getLink(*it));
|
|
return;
|
|
break;
|
|
}
|
|
break;
|
|
*/
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
/**
|
|
Handles the mouseevent if a mouse button is pressed an the mouse is moved
|
|
|
|
\param e the mouseevent
|
|
|
|
*/
|
|
|
|
void KDGanttCanvasView::contentsMouseMoveEvent ( TQMouseEvent *e )
|
|
{
|
|
if ( !mouseDown ) {
|
|
// Update cursor
|
|
bool found = false;
|
|
TQCanvasItemList il = canvas() ->collisions ( e->pos() );
|
|
TQCanvasItemList::Iterator it;
|
|
for ( it = il.begin(); it != il.end(); ++it ) {
|
|
if ( (*it)->rtti() == KDIntervalColorRectangle::RTTI ) {
|
|
found = true;
|
|
KDIntervalColorRectangle* icr = static_cast<KDIntervalColorRectangle *>( *it );
|
|
KDIntervalColorRectangle::HitTest hitTest = icr->hitTest( mySignalSender->myTimeHeader, e->pos() );
|
|
switch ( hitTest ) {
|
|
case KDIntervalColorRectangle::Start:
|
|
case KDIntervalColorRectangle::End:
|
|
setCursor( splitHCursor );
|
|
break;
|
|
default:
|
|
unsetCursor();
|
|
}
|
|
}
|
|
KDGanttViewItem *gvItem = getItem( *it );
|
|
if ( dynamic_cast<KDGanttViewTaskItem*>( gvItem ) ) {
|
|
found = true;
|
|
MovingOperation op = gvItemHitTest( gvItem, mySignalSender->myTimeHeader, e->pos() );
|
|
switch ( op ) {
|
|
case ResizingLeft:
|
|
case ResizingRight:
|
|
if ( gvItem->isResizeable() )
|
|
setCursor( splitHCursor );
|
|
break;
|
|
default:
|
|
unsetCursor();
|
|
}
|
|
}
|
|
}
|
|
if ( !found )
|
|
unsetCursor();
|
|
return;
|
|
}
|
|
|
|
const TQPoint p = e->pos();
|
|
if ( movingItem ) {
|
|
int x = tqRound( movingItem->x() );
|
|
int width = movingItem->width();
|
|
switch( movingOperation ) {
|
|
case Moving:
|
|
x += p.x() - movingStart.x();
|
|
break;
|
|
case ResizingLeft: {
|
|
width = tqRound( movingItem->x() + movingItem->width() - p.x() );
|
|
x = p.x();
|
|
break;
|
|
}
|
|
case ResizingRight:
|
|
width = p.x() - x;
|
|
break;
|
|
}
|
|
movingStart = p;
|
|
if ( movingItem->rtti() == KDIntervalColorRectangle::RTTI ) {
|
|
KDIntervalColorRectangle* icr = static_cast<KDIntervalColorRectangle *>(movingItem);
|
|
const TQDateTime newStart = mySignalSender->myTimeHeader->getDateTimeForIndex(x);
|
|
const TQDateTime newEnd = mySignalSender->myTimeHeader->getDateTimeForIndex(x + width);
|
|
icr->setDateTimes( newStart, newEnd );
|
|
emit mySignalSender->intervalColorRectangleMoved( newStart, newEnd );
|
|
mySignalSender->myTimeHeader->computeIntervals( movingItem->height() );
|
|
}
|
|
canvas()->update();
|
|
}
|
|
|
|
if ( movingGVItem ) {
|
|
int dx = movingStart.x() - e->pos().x();
|
|
int x = movingGVItem->middleLeft().x() - dx;
|
|
TQDateTime dt = mySignalSender->getDateTimeForCoordX( x, false );
|
|
int duration = movingGVItem->startTime().secsTo( movingGVItem->endTime() );
|
|
if ( movingOperation == Moving ) {
|
|
movingGVItem->setStartTime( dt );
|
|
movingGVItem->setEndTime( dt.addSecs( duration ) );
|
|
} else if ( movingOperation == ResizingLeft ) {
|
|
movingGVItem->setStartTime( dt );
|
|
} else if ( movingOperation == ResizingRight ) {
|
|
movingGVItem->setEndTime( dt.addSecs( duration ) );
|
|
}
|
|
movingStart = e->pos();
|
|
}
|
|
|
|
static int moves = 0;
|
|
if ( (currentLink || currentItem) && (moves < 3) ) {
|
|
++moves;
|
|
} else {
|
|
moves = 0;
|
|
currentLink = 0;
|
|
currentItem = 0;
|
|
}
|
|
if (autoScrollEnabled)
|
|
mousePos = e->pos()- TQPoint(contentsX(),contentsY()); // make mousePos relative 0
|
|
if (fromItem) {
|
|
//qDebug("mousemove: linking %s: %d,%d ",fromItem->listViewText().latin1(), e->pos().x(), e->pos().y());
|
|
linkLine->setPoints(linkLine->startPoint().x(), linkLine->startPoint().y(), e->pos().x(), e->pos().y());
|
|
canvas()->update();
|
|
}
|
|
// no action implemented
|
|
}
|
|
void KDGanttCanvasView::viewportPaintEvent ( TQPaintEvent * pe )
|
|
{
|
|
TQCanvasView::viewportPaintEvent ( pe );
|
|
}
|
|
void KDGanttCanvasView::set_Mouse_Tracking(bool on)
|
|
{
|
|
viewport()->setMouseTracking(on);
|
|
}
|
|
int KDGanttCanvasView::getType(TQCanvasItem* it)
|
|
{
|
|
switch (it->rtti()) {
|
|
case TQCanvasItem::Rtti_Line: return ((KDCanvasLine*)it)->myParentType;
|
|
case TQCanvasItem::Rtti_Ellipse: return ((KDCanvasEllipse *)it)->myParentType;
|
|
case TQCanvasItem::Rtti_Text: return ((KDCanvasText *)it)->myParentType;
|
|
case TQCanvasItem::Rtti_Polygon: return ((KDCanvasPolygon *)it)->myParentType;
|
|
case TQCanvasItem::Rtti_Rectangle:
|
|
case KDIntervalColorRectangle::RTTI:
|
|
return ((KDCanvasRectangle *)it)->myParentType;
|
|
}
|
|
return -1;
|
|
}
|
|
KDGanttViewItem* KDGanttCanvasView::getItem(TQCanvasItem* it)
|
|
{
|
|
switch (it->rtti()) {
|
|
case TQCanvasItem::Rtti_Line: return (KDGanttViewItem*) ((KDCanvasLine*)it)->myParentItem;
|
|
case TQCanvasItem::Rtti_Ellipse: return (KDGanttViewItem*) ((KDCanvasEllipse *)it)->myParentItem;
|
|
case TQCanvasItem::Rtti_Text: return (KDGanttViewItem*) ((KDCanvasText *)it)->myParentItem;
|
|
case TQCanvasItem::Rtti_Polygon: return (KDGanttViewItem*) ((KDCanvasPolygon *)it)->myParentItem;
|
|
case TQCanvasItem::Rtti_Rectangle: return (KDGanttViewItem*) ((KDCanvasRectangle *)it)->myParentItem;
|
|
|
|
}
|
|
return 0;
|
|
}
|
|
KDGanttViewTaskLink* KDGanttCanvasView::getLink(TQCanvasItem* it)
|
|
{
|
|
switch (it->rtti()) {
|
|
case TQCanvasItem::Rtti_Line: return (KDGanttViewTaskLink*) ((KDCanvasLine*)it)->myParentItem;
|
|
case TQCanvasItem::Rtti_Ellipse: return (KDGanttViewTaskLink*) ((KDCanvasEllipse *)it)->myParentItem;
|
|
case TQCanvasItem::Rtti_Text: return (KDGanttViewTaskLink*) ((KDCanvasText *)it)->myParentItem;
|
|
case TQCanvasItem::Rtti_Polygon: return (KDGanttViewTaskLink*) ((KDCanvasPolygon *)it)->myParentItem;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void KDGanttCanvasView::slotScrollTimer() {
|
|
int mx = mousePos.x();
|
|
int my = mousePos.y();
|
|
int dx = 0;
|
|
int dy = 0;
|
|
if (mx < 0)
|
|
dx = -5;
|
|
else if (mx > visibleWidth())
|
|
dx = 5;
|
|
if (my < 0)
|
|
dy = -5;
|
|
else if (my > visibleHeight())
|
|
dy = QMIN(5, verticalScrollBar()->maxValue()-verticalScrollBar()->value());
|
|
|
|
if (dx != 0 || dy != 0)
|
|
scrollBy(dx, dy);
|
|
}
|
|
|
|
int KDGanttCanvasView::getItemArea(KDGanttViewItem *item, int x) {
|
|
// area can be: no area = 0, Start = 1, Finish = 2
|
|
// TODO: middle (move, dnd), front, back (resize)
|
|
KDTimeTableWidget *tt = dynamic_cast<KDTimeTableWidget *>(canvas());
|
|
if (!tt) {
|
|
qWarning("Cannot cast canvas to KDTimeTableWidget");
|
|
return 0;
|
|
}
|
|
int area = 0;
|
|
int start = tt->getCoordX(item->startTime());
|
|
int end = start;
|
|
if (item->type() == KDGanttViewItem::Event) {
|
|
x > start ? area = 2 : area = 1;
|
|
} else {
|
|
end = tt->getCoordX(item->endTime());
|
|
if ((end - start)/2 > (x - start))
|
|
area = 1;
|
|
else
|
|
area = 2;
|
|
}
|
|
return area;
|
|
}
|
|
|
|
int KDGanttCanvasView::getLinkType(int from, int to) {
|
|
// from, to should be Start = 1 or Finish = 2
|
|
if ((from == 1) && (to == 1)) {
|
|
return KDGanttViewTaskLink::StartStart;
|
|
}
|
|
if ((from == 1) && (to == 2)) {
|
|
return KDGanttViewTaskLink::StartFinish;
|
|
}
|
|
if ((from == 2) && (to == 1)) {
|
|
return KDGanttViewTaskLink::FinishStart;
|
|
}
|
|
if ((from == 2) && (to == 2)) {
|
|
return KDGanttViewTaskLink::FinishFinish;
|
|
}
|
|
return KDGanttViewTaskLink::None;
|
|
}
|
|
|
|
/*!
|
|
Represents the background color for a given interval of time (across all tasks).
|
|
\sa KDGanttView::addIntervalBackgroundColor
|
|
\param view parent view
|
|
*/
|
|
KDIntervalColorRectangle::KDIntervalColorRectangle( KDGanttView* view )
|
|
: KDCanvasRectangle( view->timeTableWidget(), 0, Type_is_KDGanttGridItem ),
|
|
mStart(), mEnd()
|
|
{
|
|
setZ( -19 );
|
|
}
|
|
|
|
/*!
|
|
\param start start datetime of the time interval
|
|
\param end end datetime of the time interval
|
|
*/
|
|
void KDIntervalColorRectangle::setDateTimes( const TQDateTime& start,
|
|
const TQDateTime& end )
|
|
{
|
|
mStart = start;
|
|
mEnd = end;
|
|
if ( mEnd < mStart )
|
|
tqSwap( mStart, mEnd );
|
|
}
|
|
|
|
/*!
|
|
Sets the background color
|
|
\param color the background color
|
|
*/
|
|
void KDIntervalColorRectangle::setColor( const TQColor& color )
|
|
{
|
|
mColor = color;
|
|
}
|
|
|
|
/*!
|
|
\internal
|
|
*/
|
|
void KDIntervalColorRectangle::tqlayout( KDTimeHeaderWidget* timeHeader, int height )
|
|
{
|
|
int left = timeHeader->getCoordX(mStart);
|
|
int right = timeHeader->getCoordX(mEnd);
|
|
if ( right == left )
|
|
++right;
|
|
setPen( TQPen::NoPen );
|
|
setBrush( TQBrush(mColor, SolidPattern) );
|
|
setSize( right - left, height );
|
|
move( left, 0 );
|
|
show();
|
|
}
|
|
|
|
/*!
|
|
\internal
|
|
*/
|
|
KDIntervalColorRectangle::HitTest KDIntervalColorRectangle::hitTest( KDTimeHeaderWidget* timeHeader, const TQPoint& pos ) const
|
|
{
|
|
const int left = timeHeader->getCoordX(mStart);
|
|
const int right = timeHeader->getCoordX(mEnd);
|
|
const int width = right - left + 1;
|
|
const int x = pos.x();
|
|
if ( x < left + width / 10 )
|
|
return Start;
|
|
if ( x > right - width / 10 )
|
|
return End;
|
|
return Middle;
|
|
}
|