summaryrefslogtreecommitdiffstats
path: root/kdgantt
diff options
context:
space:
mode:
authortoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
committertoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
commit460c52653ab0dcca6f19a4f492ed2c5e4e963ab0 (patch)
tree67208f7c145782a7e90b123b982ca78d88cc2c87 /kdgantt
downloadtdepim-460c52653ab0dcca6f19a4f492ed2c5e4e963ab0.tar.gz
tdepim-460c52653ab0dcca6f19a4f492ed2c5e4e963ab0.zip
Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923 git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdepim@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'kdgantt')
-rw-r--r--kdgantt/KDGanttMinimizeSplitter.cpp1575
-rw-r--r--kdgantt/KDGanttMinimizeSplitter.h184
-rw-r--r--kdgantt/KDGanttSemiSizingControl.cpp413
-rw-r--r--kdgantt/KDGanttSemiSizingControl.h90
-rw-r--r--kdgantt/KDGanttSizingControl.cpp150
-rw-r--r--kdgantt/KDGanttSizingControl.h62
-rw-r--r--kdgantt/KDGanttView.cpp4847
-rw-r--r--kdgantt/KDGanttView.h502
-rw-r--r--kdgantt/KDGanttViewEventItem.cpp306
-rw-r--r--kdgantt/KDGanttViewEventItem.h68
-rw-r--r--kdgantt/KDGanttViewItem.cpp2571
-rw-r--r--kdgantt/KDGanttViewItem.h254
-rw-r--r--kdgantt/KDGanttViewItemDrag.cpp140
-rw-r--r--kdgantt/KDGanttViewItemDrag.h61
-rw-r--r--kdgantt/KDGanttViewSubwidgets.cpp4048
-rw-r--r--kdgantt/KDGanttViewSubwidgets.h646
-rw-r--r--kdgantt/KDGanttViewSummaryItem.cpp377
-rw-r--r--kdgantt/KDGanttViewSummaryItem.h72
-rw-r--r--kdgantt/KDGanttViewTaskItem.cpp369
-rw-r--r--kdgantt/KDGanttViewTaskItem.h73
-rw-r--r--kdgantt/KDGanttViewTaskLink.cpp1007
-rw-r--r--kdgantt/KDGanttViewTaskLink.h129
-rw-r--r--kdgantt/KDGanttViewTaskLinkGroup.cpp387
-rw-r--r--kdgantt/KDGanttViewTaskLinkGroup.h88
-rw-r--r--kdgantt/KDGanttXMLTools.cpp772
-rw-r--r--kdgantt/KDGanttXMLTools.h101
-rw-r--r--kdgantt/Makefile.am44
-rw-r--r--kdgantt/README_BEFORE_HACKING9
-rw-r--r--kdgantt/itemAttributeDialog.ui737
-rw-r--r--kdgantt/itemAttributeDialog.ui.h535
-rw-r--r--kdgantt/qlayoutengine_p.h111
31 files changed, 20728 insertions, 0 deletions
diff --git a/kdgantt/KDGanttMinimizeSplitter.cpp b/kdgantt/KDGanttMinimizeSplitter.cpp
new file mode 100644
index 00000000..790b381a
--- /dev/null
+++ b/kdgantt/KDGanttMinimizeSplitter.cpp
@@ -0,0 +1,1575 @@
+/* -*- Mode: C++ -*-
+ $Id$
+*/
+
+/****************************************************************************
+ ** 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 "KDGanttMinimizeSplitter.h"
+#ifndef QT_NO_SPLITTER
+
+#include "qpainter.h"
+#include "qdrawutil.h"
+#include "qbitmap.h"
+#if QT_VERSION >= 300
+#include "qptrlist.h"
+#include "qmemarray.h"
+#else
+#include <qlist.h>
+#include <qarray.h>
+#define QPtrList QList
+#define QMemArray QArray
+#endif
+#include "qlayoutengine_p.h"
+#include "qobjectlist.h"
+#include "qstyle.h"
+#include "qapplication.h" //sendPostedEvents
+#include <qvaluelist.h>
+#include <qcursor.h>
+#ifndef KDGANTT_MASTER_CVS
+#include "KDGanttMinimizeSplitter.moc"
+#endif
+
+
+#ifndef DOXYGEN_SKIP_INTERNAL
+
+#if QT_VERSION >= 300
+static int mouseOffset;
+static int opaqueOldPos = -1; //### there's only one mouse, but this is a bit risky
+
+
+KDGanttSplitterHandle::KDGanttSplitterHandle( Qt::Orientation o,
+ KDGanttMinimizeSplitter *parent, const char * name )
+ : QWidget( parent, name ), _activeButton( 0 ), _collapsed( false )
+{
+ s = parent;
+ setOrientation(o);
+ setMouseTracking( true );
+}
+
+QSize KDGanttSplitterHandle::sizeHint() const
+{
+ return QSize(8,8);
+}
+
+void KDGanttSplitterHandle::setOrientation( Qt::Orientation o )
+{
+ orient = o;
+#ifndef QT_NO_CURSOR
+ if ( o == KDGanttMinimizeSplitter::Horizontal )
+ setCursor( splitHCursor );
+ else
+ setCursor( splitVCursor );
+#endif
+}
+
+
+void KDGanttSplitterHandle::mouseMoveEvent( QMouseEvent *e )
+{
+ updateCursor( e->pos() );
+ if ( !(e->state()&LeftButton) )
+ return;
+
+ if ( _activeButton != 0)
+ return;
+
+ QCOORD pos = s->pick(parentWidget()->mapFromGlobal(e->globalPos()))
+ - mouseOffset;
+ if ( opaque() ) {
+ s->moveSplitter( pos, id() );
+ } else {
+ int min = pos; int max = pos;
+ s->getRange( id(), &min, &max );
+ s->setRubberband( QMAX( min, QMIN(max, pos )));
+ }
+ _collapsed = false;
+}
+
+void KDGanttSplitterHandle::mousePressEvent( QMouseEvent *e )
+{
+ if ( e->button() == LeftButton ) {
+ _activeButton = onButton( e->pos() );
+ mouseOffset = s->pick(e->pos());
+ if ( _activeButton != 0)
+ repaint();
+ updateCursor( e->pos() );
+ }
+}
+
+void KDGanttSplitterHandle::updateCursor( const QPoint& p)
+{
+ if ( onButton( p ) != 0 ) {
+ setCursor( arrowCursor );
+ }
+ else {
+ if ( orient == KDGanttMinimizeSplitter::Horizontal )
+ setCursor( splitHCursor );
+ else
+ setCursor( splitVCursor );
+ }
+}
+
+
+void KDGanttSplitterHandle::mouseReleaseEvent( QMouseEvent *e )
+{
+ if ( _activeButton != 0 ) {
+ if ( onButton( e->pos() ) == _activeButton )
+ {
+ int pos;
+ int min, max;
+ if ( !_collapsed ) {
+ s->expandPos( id(), &min, &max );
+ if ( s->minimizeDirection() == KDGanttMinimizeSplitter::Left
+ || s->minimizeDirection() == KDGanttMinimizeSplitter::Up ) {
+ pos = min;
+ }
+ else {
+ pos = max;
+ }
+
+ _origPos = s->pick(mapToParent( QPoint( 0,0 ) ));
+ s->moveSplitter( pos, id() );
+ _collapsed = true;
+ }
+ else {
+ s->moveSplitter( _origPos, id() );
+ _collapsed = false;
+ }
+
+ }
+ _activeButton = 0;
+ updateCursor( e->pos() );
+ }
+ else {
+ if ( !opaque() && e->button() == LeftButton ) {
+ QCOORD pos = s->pick(parentWidget()->mapFromGlobal(e->globalPos()))
+ - mouseOffset;
+ s->setRubberband( -1 );
+ s->moveSplitter( pos, id() );
+ }
+ }
+ repaint();
+}
+
+int KDGanttSplitterHandle::onButton( const QPoint& p )
+{
+ QValueList<QPointArray> list = buttonRegions();
+ int index = 1;
+ for( QValueList<QPointArray>::Iterator it = list.begin(); it != list.end(); ++it ) {
+ QRect rect = (*it).boundingRect();
+ rect.setLeft( rect.left()- 4 );
+ rect.setRight( rect.right() + 4);
+ rect.setTop( rect.top()- 4 );
+ rect.setBottom( rect.bottom() + 4);
+ if ( rect.contains( p ) ) {
+ return index;
+ }
+ index++;
+ }
+ return 0;
+}
+
+
+QValueList<QPointArray> KDGanttSplitterHandle::buttonRegions()
+{
+ QValueList<QPointArray> list;
+
+ int sw = 8;
+ int voffset[] = { (int) -sw*3, (int) sw*3 };
+ for ( int i = 0; i < 2; i++ ) {
+ QPointArray arr;
+ if ( !_collapsed && s->minimizeDirection() == KDGanttMinimizeSplitter::Right ||
+ _collapsed && s->minimizeDirection() == KDGanttMinimizeSplitter::Left) {
+ int mid = height()/2 + voffset[i];
+ arr.setPoints( 3,
+ 1, mid - sw + 4,
+ sw-3, mid,
+ 1, mid + sw -4);
+ }
+ else if ( !_collapsed && s->minimizeDirection() == KDGanttMinimizeSplitter::Left ||
+ _collapsed && s->minimizeDirection() == KDGanttMinimizeSplitter::Right ) {
+ int mid = height()/2 + voffset[i];
+ arr.setPoints( 3,
+ sw-4, mid - sw + 4,
+ 0, mid,
+ sw-4, mid + sw - 4);
+ }
+ else if ( !_collapsed && s->minimizeDirection() == KDGanttMinimizeSplitter::Up ||
+ _collapsed && s->minimizeDirection() == KDGanttMinimizeSplitter::Down) {
+ int mid = width()/2 + voffset[i];
+ arr.setPoints( 3,
+ mid - sw + 4, sw-4,
+ mid, 0,
+ mid + sw - 4, sw-4 );
+ }
+ else if ( !_collapsed && s->minimizeDirection() == KDGanttMinimizeSplitter::Down ||
+ _collapsed && s->minimizeDirection() == KDGanttMinimizeSplitter::Up ) {
+ int mid = width()/2 + voffset[i];
+ arr.setPoints( 3,
+ mid - sw + 4, 1,
+ mid, sw-3,
+ mid + sw -4, 1);
+ }
+ list.append( arr );
+ }
+ return list;
+}
+
+void KDGanttSplitterHandle::paintEvent( QPaintEvent * )
+{
+ QPixmap buffer( size() );
+ QPainter p( &buffer );
+
+ // Draw the splitter rectangle
+ p.setBrush( colorGroup().background() );
+ p.setPen( colorGroup().foreground() );
+ p.drawRect( rect() );
+ parentWidget()->style().drawPrimitive( QStyle::PE_Panel, &p, rect(),
+ parentWidget()->colorGroup());
+
+ int sw = 8; // Hardcoded, given I didn't use styles anymore, I didn't like to use their size
+
+ // arrow color
+ QColor col = colorGroup().background().dark( 200 );
+ p.setBrush( col );
+ p.setPen( col );
+
+ QValueList<QPointArray> list = buttonRegions();
+ int index = 1;
+ for ( QValueList<QPointArray>::Iterator it = list.begin(); it != list.end(); ++it ) {
+ if ( index == _activeButton ) {
+ p.save();
+ p.translate( parentWidget()->style().pixelMetric( QStyle::PM_ButtonShiftHorizontal ),
+ parentWidget()->style().pixelMetric( QStyle::PM_ButtonShiftVertical ) );
+ p.drawPolygon( *it, true );
+ p.restore();
+ }
+ else {
+ p.drawPolygon( *it, true );
+ }
+ index++;
+ }
+
+ // Draw the lines between the arrows
+ if ( s->minimizeDirection() == KDGanttMinimizeSplitter::Left ||
+ s->minimizeDirection() == KDGanttMinimizeSplitter::Right ) {
+ int mid = height()/2;
+ p.drawLine ( 2, mid - sw, 2, mid + sw );
+ p.drawLine ( 4, mid - sw, 4, mid + sw );
+ }
+ else if ( s->minimizeDirection() == KDGanttMinimizeSplitter::Up ||
+ s->minimizeDirection() == KDGanttMinimizeSplitter::Down ) {
+ int mid = width()/2;
+ p.drawLine( mid -sw, 2, mid +sw, 2 );
+ p.drawLine( mid -sw, 4, mid +sw, 4 );
+ }
+ bitBlt( this, 0, 0, &buffer );
+}
+#endif
+
+class QSplitterLayoutStruct
+{
+public:
+ KDGanttMinimizeSplitter::ResizeMode mode;
+ QCOORD sizer;
+ bool isSplitter;
+ QWidget *wid;
+};
+
+class QSplitterData
+{
+public:
+ QSplitterData() : opaque( FALSE ), firstShow( TRUE ) {}
+
+ QPtrList<QSplitterLayoutStruct> list;
+ bool opaque;
+ bool firstShow;
+};
+
+void kdganttGeomCalc( QMemArray<QLayoutStruct> &chain, int start, int count, int pos,
+ int space, int spacer );
+#endif // DOXYGEN_SKIP_INTERNAL
+
+
+/*!
+ \class KDGanttMinimizeSplitter KDGanttMinimizeSplitter.h
+ \brief The KDGanttMinimizeSplitter class implements a splitter
+ widget with minimize buttons.
+
+ This class (and its documentation) is largely a copy of Qt's
+ QSplitter; the copying was necessary because QSplitter is not
+ extensible at all. QSplitter and its documentation are licensed
+ according to the GPL and the Qt Professional License (if you hold
+ such a license) and are (C) Trolltech AS.
+
+ A splitter lets the user control the size of child widgets by
+ dragging the boundary between the children. Any number of widgets
+ may be controlled.
+
+ To show a QListBox, a QListView and a QTextEdit side by side:
+
+ \code
+ KDGanttMinimizeSplitter *split = new KDGanttMinimizeSplitter( parent );
+ QListBox *lb = new QListBox( split );
+ QListView *lv = new QListView( split );
+ QTextEdit *ed = new QTextEdit( split );
+ \endcode
+
+ In KDGanttMinimizeSplitter, the boundary can be either horizontal or
+ vertical. The default is horizontal (the children are side by side)
+ but you can use setOrientation( QSplitter::Vertical ) to set it to
+ vertical.
+
+ Use setResizeMode() to specify
+ that a widget should keep its size when the splitter is resized.
+
+ Although KDGanttMinimizeSplitter normally resizes the children only
+ at the end of a resize operation, if you call setOpaqueResize( TRUE
+ ) the widgets are resized as often as possible.
+
+ The initial distribution of size between the widgets is determined
+ by the initial size of each widget. You can also use setSizes() to
+ set the sizes of all the widgets. The function sizes() returns the
+ sizes set by the user.
+
+ If you hide() a child, its space will be distributed among the other
+ children. It will be reinstated when you show() it again. It is also
+ possible to reorder the widgets within the splitter using
+ moveToFirst() and moveToLast().
+*/
+
+
+
+static QSize minSize( const QWidget* /*w*/ )
+{
+ return QSize(0,0);
+}
+
+// This is the original version of minSize
+static QSize minSizeHint( const QWidget* w )
+{
+ QSize min = w->minimumSize();
+ QSize s;
+ if ( min.height() <= 0 || min.width() <= 0 )
+ s = w->minimumSizeHint();
+ if ( min.height() > 0 )
+ s.setHeight( min.height() );
+ if ( min.width() > 0 )
+ s.setWidth( min.width() );
+ return s.expandedTo(QSize(0,0));
+}
+
+
+
+/*!
+ Constructs a horizontal splitter with the \a parent and \a
+ name arguments being passed on to the QFrame constructor.
+*/
+KDGanttMinimizeSplitter::KDGanttMinimizeSplitter( QWidget *parent, const char *name )
+ :QFrame(parent,name,WPaintUnclipped)
+{
+#if QT_VERSION >= 300
+ orient = Horizontal;
+ init();
+#endif
+}
+
+/*!
+ Constructs a splitter with orientation \a o with the \a parent
+ and \a name arguments being passed on to the QFrame constructor.
+*/
+KDGanttMinimizeSplitter::KDGanttMinimizeSplitter( Orientation o, QWidget *parent, const char *name )
+ :QFrame(parent,name,WPaintUnclipped)
+{
+#if QT_VERSION >= 300
+ orient = o;
+ init();
+#endif
+}
+
+/*!
+ Destroys the splitter and any children.
+*/
+KDGanttMinimizeSplitter::~KDGanttMinimizeSplitter()
+{
+#if QT_VERSION >= 300
+ data->list.setAutoDelete( TRUE );
+ delete data;
+#endif
+}
+
+
+#if QT_VERSION >= 300
+void KDGanttMinimizeSplitter::init()
+{
+ data = new QSplitterData;
+ if ( orient == Horizontal )
+ setSizePolicy( QSizePolicy(QSizePolicy::Expanding,QSizePolicy::Minimum) );
+ else
+ setSizePolicy( QSizePolicy(QSizePolicy::Minimum,QSizePolicy::Expanding) );
+}
+#endif
+
+
+
+/*!
+ \brief the orientation of the splitter
+
+ By default the orientation is horizontal (the widgets are side by side).
+ The possible orientations are Qt:Vertical and Qt::Horizontal (the default).
+*/
+void KDGanttMinimizeSplitter::setOrientation( Orientation o )
+{
+#if QT_VERSION >= 300
+ if ( orient == o )
+ return;
+ orient = o;
+
+ if ( orient == Horizontal )
+ setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Minimum ) );
+ else
+ setSizePolicy( QSizePolicy( QSizePolicy::Minimum, QSizePolicy::Expanding ) );
+
+ QSplitterLayoutStruct *s = data->list.first();
+ while ( s ) {
+ if ( s->isSplitter )
+ ((KDGanttSplitterHandle*)s->wid)->setOrientation( o );
+ s = data->list.next(); // ### next at end of loop, no iterator
+ }
+ recalc( isVisible() );
+#endif
+}
+
+
+#if QT_VERSION >= 300
+/*!
+ Reimplemented from superclass.
+*/
+void KDGanttMinimizeSplitter::resizeEvent( QResizeEvent * )
+{
+ doResize();
+}
+
+
+/*
+ Inserts the widget \a w at the end (or at the beginning if \a first
+ is TRUE) of the splitter's list of widgets.
+
+ It is the responsibility of the caller of this function to make sure
+ that \a w is not already in the splitter and to call recalcId if
+ needed. (If \a first is TRUE, then recalcId is very probably
+ needed.)
+*/
+QSplitterLayoutStruct *KDGanttMinimizeSplitter::addWidget( QWidget *w, bool first )
+{
+ QSplitterLayoutStruct *s;
+ KDGanttSplitterHandle *newHandle = 0;
+ if ( data->list.count() > 0 ) {
+ s = new QSplitterLayoutStruct;
+ s->mode = KeepSize;
+ QString tmp = "qt_splithandle_";
+ tmp += w->name();
+ newHandle = new KDGanttSplitterHandle( orientation(), this, tmp.latin1() );
+ s->wid = newHandle;
+ newHandle->setId(data->list.count());
+ s->isSplitter = TRUE;
+ s->sizer = pick( newHandle->sizeHint() );
+ if ( first )
+ data->list.insert( 0, s );
+ else
+ data->list.append( s );
+ }
+ s = new QSplitterLayoutStruct;
+ s->mode = Stretch;
+ s->wid = w;
+ if ( !testWState( WState_Resized ) && w->sizeHint().isValid() )
+ s->sizer = pick( w->sizeHint() );
+ else
+ s->sizer = pick( w->size() );
+ s->isSplitter = FALSE;
+ if ( first )
+ data->list.insert( 0, s );
+ else
+ data->list.append( s );
+ if ( newHandle && isVisible() )
+ newHandle->show(); //will trigger sending of post events
+ return s;
+}
+
+
+/*!
+ Tells the splitter that a child widget has been inserted or removed.
+ The event is passed in \a c.
+*/
+void KDGanttMinimizeSplitter::childEvent( QChildEvent *c )
+{
+ if ( c->type() == QEvent::ChildInserted ) {
+ if ( !c->child()->isWidgetType() )
+ return;
+
+ if ( ((QWidget*)c->child())->testWFlags( WType_TopLevel ) )
+ return;
+
+ QSplitterLayoutStruct *s = data->list.first();
+ while ( s ) {
+ if ( s->wid == c->child() )
+ return;
+ s = data->list.next();
+ }
+ addWidget( (QWidget*)c->child() );
+ recalc( isVisible() );
+
+ } else if ( c->type() == QEvent::ChildRemoved ) {
+ QSplitterLayoutStruct *p = 0;
+ if ( data->list.count() > 1 )
+ p = data->list.at(1); //remove handle _after_ first widget.
+ QSplitterLayoutStruct *s = data->list.first();
+ while ( s ) {
+ if ( s->wid == c->child() ) {
+ data->list.removeRef( s );
+ delete s;
+ if ( p && p->isSplitter ) {
+ data->list.removeRef( p );
+ delete p->wid; //will call childEvent
+ delete p;
+ }
+ recalcId();
+ doResize();
+ return;
+ }
+ p = s;
+ s = data->list.next();
+ }
+ }
+}
+
+
+/*!
+ Shows a rubber band at position \a p. If \a p is negative, the
+ rubber band is removed.
+*/
+void KDGanttMinimizeSplitter::setRubberband( int p )
+{
+ QPainter paint( this );
+ paint.setPen( gray );
+ paint.setBrush( gray );
+ paint.setRasterOp( XorROP );
+ QRect r = contentsRect();
+ const int rBord = 3; //Themable????
+ int sw = style().pixelMetric(QStyle::PM_SplitterWidth, this);
+ if ( orient == Horizontal ) {
+ if ( opaqueOldPos >= 0 )
+ paint.drawRect( opaqueOldPos + sw/2 - rBord , r.y(),
+ 2*rBord, r.height() );
+ if ( p >= 0 )
+ paint.drawRect( p + sw/2 - rBord, r.y(), 2*rBord, r.height() );
+ } else {
+ if ( opaqueOldPos >= 0 )
+ paint.drawRect( r.x(), opaqueOldPos + sw/2 - rBord,
+ r.width(), 2*rBord );
+ if ( p >= 0 )
+ paint.drawRect( r.x(), p + sw/2 - rBord, r.width(), 2*rBord );
+ }
+ opaqueOldPos = p;
+}
+
+
+/*! Reimplemented from superclass. */
+bool KDGanttMinimizeSplitter::event( QEvent *e )
+{
+ if ( e->type() == QEvent::LayoutHint || ( e->type() == QEvent::Show && data->firstShow ) ) {
+ recalc( isVisible() );
+ if ( e->type() == QEvent::Show )
+ data->firstShow = FALSE;
+ }
+ return QWidget::event( e );
+}
+
+
+/*!
+ \obsolete
+
+ Draws the splitter handle in the rectangle described by \a x, \a y,
+ \a w, \a h using painter \a p.
+ \sa QStyle::drawPrimitive()
+*/
+void KDGanttMinimizeSplitter::drawSplitter( QPainter *p,
+ QCOORD x, QCOORD y, QCOORD w, QCOORD h )
+{
+ style().drawPrimitive(QStyle::PE_Splitter, p, QRect(x, y, w, h), colorGroup(),
+ (orientation() == Qt::Horizontal ?
+ QStyle::Style_Horizontal : 0));
+}
+
+
+/*!
+ Returns the id of the splitter to the right of or below the widget \a w,
+ or 0 if there is no such splitter
+ (i.e. it is either not in this KDGanttMinimizeSplitter or it is at the end).
+*/
+int KDGanttMinimizeSplitter::idAfter( QWidget* w ) const
+{
+ QSplitterLayoutStruct *s = data->list.first();
+ bool seen_w = FALSE;
+ while ( s ) {
+ if ( s->isSplitter && seen_w )
+ return data->list.at();
+ if ( !s->isSplitter && s->wid == w )
+ seen_w = TRUE;
+ s = data->list.next();
+ }
+ return 0;
+}
+
+
+/*!
+ Moves the left/top edge of the splitter handle with id \a id as
+ close as possible to position \a p, which is the distance from the
+ left (or top) edge of the widget.
+
+ For Arabic and Hebrew the layout is reversed, and using this
+ function to set the position of the splitter might lead to
+ unexpected results, since in Arabic and Hebrew the position of
+ splitter one is to the left of the position of splitter zero.
+
+ \sa idAfter()
+*/
+void KDGanttMinimizeSplitter::moveSplitter( QCOORD p, int id )
+{
+ p = adjustPos( p, id );
+
+ QSplitterLayoutStruct *s = data->list.at(id);
+ int oldP = orient == Horizontal ? s->wid->x() : s->wid->y();
+ bool upLeft;
+ if ( QApplication::reverseLayout() && orient == Horizontal ) {
+ p += s->wid->width();
+ upLeft = p > oldP;
+ } else
+ upLeft = p < oldP;
+
+ moveAfter( p, id, upLeft );
+ moveBefore( p-1, id-1, upLeft );
+
+ storeSizes();
+}
+
+
+void KDGanttMinimizeSplitter::setG( QWidget *w, int p, int s, bool isSplitter )
+{
+ if ( orient == Horizontal ) {
+ if ( QApplication::reverseLayout() && orient == Horizontal && !isSplitter )
+ p = contentsRect().width() - p - s;
+ w->setGeometry( p, contentsRect().y(), s, contentsRect().height() );
+ } else
+ w->setGeometry( contentsRect().x(), p, contentsRect().width(), s );
+}
+
+
+/*
+ Places the right/bottom edge of the widget at \a id at position \a pos.
+
+ \sa idAfter()
+*/
+void KDGanttMinimizeSplitter::moveBefore( int pos, int id, bool upLeft )
+{
+ if( id < 0 )
+ return;
+ QSplitterLayoutStruct *s = data->list.at(id);
+ if ( !s )
+ return;
+ QWidget *w = s->wid;
+ if ( w->isHidden() ) {
+ moveBefore( pos, id-1, upLeft );
+ } else if ( s->isSplitter ) {
+ int pos1, pos2;
+ int dd = s->sizer;
+ if( QApplication::reverseLayout() && orient == Horizontal ) {
+ pos1 = pos;
+ pos2 = pos + dd;
+ } else {
+ pos2 = pos - dd;
+ pos1 = pos2 + 1;
+ }
+ if ( upLeft ) {
+ setG( w, pos1, dd, TRUE );
+ moveBefore( pos2, id-1, upLeft );
+ } else {
+ moveBefore( pos2, id-1, upLeft );
+ setG( w, pos1, dd, TRUE );
+ }
+ } else {
+ int dd, newLeft, nextPos;
+ if( QApplication::reverseLayout() && orient == Horizontal ) {
+ dd = w->geometry().right() - pos;
+ dd = QMAX( pick(minSize(w)), QMIN(dd, pick(w->maximumSize())));
+ newLeft = pos+1;
+ nextPos = newLeft + dd;
+ } else {
+ dd = pos - pick( w->pos() ) + 1;
+ dd = QMAX( pick(minSize(w)), QMIN(dd, pick(w->maximumSize())));
+ newLeft = pos-dd+1;
+ nextPos = newLeft - 1;
+ }
+ setG( w, newLeft, dd, TRUE );
+ moveBefore( nextPos, id-1, upLeft );
+ }
+}
+
+
+/*
+ Places the left/top edge of the widget at \a id at position \a pos.
+
+ \sa idAfter()
+*/
+void KDGanttMinimizeSplitter::moveAfter( int pos, int id, bool upLeft )
+{
+ QSplitterLayoutStruct *s = id < int(data->list.count()) ?
+ data->list.at(id) : 0;
+ if ( !s )
+ return;
+ QWidget *w = s->wid;
+ if ( w->isHidden() ) {
+ moveAfter( pos, id+1, upLeft );
+ } else if ( pick( w->pos() ) == pos ) {
+ //No need to do anything if it's already there.
+ return;
+ } else if ( s->isSplitter ) {
+ int dd = s->sizer;
+ int pos1, pos2;
+ if( QApplication::reverseLayout() && orient == Horizontal ) {
+ pos2 = pos - dd;
+ pos1 = pos2 + 1;
+ } else {
+ pos1 = pos;
+ pos2 = pos + dd;
+ }
+ if ( upLeft ) {
+ setG( w, pos1, dd, TRUE );
+ moveAfter( pos2, id+1, upLeft );
+ } else {
+ moveAfter( pos2, id+1, upLeft );
+ setG( w, pos1, dd, TRUE );
+ }
+ } else {
+ int left = pick( w->pos() );
+ int right, dd,/* newRight,*/ newLeft, nextPos;
+ if ( QApplication::reverseLayout() && orient == Horizontal ) {
+ dd = pos - left + 1;
+ dd = QMAX( pick(minSize(w)), QMIN(dd, pick(w->maximumSize())));
+ newLeft = pos-dd+1;
+ nextPos = newLeft - 1;
+ } else {
+ right = pick( w->geometry().bottomRight() );
+ dd = right - pos + 1;
+ dd = QMAX( pick(minSize(w)), QMIN(dd, pick(w->maximumSize())));
+ /*newRight = pos+dd-1;*/
+ newLeft = pos;
+ nextPos = newLeft + dd;
+ }
+ setG( w, newLeft, dd, TRUE );
+ /*if( right != newRight )*/
+ moveAfter( nextPos, id+1, upLeft );
+ }
+}
+
+
+void KDGanttMinimizeSplitter::expandPos( int id, int* min, int* max )
+{
+ QSplitterLayoutStruct *s = data->list.at(id-1);
+ QWidget* w = s->wid;
+ *min = pick( w->mapToParent( QPoint(0,0) ) );
+
+ if ( (uint) id == data->list.count() ) {
+ pick( size() );
+ }
+ else {
+ QSplitterLayoutStruct *s = data->list.at(id+1);
+ QWidget* w = s->wid;
+ *max = pick( w->mapToParent( QPoint( w->width(), w->height() ) ) ) -8;
+ }
+}
+
+
+/*!
+ Returns the valid range of the splitter with id \a id in \a *min and \a *max.
+
+ \sa idAfter()
+*/
+
+void KDGanttMinimizeSplitter::getRange( int id, int *min, int *max )
+{
+ int minB = 0; //before
+ int maxB = 0;
+ int minA = 0;
+ int maxA = 0; //after
+ int n = data->list.count();
+ if ( id < 0 || id >= n )
+ return;
+ int i;
+ for ( i = 0; i < id; i++ ) {
+ QSplitterLayoutStruct *s = data->list.at(i);
+ if ( s->wid->isHidden() ) {
+ //ignore
+ } else if ( s->isSplitter ) {
+ minB += s->sizer;
+ maxB += s->sizer;
+ } else {
+ minB += pick( minSize(s->wid) );
+ maxB += pick( s->wid->maximumSize() );
+ }
+ }
+ for ( i = id; i < n; i++ ) {
+ QSplitterLayoutStruct *s = data->list.at(i);
+ if ( s->wid->isHidden() ) {
+ //ignore
+ } else if ( s->isSplitter ) {
+ minA += s->sizer;
+ maxA += s->sizer;
+ } else {
+ minA += pick( minSize(s->wid) );
+ maxA += pick( s->wid->maximumSize() );
+ }
+ }
+ QRect r = contentsRect();
+ if ( orient == Horizontal && QApplication::reverseLayout() ) {
+ int splitterWidth = style().pixelMetric(QStyle::PM_SplitterWidth, this);
+ if ( min )
+ *min = pick(r.topRight()) - QMIN( maxB, pick(r.size())-minA ) - splitterWidth;
+ if ( max )
+ *max = pick(r.topRight()) - QMAX( minB, pick(r.size())-maxA ) - splitterWidth;
+ } else {
+ if ( min )
+ *min = pick(r.topLeft()) + QMAX( minB, pick(r.size())-maxA );
+ if ( max )
+ *max = pick(r.topLeft()) + QMIN( maxB, pick(r.size())-minA );
+ }
+}
+
+
+/*!
+ Returns the closest legal position to \a p of the splitter with id \a id.
+
+ \sa idAfter()
+*/
+
+int KDGanttMinimizeSplitter::adjustPos( int p, int id )
+{
+ int min = 0;
+ int max = 0;
+ getRange( id, &min, &max );
+ p = QMAX( min, QMIN( p, max ) );
+
+ return p;
+}
+
+
+void KDGanttMinimizeSplitter::doResize()
+{
+ QRect r = contentsRect();
+ int i;
+ int n = data->list.count();
+ QMemArray<QLayoutStruct> a( n );
+ for ( i = 0; i< n; i++ ) {
+ a[i].init();
+ QSplitterLayoutStruct *s = data->list.at(i);
+ if ( s->wid->isHidden() ) {
+ a[i].stretch = 0;
+ a[i].sizeHint = a[i].minimumSize = 0;
+ a[i].maximumSize = 0;
+ } else if ( s->isSplitter ) {
+ a[i].stretch = 0;
+ a[i].sizeHint = a[i].minimumSize = a[i].maximumSize = s->sizer;
+ a[i].empty = FALSE;
+ } else if ( s->mode == KeepSize ) {
+ a[i].stretch = 0;
+ a[i].minimumSize = pick( minSize(s->wid) );
+ a[i].sizeHint = s->sizer;
+ a[i].maximumSize = pick( s->wid->maximumSize() );
+ a[i].empty = FALSE;
+ } else if ( s->mode == FollowSizeHint ) {
+ a[i].stretch = 0;
+ a[i].minimumSize = a[i].sizeHint = pick( s->wid->sizeHint() );
+ a[i].maximumSize = pick( s->wid->maximumSize() );
+ a[i].empty = FALSE;
+ } else { //proportional
+ a[i].stretch = s->sizer;
+ a[i].maximumSize = pick( s->wid->maximumSize() );
+ a[i].sizeHint = a[i].minimumSize = pick( minSize(s->wid) );
+ a[i].empty = FALSE;
+ }
+ }
+
+ kdganttGeomCalc( a, 0, n, pick( r.topLeft() ), pick( r.size() ), 0 );
+
+ for ( i = 0; i< n; i++ ) {
+ QSplitterLayoutStruct *s = data->list.at(i);
+ setG( s->wid, a[i].pos, a[i].size );
+ }
+
+}
+
+
+void KDGanttMinimizeSplitter::recalc( bool update )
+{
+ int fi = 2*frameWidth();
+ int maxl = fi;
+ int minl = fi;
+ int maxt = QWIDGETSIZE_MAX;
+ int mint = fi;
+ int n = data->list.count();
+ bool first = TRUE;
+ /*
+ The splitter before a hidden widget is always hidden.
+ The splitter before the first visible widget is hidden.
+ The splitter before any other visible widget is visible.
+ */
+ for ( int i = 0; i< n; i++ ) {
+ QSplitterLayoutStruct *s = data->list.at(i);
+ if ( !s->isSplitter ) {
+ QSplitterLayoutStruct *p = (i > 0) ? data->list.at( i-1 ) : 0;
+ if ( p && p->isSplitter )
+ if ( first || s->wid->isHidden() )
+ p->wid->hide(); //may trigger new recalc
+ else
+ p->wid->show(); //may trigger new recalc
+ if ( !s->wid->isHidden() )
+ first = FALSE;
+ }
+ }
+
+ bool empty=TRUE;
+ for ( int j = 0; j< n; j++ ) {
+ QSplitterLayoutStruct *s = data->list.at(j);
+ if ( !s->wid->isHidden() ) {
+ empty = FALSE;
+ if ( s->isSplitter ) {
+ minl += s->sizer;
+ maxl += s->sizer;
+ } else {
+ QSize minS = minSize(s->wid);
+ minl += pick( minS );
+ maxl += pick( s->wid->maximumSize() );
+ mint = QMAX( mint, trans( minS ));
+ int tm = trans( s->wid->maximumSize() );
+ if ( tm > 0 )
+ maxt = QMIN( maxt, tm );
+ }
+ }
+ }
+ if ( empty ) {
+ if ( parentWidget() != 0 && parentWidget()->inherits("KDGanttMinimizeSplitter") ) {
+ // nested splitters; be nice
+ maxl = maxt = 0;
+ } else {
+ // KDGanttMinimizeSplitter with no children yet
+ maxl = QWIDGETSIZE_MAX;
+ }
+ } else {
+ maxl = QMIN( maxl, QWIDGETSIZE_MAX );
+ }
+ if ( maxt < mint )
+ maxt = mint;
+
+ if ( orient == Horizontal ) {
+ setMaximumSize( maxl, maxt );
+ setMinimumSize( minl, mint );
+ } else {
+ setMaximumSize( maxt, maxl );
+ setMinimumSize( mint, minl );
+ }
+ if ( update )
+ doResize();
+}
+
+/*!
+ Sets resize mode of \a w to \a mode.
+
+ \sa ResizeMode
+*/
+
+void KDGanttMinimizeSplitter::setResizeMode( QWidget *w, ResizeMode mode )
+{
+ processChildEvents();
+ QSplitterLayoutStruct *s = data->list.first();
+ while ( s ) {
+ if ( s->wid == w ) {
+ s->mode = mode;
+ return;
+ }
+ s = data->list.next();
+ }
+ s = addWidget( w, TRUE );
+ s->mode = mode;
+}
+
+
+/*!
+ Returns TRUE if opaque resize is on; otherwise returns FALSE.
+
+ \sa setOpaqueResize()
+*/
+
+bool KDGanttMinimizeSplitter::opaqueResize() const
+{
+ return data->opaque;
+}
+
+
+/*!
+ If \a on is TRUE then opaque resizing is turned on; otherwise
+ opaque resizing is turned off.
+ Opaque resizing is initially turned off.
+
+ \sa opaqueResize()
+*/
+
+void KDGanttMinimizeSplitter::setOpaqueResize( bool on )
+{
+ data->opaque = on;
+}
+
+
+/*!
+ Moves widget \a w to the leftmost/top position.
+*/
+
+void KDGanttMinimizeSplitter::moveToFirst( QWidget *w )
+{
+ processChildEvents();
+ bool found = FALSE;
+ QSplitterLayoutStruct *s = data->list.first();
+ while ( s ) {
+ if ( s->wid == w ) {
+ found = TRUE;
+ QSplitterLayoutStruct *p = data->list.prev();
+ if ( p ) { // not already at first place
+ data->list.take(); //take p
+ data->list.take(); // take s
+ data->list.insert( 0, p );
+ data->list.insert( 0, s );
+ }
+ break;
+ }
+ s = data->list.next();
+ }
+ if ( !found )
+ addWidget( w, TRUE );
+ recalcId();
+}
+
+
+/*!
+ Moves widget \a w to the rightmost/bottom position.
+*/
+
+void KDGanttMinimizeSplitter::moveToLast( QWidget *w )
+{
+ processChildEvents();
+ bool found = FALSE;
+ QSplitterLayoutStruct *s = data->list.first();
+ while ( s ) {
+ if ( s->wid == w ) {
+ found = TRUE;
+ data->list.take(); // take s
+ QSplitterLayoutStruct *p = data->list.current();
+ if ( p ) { // the splitter handle after s
+ data->list.take(); //take p
+ data->list.append( p );
+ }
+ data->list.append( s );
+ break;
+ }
+ s = data->list.next();
+ }
+ if ( !found )
+ addWidget( w);
+ recalcId();
+}
+
+
+void KDGanttMinimizeSplitter::recalcId()
+{
+ int n = data->list.count();
+ for ( int i = 0; i < n; i++ ) {
+ QSplitterLayoutStruct *s = data->list.at(i);
+ if ( s->isSplitter )
+ ((KDGanttSplitterHandle*)s->wid)->setId(i);
+ }
+}
+
+
+/*! Reimplemented from superclass.
+*/
+QSize KDGanttMinimizeSplitter::sizeHint() const
+{
+ constPolish();
+ int l = 0;
+ int t = 0;
+ if ( children() ) {
+ const QObjectList * c = children();
+ QObjectListIt it( *c );
+ QObject * o;
+
+ while( (o=it.current()) != 0 ) {
+ ++it;
+ if ( o->isWidgetType() &&
+ !((QWidget*)o)->isHidden() ) {
+ QSize s = ((QWidget*)o)->sizeHint();
+ if ( s.isValid() ) {
+ l += pick( s );
+ t = QMAX( t, trans( s ) );
+ }
+ }
+ }
+ }
+ return orientation() == Horizontal ? QSize( l, t ) : QSize( t, l );
+}
+
+
+/*!
+\reimp
+*/
+
+QSize KDGanttMinimizeSplitter::minimumSizeHint() const
+{
+ constPolish();
+ int l = 0;
+ int t = 0;
+ if ( children() ) {
+ const QObjectList * c = children();
+ QObjectListIt it( *c );
+ QObject * o;
+
+ while( (o=it.current()) != 0 ) {
+ ++it;
+ if ( o->isWidgetType() &&
+ !((QWidget*)o)->isHidden() ) {
+ QSize s = minSizeHint((QWidget*)o);
+ if ( s.isValid() ) {
+ l += pick( s );
+ t = QMAX( t, trans( s ) );
+ }
+ }
+ }
+ }
+ return orientation() == Horizontal ? QSize( l, t ) : QSize( t, l );
+}
+
+
+/*
+ Calculates stretch parameters from current sizes
+*/
+
+void KDGanttMinimizeSplitter::storeSizes()
+{
+ QSplitterLayoutStruct *s = data->list.first();
+ while ( s ) {
+ if ( !s->isSplitter )
+ s->sizer = pick( s->wid->size() );
+ s = data->list.next();
+ }
+}
+
+
+#if 0 // ### remove this code ASAP
+
+/*!
+ Hides \a w if \a hide is TRUE and updates the splitter.
+
+ \warning Due to a limitation in the current implementation,
+ calling QWidget::hide() will not work.
+*/
+
+void KDGanttMinimizeSplitter::setHidden( QWidget *w, bool hide )
+{
+ if ( w == w1 ) {
+ w1show = !hide;
+ } else if ( w == w2 ) {
+ w2show = !hide;
+ } else {
+#ifdef QT_CHECK_RANGE
+ qWarning( "KDGanttMinimizeSplitter::setHidden(), unknown widget" );
+#endif
+ return;
+ }
+ if ( hide )
+ w->hide();
+ else
+ w->show();
+ recalc( TRUE );
+}
+
+
+/*!
+ Returns the hidden status of \a w
+*/
+
+bool KDGanttMinimizeSplitter::isHidden( QWidget *w ) const
+{
+ if ( w == w1 )
+ return !w1show;
+ else if ( w == w2 )
+ return !w2show;
+#ifdef QT_CHECK_RANGE
+ else
+ qWarning( "KDGanttMinimizeSplitter::isHidden(), unknown widget" );
+#endif
+ return FALSE;
+}
+#endif
+
+
+/*!
+ Returns a list of the size parameters of all the widgets in this
+ splitter.
+
+ Giving the values to another splitter's setSizes() function will
+ produce a splitter with the same layout as this one.
+
+ Note that if you want to iterate over the list, you should
+ iterate over a copy, e.g.
+ \code
+ QValueList<int> list = mySplitter.sizes();
+ QValueList<int>::Iterator it = list.begin();
+ while( it != list.end() ) {
+ myProcessing( *it );
+ ++it;
+ }
+ \endcode
+
+ \sa setSizes()
+*/
+
+QValueList<int> KDGanttMinimizeSplitter::sizes() const
+{
+ if ( !testWState(WState_Polished) ) {
+ QWidget* that = (QWidget*) this;
+ that->polish();
+ }
+ QValueList<int> list;
+ QSplitterLayoutStruct *s = data->list.first();
+ while ( s ) {
+ if ( !s->isSplitter )
+ list.append( s->sizer );
+ s = data->list.next();
+ }
+ return list;
+}
+
+
+
+/*!
+ Sets the size parameters to the values given in \a list.
+ If the splitter is horizontal, the values set the sizes from
+ left to right. If it is vertical, the sizes are applied from
+ top to bottom.
+ Extra values in \a list are ignored.
+
+ If \a list contains too few values, the result is undefined
+ but the program will still be well-behaved.
+
+ \sa sizes()
+*/
+
+void KDGanttMinimizeSplitter::setSizes( QValueList<int> list )
+{
+ processChildEvents();
+ QValueList<int>::Iterator it = list.begin();
+ QSplitterLayoutStruct *s = data->list.first();
+ while ( s && it != list.end() ) {
+ if ( !s->isSplitter ) {
+ s->sizer = *it;
+ ++it;
+ }
+ s = data->list.next();
+ }
+ doResize();
+}
+
+
+/*!
+ Gets all posted child events, ensuring that the internal state of
+ the splitter is consistent.
+*/
+
+void KDGanttMinimizeSplitter::processChildEvents()
+{
+ QApplication::sendPostedEvents( this, QEvent::ChildInserted );
+}
+
+
+/*!
+ Reimplemented from superclass.
+*/
+
+void KDGanttMinimizeSplitter::styleChange( QStyle& old )
+{
+ int sw = style().pixelMetric(QStyle::PM_SplitterWidth, this);
+ QSplitterLayoutStruct *s = data->list.first();
+ while ( s ) {
+ if ( s->isSplitter )
+ s->sizer = sw;
+ s = data->list.next();
+ }
+ doResize();
+ QFrame::styleChange( old );
+}
+
+#endif
+
+/*!
+ Specifies the direction of the minimize buttons.
+ If the orientation of the splitter is horizontal then with
+ KDGanttMinimizeSplitter::Left or KDGanttMinimizeSplitter::Right should be used,
+ otherwise either KDGanttMinimizeSplitter::Up or KDGanttMinimizeSplitter::Down
+ should be used.
+*/
+void KDGanttMinimizeSplitter::setMinimizeDirection( Direction direction )
+{
+ _direction = direction;
+}
+
+/*!
+ Returns the direction of the minimize buttons.
+*/
+KDGanttMinimizeSplitter::Direction KDGanttMinimizeSplitter::minimizeDirection() const
+{
+ return _direction;
+}
+
+/*
+ This is a copy of qGeomCalc() in qlayoutengine.cpp which
+ unfortunately isn't exported.
+*/
+static inline int toFixed( int i ) { return i * 256; }
+static inline int fRound( int i ) {
+ return ( i % 256 < 128 ) ? i / 256 : 1 + i / 256;
+}
+void kdganttGeomCalc( QMemArray<QLayoutStruct> &chain, int start, int count, int pos,
+ int space, int spacer )
+{
+ typedef int fixed;
+ int cHint = 0;
+ int cMin = 0;
+ int cMax = 0;
+ int sumStretch = 0;
+ int spacerCount = 0;
+
+ bool wannaGrow = FALSE; // anyone who really wants to grow?
+ // bool canShrink = FALSE; // anyone who could be persuaded to shrink?
+
+ int i;
+ for ( i = start; i < start + count; i++ ) {
+ chain[i].done = FALSE;
+ cHint += chain[i].sizeHint;
+ cMin += chain[i].minimumSize;
+ cMax += chain[i].maximumSize;
+ sumStretch += chain[i].stretch;
+ if ( !chain[i].empty )
+ spacerCount++;
+ wannaGrow = wannaGrow || chain[i].expansive;
+ }
+
+ int extraspace = 0;
+ if ( spacerCount )
+ spacerCount--; // only spacers between things
+ if ( space < cMin + spacerCount * spacer ) {
+ // qDebug("not enough space");
+ for ( i = start; i < start+count; i++ ) {
+ chain[i].size = chain[i].minimumSize;
+ chain[i].done = TRUE;
+ }
+ } else if ( space < cHint + spacerCount*spacer ) {
+ // Less space than sizeHint, but more than minimum.
+ // Currently take space equally from each, like in Qt 2.x.
+ // Commented-out lines will give more space to stretchier items.
+ int n = count;
+ int space_left = space - spacerCount*spacer;
+ int overdraft = cHint - space_left;
+ //first give to the fixed ones:
+ for ( i = start; i < start+count; i++ ) {
+ if ( !chain[i].done && chain[i].minimumSize >= chain[i].sizeHint) {
+ chain[i].size = chain[i].sizeHint;
+ chain[i].done = TRUE;
+ space_left -= chain[i].sizeHint;
+ // sumStretch -= chain[i].stretch;
+ n--;
+ }
+ }
+ bool finished = n == 0;
+ while ( !finished ) {
+ finished = TRUE;
+ fixed fp_over = toFixed( overdraft );
+ fixed fp_w = 0;
+
+ for ( i = start; i < start+count; i++ ) {
+ if ( chain[i].done )
+ continue;
+ // if ( sumStretch <= 0 )
+ fp_w += fp_over / n;
+ // else
+ // fp_w += (fp_over * chain[i].stretch) / sumStretch;
+ int w = fRound( fp_w );
+ chain[i].size = chain[i].sizeHint - w;
+ fp_w -= toFixed( w ); //give the difference to the next
+ if ( chain[i].size < chain[i].minimumSize ) {
+ chain[i].done = TRUE;
+ chain[i].size = chain[i].minimumSize;
+ finished = FALSE;
+ overdraft -= chain[i].sizeHint - chain[i].minimumSize;
+ // sumStretch -= chain[i].stretch;
+ n--;
+ break;
+ }
+ }
+ }
+ } else { //extra space
+ int n = count;
+ int space_left = space - spacerCount*spacer;
+ // first give to the fixed ones, and handle non-expansiveness
+ for ( i = start; i < start + count; i++ ) {
+ if ( !chain[i].done && (chain[i].maximumSize <= chain[i].sizeHint
+ || wannaGrow && !chain[i].expansive) ) {
+ chain[i].size = chain[i].sizeHint;
+ chain[i].done = TRUE;
+ space_left -= chain[i].sizeHint;
+ sumStretch -= chain[i].stretch;
+ n--;
+ }
+ }
+ extraspace = space_left;
+ /*
+ Do a trial distribution and calculate how much it is off.
+ If there are more deficit pixels than surplus pixels, give
+ the minimum size items what they need, and repeat.
+ Otherwise give to the maximum size items, and repeat.
+
+ I have a wonderful mathematical proof for the correctness
+ of this principle, but unfortunately this comment is too
+ small to contain it.
+ */
+ int surplus, deficit;
+ do {
+ surplus = deficit = 0;
+ fixed fp_space = toFixed( space_left );
+ fixed fp_w = 0;
+ for ( i = start; i < start+count; i++ ) {
+ if ( chain[i].done )
+ continue;
+ extraspace = 0;
+ if ( sumStretch <= 0 )
+ fp_w += fp_space / n;
+ else
+ fp_w += (fp_space * chain[i].stretch) / sumStretch;
+ int w = fRound( fp_w );
+ chain[i].size = w;
+ fp_w -= toFixed( w ); // give the difference to the next
+ if ( w < chain[i].sizeHint ) {
+ deficit += chain[i].sizeHint - w;
+ } else if ( w > chain[i].maximumSize ) {
+ surplus += w - chain[i].maximumSize;
+ }
+ }
+ if ( deficit > 0 && surplus <= deficit ) {
+ // give to the ones that have too little
+ for ( i = start; i < start+count; i++ ) {
+ if ( !chain[i].done &&
+ chain[i].size < chain[i].sizeHint ) {
+ chain[i].size = chain[i].sizeHint;
+ chain[i].done = TRUE;
+ space_left -= chain[i].sizeHint;
+ sumStretch -= chain[i].stretch;
+ n--;
+ }
+ }
+ }
+ if ( surplus > 0 && surplus >= deficit ) {
+ // take from the ones that have too much
+ for ( i = start; i < start+count; i++ ) {
+ if ( !chain[i].done &&
+ chain[i].size > chain[i].maximumSize ) {
+ chain[i].size = chain[i].maximumSize;
+ chain[i].done = TRUE;
+ space_left -= chain[i].maximumSize;
+ sumStretch -= chain[i].stretch;
+ n--;
+ }
+ }
+ }
+ } while ( n > 0 && surplus != deficit );
+ if ( n == 0 )
+ extraspace = space_left;
+ }
+
+ // as a last resort, we distribute the unwanted space equally
+ // among the spacers (counting the start and end of the chain).
+
+ //### should do a sub-pixel allocation of extra space
+ int extra = extraspace / ( spacerCount + 2 );
+ int p = pos + extra;
+ for ( i = start; i < start+count; i++ ) {
+ chain[i].pos = p;
+ p = p + chain[i].size;
+ if ( !chain[i].empty )
+ p += spacer+extra;
+ }
+}
+
+#endif
+
+/*!
+ \enum KDGanttMinimizeSplitter::Direction
+
+ The values of this enumeration describe into which direction the
+ splitter will collapse its child widgets. By extension, it also
+ specifies the orientation of the splitter; collapsing to the left or
+ to the right results in a horizontal splitter, collapsing to the top
+ or bottom in a vertical splitter.
+*/
+
+/*!
+ \fn Orientation KDGanttMinimizeSplitter::orientation() const
+
+ Returns the orientation of the splitter.
+*/
+
+/*! \enum KDGanttMinimizeSplitter::ResizeMode
+
+ This enum type describes how KDGanttMinimizeSplitter will resize each of its child widgets. The currently defined values are:
+
+ Stretch: the widget will be resized when the splitter
+ itself is resized.
+
+ KeepSize: KDGanttMinimizeSplitter will try to keep this widget's size
+ unchanged.
+
+ FollowSizeHint: KDGanttMinimizeSplitter will resize the widget when the
+ widget's size hint changes.
+*/
+
diff --git a/kdgantt/KDGanttMinimizeSplitter.h b/kdgantt/KDGanttMinimizeSplitter.h
new file mode 100644
index 00000000..1581d615
--- /dev/null
+++ b/kdgantt/KDGanttMinimizeSplitter.h
@@ -0,0 +1,184 @@
+/* -*- Mode: C++ -*-
+ $Id$
+*/
+
+/****************************************************************************
+ ** Copyright (C) 2001-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.
+ **
+ **********************************************************************/
+
+#ifndef KDGANTTMINIMIZESPLITTER_H
+#define KDGANTTMINIMIZESPLITTER_H
+
+#ifndef QT_H
+#include "qframe.h"
+#include "qvaluelist.h"
+#endif // QT_H
+
+#ifndef QT_NO_SPLITTER
+
+class QSplitterData;
+class QSplitterLayoutStruct;
+
+class KDGanttMinimizeSplitter : public QFrame
+{
+ Q_OBJECT
+ Q_ENUMS( Direction )
+ Q_PROPERTY( Orientation orientation READ orientation WRITE setOrientation )
+ Q_PROPERTY( Direction minimizeDirection READ minimizeDirection WRITE setMinimizeDirection )
+
+public:
+ enum ResizeMode { Stretch, KeepSize, FollowSizeHint };
+ enum Direction { Left, Right, Up, Down };
+
+ KDGanttMinimizeSplitter( QWidget* parent=0, const char* name=0 );
+ KDGanttMinimizeSplitter( Orientation, QWidget* parent=0, const char* name=0 );
+ ~KDGanttMinimizeSplitter();
+
+ virtual void setOrientation( Orientation );
+ Orientation orientation() const { return orient; }
+
+ void setMinimizeDirection( Direction );
+ Direction minimizeDirection() const;
+
+#if QT_VERSION >= 300
+ virtual void setResizeMode( QWidget *w, ResizeMode );
+ virtual void setOpaqueResize( bool = TRUE );
+ bool opaqueResize() const;
+
+ void moveToFirst( QWidget * );
+ void moveToLast( QWidget * );
+
+ void refresh() { recalc( TRUE ); }
+ virtual QSize sizeHint() const;
+ virtual QSize minimumSizeHint() const;
+
+ QValueList<int> sizes() const;
+ void setSizes( QValueList<int> );
+
+ void expandPos( int id, int* min, int* max );
+protected:
+ void childEvent( QChildEvent * );
+
+ bool event( QEvent * );
+ void resizeEvent( QResizeEvent * );
+
+ int idAfter( QWidget* ) const;
+
+ void moveSplitter( QCOORD pos, int id );
+ virtual void drawSplitter( QPainter*, QCOORD x, QCOORD y,
+ QCOORD w, QCOORD h );
+ void styleChange( QStyle& );
+ int adjustPos( int , int );
+ virtual void setRubberband( int );
+ void getRange( int id, int*, int* );
+
+private:
+ void init();
+ void recalc( bool update = FALSE );
+ void doResize();
+ void storeSizes();
+ void processChildEvents();
+ QSplitterLayoutStruct *addWidget( QWidget*, bool first = FALSE );
+ void recalcId();
+ void moveBefore( int pos, int id, bool upLeft );
+ void moveAfter( int pos, int id, bool upLeft );
+ void setG( QWidget *w, int p, int s, bool isSplitter = FALSE );
+
+ QCOORD pick( const QPoint &p ) const
+ { return orient == Horizontal ? p.x() : p.y(); }
+ QCOORD pick( const QSize &s ) const
+ { return orient == Horizontal ? s.width() : s.height(); }
+
+ QCOORD trans( const QPoint &p ) const
+ { return orient == Vertical ? p.x() : p.y(); }
+ QCOORD trans( const QSize &s ) const
+ { return orient == Vertical ? s.width() : s.height(); }
+
+ QSplitterData *data;
+#endif
+
+private:
+ Orientation orient;
+ Direction _direction;
+#ifndef DOXYGEN_SKIP_INTERNAL
+ friend class KDGanttSplitterHandle;
+#endif
+private: // Disabled copy constructor and operator=
+#if defined(Q_DISABLE_COPY)
+ KDGanttMinimizeSplitter( const KDGanttMinimizeSplitter & );
+ KDGanttMinimizeSplitter& operator=( const KDGanttMinimizeSplitter & );
+#endif
+};
+
+#ifndef DOXYGEN_SKIP_INTERNAL
+// This class was continued from a verbatim copy of the
+// QSplitterHandle pertaining to the Qt Enterprise License and the
+// GPL. It has only been renamed to KDGanttSplitterHandler in order to
+// avoid a symbol clash on some platforms.
+class KDGanttSplitterHandle : public QWidget
+{
+ Q_OBJECT
+#if QT_VERSION >= 300
+public:
+ KDGanttSplitterHandle( Qt::Orientation o,
+ KDGanttMinimizeSplitter *parent, const char* name=0 );
+ void setOrientation( Qt::Orientation o );
+ Qt::Orientation orientation() const { return orient; }
+
+ bool opaque() const { return s->opaqueResize(); }
+
+ QSize sizeHint() const;
+
+ int id() const { return myId; } // data->list.at(id())->wid == this
+ void setId( int i ) { myId = i; }
+
+protected:
+ QValueList<QPointArray> buttonRegions();
+ void paintEvent( QPaintEvent * );
+ void mouseMoveEvent( QMouseEvent * );
+ void mousePressEvent( QMouseEvent * );
+ void mouseReleaseEvent( QMouseEvent * );
+ int onButton( const QPoint& p );
+ void updateCursor( const QPoint& p );
+
+private:
+ Qt::Orientation orient;
+ bool opaq;
+ int myId;
+
+ KDGanttMinimizeSplitter *s;
+ int _activeButton;
+ bool _collapsed;
+ int _origPos;
+#endif
+};
+#endif
+
+#endif // QT_NO_SPLITTER
+
+#endif // KDGANTTMINIMIZESPLITTER_H
diff --git a/kdgantt/KDGanttSemiSizingControl.cpp b/kdgantt/KDGanttSemiSizingControl.cpp
new file mode 100644
index 00000000..91629662
--- /dev/null
+++ b/kdgantt/KDGanttSemiSizingControl.cpp
@@ -0,0 +1,413 @@
+/* -*- Mode: C++ -*-
+ $Id$
+*/
+
+/****************************************************************************
+ ** 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 "KDGanttSemiSizingControl.h"
+#include <qpushbutton.h>
+#include <qpointarray.h>
+#include <qpainter.h>
+#include <qbitmap.h>
+#include <qtooltip.h>
+#include <qwhatsthis.h>
+/*!
+ \class KDGanttSemiSizingControl KDGanttSemiSizingControl.h
+ This class provides exactly one child widget with a button for
+ minimizing and restoring. You can also specify a so-called minimize
+ widget that will be shown in place of the child widget while the
+ latter one is minimized. While the child widget is not minimized,
+ the minimize widget will not be visible.
+
+ If you add more than one child widget (besides the minimize widget),
+ only the last one added will be visible.
+*/
+
+
+/*!
+ Constructs an empty semi sizing control with horizontal
+ orientation and the control arrow button on top of the controlled
+ widget.
+
+ \param parent the parent widget. This parameter is passed to the
+ base class.
+ \param name the internal widget name. This parameter is passed to
+ the base class.
+*/
+
+KDGanttSemiSizingControl::KDGanttSemiSizingControl( QWidget* parent,
+ const char* name ) :
+ KDGanttSizingControl( parent, name ), _orient( Horizontal ),
+ _arrowPos( Before ), _minimizedWidget(0), _maximizedWidget(0)
+{
+ init();
+}
+
+
+/*!
+ Constructs an empty semi sizing control with the specified
+ orientation and the control arrow button either on top or left of
+ the controlled widget (depending on the orientation).
+
+ \param orientation the orientation of the splitter
+ \param parent the parent widget. This parameter is passed to the
+ base class.
+ \param name the internal widget name. This parameter is passed to
+ the base class.
+*/
+
+KDGanttSemiSizingControl::KDGanttSemiSizingControl( Orientation orientation,
+ QWidget* parent,
+ const char* name ) :
+ KDGanttSizingControl( parent, name ), _orient( orientation ),
+ _arrowPos( Before ), _minimizedWidget(0), _maximizedWidget(0)
+{
+ init();
+}
+
+
+/*!
+ Constructs an empty semi sizing control with the specified
+ orientation and position of the control arrow button.
+
+ \param arrowPosition specifies whether the control arrow button
+ should appear before or after the controlled widget
+ \param orientation the orientation of the splitter
+ \param parent the parent widget. This parameter is passed to the
+ base class.
+ \param name the internal widget name. This parameter is passed to
+ the base class.
+*/
+
+KDGanttSemiSizingControl::KDGanttSemiSizingControl( ArrowPosition arrowPosition,
+ Orientation orientation,
+ QWidget* parent,
+ const char* name ) :
+ KDGanttSizingControl( parent, name ), _orient( orientation ),
+ _arrowPos( arrowPosition ), _minimizedWidget(0), _maximizedWidget(0)
+{
+ init();
+}
+
+
+/*!
+ Specifies the widget that should be shown while the child widget is
+ minimized. This so-called minimize widget should be a child widget
+ of the KDGanttSemiSizingControl.
+
+ \param widget the minimize widget
+ \sa minimizedWidget()
+*/
+
+void KDGanttSemiSizingControl::setMinimizedWidget( QWidget* widget )
+{
+ _minimizedWidget = widget;
+ if( _minimizedWidget ) _minimizedWidget->hide();
+ setup();
+}
+
+
+/*!
+ Returns the widget that is shown while the child widget is
+ minimized.
+
+ \return the minimize widget
+ \sa setMinimizedWidget()
+*/
+
+QWidget* KDGanttSemiSizingControl::minimizedWidget() const
+{
+ return _minimizedWidget;
+}
+
+/*!
+ Specifies the widget that should be shown while the child widget is
+ maximized. This so-called maximize widget should be a child widget
+ of the KDGanttSemiSizingControl.
+
+ \param widget the minimize widget
+ \sa maximizedWidget()
+*/
+
+void KDGanttSemiSizingControl::setMaximizedWidget( QWidget* widget )
+{
+ _maximizedWidget = widget;
+ //if( _maximizedWidget ) _maximizedWidget->show();
+ setup();
+}
+
+/*!
+ Returns the widget that is shown while the child widget is
+ maximized.
+
+ \return the maximize widget
+ \sa setMaximizedWidget()
+*/
+
+QWidget* KDGanttSemiSizingControl::maximizedWidget() const
+{
+ return _maximizedWidget;
+}
+
+
+
+/*!
+ Sets the orientation of the simple sizing control.
+
+ \param orientation the new orientation
+ \sa orientation()
+*/
+
+void KDGanttSemiSizingControl::setOrientation( Qt::Orientation orientation )
+{
+ if ( _orient != orientation ) {
+ _orient = orientation;
+ setup();
+ }
+}
+
+
+/*!
+ Returns the orientation of the simple sizing control.
+ \return the orientation
+ \sa setOrientation()
+*/
+
+Qt::Orientation KDGanttSemiSizingControl::orientation() const
+{
+ return _orient;
+}
+
+
+/*!
+ Returns the position of the control arrow button.
+
+ \param arrowPosition the position of the control arrow button
+ \sa arrowPosition()
+*/
+
+void KDGanttSemiSizingControl::setArrowPosition( ArrowPosition arrowPosition )
+{
+ if ( _arrowPos != arrowPosition ) {
+ _arrowPos = arrowPosition;
+ setup();
+ }
+}
+
+
+/*!
+ Returns the position of the control arrow button.
+
+ \return the position of the control arrow button
+ \sa setArrowPosition()
+*/
+
+KDGanttSemiSizingControl::ArrowPosition KDGanttSemiSizingControl::arrowPosition() const
+{
+ return _arrowPos;
+}
+
+
+/*!
+ \enum KDGanttSemiSizingControl::ArrowPosition
+
+ This enum is used for specifying whether the control arrow button
+ should appear before (on top of, left of) or after (below, right of)
+ the controlled widget.
+*/
+
+void KDGanttSemiSizingControl::init()
+{
+ _but = new QPushButton( this );
+ _but->setSizePolicy( QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ) );
+ connect( _but, SIGNAL( clicked() ), this, SLOT(changeState()) );
+ _layout = 0;
+ QWhatsThis::add( _but, "Click on this button to show the \nlegend at the bottom of the widget");
+ QToolTip::add( _but, "Show / hide legend");
+
+
+}
+
+void KDGanttSemiSizingControl::setup()
+{
+ //-------------------------------------------------- Setup layout
+ delete _layout;
+ QBoxLayout* butLayout; // _layout will delete me
+
+ if ( _orient == Horizontal || isMinimized() )
+ _layout = new QHBoxLayout( this );
+ else
+ _layout = new QVBoxLayout( this );
+
+ if ( _orient == Vertical && !isMinimized() )
+ butLayout = new QHBoxLayout( _layout );
+ else
+ butLayout = new QVBoxLayout( _layout );
+
+
+
+ //---------------------------------------- Set the arrow on the button
+ if ( !isMinimized() ) {
+ _but->setPixmap( pixmap( Down ) );
+ }
+ else {
+ if ( _arrowPos == Before ) {
+ _but->setPixmap( pixmap( Right ) );
+ }
+ else {
+ _but->setPixmap( pixmap( Left ) );
+ }
+ }
+
+ //------------------------------ Setup the button at the correct possition
+ if ( _arrowPos == After && _orient == Vertical && !isMinimized() ) {
+ butLayout->addStretch( 1 );
+ butLayout->addWidget( _but, 0, Qt::AlignLeft );
+ }
+ else {
+ butLayout->addWidget( _but, 0, Qt::AlignRight );
+ butLayout->addStretch( 1 );
+ }
+
+ // Set widget in the correct possition
+ QWidget* widget;
+ /* ************************** old code ***************
+ if ( isMinimized() )
+ widget = _minimizedWidget;
+ else
+ widget = _maximizedWidget;
+ if( widget ) {
+ if ( _arrowPos == Before || _orient == Vertical && !isMinimized() )
+ _layout->addWidget( widget, 1 );
+ else
+ _layout->insertWidget( 0, widget, 1 );
+ }
+ ************************************************** */
+ // hack for the usage in KDGantt as pop-up legend widget
+ // for this purpose,
+ // the _maximizedWidget must be a child of the parent of this widget
+
+ if ( isMinimized() ) {
+ widget = _minimizedWidget;
+ if( widget ) {
+ if ( _arrowPos == Before || _orient == Vertical && !isMinimized() )
+ _layout->addWidget( widget, 1 );
+ else
+ _layout->insertWidget( 0, widget, 1 );
+ }
+ }
+ else {
+ if ( _arrowPos == Before || _orient == Vertical && !isMinimized() )
+ _layout->addStretch( 1 );
+ else
+ _layout->insertStretch( 0, 1 );
+ widget = _maximizedWidget;
+ // the following is only the special case
+ // arrowPos == Before and _orient == Vertical
+ //widget->move( 0+x(), _but->height()+y());
+ }
+}
+
+
+/*!
+ Restores or minimizes the child widget. \a minimize() does exactly the
+ opposite to this method.
+
+ \param restore true to restore, false to minimize
+ \sa minimize()
+*/
+
+void KDGanttSemiSizingControl::restore( bool restore )
+{
+ if ( ! restore ) {
+ minimize( true );
+ }
+ else {
+ if( _maximizedWidget ) _maximizedWidget->show();
+ if( _minimizedWidget ) _minimizedWidget->hide();
+ KDGanttSizingControl::restore( restore );
+ setup();
+ }
+}
+
+/*!
+ Restores or minimizes the child widget. \a restore() does exactly the
+ opposite to this method.
+
+ \param minimize true to minimize, false to restore
+ \sa restore()
+
+*/
+
+void KDGanttSemiSizingControl::minimize( bool minimize )
+{
+ if ( ! minimize ) {
+ restore( true );
+ }
+ else {
+ if( _minimizedWidget ) _minimizedWidget->show();
+ if( _maximizedWidget ) _maximizedWidget->hide();
+ KDGanttSizingControl::minimize( minimize );
+ setup();
+ }
+}
+
+QPixmap KDGanttSemiSizingControl::pixmap( Direction direction ) {
+ int s = 10;
+ QPixmap pix( s, s );
+ pix.fill( blue );
+
+ QPointArray arr;
+ switch ( direction ) {
+ case Up: arr.setPoints( 3, 0, s-1, s-1, s-1, 0, s/2 ); ;break;
+ case Down: arr.setPoints( 3, 0, 0, s-1, 0, s/2, s-1 ); break;
+ case Left: arr.setPoints( 3, s-1, 0, s-1, s-1, 0, s/2 ); break;
+ case Right: arr.setPoints( 3, 0,0, s-1, s/2, 0, s-1 ); break;
+ }
+
+ QPainter p( &pix );
+ p.setPen( black );
+ p.setBrush( colorGroup().button() );
+ p.drawPolygon( arr );
+ QBitmap bit( s, s );
+ bit.fill( color0 );
+
+ QPainter p2( &bit );
+ p2.setPen( color1 );
+ p2.setBrush( color1 );
+ p2.drawPolygon( arr );
+ pix.setMask( bit );
+ return pix;
+}
+
+#ifndef KDGANTT_MASTER_CVS
+#include "KDGanttSemiSizingControl.moc"
+#endif
diff --git a/kdgantt/KDGanttSemiSizingControl.h b/kdgantt/KDGanttSemiSizingControl.h
new file mode 100644
index 00000000..6fb56e32
--- /dev/null
+++ b/kdgantt/KDGanttSemiSizingControl.h
@@ -0,0 +1,90 @@
+/* -*- Mode: C++ -*-
+ $Id$
+*/
+
+/****************************************************************************
+ ** 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.
+ **
+ **********************************************************************/
+
+
+#ifndef KDGANTTSEMISIZINGCONTROL_H
+#define KDGANTTSEMISIZINGCONTROL_H
+
+#include "KDGanttSizingControl.h"
+#include <qlayout.h>
+class QPushButton;
+class QBoxLayout;
+
+class KDGanttSemiSizingControl : public KDGanttSizingControl
+{
+ Q_PROPERTY( ArrowPosition arrowPosition READ arrowPosition WRITE setArrowPosition )
+ Q_ENUMS( ArrowPosition )
+ Q_OBJECT
+
+public:
+ enum ArrowPosition { Before, After };
+
+ KDGanttSemiSizingControl( QWidget* parent = 0, const char* name = 0 );
+ KDGanttSemiSizingControl( Orientation orientation, QWidget* parent = 0,
+ const char* name = 0 );
+ KDGanttSemiSizingControl( ArrowPosition arrowPosition,
+ Orientation orientation, QWidget* parent = 0,
+ const char* name = 0 );
+
+ void setMinimizedWidget( QWidget* widget );
+ void setMaximizedWidget( QWidget* widget );
+ QWidget* minimizedWidget() const;
+ QWidget* maximizedWidget() const;
+
+ void setOrientation( Qt::Orientation orientation );
+ Qt::Orientation orientation() const;
+
+ void setArrowPosition( ArrowPosition arrowPosition );
+ ArrowPosition arrowPosition() const;
+
+public slots:
+ virtual void minimize( bool minimize );
+ virtual void restore( bool restore );
+
+protected:
+ void setup();
+ void init();
+ enum Direction {Left, Right, Up, Down };
+ QPixmap pixmap( Direction );
+
+private:
+ Orientation _orient;
+ ArrowPosition _arrowPos;
+ QWidget* _minimizedWidget;
+ QWidget* _maximizedWidget;
+ QBoxLayout* _layout;
+ QPushButton* _but;
+};
+
+
+#endif
diff --git a/kdgantt/KDGanttSizingControl.cpp b/kdgantt/KDGanttSizingControl.cpp
new file mode 100644
index 00000000..5f4c004a
--- /dev/null
+++ b/kdgantt/KDGanttSizingControl.cpp
@@ -0,0 +1,150 @@
+/* -*- Mode: C++ -*-
+ $Id$
+*/
+/****************************************************************************
+ ** 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 "KDGanttSizingControl.h"
+
+/*!
+ \class KDGanttSizingControl KDGanttSizingControl.h
+ This class is a common-base class for all sizing controls in this
+ library.
+
+ It provides common signals and slots for minimizing and restoring
+ child widgets.
+
+ This class cannot be instantiated by itself, use one of the
+ subclasses instead.
+*/
+
+/*!
+ Constructs an empty KDGanttSizing Control.
+
+ \param parent the parent widget. This parameter is passed to the
+ base class.
+ \param name the internal widget name. This parameter is passed to
+ the base class.
+ \param f window flags. This parameter is passed to the base class.
+
+*/
+
+KDGanttSizingControl::KDGanttSizingControl( QWidget* parent, const char* name, WFlags f )
+ :QWidget( parent, name, f ), _isMinimized( false )
+{
+}
+
+
+/*!
+ Restores or minimizes the child widget. \a minimize() does exactly the
+ opposite to this method.
+
+ \param restore true to restore, false to minimize
+ \sa minimize()
+*/
+
+void KDGanttSizingControl::restore( bool restore )
+{
+ _isMinimized = !restore;
+ if ( restore )
+ emit restored( this );
+ else
+ emit minimized( this );
+}
+
+
+
+
+/*!
+ Restores or minimizes the child widget. \a restore() does exactly the
+ opposite to this method.
+
+ \param minimize true to minimize, false to restore
+ \sa restore()
+
+*/
+
+void KDGanttSizingControl::minimize( bool minimize )
+{
+ _isMinimized = minimize;
+ if ( minimize )
+ emit minimized( this );
+ else
+ emit restored( this );
+}
+
+
+/*!
+ Returns whether the widget is minimized.
+*/
+
+bool KDGanttSizingControl::isMinimized() const
+{
+ return _isMinimized;
+}
+
+/*!
+ Change state from either minimized to restored or visa versa.
+*/
+
+void KDGanttSizingControl::changeState()
+{
+ restore(_isMinimized);
+}
+
+
+/*!
+ \fn void KDGanttSizingControl::minimized( KDGanttSizingControl* )
+
+ This signal is emitted when the user hides a controlled widget. The
+ KDGanttSizingControl pointer given as parameter is a pointer to the widget
+ itself. Normally the sender should not know the receiver, but in this
+ case the receiver is likely the widget containing the KDGanttSizingControl,
+ and when the KDGanttSizingControl widget is minimized/restored it might want
+ to change stretching for the widget. See the example
+ test/semisizingcontrol
+*/
+
+
+/*!
+ \fn void KDGanttSizingControl::restored( KDGanttSizingControl* )
+
+ This signal is emitted when the user unhides a controlled widget. The
+ KDGanttSizingControl pointer given as parameter is a pointer to the widget
+ itself. Normally the sender should not know the receiver, but in this
+ case the receiver is likely the widget containing the KDGanttSizingControl,
+ and when the KDGanttSizingControl widget is minimized/restored it might want
+ to change stretching for the widget. See the example
+ test/semisizingcontrol
+*/
+
+#ifndef KDGANTT_MASTER_CVS
+#include "KDGanttSizingControl.moc"
+#endif
diff --git a/kdgantt/KDGanttSizingControl.h b/kdgantt/KDGanttSizingControl.h
new file mode 100644
index 00000000..12fa075e
--- /dev/null
+++ b/kdgantt/KDGanttSizingControl.h
@@ -0,0 +1,62 @@
+/* -*- Mode: C++ -*-
+ $Id$
+*/
+/****************************************************************************
+ ** 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.
+ **
+ **********************************************************************/
+
+#ifndef KDGANTTSIZINGCONTROL_H
+#define KDGANTTSIZINGCONTROL_H
+
+#include <qwidget.h>
+
+class KDGanttSizingControl : public QWidget
+{
+ Q_OBJECT
+
+public:
+ bool isMinimized() const;
+
+protected:
+ KDGanttSizingControl( QWidget* parent = 0, const char* name = 0, WFlags f = 0 );
+
+public slots:
+ virtual void minimize( bool minimize );
+ virtual void restore( bool restore );
+ void changeState();
+
+signals:
+ void minimized( KDGanttSizingControl* );
+ void restored( KDGanttSizingControl* );
+
+private:
+ bool _isMinimized;
+};
+
+
+#endif
diff --git a/kdgantt/KDGanttView.cpp b/kdgantt/KDGanttView.cpp
new file mode 100644
index 00000000..0b09ce10
--- /dev/null
+++ b/kdgantt/KDGanttView.cpp
@@ -0,0 +1,4847 @@
+/* -*- 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 "KDGanttView.h"
+#include "KDGanttViewSubwidgets.h"
+#include "KDGanttMinimizeSplitter.h"
+#include "KDGanttViewItem.h"
+#include "KDGanttXMLTools.h"
+#include "itemAttributeDialog.h"
+#include <qprinter.h>
+#include <qpainter.h>
+#include <qlayout.h>
+#include <qpaintdevicemetrics.h>
+#include <qfile.h>
+#include <qheader.h>
+#include <qscrollview.h>
+#include <qapplication.h>
+#include <qevent.h>
+#include <qiconview.h>
+
+#include <qmessagebox.h>
+#include <qfileinfo.h>
+
+#ifndef KDGANTT_MASTER_CVS
+#include "KDGanttView.moc"
+#endif
+
+#if defined KDAB_EVAL
+#include "../evaldialog/evaldialog.h"
+#endif
+
+/*!
+ \class KDGanttView KDGanttView.h
+ This class represents a Gantt view with the Gantt chart, the header,
+ an optional listview and an optional legend.
+
+ In order to set up a Gantt view, create an object of this class, and
+ populate it with a number of \a KDGanttViewItem objects.
+
+ If you experience problems with the repainting of the content of the
+ Gantt View after scrolling, call \a setRepaintMode().
+*/
+
+/*!
+ Constructs an empty KDGanttView.
+
+ \param parent the widget parent
+ \param name the internal debugging name
+*/
+
+KDGanttView::KDGanttView( QWidget* parent, const char* name )
+ : KDGanttMinimizeSplitter( Qt::Vertical, parent, name ),
+ myCanvasView(0),
+ myTimeHeaderScroll(0),
+ mFixedHorizon( false )
+{
+#if defined KDAB_EVAL
+ EvalDialog::checkEvalLicense( "KD Gantt" );
+#endif
+ myCurrentItem = 0;
+ setMinimizeDirection ( KDGanttMinimizeSplitter::Down );
+ mySplitter = new KDGanttMinimizeSplitter( this );
+ mySplitter->setMinimizeDirection ( KDGanttMinimizeSplitter::Left );
+ leftWidget = new QVBox( mySplitter );
+ rightWidget = new QVBox( mySplitter );
+
+ myLegend = new KDLegendWidget( leftWidget, this );
+ spacerLeft = new QHBox( leftWidget );
+ myListView = new KDListView(leftWidget, this);
+ myListView->setVScrollBarMode (QScrollView::AlwaysOff );
+ connect( myListView, SIGNAL( selectionChanged( QListViewItem* ) ),
+ this, SLOT( slotSelectionChanged( QListViewItem* ) ) );
+
+ connect( myListView, SIGNAL( mouseButtonClicked ( int, QListViewItem * , const QPoint &, int ) ), this, SLOT( slotmouseButtonClicked ( int , QListViewItem * , const QPoint &, int ) ) );
+ connect( myListView, SIGNAL( contextMenuRequested ( QListViewItem * , const QPoint &, int ) ), this, SLOT( slotcontextMenuRequested ( QListViewItem * , const QPoint & , int ) ) );
+
+ connect( myListView, SIGNAL(currentChanged( QListViewItem * ) ), this, SLOT(slotCurrentChanged ( QListViewItem * ) ) );
+ connect( myListView, SIGNAL(itemRenamed ( QListViewItem * , int , const QString & ) ), this, SLOT(slotItemRenamed ( QListViewItem *, int , const QString & ) ) );
+ connect( myListView, SIGNAL(mouseButtonPressed( int, QListViewItem * , const QPoint &, int ) ), this, SLOT(slotMouseButtonPressed ( int , QListViewItem * , const QPoint & , int ) ) );
+
+ //connect( myListView, SIGNAL( ), this, SLOT( ) );
+ myTimeTable = new KDTimeTableWidget (rightWidget,this);
+
+ spacerRight = new QWidget( rightWidget );
+
+ myTimeHeaderContainer = new QHBox( rightWidget );
+ myTimeHeaderContainer->setFrameStyle( QFrame::NoFrame );
+ myTimeHeaderContainer->setMargin( 0 );
+ myTimeHeaderScroll = new QScrollView ( myTimeHeaderContainer );
+ myTimeHeaderScroll->setHScrollBarMode( QScrollView::AlwaysOff );
+ myTimeHeaderScroll->setVScrollBarMode( QScrollView::AlwaysOff );
+ timeHeaderSpacerWidget = new QWidget( myTimeHeaderContainer );
+
+
+ /*
+ myTimeHeaderScroll = new QScrollView ( rightWidget );
+ myTimeHeaderScroll->setHScrollBarMode( QScrollView::AlwaysOff );
+ myTimeHeaderScroll->setVScrollBarMode( QScrollView::AlwaysOn );
+ */
+ //myTimeHeader = new KDTimeHeaderWidget (rightWidget,this);
+ myTimeHeader = new KDTimeHeaderWidget (myTimeHeaderScroll->viewport(),this);
+ myTimeHeaderScroll->addChild( myTimeHeader );
+ myTimeHeaderScroll->viewport()->setBackgroundColor( myTimeHeader->backgroundColor() );
+ timeHeaderSpacerWidget->setBackgroundColor( myTimeHeader->backgroundColor() );
+ myCanvasView = new KDGanttCanvasView (this,myTimeTable,rightWidget);
+ myTimeHeaderScroll->setFrameStyle( QFrame::NoFrame );
+ //
+ myCanvasView->setFrameStyle( QFrame::NoFrame );
+ myCanvasView->setMargin( 0 );
+ //
+ myTimeHeaderScroll->setMargin( 0 );//myCanvasView->frameWidth() );
+ setFrameStyle(myListView->frameStyle());
+ setLineWidth( 2 );
+ myListView->setFrameStyle( QFrame::NoFrame );
+ myListView->setMargin( 0 );
+ QObject::connect(myListView, SIGNAL ( expanded ( QListViewItem * ) ) , myTimeTable , SLOT( expandItem(QListViewItem * ))) ;
+ QObject::connect(myListView, SIGNAL (collapsed ( QListViewItem * ) ) , myTimeTable , SLOT(collapseItem(QListViewItem * ))) ;
+
+ timeHeaderSpacerWidget->setFixedWidth(myCanvasView->verticalScrollBar()->width() );
+ listViewIsVisible = true;
+ chartIsEditable = true;
+ editorIsEnabled = true;
+ _displaySubitemsAsGroup = false;
+ initDefaults();
+ _showHeader = false;
+
+ myTextColor = Qt::black;
+ myLegendItems = new QPtrList<legendItem>;
+ //QObject::connect( this, SIGNAL (itemDoubleClicked( KDGanttViewItem* ) ) , this, SLOT( editItem( KDGanttViewItem* ))) ;
+ myItemAttributeDialog = new itemAttributeDialog();
+ setRepaintMode( KDGanttView::Medium );
+ //setRepaintMode( KDGanttView::Always );
+ setShowLegendButton( true );
+ setHeaderVisible( false );
+
+ // now connecting the widgets
+ connect(myCanvasView->horizontalScrollBar(), SIGNAL ( valueChanged ( int )) ,myTimeHeaderScroll->horizontalScrollBar(), SLOT( setValue ( int))) ;
+ connect(myCanvasView, SIGNAL ( heightResized( int )) ,myTimeTable, SLOT( checkHeight ( int))) ;
+ connect(myCanvasView, SIGNAL ( widthResized( int )) ,myTimeHeader, SLOT( checkWidth ( int))) ;
+
+ QObject::connect(myCanvasView->verticalScrollBar(), SIGNAL ( valueChanged ( int ) ) ,myListView->verticalScrollBar(), SLOT( setValue ( int ))) ;
+ connect(myTimeHeader, SIGNAL ( sizeChanged( int ) ) ,this, SLOT(slotHeaderSizeChanged() )) ;
+ connect(myTimeHeader, SIGNAL ( sizeChanged( int ) ) ,myTimeTable, SLOT(resetWidth( int ) )) ;
+ connect(myListView, SIGNAL ( contentsMoving ( int, int ) ) ,myCanvasView, SLOT( moveMyContent( int, int ))) ;
+ connect(myTimeTable, SIGNAL ( heightComputed ( int ) ) ,myCanvasView, SLOT( setMyContentsHeight( int ))) ;
+ // the next three are for adding new ticks at left/right
+ connect( myCanvasView->horizontalScrollBar(), SIGNAL (prevLine () ) ,this, SLOT(addTickLeft()));
+ connect( myCanvasView->horizontalScrollBar(), SIGNAL (nextLine () ) ,this, SLOT(addTickRight()));
+ connect( myCanvasView->horizontalScrollBar(), SIGNAL (valueChanged ( int ) ) ,this, SLOT( enableAdding( int )));
+
+ // now initing
+ fCenterTimeLineAfterShow = false;
+ fDragEnabled = false;
+ fDropEnabled = false;
+ closingBlocked = false;
+ myTimeHeader->computeTicks();
+ centerTimelineAfterShow( QDateTime::currentDateTime () );
+ setDisplayEmptyTasksAsLine( false );
+ QValueList<int> list;
+ list.append(240);
+ list.append(530);
+ mySplitter->setSizes( list );
+ myTimeTable->setBlockUpdating();// block updating until this->show() is called
+}
+
+
+
+KDGanttView::~KDGanttView()
+{
+ setUpdateEnabled(false);
+ // delete cut item, if there is any
+ myCanvasView->resetCutPaste( 0 );
+ myTimeTable->clearTaskLinks();
+}
+/*!
+ Enables or disables updating of the content of the Gantt view.
+ To avoid flickering in the Gantt view while inserting large amounts
+ of Gantt items, you should call
+
+ bool upd = KDGanttView::getUpdateEnabled();
+ KDGanttView::settUpdateEnabled( false );
+ ... insert items here ...
+ KDGanttView::settUpdateEnabled( upd );
+
+ With this code, you avoid unwanted side effects with other parts in
+ your code, where you disable (and re-enable) the update.
+
+ When calling setUpdateEnabled( true ),
+ all the content is recomputed, resized, and updated.
+
+ Before calling show() for the first time, updating is disabled.
+ When calling show(), updating is automatically enabled.
+
+ \param enable if true, the content of the Gantt view is updated after
+ every insertion of a new item.
+ \sa getUpdateEnabled()
+*/
+void KDGanttView::setUpdateEnabled( bool enable )
+{
+ myTimeTable->setBlockUpdating( !enable );
+ if ( enable ) {
+ myTimeTable->updateMyContent();
+ myCanvasView->setMyContentsHeight( 0 );
+ }
+}
+
+/*!
+ Returns whether updating is enabled or not.
+
+ \return true, if updating is enabled
+ \sa setUpdateEnabled()
+*/
+
+bool KDGanttView::getUpdateEnabled() const
+{
+ return !myTimeTable->blockUpdating();
+}
+
+
+
+
+/*!
+ Sets the maximum width of the Gantt view part widget in pixels.
+ The largest allowed width is 32767.
+ \param w the maximum width
+*/
+
+void KDGanttView::setGanttMaximumWidth( int w )
+{
+ myTimeHeader->setMaximumWidth ( w );
+}
+/*!
+ Returns the maximum width of the Gantt view part widget in pixels.
+ The default maximum width is 32767 pixels.
+
+ \return the maximum width of the Gantt view part widget in pixels.
+*/
+
+int KDGanttView::ganttMaximumWidth() const
+{
+ return myTimeHeader->maximumWidth();
+}
+
+/*!
+ Updates the content of the GanttView and shows it.
+ Automatically sets setUpdateEnabled( true ).
+ \sa setUpdateEnabled()
+*/
+
+void KDGanttView::show()
+{
+ myTimeTable->setBlockUpdating( false );
+ if (myCanvasView->horizontalScrollBar()->value() > 0 )
+ myCanvasView->horizontalScrollBar()->setValue(myCanvasView->horizontalScrollBar()->value()-1 );
+ else
+ myCanvasView->horizontalScrollBar()->setValue(1 );
+ myTimeTable->updateMyContent();
+ QWidget::show();
+ myCanvasView->setMyContentsHeight( 0 );
+ if ( fCenterTimeLineAfterShow ) {
+ fCenterTimeLineAfterShow = false;
+ centerTimeline (dtCenterTimeLineAfterShow);
+ }
+}
+/*!
+ Closes the widget.
+ The closing is rejected, if a repainting is currently being done.
+ \param alsoDelete if true, the widget is deleted
+ \return true, if the widget was closed
+*/
+
+bool KDGanttView::close ( bool alsoDelete )
+{
+ //qDebug("close ");
+ if ( closingBlocked )
+ return false;
+ return QWidget::close ( alsoDelete );
+}
+
+
+/*!
+ Returns a useful size for the view.
+ Returned width:
+ sizeHint().width() of the list view + width of TimeTable
+ Returned height:
+ height() of TimeHeader + height() of TimeTable + height() of Legend (if shown)
+*/
+
+QSize KDGanttView::sizeHint() const
+{
+ bool block = myTimeTable->blockUpdating();
+ myTimeTable->setBlockUpdating( false );
+ myTimeTable->updateMyContent();
+ /* The below causes recursive calls to various size updating methods, which
+ * cause QCanvas to hide and show items like mad, which is very slow. If
+ * there is a legitimate gui updating issue here somewhere, it will need
+ * to be solved differently.
+ */
+ //qApp->processEvents();
+ int hintHeight = myTimeHeader->height();
+ int legendHeight = 0;
+ if ( showLegendButton() )
+ legendHeight = myLegend->height();
+ int listViewHeaderHeight = 0;
+ if ( headerVisible() )
+ listViewHeaderHeight = myListView->header()->height();
+ if ( hintHeight < legendHeight+listViewHeaderHeight )
+ hintHeight = legendHeight + listViewHeaderHeight;
+ hintHeight += myListView->horizontalScrollBar()->height();
+ if ( myLegend->isShown() )
+ hintHeight += myLegend->legendSizeHint().height() +10;
+ hintHeight += myTimeTable->minimumHeight+myListView->frameWidth()*2+2;
+ int hintWid = myListView->sizeHint().width();
+ //hintWid += myTimeHeader->mySizeHint+myCanvasView->verticalScrollBar()->width();
+ hintWid += myCanvasView->sizeHint().width();
+ // add 10 for the splitter-bars
+ // qDebug("sizehint %d %d ",hintWid+10, hintHeight );
+ myTimeTable->setBlockUpdating( block );
+ return QSize( hintWid+10, hintHeight );
+}
+
+
+/*!
+ Specifies whether the legend button should be visible. By default,
+ it is visible.
+
+ \param show true to show the legend button, false to hide it
+ \sa showLegendButton()
+*/
+void KDGanttView::setShowLegendButton( bool show )
+{
+ _showLegendButton = show;
+ if ( show )
+ myLegend->show();
+ else
+ myLegend->hide();
+ slotHeaderSizeChanged();
+}
+
+
+/*!
+ Returns whether the legend button is visible.
+
+ \return whether the legend button is visible
+ \sa setShowLegendButton()
+*/
+bool KDGanttView::showLegendButton() const
+{
+ return _showLegendButton;
+}
+
+
+/*!
+ Specifies whether the listview header should be visible. By default,
+ it is not visible.
+
+ \param visible true to make the header visible, false to make it invisible
+*/
+void KDGanttView::setHeaderVisible( bool visible )
+{
+ if( visible )
+ myListView->header()->show();
+ else
+ myListView->header()->hide();
+ _showHeader = visible;
+ slotHeaderSizeChanged();
+}
+
+
+/*!
+ Returns whether the listview header is visible.
+
+ \return whether the header is visible
+*/
+bool KDGanttView::headerVisible() const
+{
+ return _showHeader;
+}
+
+
+/*!
+ Returns the corresponding date and time of the coordinate X in the
+ Gantt view.
+
+ \param coordX the coordinate to search for
+ \param global true if coordX is a global position, false otherwise
+ \return the date and time at coordinate X in the Gantt view.
+*/
+QDateTime KDGanttView::getDateTimeForCoordX(int coordX, bool global ) const
+{
+ // default for myTimeHeader->getDateTimeForIndex() is local
+ return myTimeHeader->getDateTimeForIndex(coordX, !global );
+}
+
+
+/*!
+ Implements a casted pass-through of the selectionChanged() signal.
+*/
+void KDGanttView::slotSelectionChanged( QListViewItem* item )
+{
+ KDGanttViewItem* gItem = static_cast<KDGanttViewItem*>( item );
+ Q_ASSERT( gItem );
+ emit lvSelectionChanged( gItem );
+}
+
+
+/*
+ Implements a casted pass-through of the mouseButtonClicked() signal.
+ Signals itemLeftClicked() , itemMidClicked() are emitted as well.
+*/
+void KDGanttView::slotmouseButtonClicked ( int button, QListViewItem * item,
+ const QPoint & pos, int c )
+{
+ KDGanttViewItem* gItem = static_cast<KDGanttViewItem*>( item );
+ emit lvMouseButtonClicked ( button , gItem, pos, c );
+ if (gItem == 0 && myCurrentItem != 0 ) {
+ myCurrentItem = 0;
+ emit lvCurrentChanged( gItem );
+ }
+ if (gItem != 0 && myCurrentItem == 0 ) {
+ myCurrentItem = gItem;
+ emit lvCurrentChanged( gItem );
+ }
+
+ // removed - makes no sense!
+ //emit mouseButtonClicked ( button , gItem, pos, c );
+ {
+ switch ( button ) {
+ case LeftButton:
+ emit lvItemLeftClicked( gItem );
+ emit itemLeftClicked( gItem );
+ break;
+ case MidButton:
+ emit lvItemMidClicked( gItem );
+ emit itemMidClicked( gItem );
+ break;
+ }
+ }
+}
+
+
+/*
+ Implements a casted pass-through of the contextMenuRequested() signal.
+ The signal itemRightClicked() is emitted as well;
+ the position is the global position.
+*/
+void KDGanttView::slotcontextMenuRequested ( QListViewItem * item, const QPoint & pos, int col )
+{
+ KDGanttViewItem* gItem = static_cast<KDGanttViewItem*>( item );
+ emit lvContextMenuRequested ( gItem, pos, col );
+ emit lvItemRightClicked( gItem );
+ emit itemRightClicked( gItem );
+}
+
+
+void KDGanttView::emptySpaceDoubleClicked( QMouseEvent * e )
+{
+ emit dateTimeDoubleClicked( getDateTimeForCoordX( e->x(), false ) );
+}
+
+
+/*
+ Implements a casted pass-through of the currentChanged() signal.
+*/
+void KDGanttView::slotCurrentChanged ( QListViewItem * item )
+{
+ KDGanttViewItem* gItem = static_cast<KDGanttViewItem*>( item );
+ myCurrentItem = gItem;
+ emit lvCurrentChanged( gItem );
+}
+
+
+/*
+ Implements a casted pass-through of the itemRenamed() signal.
+*/
+void KDGanttView::slotItemRenamed ( QListViewItem * item , int col,
+ const QString & text )
+{
+ KDGanttViewItem* gItem = static_cast<KDGanttViewItem*>( item );
+ emit lvItemRenamed( gItem, col, text );
+}
+
+
+/*
+ Implements a casted pass-through of the mouseButtonPressed() signal.
+*/
+void KDGanttView::slotMouseButtonPressed ( int button, QListViewItem * item,
+ const QPoint & pos, int c )
+{
+ KDGanttViewItem* gItem = static_cast<KDGanttViewItem*>( item );
+ emit lvMouseButtonPressed( button, gItem, pos, c );
+}
+
+
+/*!
+ Specifies whether the content should be repainted after scrolling or
+ not.
+
+ \param mode If No, there is no repainting after scrolling. This is
+ the fastest mode.
+ If Medium, there is extra repainting after releasing the
+ scrollbar. This provides fast scrolling with updated content
+ after scrolling. Recommended, when repaint problems occur.
+ This is the default value after startup.
+ If Always, there is an extra update after every move of the
+ scrollbar. This entails slow scrolling with updated
+ content at all time.
+*/
+void KDGanttView::setRepaintMode( RepaintMode mode )
+{
+
+ QScrollBar *cvh, *cvv;
+ cvh = myCanvasView->horizontalScrollBar();
+ cvv = myCanvasView->verticalScrollBar();
+ // first disconnect
+ cvh->disconnect( this );
+ cvv->disconnect( this );
+
+ switch ( mode ) {
+ case No:
+
+ break;
+ case Medium:
+ connect( cvv, SIGNAL (sliderReleased () ) ,this, SLOT(forceRepaint()));
+ connect( cvh, SIGNAL (sliderReleased () ) ,this, SLOT(forceRepaint()));
+ connect( cvv, SIGNAL (nextLine () ) ,this, SLOT(forceRepaint()));
+ connect( cvh, SIGNAL (nextLine () ) ,this, SLOT(forceRepaint()));
+ connect( cvv, SIGNAL (prevLine () ) ,this, SLOT(forceRepaint()));
+ connect( cvh, SIGNAL (prevLine () ) ,this, SLOT(forceRepaint()));
+ break;
+ case Always:
+ connect( cvv, SIGNAL (valueChanged ( int ) ) ,this, SLOT(forceRepaint( int )));
+ connect( cvh, SIGNAL (valueChanged ( int ) ) ,this, SLOT(forceRepaint( int )));
+ connect( cvv, SIGNAL (sliderReleased () ) ,this, SLOT(forceRepaint()));
+ connect( cvh, SIGNAL (sliderReleased () ) ,this, SLOT(forceRepaint()));
+ break;
+ }
+}
+
+
+void KDGanttView::forceRepaint( int )
+{
+ if ( myTimeTable->blockUpdating() )
+ return;
+ // qDebug("forceRepaint( int ) ");
+ myTimeTable->setAllChanged();
+ myTimeTable->update();
+}
+
+
+void KDGanttView::slotHeaderSizeChanged()
+{
+ int legendHeight = 0;
+ if ( showLegendButton() )
+ legendHeight = 24;
+ int listViewHeaderHeight = 0;
+ if ( headerVisible() )
+ listViewHeaderHeight = myListView->header()->height();
+ int timeHeaderHeight = myTimeHeader->height()+myTimeHeaderScroll->frameWidth()*2;;
+ int diffY = timeHeaderHeight-legendHeight-listViewHeaderHeight;
+ if ( diffY < 0 ) {
+ spacerLeft->setFixedHeight( 0 );
+ spacerRight->setFixedHeight(-diffY);
+ } else {
+ spacerRight->setFixedHeight( 0 );
+ spacerLeft->setFixedHeight( diffY );
+ }
+ myLegend->setFixedHeight( legendHeight );
+ myTimeHeaderContainer->setFixedHeight( timeHeaderHeight );
+}
+
+
+/*!
+ Specifies whether the legend should be shown as a dock window or not.
+
+ \param show if true, show legend as a dock window
+ \sa showLegend(), legendIsDockwindow(), legendDockwindow()
+*/void KDGanttView::setLegendIsDockwindow( bool show )
+{
+ bool isdock = myLegend->asDockwindow();
+ if ( show != isdock ) {
+ myLegend->setAsDockwindow(show);
+ // legend is cleared - reinit legend with list
+ legendItem* li;
+ for ( li = myLegendItems->first(); li; li = myLegendItems->next() ) {
+ myLegend->addLegendItem(li->shape, li->color, li->text );
+ }
+ }
+}
+
+
+/*!
+ Returns whether the legend is shown as a dock window
+
+ \return true if the legend is shown as a dock window
+ \sa setShowLegend(), setLegendIsDockwindow(), legendDockwindow()
+*/bool KDGanttView::legendIsDockwindow() const
+{
+ return myLegend->asDockwindow();
+}
+
+
+/*!
+ Returns the pointer to the legend dock window.
+ DO NOT DELETE THIS POINTER!
+ If the legend is not a dock window, 0 is returned
+ To set the legend as a dock window, call
+ KDGanttView::setLegendIsDockwindow( true );
+
+ \return the pointer to the legend dock window
+ 0 is returned, if the legend is no dock window
+ DO NOT DELETE THIS POINTER!
+ \sa setShowLegend(), setLegendIsDockwindow(),legendIsDockwindow()
+*/
+QDockWindow* KDGanttView::legendDockwindow() const
+{
+ return myLegend->dockwindow();
+}
+
+
+/*!
+ Specifies whether the legend should be shown or not. Besides setting
+ this programmatically, the user can also show/hide the legend by
+ using the button provided for this purpose.
+
+ \param show force legend to be shown
+ \sa showLegend()
+*/
+void KDGanttView::setShowLegend( bool show )
+{
+ myLegend->showMe(show);
+}
+
+
+/*!
+ Returns whether the legend is currently shown. The visibility of the
+ legend can be changed both by \a setShowLegend(), and interactively
+ by the user.
+
+ \return true if the legend is currently visible
+ \sa setShowLegend()
+*/
+bool KDGanttView::showLegend() const
+{
+ return myLegend->isShown();
+}
+
+
+/*!
+ Specifies whether the listview of the Gantt view should be shown or
+ not.
+
+ \param show pass true in order to show the listview and false in
+ order to hide it.
+ \sa showListView()
+*/
+void KDGanttView::setShowListView( bool show )
+{
+ if(listViewIsVisible == show) return;
+ listViewIsVisible = show;
+ if (listViewIsVisible)
+ myListView->parentWidget()->show();
+ else
+ myListView->parentWidget()->hide();
+}
+
+
+/*!
+ Returns whether the listview of the Gantt view is shown or not.
+
+ \return true if the listview is shown
+ \sa setShowListView()
+*/
+bool KDGanttView::showListView() const
+{
+ return listViewIsVisible;
+}
+
+
+/*!
+ Specifies whether it should be possible to edit the appearance of a
+ Gantt item visually in a dialog by double-clicking the item.
+
+ \param enable pass true in order to enable the visual editor and
+ false in order to turn it off
+ \sa editorEnabled()
+*/
+
+void KDGanttView::setEditorEnabled( bool enable )
+{
+ editorIsEnabled = enable;
+}
+
+
+/*!
+ Returns whether it is possible to edit the appearance of a Gantt
+ item visually in a dialog by double-clicking the item.
+
+ \return true if visual editing is enabled, false otherwise
+ \sa setEditorEnabled()
+*/
+
+bool KDGanttView::editorEnabled() const
+{
+ return editorIsEnabled;
+}
+
+
+/*!
+ Specifies whether the Gantt chart is user-editable.
+
+ \param editable pass true in order to get a user-editable Gantt
+ chart, pass false in order to get a read-only chart
+ \sa editable()
+*/
+
+void KDGanttView::setEditable( bool editable )
+{
+ chartIsEditable = editable;
+}
+
+
+/*!
+ Returns whether the Gantt chart is user-editable
+
+ \return true if the Gantt chart is user-editable
+ \sa setEditable()
+*/
+
+bool KDGanttView::editable() const
+{
+ return chartIsEditable;
+}
+
+
+/*!
+ Saves the state of the Gantt view in an IO device in XML format. The saved
+ data can be reloaded with \a loadProject().
+
+ \param device a pointer to the IO device in which to store the Gantt
+ view state.
+ \return true if the data could be written, false if an error
+ occurred
+ \sa loadProject()
+*/
+
+bool KDGanttView::saveProject( QIODevice* device )
+{
+ Q_ASSERT( device );
+
+ QDomDocument doc = saveXML();
+ if( device->isOpen() )
+ device->close();
+ if( device->open( IO_WriteOnly ) ) {
+ QTextStream ts( device );
+ ts << doc.toString();
+ return true;
+ } else
+ return false;
+}
+
+
+/*!
+ Loads a previously saved state of the Gantt view. All current
+ settings and items are discarded before loading the data.
+
+ \param device a pointer to the IO device from which to load the
+ Gantt view state.
+ \return true if the file could be read, false if an error
+ occurred
+ \sa saveProject()
+*/
+
+bool KDGanttView::loadProject( QIODevice* device )
+{
+ Q_ASSERT( device );
+
+ if( device->isOpen() )
+ device->close();
+ if( device->open( IO_ReadOnly ) ) {
+ QDomDocument doc( "GanttView" );
+ QString err;
+ int errline, errcol;
+ if ( !doc.setContent( device, &err, &errline, &errcol ) ) {
+ qDebug("KDGantt::Error parsing XML data at line %d. Message is:", errline );
+ qDebug("%s ", err.latin1());
+ device->close();
+ return false;
+ }
+ device->close();
+ return loadXML( doc );
+ } else
+ return false;
+}
+
+
+/*!
+ Sends a Gantt view to a printer. The printer should already be set
+ up for printing (by calling QPrinter::setup()).
+ If the printer is not set up, QPrinter::setup() is called before printing
+
+ You can specify, whether the ListView, TimeLine, or Legend will be
+ printed. All combinations of these three widgets are allowed.
+
+ \param printer a pointer to the printer to print on. If printer is
+ 0, the method creates a temporary printer and discards it when it is
+ done printing.
+ \param printListView if true, the list view is printed
+ \param printTimeLine if true, the time line is printed
+ \param printLegend if true, the legend is printed
+
+ \sa drawContents()
+*/
+
+void KDGanttView::print( QPrinter* printer ,
+ bool printListView, bool printTimeLine,
+ bool printLegend )
+{
+ bool deletePrinter = false;
+ if (! printer ) {
+ printer = new QPrinter();
+ deletePrinter = true;
+ if ( !printer->setup()) {
+ delete printer;
+ return;
+ }
+ }
+ // now we have a printer to print on
+ QPainter p( printer );
+ // get the paper metrics
+ QPaintDeviceMetrics m = QPaintDeviceMetrics ( printer );
+ float dx, dy;
+ // get the size of the desired output for scaling.
+ // here we want to print all: ListView, TimeLine, and Legend
+ // for this purpose, we call drawContents() with a 0 pointer as painter
+ QSize size = drawContents( 0, printListView, printTimeLine, printLegend );
+
+ // at the top, we want to print current time/date
+ QString date = "Printing Time: " + QDateTime::currentDateTime().toString();
+ int hei = p.boundingRect(0,0, 5, 5, Qt::AlignLeft, date ).height();
+ p.drawText( 0, 0, date );
+
+ // compute the scale
+ dx = (float) m.width() / (float)size.width();
+ dy = (float)(m.height() - ( 2 * hei )) / (float)size.height();
+ float scale;
+ // scale to fit the width or height of the paper
+ if ( dx < dy )
+ scale = dx;
+ else
+ scale = dy;
+ // set the scale
+ p.scale( scale, scale );
+ // now printing with y offset: 2 hei
+ p.translate( 0, 2*hei );
+ drawContents( &p, printListView, printTimeLine, printLegend );
+ // the drawContents() has the side effect, that the painter translation is
+ // after drawContents() set to the bottom of the painted stuff
+ // for instance a
+ // p.drawText(0, 0, "printend");
+ // would be painted directly below the paintout of drawContents()
+ p.end();
+ if ( deletePrinter )
+ delete printer;
+}
+
+
+/*!
+ Paints a Gantt view on a QPainter.
+ You can specify, whether the list view, the time line, or the legend
+ is painted.
+ All combinations of these three widgets are allowed.
+ Returns the size of the painted area.
+ Paints the list view in the top-left corner, the time line to the
+ right of the list view, and the legend below the list view.
+ If called with \a p = 0, nothing is painted and only
+ the size of the painted area is computed.
+ This is useful for determining only the painted area and setting
+ the scale of the painter, before calling this method with a painter.
+ In order to get the output fitted to your paper and your printer,
+ call first
+ QSize size = drawContents( 0, printListView, printTimeLine, printLegend );
+ //then compute the scale
+ dx = paper.width() / size.width();
+ dy = paper.height() / size.height();
+ //then make float scale to fit the width or height of the paper
+ if ( dx < dy )
+ scale = dx;
+ else
+ scale = dy;
+ // then set the scale
+ p.scale( scale, scale );
+ // and now call drawContents with painter p
+ drawContents( &p, printListView, printTimeLine, printLegend );
+
+ For a detailed example, please see the commented source code in
+ KDGanttView::print(...)
+
+ \param p a pointer to the painter to paint on. If p is
+ 0, nothing is painted and only the size of the painted area is computed
+ \param drawListView if true, the list view is painted
+ \param drawTimeLine if true, the time line is painted
+ \param drawLegend if true, the legend is painted
+ \return the size of the painted area
+ \sa print()
+*/
+QSize KDGanttView::drawContents( QPainter* p,
+ bool drawListView , bool drawTimeLine, bool drawLegend )
+{
+ QSize size;
+ int lvX, lvY, thX, thY, tlX, tlY, lwX, lwY, allX, allY;
+ lvX = myListView->contentsWidth();
+ lvY = myCanvasView->canvas()->height() + 20;
+ thX = myTimeHeader->width();
+ thY = myTimeHeader->height();
+ tlX = myCanvasView->canvas()->width();
+ tlY = lvY;
+ lwX = myLegend->legendSize().width();
+ lwY = myLegend->legendSize().height();
+ allX = 0;
+ allY = 0;
+ if ( drawListView ) {
+ allX += lvX;
+ allY += tlY;
+ }
+ if ( drawTimeLine ) {
+ allX += thX;
+ allY += thY;
+ }
+ if ( drawLegend ) {
+ allY += lwY;
+ if ( allX < lwX )
+ allX = lwX ;
+ }
+ size = QSize( allX, allY );
+ int temp = 0;
+ if ( p ) {
+ if ( drawListView ) {
+ if ( drawTimeLine )
+ temp = thY;
+ p->translate( 0, temp );
+ //HACK: Only draw list headers if we draw timeline, else
+ // there is no room for it. This will most probably be changed
+ // with qt4 anyway, so I think we can live with it atm.
+ myListView->drawToPainter( p, drawTimeLine );
+ p->translate( lvX, -temp);
+ }
+ if ( drawTimeLine ) {
+ p->translate( myCanvasView->frameWidth(), 0);
+ myTimeHeader->repaintMe( 0, myTimeHeader->width(), p );
+ p->translate( -myCanvasView->frameWidth(), thY);
+ myCanvasView->drawToPainter( p );
+ if ( drawListView )
+ p->translate( -lvX, tlY);
+ else
+ p->translate( 0, tlY);
+ } else {
+ if ( drawListView )
+ p->translate( -lvX, 0 );
+ }
+ if ( drawLegend ) {
+ myLegend->drawToPainter( p );
+ p->translate( 0, lwY );
+ }
+ }
+ return size;
+}
+
+/*!
+ Zooms into the Gantt chart. Values less than 1 mean zooming in,
+ values greater than 1 mean zooming out. A zooming factor of exactly
+ 1.0 means original size.
+
+ \param factor the zoom factor
+ \param absolute if true, factor is interpreted absolutely, if false,
+ factor is interpreted relatively to the current zoom factor
+ \sa zoomToFit()
+ \sa zoomToSelection()
+ \sa zoomFactor()
+*/
+
+void KDGanttView::setZoomFactor( double factor, bool absolute )
+{
+ myTimeHeader->zoom(factor,absolute);
+}
+
+
+/*!
+ Returns the current zoom factor.
+
+ \return the current zoom factor
+ \sa zoomToFit(), zoomToSelection(), setZoomFactor()
+*/
+
+double KDGanttView::zoomFactor() const
+{
+ return myTimeHeader->zoomFactor();
+}
+
+
+/*!
+ Zooms such that the Gantt chart is less than the available space of the widget.
+
+ \sa setZoomFactor()
+ \sa zoomFactor()
+ \sa zoomToSelection()
+*/
+
+void KDGanttView::zoomToFit()
+{
+ myTimeHeader->zoomToFit();
+}
+
+
+/*!
+ Zooms so that at least the selected time period is visible after the zoom.
+
+ \param start the new font of the widget
+ \param end the new font of the widget
+
+ \sa setZoomFactor()
+ \sa zoomFactor()
+ \sa zoomToFit()
+*/
+
+void KDGanttView::zoomToSelection( const QDateTime& start, const QDateTime& end )
+{
+
+ myTimeHeader->zoomToSelection( start, end);
+
+}
+
+
+/*!
+ Makes sure that the specified Gantt item is visible without
+ scrolling.
+
+ \sa center(), centerTimelineAfterShow()
+*/
+void KDGanttView::ensureVisible( KDGanttViewItem* item )
+{
+ myListView->ensureItemVisible (item);
+}
+
+
+/*!
+ Makes sure that the specified QDateTime is in the center of the
+ visible Gantt chart (if possible).
+ If you want to center the timeline when the KDGanttView is hidden,
+ calling centerTimelineAfterShow() is the better alternative.
+
+ \sa center(), centerTimelineAfterShow()
+*/
+void KDGanttView::centerTimeline( const QDateTime& center )
+{
+ myTimeHeader->centerDateTime( center );
+}
+
+
+/*!
+ Makes sure that the specified QDateTime is in the center of the
+ visible Gantt chart (if possible). If the KDGanttView is currently
+ hidden, this method resets the center once again after the next
+ show() call. Use this method if you want to center the timeline when
+ the KDGanttView is hidden. After calling KDGanttView::show(), there
+ may be computations of the sizes of the widgets and subwidgets and
+ of the automatically computed start datetime. This method ensures
+ that the center of the timeline is to be properly reset after
+ show().
+
+ \sa center(), centerTimeline()
+*/
+void KDGanttView::centerTimelineAfterShow( const QDateTime& center )
+{
+ myTimeHeader->centerDateTime( center );
+ if ( ! isVisible() ) {
+ dtCenterTimeLineAfterShow = center;
+ fCenterTimeLineAfterShow = true;
+ }
+}
+
+/*!
+ Sets the timeline to the horizon start.
+*/
+
+void KDGanttView::setTimelineToStart()
+{
+ myCanvasView->horizontalScrollBar()->setValue( 0 );
+}
+
+
+/*!
+ Sets the timeline to the horizon end.
+*/
+void KDGanttView::setTimelineToEnd()
+{
+ myCanvasView->horizontalScrollBar()->setValue(myCanvasView->horizontalScrollBar()->maxValue());
+}
+
+
+/*!
+ Add \a num minor ticks of the current scale of the timeline
+ to the start of the timeline.
+ The timeline is not set automatically at the start.
+ Call \a setTimelineToStart() to ensure that the timeline is at the start
+ after calling this method.
+
+ \param num the number of minor ticks which should be added
+ \sa addTicksRight(),setTimelineToStart(), setTimelineToEnd()
+*/
+void KDGanttView::addTicksLeft( int num )
+{
+ myTimeHeader->addTickLeft( num );
+}
+
+
+/*!
+ Add \a num minor ticks of the current scale of the timeline
+ to the end of the timeline.
+ The timeline is not set automatically at the end.
+ Call \a setTimelineToEnd() to ensure that the timeline is at the end
+ after calling this method.
+ \param num the number of minor ticks which should be added
+ \sa addTicksLeft(),setTimelineToStart(), setTimelineToEnd()
+*/
+void KDGanttView::addTicksRight( int num )
+{
+ myTimeHeader->addTickRight( num );
+}
+
+
+/*!
+ Makes sure that the specified Gantt item is in the center of the
+ visible Gantt chart (if possible).
+*/
+void KDGanttView::center( KDGanttViewItem* item )
+{
+ ensureVisible(item);
+ int x = myListView->contentsWidth()/2;
+ int y = myListView->itemPos (item );
+ myListView->center(x,y);
+}
+
+
+/*!
+ Specifies whether task links should be shown.
+
+ \param show true for showing task links, false for not showing them
+ \sa showTaskLinks(), KDGanttViewTaskLink
+*/
+void KDGanttView::setShowTaskLinks( bool show )
+{
+ myTimeTable->setShowTaskLinks(show);
+
+}
+
+
+/*!
+ Returns whether task links should be shown.
+
+ \return true if task links are shown, false otherwise
+ \sa setShowTaskLinks(), KDGanttViewTaskLink
+*/
+bool KDGanttView::showTaskLinks() const
+{
+ return myTimeTable->showTaskLinks();
+}
+
+
+/*!
+ Sets the font in the left list view widget and
+ in the right time header widget.
+ The settings of the fonts in the time table widget are not effected.
+
+ \param font the new font of the widget
+*/
+void KDGanttView::setFont(const QFont& font)
+{
+ myListView->setFont(font);
+ myListView->repaint();
+ myTimeHeader->setFont(font);
+ myLegend->setFont( font );
+ QWidget::setFont( font );
+ setScale(scale());
+}
+
+
+/*!
+ Specifies whether the configure popup menu should be shown on
+ right click on the time header widget.
+ This menu lets the user quickly change
+ the zoom factor,
+ the scale mode (minute, hour, day, week, month, auto) ,
+ the time format,
+ the year format,
+ the grid format,
+ and printing.
+ The default setting is not to show the popup menu.
+ This functionality must be enabled explicitly by the application
+ developer.
+ You can disable each submenu of the popmenu.
+
+ \param show true in order to show the popup menu, false in order not
+ to. The default is true.
+ \param showZoom show the zoom submenu, default: true
+ \param showScale show the scale submenu, default: true
+ \param showTime show the time format submenu, default: true
+ \param showYear show the year format submenu, default: true
+ \param showGrid show the grid submenu, default: true
+ \param showPrint show the print submenu, default: false
+*/
+void KDGanttView::setShowHeaderPopupMenu( bool show,
+ bool showZoom,
+ bool showScale,
+ bool showTime,
+ bool showYear,
+ bool showGrid,
+ bool showPrint)
+{
+ myTimeHeader->setShowPopupMenu( show,showZoom,showScale,showTime,
+ showYear,showGrid,showPrint );
+}
+
+
+/*!
+ Returns whether the configure popup menu should be shown on right
+ click on the time header widget.
+
+ \return true if the popup menu should be shown
+*/
+bool KDGanttView::showHeaderPopupMenu() const
+{
+ return myTimeHeader->showPopupMenu();
+}
+//****************************************************
+
+
+/*!
+ Specifies whether the add item popup menu should be shown on
+ right click on the time table widget.
+ This menu lets the user quickly add new items to the Gantt view
+ (as root, as child or after an item).
+ It also offers cutting and pasting of items.
+
+ The default setting is that the popup menu is not shown.
+ It must be enabled by the program.
+
+ \param show true in order to show popup menu, false in order not to
+
+*/
+void KDGanttView::setShowTimeTablePopupMenu( bool show )
+{
+ myCanvasView->setShowPopupMenu( show );
+}
+
+
+/*!
+ Returns whether the add item popup menu should be shown on right
+ click on the time table widget.
+
+ \return true if the popup menu should be shown
+*/
+bool KDGanttView::showTimeTablePopupMenu() const
+{
+ return myCanvasView->showPopupMenu();
+}
+
+
+/*!
+ Sets the shapes for a certain type of Gantt item. Not all items use
+ all three shapes (e.g., only summary items use the middle shape).
+
+ This setting overrides any shape settings made on individual items.
+ These settings will be taken as initial values of any newly created
+ item of this certain type.
+ See also the documentation of the KDGanttViewItem class.
+
+ \param type the type of Gantt items for which to set the shapes
+ \param start the shape to use for the beginning of the item
+ \param middle the shape to use for the middle of the item
+ \param end the shape to use for the end of the item
+ \param overwriteExisting if true, overwrites existing shape settings
+ in the individual items
+ \sa shapes()
+*/
+void KDGanttView::setShapes( KDGanttViewItem::Type type,
+ KDGanttViewItem::Shape start,
+ KDGanttViewItem::Shape middle,
+ KDGanttViewItem::Shape end,
+ bool overwriteExisting )
+{
+ if ( overwriteExisting ) {
+ QListViewItemIterator it(myListView);
+ for ( ; it.current(); ++it ) {
+ if ( ((KDGanttViewItem*)it.current())->type() == type)
+ ((KDGanttViewItem*)it.current())->setShapes(start,middle, end );
+ }
+ }
+ int index = getIndex( type );
+ myDefaultShape [index*3] = start;
+ myDefaultShape [index*3+1] = middle;
+ myDefaultShape [index*3+2] = end;
+ undefinedShape[index] = false;
+}
+
+
+/*!
+ Queries the shapes for a particular type of Gantt item.
+
+ \param type the type of Gantt items for which to query the shapes
+ \param start the start shape is returned in this parameter
+ \param middle the middle shape is returned in this parameter
+ \param end the end shape is returned in this parameter
+ \return true if there was a general shape set for the specified
+ type. If the return value is false, the values of the three shape
+ parameters are undefined.
+ \sa setShapes()
+*/
+bool KDGanttView::shapes( KDGanttViewItem::Type type,
+ KDGanttViewItem::Shape& start,
+ KDGanttViewItem::Shape& middle,
+ KDGanttViewItem::Shape& end ) const
+{
+ int index = getIndex( type );
+ start = myDefaultShape [index*3];
+ middle = myDefaultShape [index*3+1];
+ end = myDefaultShape [index*3+2];
+ return !undefinedShape[index];
+}
+
+
+/*!
+ Sets the colors for a certain type of Gantt item. Not all items use
+ all three colors (e.g., only summary items use the middle color).
+
+ This setting overrides any color settings made on individual items.
+ These settings will be taken as initial values of any newly created
+ item of this certain type.
+ See also the description of the KDGanttViewItem class.
+
+ \param type the type of Gantt items for which to set the colors
+ \param start the color to use for the beginning of the item
+ \param middle the color to use for the middle of the item
+ \param end the color to use for the end of the item
+ \param overwriteExisting if true, overwrites existing color settings
+ on invididual items
+ \sa colors(), setDefaultColors(), defaultColors()
+*/
+void KDGanttView::setColors( KDGanttViewItem::Type type,
+ const QColor& start, const QColor& middle,
+ const QColor& end,
+ bool overwriteExisting )
+{
+ if ( overwriteExisting ) {
+ QListViewItemIterator it(myListView);
+ for ( ; it.current(); ++it ) {
+ if ( ((KDGanttViewItem*)it.current())->type() == type)
+ ((KDGanttViewItem*)it.current())->setColors(start,middle, end );
+ }
+ }
+ int index = getIndex( type );
+ myColor [index*3] = start;
+ myColor [index*3+1] = middle;
+ myColor [index*3+2] = end;
+ undefinedColor[index] = false;
+}
+
+
+/*!
+ Queries the colors for a particular type of Gantt item.
+
+ \param type the type of Gantt items for which to query the colors
+ \param start the start color is returned in this parameter
+ \param middle the middle color is returned in this parameter
+ \param end the end color is returned in this parameter
+ \return true if there was a general color set for the specified
+ type. If the return value is false, the values of the three color
+ parameters are undefined.
+ \sa setColors(), setDefaultColor(), defaultColor()
+*/
+bool KDGanttView::colors( KDGanttViewItem::Type type,
+ QColor& start, QColor& middle, QColor& end ) const
+{
+ int index = getIndex( type );
+ start = myColor [index*3];
+ middle = myColor [index*3+1];
+ end = myColor [index*3+2];
+ return !undefinedColor[index];
+}
+
+
+/*!
+ Sets the highlight colors for a certain type of Gantt item. Not
+ all items use all three highlight colors (e.g., only summary items
+ use the middle highlight color).
+
+ This setting overrides any highlight color settings made on
+ individual items.
+ These settings will be taken as initial values of any newly created
+ item of this certain type.
+ See also the description of the KDGanttViewItem class.
+
+ \param type the type of Gantt items for which to set the highlight colors
+ \param start the highlight color to use for the beginning of the item
+ \param middle the highlight color to use for the middle of the item
+ \param end the highlight color to use for the end of the item
+ \param overwriteExisting if true, overwrites existing color settings
+ in the individual items
+ \sa highlightColors(), setDefaultHighlightColor(), defaultHighlightColor()
+*/
+void KDGanttView::setHighlightColors( KDGanttViewItem::Type type,
+ const QColor& start,
+ const QColor& middle,
+ const QColor& end,
+ bool overwriteExisting )
+{
+ if ( overwriteExisting ) {
+ QListViewItemIterator it(myListView);
+ for ( ; it.current(); ++it ) {
+ if ( ((KDGanttViewItem*)it.current())->type() == type)
+ ((KDGanttViewItem*)it.current())->setHighlightColors(start,middle, end );
+ }
+ }
+ int index = getIndex( type );
+ myColorHL [index*3] = start;
+ myColorHL [index*3+1] = middle;
+ myColorHL [index*3+2] = end;
+ undefinedColorHL[index] = false;
+
+}
+
+
+/*!
+ Queries the highlight colors for a particular type of Gantt item.
+
+ \param type the type of Gantt items for which to query the highlight
+ colors
+ \param start the start highlight color is returned in this parameter
+ \param middle the middle highlight color is returned in this parameter
+ \param end the end highlight color is returned in this parameter
+ \return true if there was a general highlight color set for the specified
+ type. If the return value is false, the values of the three highlight color
+ parameters are undefined.
+ \sa setHighlightColors(), setDefaultHighlightColor(),
+ defaultHighlightColor()
+*/
+bool KDGanttView::highlightColors( KDGanttViewItem::Type type,
+ QColor& start, QColor& middle,
+ QColor& end ) const
+{
+ int index = getIndex( type );
+ start = myColorHL [index*3];
+ middle = myColorHL [index*3+1];
+ end = myColorHL [index*3+2];
+ return !undefinedColorHL[index];
+}
+
+
+/*!
+ Sets the color used for texts in the Gantt chart.
+ Overrides all individual settings of the Gantt items.
+
+ \param color the text color to use
+ \sa textColor()
+*/
+void KDGanttView::setTextColor( const QColor& color )
+{
+ QListViewItemIterator it(myListView);
+ for ( ; it.current(); ++it ) {
+ ((KDGanttViewItem*)it.current())->setTextColor(color);
+ }
+ myTextColor = color;
+}
+
+
+/*!
+ Returns the color used for texts in the Gantt chart.
+
+ \return the color used for texts in the Gantt chart.
+ \sa setTextColor()
+*/
+QColor KDGanttView::textColor() const
+{
+ return myTextColor;
+}
+
+
+/*!
+ Specifies the brush in which the 'showNoInformation' line of items
+ should be drawn.
+
+ \param brush the brush of the 'showNoInformation' lines
+ \sa KDGanttViewItem::showNoInformation(),
+ KDGanttViewItem::setShowNoInformation(),
+ KDGanttView::noInformationBrush()
+
+*/
+void KDGanttView::setNoInformationBrush( const QBrush& brush )
+{
+ myTimeTable->setNoInformationBrush( brush );
+}
+
+
+/*!
+ Returns the brush of the 'showNoInformation' lines
+ \return the brush of the 'showNoInformation' lines
+ \sa KDGanttViewItem::showNoInformation(), KDGanttViewItem::setShowNoInformation(),
+ setNoInformationBrush()
+*/
+QBrush KDGanttView::noInformationBrush() const
+{
+ return myTimeTable->noInformationBrush();
+}
+
+
+/*!
+ Removes all items from the legend.
+
+ \sa addLegendItem()
+*/
+void KDGanttView::clearLegend( )
+{
+ myLegend->clearLegend();
+ myLegendItems->setAutoDelete( true );
+ delete myLegendItems;
+ myLegendItems = new QPtrList<legendItem>;
+}
+
+
+/*!
+ Adds an item to the legend.
+
+ \param shape the shape to display
+ \param shapeColor the color in which to display the shape
+ \param text the text to display
+ \sa clearLegend()
+*/
+void KDGanttView::addLegendItem( KDGanttViewItem::Shape shape,
+ const QColor& shapeColor,
+ const QString& text )
+{
+ myLegend->addLegendItem( shape,shapeColor,text );
+ legendItem* item = new legendItem;
+ item->shape = shape;
+ item->color = shapeColor;
+ item->text = text;
+ myLegendItems->append( item );
+}
+
+
+/*!
+ 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 KDGanttView::setHorizonStart( const QDateTime& start )
+{
+ myTimeHeader->setHorizonStart(start);
+}
+
+
+/*!
+ Returns the start of the horizon of the Gantt chart.
+
+ \return the start of the horizon of the Gantt chart
+ \sa setHorizonStart()
+*/
+QDateTime KDGanttView::horizonStart() const
+{
+ return myTimeHeader->horizonStart();
+}
+
+
+/*!
+ 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 KDGanttView::setHorizonEnd( const QDateTime& end )
+{
+ myTimeHeader->setHorizonEnd(end);
+}
+
+
+/*!
+ Returns the end of the horizon of the Gantt chart.
+
+ \return the end of the horizon of the Gantt chart
+ \sa setHorizonEnd()
+
+*/
+QDateTime KDGanttView::horizonEnd() const
+{
+ return myTimeHeader->horizonEnd();
+}
+
+
+/*!
+ Configures the unit of the lower scale of the header. The higher
+ unit is computed automatically.
+
+ \param unit the unit of the lower scale of the header.
+ \sa scale()
+*/
+void KDGanttView::setScale( Scale unit )
+{
+ myTimeHeader->setScale( unit );
+}
+
+
+/*!
+ Returns the unit of the lower scale of the header.
+
+ \return the unit of the lower scale of the header.
+ \sa setScale()
+*/
+KDGanttView::Scale KDGanttView::scale() const
+{
+ return myTimeHeader->scale();
+}
+
+
+/*!
+ Sets the maximum allowed time scale of the lower scale of the header.
+
+ \param unit the unit of the lower scale of the header.
+ \sa scale()
+*/
+void KDGanttView::setMaximumScale( Scale unit )
+{
+ myTimeHeader->setMaximumScale( unit );
+}
+
+
+/*!
+ Returns the maximum allowed time scale of the lower scale of the header.
+
+ \return the unit of the lower scale of the header.
+ \sa setScale()
+*/
+KDGanttView::Scale KDGanttView::maximumScale() const
+{
+ return myTimeHeader->maximumScale();
+}
+
+
+/*!
+ Sets the minimum allowed time scale of the lower scale of the header.
+
+ \param unit the unit of the lower scale of the header.
+ \sa scale()
+*/
+void KDGanttView::setMinimumScale( Scale unit )
+{
+ myTimeHeader->setMinimumScale( unit );
+}
+
+
+/*!
+ Returns the minimum allowed time scale of the lower scale of the header.
+
+ \return the unit of the lower scale of the header.
+ \sa setScale()
+*/
+KDGanttView::Scale KDGanttView::minimumScale() const
+{
+ return myTimeHeader->minimumScale();
+}
+
+
+/*!
+ Sets the absolute number of minor ticks, if scaling is set to Auto.
+ If the scale mode is set to Auto, then the actual scale and
+ the minorScaleCount is automatically computed, such that there are
+ count minor ticks
+
+ \param count the number of minor ticks
+ \sa autoScaleMinorTickCount(),setScale(),scale()
+*/
+void KDGanttView::setAutoScaleMinorTickCount( int count )
+{
+ myTimeHeader->setAutoScaleMinorTickCount( count );
+}
+
+
+/*!
+ Returns the absolut number of minor ticks, if scaling is set to Auto
+
+ \return the absolut number of minor ticks
+ \sa setAutoScaleMinorTickCount(),setScale(),scale()
+*/
+int KDGanttView::autoScaleMinorTickCount() const
+{
+ return myTimeHeader->autoScaleMinorTickCount();
+}
+
+
+/*!
+ Sets the minimum width that 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 KDGanttView::setMinimumColumnWidth( int width )
+{
+ myTimeHeader->setMinimumColumnWidth( width );
+}
+
+
+/*!
+ Returns the minimum width a column needs to have.
+
+ \return the column minimum width
+ \sa setMinimumColumnWidth()
+*/
+int KDGanttView::minimumColumnWidth() const
+{
+ return myTimeHeader->minimumColumnWidth();
+}
+
+
+/*!
+ 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 KDGanttView::setYearFormat( YearFormat format )
+{
+ myTimeHeader->setYearFormat(format );
+}
+
+
+/*!
+ Returns the format in which to display years.
+
+ \return the year format
+ \sa setYearFormat(), setHourFormat(), hourFormat()
+*/
+KDGanttView::YearFormat KDGanttView::yearFormat() const
+{
+ return myTimeHeader->yearFormat();
+}
+
+
+/*!
+ 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 KDGanttView::setHourFormat( HourFormat format )
+{
+ myTimeHeader->setHourFormat( format );
+}
+
+
+/*!
+ Returns the format in which to display hours.
+
+ \return the hour format
+ \sa setHourFormat(), setYearFormat(), yearFormat()
+
+*/
+KDGanttView::HourFormat KDGanttView::hourFormat() const
+{
+ return myTimeHeader->hourFormat();
+}
+
+
+/*!
+ Hides/shows the grid for the major ticks of the time header in the gantt view.
+
+ \param show true in order to show ticks, false in order to hide them.
+ If show is true, setShowMinorTicks( false ) is performed automatically
+ to hide the grid of the minor ticks.
+ In order to show now grid, call setShowMinorTicks( false ) and
+ setShowMajorTicks( false ).
+ \sa showMajorTicks(), setShowMinorTicks(), showMinorTicks()
+*/
+void KDGanttView::setShowMajorTicks( bool show )
+{
+ myTimeHeader->setShowMajorTicks(show );
+}
+
+
+/*!
+ Returns whether the grid is shown on the major scale.
+
+ \return true if ticks are shown on the major scale
+ \sa setShowMajorTicks(), setShowMinorTicks(), showMinorTicks()
+*/
+bool KDGanttView::showMajorTicks() const
+{
+ return myTimeHeader->showMajorTicks();
+}
+
+
+/*!
+ Hides/shows the grid for the minor ticks of the time header in the gantt view.
+
+ \param show true in order to show ticks, false in order to hide them.
+ If show is true, setShowMajorTicks( false ) is performed automatically
+ to hide the grid of the major ticks.
+ In order to show now grid, call setShowMinorTicks( false ) and
+ setShowMajorTicks( false ).
+
+ \sa showMinorTicks(), setShowMajorTicks(), showMajorTicks()
+
+*/
+void KDGanttView::setShowMinorTicks( bool show)
+{
+ myTimeHeader->setShowMinorTicks( show );
+}
+
+
+/*!
+ Returns whether ticks are shown on the minor scale.
+
+ \return true if ticks are shown on the minor scale
+ \sa setShowMinorTicks(), setShowMajorTicks(), showMajorTicks()
+*/
+bool KDGanttView::showMinorTicks() const
+{
+ return myTimeHeader->showMinorTicks();
+}
+
+
+/*!
+ Sets the background color for the column closest to \a column.
+ It can be specified whether the color should be shown in all scales or
+ only in specific scales.
+ If you want to define the color only for the daily view, specify
+ mini and maxi as Day.
+ If there is no value specified for mini and maxi, the color for the column
+ is shown on all scales. Note that it is possible that there are two
+ values for a column in a scale. In this case, the shown color is unspecified.
+
+ \param column the column to set the background color for
+ \param color the background color
+ \param mini show the colour only in scales greater than this
+ \param maxi show the colour only in scales lesser than this
+ \sa columnBackgroundColor(), setWeekendBackgroundColor(),
+ weekendBackgroundColor()
+*/
+void KDGanttView::setColumnBackgroundColor( const QDateTime& column,
+ const QColor& color ,
+ Scale mini, Scale maxi )
+{
+ myTimeHeader->setColumnBackgroundColor( column, color,mini,maxi );
+}
+
+#if 0
+/*!
+ Sets the background color for a time interval given by \a start and
+ \a end. \a start may be later than \a end. If there is already a
+ background interval with the same \a start and \a end values
+ defined, the values (i.e. const QColor& color , Scale mini, Scale
+ maxi) of this background interval are changed. Change the times of
+ an already defined interval with \a changeBackgroundInterval().
+ Delete an already defined interval with \a
+ deleteBackgroundInterval().
+
+ It can be defined, whether the color should be shown in all scales or
+ only in specific scales.
+ If you want to define the color only for the daily view, scecify
+ mini and maxi as Day.
+ If there is no value for mini/maxi specified, the color for the columns
+ is shown in all scales.
+
+ \param start start datetime of the time interval
+ \param end end datetime of the time interval
+ \param color the background color
+ \param mini show the color only in scales greater than this
+ \param maxi show the color only in scales lesser than this
+ \sa changeBackgroundInterval(), deleteBackgroundInterval(),
+ columnBackgroundColor(), setWeekendBackgroundColor(),
+ weekendBackgroundColor()
+*/
+void KDGanttView::setIntervalBackgroundColor( const QDateTime& start,
+ const QDateTime& end,
+ const QColor& color ,
+ Scale mini, Scale maxi )
+{
+ myTimeHeader->setIntervalBackgroundColor( start, end, color,mini,maxi );
+}
+
+
+/*!
+ Changes the times of an already defined background color interval.
+ The new values \a startnew and \a endnew should not be datetime
+ values of an already defined background color interval.
+ If that is the case, nothing is changed and false is returned.
+
+ \param oldstart the start date and time of the interval to change
+ \param oldend the end date and time of the interval to change
+ \param newstart the new start date and time
+ \param newend the new end date and time
+ \return true, if there is a backgroundcolor interval with values
+ \a start and \a end found and the new values \a startnew and \a endnew
+ are not datetime values of an already defined background color interval.
+ Returns false otherwise.
+ \sa changeBackgroundInterval(), deleteBackgroundInterval(),
+ columnBackgroundColor(), setWeekendBackgroundColor(),
+ weekendBackgroundColor()
+*/
+bool KDGanttView::changeBackgroundInterval( const QDateTime& oldstart,
+ const QDateTime& oldend,
+ const QDateTime& newstart,
+ const QDateTime& newend )
+{
+ return myTimeHeader->changeBackgroundInterval( oldstart, oldend,
+ newstart, newend );
+}
+
+/*!
+ Deletes an already defined background color interval.
+
+ \param start start datetime of time interval
+ \param end end datetime of time interval
+ \return true, if there is a backgroundcolor interval with values
+ \a start and \a end found (and hence deleted).
+ \sa changeBackgroundInterval(), columnBackgroundColor()
+*/
+bool KDGanttView::deleteBackgroundInterval( const QDateTime& start,
+ const QDateTime& end)
+{
+ return myTimeHeader->deleteBackgroundInterval( start, end );
+}
+#endif
+
+/*!
+ Adds a filled rectangle for a time interval given by \a start and
+ \a end, across all tasks. \a start may be later than \a end.
+ \sa KDIntervalColorRectangle
+*/
+void KDGanttView::addIntervalBackgroundColor( KDIntervalColorRectangle* newItem )
+{
+ myTimeHeader->addIntervalBackgroundColor( newItem );
+}
+
+/*!
+ Removes all background color settings set with setColumnBackgroundColor()
+ and setIntervalBackgroundColor().
+ Does not affect the settings of setWeekendBackgroundColor().
+
+ \sa setColumnBackgroundColor(), setWeekendBackgroundColor(),
+ weekendBackgroundColor(), setIntervalBackgroundColor()
+*/
+void KDGanttView::clearBackgroundColor()
+{
+ myTimeHeader->clearBackgroundColor();
+}
+
+
+/*!
+ Returns the background color for the column closest to \a column.
+
+ \param column the column to query the background color for
+ \return the background color of the specified color
+ \sa setColumnBackgroundColor(), setWeekendBackgroundColor(),
+ weekendBackgroundColor()
+*/
+QColor KDGanttView::columnBackgroundColor( const QDateTime& column ) const
+{
+ return myTimeHeader->columnBackgroundColor( column ) ;
+}
+
+
+/*!
+ 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 KDGanttView::setWeekendBackgroundColor( const QColor& color )
+{
+ myTimeHeader->setWeekendBackgroundColor( color );
+}
+
+
+/*!
+ Returns the background color for weekend days.
+
+ \return the background color for weekend days
+ \sa setWeekendBackgroundColor(), setWeekendDays(), weekendDays()
+*/
+QColor KDGanttView::weekendBackgroundColor() const
+{
+ return myTimeHeader->weekendBackgroundColor();
+}
+
+
+/*!
+ Specifies the background color for weekday days. If no individual
+ days are visible on the Gantt chart, this method has no visible
+ effect. The days are specified as an intervals 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 KDGanttView::setWeekdayBackgroundColor( const QColor& color, int weekday )
+{
+ myTimeHeader->setWeekdayBackgroundColor( color, weekday );
+}
+
+
+/*!
+ Returns the background color for weekday days.
+
+ \param weekday the day of the week (Monday = 1, Sunday = 7)
+ \return the background color for weekend days
+ \sa setWeekendBackgroundColor(), setWeekendDays(), weekendDays()
+*/
+QColor KDGanttView::weekdayBackgroundColor(int weekday) const
+{
+ return myTimeHeader->weekdayBackgroundColor( 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 KDGanttView::setWeekendDays( int start, int end )
+{
+ myTimeHeader->setWeekendDays( start, end );
+}
+
+
+/*!
+ 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 KDGanttView::weekendDays( int& start, int& end ) const
+{
+ myTimeHeader->weekendDays( start, end );
+}
+
+
+/*!
+ \fn void KDGanttView::itemLeftClicked( KDGanttViewItem* )
+
+ This signal is emitted when the user clicks on an item with the left
+ mouse button.
+*/
+
+
+/*!
+ \fn void KDGanttView::itemMidClicked( KDGanttViewItem* )
+
+ This signal is emitted when the user clicks on an item with the middle
+ mouse button.
+*/
+
+
+/*!
+ \fn void KDGanttView::itemRightClicked( KDGanttViewItem* )
+
+ This signal is emitted when the user clicks on an item with the right
+ mouse button.
+*/
+
+
+/*!
+ \fn void KDGanttView::itemDoubleClicked( KDGanttViewItem* )
+
+ This signal is emitted when the user double-clicks an item.
+*/
+
+
+/*!
+ \fn void KDGanttView::itemConfigured( KDGanttViewItem* )
+
+ This signal is emitted when the user has configured an item
+ visually.
+*/
+
+
+
+/*!
+ \fn void KDGanttView::taskLinkLeftClicked( KDGanttViewTaskLink* )
+
+ This signal is emitted when the user clicks on a task link with the
+ left mouse button.
+*/
+
+
+/*!
+ \fn void KDGanttView::taskLinkMidClicked( KDGanttViewTaskLink* )
+
+ This signal is emitted when the user clicks on a task link with the
+ middle mouse button.
+*/
+
+
+/*!
+ \fn void KDGanttView::taskLinkRightClicked( KDGanttViewTaskLink* )
+
+ This signal is emitted when the user clicks on a task link with the
+ right mouse button.
+*/
+
+
+/*!
+ \fn void KDGanttView::taskLinkDoubleClicked( KDGanttViewTaskLink* )
+
+ This signal is emitted when the user double-clicks a task link.
+*/
+
+
+/*!
+ \enum KDGanttView::YearFormat
+
+ This enum is used to specify the year format used in the header.
+*/
+
+
+/*!
+ \enum KDGanttView::HourFormat
+
+ This enum is used to specify the hour format used in the header.
+*/
+
+
+/*!
+ \enum KDGanttView::Scale
+
+ This enum is used to specify the units of the scales in the header.
+*/
+
+
+
+
+/*!
+ Sets the number of ticks in the major scale.
+
+ \param count the number of ticks in the major scale
+ \sa majorScaleCount(), setMinorScaleCount(), minorScaleCount()
+*/
+void KDGanttView::setMajorScaleCount( int count )
+{
+ myTimeHeader->setMajorScaleCount(count );
+}
+
+
+/*!
+ 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 KDGanttView::majorScaleCount() const
+{
+ return myTimeHeader->majorScaleCount();
+}
+
+
+/*!
+ Sets the number of ticks in the minor scale.
+
+ \param count the number of ticks in the minor scale
+ \sa minorScaleCount, setMajorScaleCount, majorScaleCount()
+*/
+void KDGanttView::setMinorScaleCount( int count )
+{
+ myTimeHeader->setMinorScaleCount(count );
+}
+
+
+/*!
+ 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 KDGanttView::minorScaleCount() const
+{
+ return myTimeHeader->minorScaleCount();
+
+}
+
+
+/*!
+ Sets the default color for a particular type of Gantt item that is
+ used for the item if no specific start, middle, or end colors are
+ set.
+
+ \param type the type of Gantt items for which to query the highlight
+ colors
+ \param color the default color to use
+ \param overwriteExisting if true, existing settings for individual
+ items are overwritten
+ \sa defaultColor(), setColors(), colors()
+*/
+void KDGanttView::setDefaultColor( KDGanttViewItem::Type type,
+ const QColor& color,
+ bool overwriteExisting )
+{
+ if ( overwriteExisting ) {
+ QListViewItemIterator it(myListView);
+ for ( ; it.current(); ++it ) {
+ if ( ((KDGanttViewItem*)it.current())->type() == type)
+ ((KDGanttViewItem*)it.current())->setDefaultColor(color );
+ }
+ }
+ int index = getIndex( type );
+ myDefaultColor [index] = color;
+}
+
+
+
+/*!
+ Returns the default color for a particular type of Gantt item that
+ is used for the item if no specific start, middle, or end colors are
+ set.
+
+ \param type the type of Gantt items for which to query the highlight
+ colors
+ \return color the default color used
+ \sa setDefaultColor(), setColors(), colors()
+*/
+QColor KDGanttView::defaultColor( KDGanttViewItem::Type type ) const
+{
+ int index = getIndex( type );
+ return myDefaultColor [index];
+}
+
+
+/*!
+ Sets the default highlighting color for a particular type of
+ Gantt item that is used for the item if no specific start, middle,
+ or end colors are set.
+
+ \param type the type of Gantt items for which to query the highlight
+ colors
+ \param color the default highlighting color to use
+ \param overwriteExisting if true, existing color settings in
+ individual items are overwritten
+ \sa defaultHighlightColor(), setHighlightColors(), highlightColors()
+*/
+void KDGanttView::setDefaultHighlightColor( KDGanttViewItem::Type type,
+ const QColor& color,
+ bool overwriteExisting )
+{
+ if ( overwriteExisting ) {
+ QListViewItemIterator it(myListView);
+ for ( ; it.current(); ++it ) {
+ if ( ((KDGanttViewItem*)it.current())->type() == type)
+ ((KDGanttViewItem*)it.current())->setDefaultHighlightColor(color );
+ }
+ }
+ int index = getIndex( type );
+ myDefaultColorHL [index] = color;
+}
+
+
+
+/*!
+ Returns the default highlighting color for a particular type of
+ Gantt item that is used for the item if no specific start, middle,
+ or end colors are set.
+
+ \param type the type of Gantt items for which to query the highlight
+ colors
+ \return color the default highlighting color used
+ \sa setDefaultHighlightColor(), setHighlightColors(), highlightColors()
+*/
+QColor KDGanttView::defaultHighlightColor( KDGanttViewItem::Type type ) const
+{
+ int index = getIndex( type );
+ return myDefaultColorHL [index];
+}
+
+
+/*!
+ Returns the first item in the Gantt view.
+
+ \return the first item in the Gantt view, 0 if there are no items
+*/
+KDGanttViewItem* KDGanttView::firstChild() const
+{
+ return (KDGanttViewItem*)myListView->firstChild();
+
+}
+/*!
+ This method turns calendar mode on and off. In calendar mode, only
+ those items can be opened which have subitems which have
+ subitems. I.e., if an item contains multiple calendars, it can be
+ opened, but not a calendar item itself. If you want to use this
+ GanttView as a calendar view, you have to call
+ setDisplaySubitemsAsGroup( true ); to use the root items as calendar
+ items. To create new calendar entries for these root items, create
+ a new KDGanttViewTaskItem with this root item as a parent. If you
+ want an item with subitems to behave like a calendar (which is
+ possibly empty at startup), please call setIsCalendar( true ); for
+ this item.
+
+ \param mode if true, the calendar view mode is turned on
+ if false, the calendar view mode is turned off
+ \sa setDisplaySubitemsAsGroup(), displaySubitemsAsGroup(), calendarMode()
+*/
+void KDGanttView::setCalendarMode( bool mode )
+{
+ myListView->setCalendarMode( mode );
+}
+
+
+/*!
+ Returns true, if the Gantt view is in calendar mode. See
+ setCalendarMode() for the meaning of calendar mode.
+
+ \return returns true, if the Gantt view is in calendermode
+ \sa setCalendarMode()
+*/
+bool KDGanttView::calendarMode() const
+{
+ return myListView->calendarMode();
+}
+
+
+
+/*!
+ This method specifies whether hidden subitems should be displayed.
+ It iterates over all KDGanttViewItems in this Gantt view
+ and sets their displaySubitemsAsGroup() property.
+ All newly created items will have this setting by default.
+ \param show if true, the hidden subitems are displayed in all items of
+ this Gantt view.
+ \sa KDGanttViewItem::setDisplaySubitemsAsGroup(), KDGanttViewItem::displaySubitemsAsGroup()
+*/
+void KDGanttView::setDisplaySubitemsAsGroup( bool show )
+{
+ QListViewItemIterator it( myListView );
+ for ( ; it.current(); ++it ) {
+ KDGanttViewItem* currentItem = ( KDGanttViewItem* )it.current();
+ currentItem->setDisplaySubitemsAsGroup( show );
+ }
+ _displaySubitemsAsGroup = show;
+}
+
+
+/*!
+ Returns, whether new items are created with the
+ displayHiddenSubitems property.
+ \return true, if hidden subitems should be displayed on newly created items.
+ \sa setDisplaySubitemsAsGroup(),
+ KDGanttViewItem::setDisplaySubitemsAsGroup(),
+ KDGanttViewItem::displaySubitemsAsGroup()
+*/
+bool KDGanttView::displaySubitemsAsGroup() const
+{
+ return _displaySubitemsAsGroup;
+}
+
+
+/*!
+ This method specifies whether tasks where the start time and the end
+ time are the same are displayed
+ as a line over the full height of the Gantt view.
+ \param show if true, tasks with starttime == endtime are displayed
+ as a line
+*/
+void KDGanttView::setDisplayEmptyTasksAsLine( bool show )
+{
+ _displayEmptyTasksAsLine = show;
+}
+
+
+/*!
+ Returns, whether tasks where the start time and the end time are the
+ same are displayed
+ as a line over the full height of the Gantt view.
+ \return true, if empty tasks are displayed as line.
+*/
+bool KDGanttView::displayEmptyTasksAsLine() const
+{
+ return _displayEmptyTasksAsLine;
+}
+
+
+/*!
+ Defines the horizontal background lines of the Gantt chart.
+ Call setHorBackgroundLines()
+ (equivalent to setHorBackgroundLines( 2, QBrush( QColor ( 240,240,240 )) ) )
+ to draw a light grey horizontal background line for every second Gantt item.
+ Call setHorBackgroundLines(0) in order to not show horizontal
+ background lines.
+ You may specify the number of lines and the brush of the lines.
+
+ \param count for count >= 2, every count line gets a backgroud
+ specified by brush
+ for count < 2, no background lines are drawn
+ \param brush the brush of the lines
+*/
+void KDGanttView::setHorBackgroundLines( int count, QBrush brush )
+{
+ myTimeTable->setHorBackgroundLines( count, brush );
+}
+
+
+/*!
+ Returns the definition of the horizontal background lines of the
+ Gantt chart.
+
+ \param brush the brush of the lines
+ \return every nth line gets a background specified by brush
+ if 0 is returned, no backgroud lines are drawn
+
+*/
+int KDGanttView::horBackgroundLines( QBrush& brush )
+{
+ return myTimeTable->horBackgroundLines( brush );
+}
+
+
+/*!
+ Returns the last item in the Gantt view
+
+ \return the last item in the Gantt view, 0 if there are no items
+*/
+KDGanttViewItem* KDGanttView::lastItem() const
+{
+ return (KDGanttViewItem*)myListView->lastItem ();
+}
+
+
+/*!
+ Returns the list of task links in the Gantt view.
+
+ \return the list of task links in the Gantt view
+*/
+QPtrList<KDGanttViewTaskLink> KDGanttView::taskLinks() const
+{
+
+ return myTimeTable->taskLinks();
+}
+
+
+/*!
+ Returns the list of task link groups in the Gantt view.
+
+ \return the list of task link groups in the Gantt view
+*/
+QPtrList<KDGanttViewTaskLinkGroup> KDGanttView::taskLinkGroups() const
+{
+ return myTaskLinkGroupList;
+}
+
+
+/**
+ Reads the parameters of the view from an XML document.
+ \param doc the XML document to read from
+ \return true if the parameters could be read, false if a file
+ format error occurred
+ \sa saveXML
+*/
+bool KDGanttView::loadXML( const QDomDocument& doc )
+{
+ QDomElement docRoot = doc.documentElement(); // ChartParams element
+ QDomNode node = docRoot.firstChild();
+ while( !node.isNull() ) {
+ QDomElement element = node.toElement();
+ if( !element.isNull() ) { // was really an element
+ QString tagName = element.tagName();
+ if( tagName == "ShowLegend" ) {
+ bool value;
+ if( KDGanttXML::readBoolNode( element, value ) )
+ setShowLegend( value );
+ } else if( tagName == "ShowLegendButton" ) {
+ bool value;
+ if( KDGanttXML::readBoolNode( element, value ) )
+ setShowLegendButton( value );
+ } else if( tagName == "LegendIsDockWindow" ) {
+ bool value;
+ if( KDGanttXML::readBoolNode( element, value ) )
+ setLegendIsDockwindow( value );
+ } else if( tagName == "ShowListView" ) {
+ bool value;
+ if( KDGanttXML::readBoolNode( element, value ) )
+ setShowListView( value );
+ } else if( tagName == "ShowHeader" ) {
+ bool value;
+ if( KDGanttXML::readBoolNode( element, value ) )
+ setHeaderVisible( value );
+ } else if( tagName == "ShowTaskLinks" ) {
+ bool value;
+ if( KDGanttXML::readBoolNode( element, value ) )
+ setShowTaskLinks( value );
+ } else if( tagName == "EditorEnabled" ) {
+ bool value;
+ if( KDGanttXML::readBoolNode( element, value ) )
+ setEditorEnabled( value );
+ } else if( tagName == "DisplayEmptyTasksAsLine" ) {
+ bool value;
+ if( KDGanttXML::readBoolNode( element, value ) )
+ setDisplayEmptyTasksAsLine( value );
+ } else if( tagName == "GlobalFont" ) {
+ QFont font;
+ if( KDGanttXML::readFontNode( element, font ) )
+ setFont( font );
+ } else if( tagName == "HorizonStart" ) {
+ QDateTime value;
+ if( KDGanttXML::readDateTimeNode( element, value ) )
+ setHorizonStart( value );
+ } else if( tagName == "HorizonEnd" ) {
+ QDateTime value;
+ if( KDGanttXML::readDateTimeNode( element, value ) )
+ setHorizonEnd( value );
+ } else if( tagName == "Scale" ) {
+ QString value;
+ if( KDGanttXML::readStringNode( element, value ) )
+ setScale( stringToScale( value ) );
+ } else if( tagName == "MinimumScale" ) {
+ QString value;
+ if( KDGanttXML::readStringNode( element, value ) )
+ setMinimumScale( stringToScale( value ) );
+ } else if( tagName == "MaximumScale" ) {
+ QString value;
+ if( KDGanttXML::readStringNode( element, value ) )
+ setMaximumScale( stringToScale( value ) );
+ } else if( tagName == "YearFormat" ) {
+ QString value;
+ if( KDGanttXML::readStringNode( element, value ) )
+ setYearFormat( stringToYearFormat( value ) );
+ } else if( tagName == "HourFormat" ) {
+ QString value;
+ if( KDGanttXML::readStringNode( element, value ) )
+ setHourFormat( stringToHourFormat( value ) );
+ } else if( tagName == "ShowMinorTicks" ) {
+ bool value;
+ if( KDGanttXML::readBoolNode( element, value ) )
+ setShowMinorTicks( value );
+ } else if( tagName == "ShowMajorTicks" ) {
+ bool value;
+ if( KDGanttXML::readBoolNode( element, value ) )
+ setShowMajorTicks( value );
+ } else if( tagName == "DragEnabled" ) {
+ bool value;
+ if( KDGanttXML::readBoolNode( element, value ) )
+ setDragEnabled( value );
+ } else if( tagName == "DropEnabled" ) {
+ bool value;
+ if( KDGanttXML::readBoolNode( element, value ) )
+ setDropEnabled( value );
+ } else if( tagName == "CalendarMode" ) {
+ bool value;
+ if( KDGanttXML::readBoolNode( element, value ) )
+ setCalendarMode( value );
+ } else if( tagName == "Editable" ) {
+ bool value;
+ if( KDGanttXML::readBoolNode( element, value ) )
+ setEditable( value );
+ } else if( tagName == "TextColor" ) {
+ QColor value;
+ if( KDGanttXML::readColorNode( element, value ) )
+ setTextColor( value );
+ } else if( tagName == "MajorScaleCount" ) {
+ int value;
+ if( KDGanttXML::readIntNode( element, value ) )
+ setMajorScaleCount( value );
+ } else if( tagName == "MinorScaleCount" ) {
+ int value;
+ if( KDGanttXML::readIntNode( element, value ) )
+ setMinorScaleCount( value );
+ } else if( tagName == "AutoScaleMinorTickCount" ) {
+ int value;
+ if( KDGanttXML::readIntNode( element, value ) )
+ setAutoScaleMinorTickCount( value );
+ } else if( tagName == "MinimumColumnWidth" ) {
+ int value;
+ if( KDGanttXML::readIntNode( element, value ) )
+ setMinimumColumnWidth( value );
+ } else if( tagName == "GanttMaximumWidth" ) {
+ int value;
+ if( KDGanttXML::readIntNode( element, value ) )
+ setGanttMaximumWidth( value );
+ } else if( tagName == "NoInformationBrush" ) {
+ QBrush value;
+ if( KDGanttXML::readBrushNode( element, value ) )
+ setNoInformationBrush( value );
+ } else if( tagName == "GanttViewBackgroundColor" ) {
+ QColor value;
+ if( KDGanttXML::readColorNode( element, value ) )
+ setGvBackgroundColor( value );
+ } else if( tagName == "ListViewBackgroundColor" ) {
+ QColor value;
+ if( KDGanttXML::readColorNode( element, value ) )
+ setLvBackgroundColor( value );
+ } else if( tagName == "TimeHeaderBackgroundColor" ) {
+ QColor value;
+ if( KDGanttXML::readColorNode( element, value ) )
+ setTimeHeaderBackgroundColor( value );
+ } else if( tagName == "LegendHeaderBackgroundColor" ) {
+ QColor value;
+ if( KDGanttXML::readColorNode( element, value ) )
+ setLegendHeaderBackgroundColor( value );
+ } else if( tagName == "WeekendBackgroundColor" ) {
+ QColor value;
+ if( KDGanttXML::readColorNode( element, value ) )
+ setWeekendBackgroundColor( value );
+ } else if( tagName == "WeekdayBackgroundColor" ) {
+ QDomNode node = element.firstChild();
+ int day = 0;
+ QColor color;
+ while( !node.isNull() ) {
+ QDomElement element = node.toElement();
+ if( !element.isNull() ) { // was really an elemente
+ QString tagName = element.tagName();
+ if( tagName == "Day" ) {
+ int value;
+ if( KDGanttXML::readIntNode( element, value ) )
+ day = value;
+ } else if( tagName == "Color" ) {
+ QColor value;
+ if( KDGanttXML::readColorNode( element, value ) )
+ color = value;
+ } else {
+ qDebug( "Unrecognized tag name: %s", tagName.latin1() );
+ Q_ASSERT( false );
+ }
+ }
+ node = node.nextSibling();
+ }
+
+ if( day && color.isValid() )
+ setWeekdayBackgroundColor( color, day );
+ } else if( tagName == "WeekendDays" ) {
+ QString startString = element.attribute( "Start" );
+ QString endString = element.attribute( "End" );
+ bool startOk = false, endOk = false;
+ int start = startString.toInt( &startOk );
+ int end = startString.toInt( &endOk );
+ if( startOk && endOk )
+ setWeekendDays( start, end );
+ } else if( tagName == "ZoomFactor" ) {
+ double value;
+ if( KDGanttXML::readDoubleNode( element, value ) )
+ setZoomFactor( value, true );
+ } else if( tagName == "ShowHeaderPopupMenu" ) {
+ bool value;
+ if( KDGanttXML::readBoolNode( element, value ) )
+ setShowHeaderPopupMenu( value );
+ } else if( tagName == "ShowTimeTablePopupMenu" ) {
+ bool value;
+ if( KDGanttXML::readBoolNode( element, value ) )
+ setShowTimeTablePopupMenu( value );
+ } else if( tagName == "Shapes" ) {
+ QDomNode node = element.firstChild();
+ bool undefinedShape = false;
+ while( !node.isNull() ) {
+ QDomElement element = node.toElement();
+ if( !element.isNull() ) { // was really an elemente
+ QString tagName = element.tagName();
+ if( tagName == "Event" ) {
+ KDGanttViewItem::Shape startShape, middleShape, endShape;
+ startShape = KDGanttViewItem::TriangleDown;
+ middleShape = KDGanttViewItem::TriangleDown;
+ endShape = KDGanttViewItem::TriangleDown;
+ QDomNode node = element.firstChild();
+ while( !node.isNull() ) {
+ QDomElement element = node.toElement();
+ if( !element.isNull() ) { // was really an elemente
+ QString tagName = element.tagName();
+ if( tagName == "Start" ) {
+ QString value;
+ if( KDGanttXML::readStringNode( element, value ) )
+ startShape = KDGanttViewItem::stringToShape( value );
+ if ( value == "Undefined" )
+ undefinedShape = true;
+ } else if( tagName == "Middle" ) {
+ QString value;
+ if( KDGanttXML::readStringNode( element, value ) )
+ middleShape = KDGanttViewItem::stringToShape( value );
+ if ( value == "Undefined" )
+ undefinedShape = true;
+ } else if( tagName == "End" ) {
+ QString value;
+ if( KDGanttXML::readStringNode( element, value ) )
+ endShape = KDGanttViewItem::stringToShape( value );
+ if ( value == "Undefined" )
+ undefinedShape = true;
+ } else {
+ qDebug( "Unrecognized tag name: %s", tagName.latin1() );
+ Q_ASSERT( false );
+ }
+ }
+ node = node.nextSibling();
+ }
+ if ( ! undefinedShape )
+ setShapes( KDGanttViewItem::Event, startShape,
+ middleShape, endShape, false );
+ undefinedShape = false;
+ } else if( tagName == "Task" ) {
+ KDGanttViewItem::Shape startShape, middleShape, endShape;
+ startShape = KDGanttViewItem::TriangleDown;
+ middleShape = KDGanttViewItem::TriangleDown;
+ endShape = KDGanttViewItem::TriangleDown;
+ QDomNode node = element.firstChild();
+ while( !node.isNull()) {
+ QDomElement element = node.toElement();
+ if( !element.isNull() ) { // was really an elemente
+ QString tagName = element.tagName();
+ if( tagName == "Start" ) {
+ QString value;
+ if( KDGanttXML::readStringNode( element, value ) )
+ startShape = KDGanttViewItem::stringToShape( value );
+ if ( value == "Undefined" )
+ undefinedShape = true;
+ } else if( tagName == "Middle" ) {
+ QString value;
+ if( KDGanttXML::readStringNode( element, value ) )
+ middleShape = KDGanttViewItem::stringToShape( value );
+ if ( value == "Undefined" )
+ undefinedShape = true;
+ } else if( tagName == "End" ) {
+ QString value;
+ if( KDGanttXML::readStringNode( element, value ) )
+ endShape = KDGanttViewItem::stringToShape( value );
+ if ( value == "Undefined" )
+ undefinedShape = true;
+ } else {
+ qDebug( "Unrecognized tag name: %s", tagName.latin1() );
+ Q_ASSERT( false );
+ }
+ }
+ node = node.nextSibling();
+ }
+ if ( ! undefinedShape )
+ setShapes( KDGanttViewItem::Task, startShape, middleShape, endShape, false );
+ undefinedShape = false;
+ } else if( tagName == "Summary" ) {
+ KDGanttViewItem::Shape startShape, middleShape, endShape;
+ startShape = KDGanttViewItem::TriangleDown;
+ middleShape = KDGanttViewItem::TriangleDown;
+ endShape = KDGanttViewItem::TriangleDown;
+ QDomNode node = element.firstChild();
+ while( !node.isNull() ) {
+ QDomElement element = node.toElement();
+ if( !element.isNull() ) { // was really an elemente
+ QString tagName = element.tagName();
+ if( tagName == "Start" ) {
+ QString value;
+ if( KDGanttXML::readStringNode( element, value ) )
+ startShape = KDGanttViewItem::stringToShape( value );
+ if ( value == "Undefined" )
+ undefinedShape = true;
+ } else if( tagName == "Middle" ) {
+ QString value;
+ if( KDGanttXML::readStringNode( element, value ) )
+ middleShape = KDGanttViewItem::stringToShape( value );
+ if ( value == "Undefined" )
+ undefinedShape = true;
+ } else if( tagName == "End" ) {
+ QString value;
+ if( KDGanttXML::readStringNode( element, value ) )
+ endShape = KDGanttViewItem::stringToShape( value );
+ if ( value == "Undefined" )
+ undefinedShape = true;
+ } else {
+ qDebug( "Unrecognized tag name: %s", tagName.latin1() );
+ Q_ASSERT( false );
+ }
+ }
+ node = node.nextSibling();
+ }
+ if ( ! undefinedShape )
+ setShapes( KDGanttViewItem::Summary, startShape,
+ middleShape, endShape, false );
+ undefinedShape = false;
+ } else {
+ qDebug( "Unrecognized tag name: %s", tagName.latin1() );
+ Q_ASSERT( false );
+ }
+ }
+ node = node.nextSibling();
+ }
+ } else if( tagName == "Colors" ) {
+ QDomNode node = element.firstChild();
+ while( !node.isNull()) {
+ QDomElement element = node.toElement();
+ if( !element.isNull() ) { // was really an elemente
+ QString tagName = element.tagName();
+ if( tagName == "Event" ) {
+ QColor startColor, middleColor, endColor;
+ QDomNode node = element.firstChild();
+ while( !node.isNull() ) {
+ QDomElement element = node.toElement();
+ if( !element.isNull() ) { // was really an elemente
+ QString tagName = element.tagName();
+ if( tagName == "Start" ) {
+ QColor value;
+ if( KDGanttXML::readColorNode( element, value ) )
+ startColor = value;
+ } else if( tagName == "Middle" ) {
+ QColor value;
+ if( KDGanttXML::readColorNode( element, value ) )
+ middleColor = value;
+ } else if( tagName == "End" ) {
+ QColor value;
+ if( KDGanttXML::readColorNode( element, value ) )
+ endColor = value;
+ } else {
+ qDebug( "Unrecognized tag name: %s", tagName.latin1() );
+ Q_ASSERT( false );
+ }
+ }
+ node = node.nextSibling();
+ }
+ setColors( KDGanttViewItem::Event, startColor,
+ middleColor, endColor, false );
+ } else if( tagName == "Task" ) {
+ QColor startColor, middleColor, endColor;
+ QDomNode node = element.firstChild();
+ while( !node.isNull() ) {
+ QDomElement element = node.toElement();
+ if( !element.isNull() ) { // was really an elemente
+ QString tagName = element.tagName();
+ if( tagName == "Start" ) {
+ QColor value;
+ if( KDGanttXML::readColorNode( element, value ) )
+ startColor = value;
+ } else if( tagName == "Middle" ) {
+ QColor value;
+ if( KDGanttXML::readColorNode( element, value ) )
+ middleColor = value;
+ } else if( tagName == "End" ) {
+ QColor value;
+ if( KDGanttXML::readColorNode( element, value ) )
+ endColor = value;
+ } else {
+ qDebug( "Unrecognized tag name: %s", tagName.latin1() );
+ Q_ASSERT( false );
+ }
+ }
+ node = node.nextSibling();
+ }
+ setColors( KDGanttViewItem::Task, startColor,
+ middleColor, endColor, false );
+ } else if( tagName == "Summary" ) {
+ QColor startColor, middleColor, endColor;
+ QDomNode node = element.firstChild();
+ while( !node.isNull() ) {
+ QDomElement element = node.toElement();
+ if( !element.isNull() ) { // was really an elemente
+ QString tagName = element.tagName();
+ if( tagName == "Start" ) {
+ QColor value;
+ if( KDGanttXML::readColorNode( element, value ) )
+ startColor = value;
+ } else if( tagName == "Middle" ) {
+ QColor value;
+ if( KDGanttXML::readColorNode( element, value ) )
+ middleColor = value;
+ } else if( tagName == "End" ) {
+ QColor value;
+ if( KDGanttXML::readColorNode( element, value ) )
+ endColor = value;
+ } else {
+ qDebug( "Unrecognized tag name: %s", tagName.latin1() );
+ Q_ASSERT( false );
+ }
+ }
+ node = node.nextSibling();
+ }
+ setColors( KDGanttViewItem::Summary, startColor,
+ middleColor, endColor , false);
+ } else {
+ qDebug( "Unrecognized tag name: %s", tagName.latin1() );
+ Q_ASSERT( false );
+ }
+ }
+ node = node.nextSibling();
+ }
+ } else if( tagName == "DefaultColors" ) {
+ QDomNode node = element.firstChild();
+ while( !node.isNull() ) {
+ QDomElement element = node.toElement();
+ if( !element.isNull() ) { // was really an element
+ QString tagName = element.tagName();
+ if( tagName == "Event" ) {
+ QColor value;
+ if( KDGanttXML::readColorNode( element, value ) )
+ setDefaultColor( KDGanttViewItem::Event,
+ value, false );
+ } else if( tagName == "Task" ) {
+ QColor value;
+ if( KDGanttXML::readColorNode( element, value ) )
+ setDefaultColor( KDGanttViewItem::Task,
+ value, false );
+ } else if( tagName == "Summary" ) {
+ QColor value;
+ if( KDGanttXML::readColorNode( element, value ) )
+ setDefaultColor( KDGanttViewItem::Summary,
+ value , false);
+ } else {
+ qDebug( "Unrecognized tag name: %s", tagName.latin1() );
+ Q_ASSERT( false );
+ }
+ }
+
+ node = node.nextSibling();
+ }
+ } else if( tagName == "HighlightColors" ) {
+ QDomNode node = element.firstChild();
+ while( !node.isNull() ) {
+ QDomElement element = node.toElement();
+ if( !element.isNull() ) { // was really an elemente
+ QString tagName = element.tagName();
+ if( tagName == "Event" ) {
+ QColor startColor, middleColor, endColor;
+ QDomNode node = element.firstChild();
+ while( !node.isNull() ) {
+ QDomElement element = node.toElement();
+ if( !element.isNull() ) { // was really an elemente
+ QString tagName = element.tagName();
+ if( tagName == "Start" ) {
+ QColor value;
+ if( KDGanttXML::readColorNode( element, value ) )
+ startColor = value;
+ } else if( tagName == "Middle" ) {
+ QColor value;
+ if( KDGanttXML::readColorNode( element, value ) )
+ middleColor = value;
+ } else if( tagName == "End" ) {
+ QColor value;
+ if( KDGanttXML::readColorNode( element, value ) )
+ endColor = value;
+ } else {
+ qDebug( "Unrecognized tag name: %s", tagName.latin1() );
+ Q_ASSERT( false );
+ }
+ }
+ node = node.nextSibling();
+ }
+ setHighlightColors( KDGanttViewItem::Event,
+ startColor,
+ middleColor, endColor, false );
+ } else if( tagName == "Task" ) {
+ QColor startColor, middleColor, endColor;
+ QDomNode node = element.firstChild();
+ while( !node.isNull() ) {
+ QDomElement element = node.toElement();
+ if( !element.isNull() ) { // was really an elemente
+ QString tagName = element.tagName();
+ if( tagName == "Start" ) {
+ QColor value;
+ if( KDGanttXML::readColorNode( element, value ) )
+ startColor = value;
+ } else if( tagName == "Middle" ) {
+ QColor value;
+ if( KDGanttXML::readColorNode( element, value ) )
+ middleColor = value;
+ } else if( tagName == "End" ) {
+ QColor value;
+ if( KDGanttXML::readColorNode( element, value ) )
+ endColor = value;
+ } else {
+ qDebug( "Unrecognized tag name: %s", tagName.latin1() );
+ Q_ASSERT( false );
+ }
+ }
+ node = node.nextSibling();
+ }
+ setHighlightColors( KDGanttViewItem::Task,
+ startColor,
+ middleColor, endColor , false);
+ } else if( tagName == "Summary" ) {
+ QColor startColor, middleColor, endColor;
+ QDomNode node = element.firstChild();
+ while( !node.isNull() ) {
+ QDomElement element = node.toElement();
+ if( !element.isNull() ) { // was really an elemente
+ QString tagName = element.tagName();
+ if( tagName == "Start" ) {
+ QColor value;
+ if( KDGanttXML::readColorNode( element, value ) )
+ startColor = value;
+ } else if( tagName == "Middle" ) {
+ QColor value;
+ if( KDGanttXML::readColorNode( element, value ) )
+ middleColor = value;
+ } else if( tagName == "End" ) {
+ QColor value;
+ if( KDGanttXML::readColorNode( element, value ) )
+ endColor = value;
+ } else {
+ qDebug( "Unrecognized tag name: %s", tagName.latin1() );
+ Q_ASSERT( false );
+ }
+ }
+ node = node.nextSibling();
+ }
+ setHighlightColors( KDGanttViewItem::Summary,
+ startColor,
+ middleColor, endColor, false );
+ } else {
+ qDebug( "Unrecognized tag name: %s", tagName.latin1() );
+ Q_ASSERT( false );
+ }
+ }
+ node = node.nextSibling();
+ }
+ } else if( tagName == "DefaultHighlightColors" ) {
+ QDomNode node = element.firstChild();
+ while( !node.isNull() ) {
+ QDomElement element = node.toElement();
+ if( !element.isNull() ) { // was really an element
+ QString tagName = element.tagName();
+ if( tagName == "Event" ) {
+ QColor value;
+ if( KDGanttXML::readColorNode( element, value ) )
+ setDefaultHighlightColor( KDGanttViewItem::Event,
+ value , false);
+ } else if( tagName == "Task" ) {
+ QColor value;
+ if( KDGanttXML::readColorNode( element, value ) )
+ setDefaultHighlightColor( KDGanttViewItem::Task,
+ value, false );
+ } else if( tagName == "Summary" ) {
+ QColor value;
+ if( KDGanttXML::readColorNode( element, value ) )
+ setDefaultHighlightColor( KDGanttViewItem::Summary,
+ value, false );
+ } else {
+ qDebug( "Unrecognized tag name: %s", tagName.latin1() );
+ Q_ASSERT( false );
+ }
+ }
+
+ node = node.nextSibling();
+ }
+ } else if( tagName == "Items" ) {
+ QDomNode node = element.firstChild();
+ KDGanttViewItem* previous = 0;
+ while( !node.isNull() ) {
+ QDomElement element = node.toElement();
+ if( !element.isNull() ) { // was really an element
+ QString tagName = element.tagName();
+ if( tagName == "Item" ) {
+ KDGanttViewItem* newItem;
+ if( previous )
+ newItem =
+ KDGanttViewItem::createFromDomElement( this,
+ previous,
+ element );
+ else
+ newItem =
+ KDGanttViewItem::createFromDomElement( this,
+ element );
+ previous = newItem;
+ } else {
+ qDebug( "Unrecognized tag name: %s", tagName.latin1() );
+ Q_ASSERT( false );
+ }
+ }
+
+ node = node.nextSibling();
+ }
+ } else if( tagName == "TaskLinks" ) {
+ QDomNode node = element.firstChild();
+ while( !node.isNull() ) {
+ QDomElement element = node.toElement();
+ if( !element.isNull() ) { // was really an element
+ QString tagName = element.tagName();
+ if( tagName == "TaskLink" )
+ KDGanttViewTaskLink::createFromDomElement( element );
+ else {
+ qDebug( "Unrecognized tag name: %s", tagName.latin1() );
+ Q_ASSERT( false );
+ }
+ }
+
+ node = node.nextSibling();
+ }
+ } else if( tagName == "TaskLinkGroups" ) {
+ QDomNode node = element.firstChild();
+ while( !node.isNull() ) {
+ QDomElement element = node.toElement();
+ if( !element.isNull() ) { // was really an element
+ QString tagName = element.tagName();
+ if( tagName == "TaskLink" )
+ KDGanttViewTaskLinkGroup::createFromDomElement( element );
+ } else {
+ qDebug( "Unrecognized tag name: %s", tagName.latin1() );
+ Q_ASSERT( false );
+ }
+
+ node = node.nextSibling();
+ }
+ } else if( tagName == "ColumnBackgroundColors" ) {
+ QDomNode node = element.firstChild();
+ while( !node.isNull() ) {
+ QDomElement element = node.toElement();
+ if( !element.isNull() ) { // was really an element
+ QString tagName = element.tagName();
+ if( tagName == "ColumnBackgroundColor" ) {
+ QDomNode node = element.firstChild();
+ QDateTime dateTime;
+ QColor color;
+ while( !node.isNull() ) {
+ QDomElement element = node.toElement();
+ if( !element.isNull() ) { // was
+ // really an
+ // element
+ QString tagName = element.tagName();
+ if( tagName == "DateTime" ) {
+ QDateTime value;
+ if( KDGanttXML::readDateTimeNode( element, value ) )
+ dateTime = value;
+ } else if( tagName == "Color" ) {
+ QColor value;
+ if( KDGanttXML::readColorNode( element, value ) )
+ color = value;
+ } else {
+ qDebug( "Unrecognized tag name: %s", tagName.latin1() );
+ Q_ASSERT( false );
+ }
+ }
+
+ node = node.nextSibling();
+ }
+ setColumnBackgroundColor( dateTime, color );
+ } else {
+ qDebug( "Unrecognized tag name: %s", tagName.latin1() );
+ Q_ASSERT( false );
+ }
+ }
+ node = node.nextSibling();
+ }
+ } else if( tagName == "LegendItems" ) {
+ clearLegend();
+ QDomNode node = element.firstChild();
+ while( !node.isNull() ) {
+ QDomElement element = node.toElement();
+ if( !element.isNull() ) { // was really an element
+ QString tagName = element.tagName();
+ if( tagName == "LegendItem" ) {
+ KDGanttViewItem::Shape tempLegendShape;
+ tempLegendShape = KDGanttViewItem::TriangleDown;
+ QColor tempLegendColor;
+ QString tempLegendString;
+ bool ok = true;
+ QDomNode node = element.firstChild();
+ while( !node.isNull() ) {
+ QDomElement element = node.toElement();
+ if( !element.isNull() ) { // was really an element
+ QString tagName = element.tagName();
+ if( tagName == "Shape" ) {
+ QString value;
+ if( KDGanttXML::readStringNode( element, value ) )
+ tempLegendShape = KDGanttViewItem::stringToShape( value );
+ else
+ ok = false;
+ } else if( tagName == "Color" ) {
+ QColor value;
+ if( KDGanttXML::readColorNode( element, value ) )
+ tempLegendColor = value;
+ else
+ ok = false;
+ } else if( tagName == "Text" ) {
+ QString value;
+ if( KDGanttXML::readStringNode( element, value ) )
+ tempLegendString = value;
+ else
+ ok = false;
+ } else {
+ qDebug( "Unrecognized tag name: %s", tagName.latin1() );
+ Q_ASSERT( false );
+ }
+ }
+ node = node.nextSibling();
+ }
+ if( ok ) {
+ addLegendItem( tempLegendShape,
+ tempLegendColor,
+ tempLegendString );
+ qDebug( "Adding legend item %s", tempLegendString.latin1() );
+ }
+ } else {
+ qDebug( "Unrecognized tag name: %s", tagName.latin1() );
+ Q_ASSERT( false );
+ }
+ }
+ node = node.nextSibling();
+ }
+ } else {
+ qDebug( "Unrecognized tag name: %s", tagName.latin1() );
+ Q_ASSERT( false );
+ }
+ }
+
+ node = node.nextSibling();
+ } // while
+ return true; /* FIXME: Do real error-reporting. The ASSERT's should be "return false" stmnts */
+} // method
+
+
+/**
+ Saves the parameters of the view parameters to an XML document.
+
+ \param withPI pass true to store processing instructions, false to
+ leave them out
+ \return the XML document that represents the parameters
+ \sa loadXML
+*/
+QDomDocument KDGanttView::saveXML( bool withPI ) const
+{
+ // Create an inital DOM document
+ QString docstart = "<GanttView/>";
+
+ QDomDocument doc( "GanttView" );
+ doc.setContent( docstart );
+ if( withPI ) {
+ QDomProcessingInstruction pin = doc.createProcessingInstruction( "kdgantt", "version=\"1.0\" encoding=\"UTF-8\"" ) ;
+ doc.appendChild ( pin );
+ }
+
+ QDomElement docRoot = doc.documentElement();
+ docRoot.setAttribute( "xmlns", "http://www.klaralvdalens-datakonsult.se/kdgantt" );
+ docRoot.setAttribute( "xmlns:xsi", "http://www.w3.org/2000/10/XMLSchema-instance" );
+ docRoot.setAttribute( "xsi:schemaLocation", "http://www.klaralvdalens-datakonsult.se/kdgantt" );
+
+ // the ShowLegend element
+ KDGanttXML::createBoolNode( doc, docRoot, "ShowLegend", showLegend() );
+
+ // the ShowLegendButton element
+ KDGanttXML::createBoolNode( doc, docRoot, "ShowLegendButton",
+ showLegendButton() );
+
+ // the LegendIsDockWindow element
+ KDGanttXML::createBoolNode( doc, docRoot, "LegendIsDockWindow",
+ legendIsDockwindow() );
+
+ // the ShowListView element
+ KDGanttXML::createBoolNode( doc, docRoot, "ShowListView", showListView() );
+
+ // the ShowHeader element
+ KDGanttXML::createBoolNode( doc, docRoot, "ShowHeader", headerVisible() );
+
+ // the ShowTaskLinks element
+ KDGanttXML::createBoolNode( doc, docRoot, "ShowTaskLinks", showTaskLinks() );
+
+ // the EditorEnabled element
+ KDGanttXML::createBoolNode( doc, docRoot, "EditorEnabled", editorEnabled() );
+
+ // the global font element
+ KDGanttXML::createFontNode( doc, docRoot, "GlobalFont", font() );
+
+ // the DisplayEmptyTasksAsLine element
+ KDGanttXML::createBoolNode( doc, docRoot, "DisplayEmptyTasksAsLine",
+ displayEmptyTasksAsLine() );
+
+ // the HorizonStart element
+ KDGanttXML::createDateTimeNode( doc, docRoot, "HorizonStart", horizonStart() );
+
+ // the HorizonEnd element
+ KDGanttXML::createDateTimeNode( doc, docRoot, "HorizonEnd", horizonEnd() );
+
+ // the Scale, MinimumScale, MaximumScale elements
+ KDGanttXML::createStringNode( doc, docRoot, "Scale", scaleToString( scale() ) );
+ KDGanttXML::createStringNode( doc, docRoot, "MinimumScale",
+ scaleToString( minimumScale() ) );
+ KDGanttXML::createStringNode( doc, docRoot, "MaximumScale",
+ scaleToString( maximumScale() ) );
+
+ // the YearFormat element
+ KDGanttXML::createStringNode( doc, docRoot, "YearFormat",
+ yearFormatToString( yearFormat() ) );
+
+ // the HourFormat element
+ KDGanttXML::createStringNode( doc, docRoot, "HourFormat",
+ hourFormatToString( hourFormat() ) );
+
+ // the ShowMinorTicks element
+ KDGanttXML::createBoolNode( doc, docRoot, "ShowMinorTicks", showMinorTicks() );
+
+ // the ShowMajorTicks element
+ KDGanttXML::createBoolNode( doc, docRoot, "ShowMajorTicks", showMajorTicks() );
+
+ // the Editable element
+ KDGanttXML::createBoolNode( doc, docRoot, "Editable", editable() );
+
+ // the TextColor element
+ KDGanttXML::createColorNode( doc, docRoot, "TextColor", textColor() );
+
+ // the MajorScaleCount element
+ KDGanttXML::createIntNode( doc, docRoot, "MajorScaleCount", majorScaleCount() );
+
+ // the MinorScaleCount element
+ KDGanttXML::createIntNode( doc, docRoot, "MinorScaleCount", minorScaleCount() );
+
+ // the AutoScaleMinorTickCount element
+ KDGanttXML::createIntNode( doc, docRoot, "AutoScaleMinorTickCount",
+ autoScaleMinorTickCount() );
+
+ // the MinimumColumnWidth element
+ KDGanttXML::createIntNode( doc, docRoot, "MinimumColumnWidth",
+ minimumColumnWidth() );
+
+ // the GanttMaximumWidth element
+ KDGanttXML::createIntNode( doc, docRoot, "GanttMaximumWidth",
+ ganttMaximumWidth() );
+
+ // the NoInformationBrush element
+ KDGanttXML::createBrushNode( doc, docRoot, "NoInformationBrush",
+ noInformationBrush() );
+
+ // the GanttViewBackgroundColor element
+ KDGanttXML::createColorNode( doc, docRoot, "GanttViewBackgroundColor",
+ gvBackgroundColor() );
+
+ // the ListViewBackgroundColor element
+ KDGanttXML::createColorNode( doc, docRoot, "ListViewBackgroundColor",
+ lvBackgroundColor() );
+
+ // the TimeHeaderBackgroundColor element
+ KDGanttXML::createColorNode( doc, docRoot, "TimeHeaderBackgroundColor",
+ timeHeaderBackgroundColor() );
+
+ // the LegendHeaderBackgroundColor element
+ KDGanttXML::createColorNode( doc, docRoot, "LegendHeaderBackgroundColor",
+ legendHeaderBackgroundColor() );
+
+ // the WeekendBackgroundColor element
+ KDGanttXML::createColorNode( doc, docRoot, "WeekendBackgroundColor",
+ weekendBackgroundColor() );
+
+ // the WeekdayBackgroundColor elements
+ for( int weekday = 1; weekday <= 7; weekday++ ) {
+ QColor color = weekdayBackgroundColor( weekday );
+ if( color.isValid() ) {
+ QDomElement weekendBackgroundColorElement = doc.createElement( "WeekdayBackgroundColor" );
+ docRoot.appendChild( weekendBackgroundColorElement );
+ KDGanttXML::createIntNode( doc, weekendBackgroundColorElement,
+ "Day", weekday );
+ KDGanttXML::createColorNode( doc, weekendBackgroundColorElement,
+ "Color", color );
+ }
+ }
+
+ // the WeekendDays element
+ QDomElement weekendDaysElement = doc.createElement( "WeekendDays" );
+ docRoot.appendChild( weekendDaysElement );
+ int weekendStart, weekendEnd;
+ weekendDays( weekendStart, weekendEnd );
+ weekendDaysElement.setAttribute( "Start", weekendStart );
+ weekendDaysElement.setAttribute( "End", weekendStart );
+
+ // the ZoomFactor element
+ KDGanttXML::createDoubleNode( doc, docRoot, "ZoomFactor",
+ zoomFactor() );
+
+ // the ShowHeaderPopupMenu element
+ KDGanttXML::createBoolNode( doc, docRoot, "ShowHeaderPopupMenu",
+ showHeaderPopupMenu() );
+
+ // the ShowTimeTablePopupMenu element
+ KDGanttXML::createBoolNode( doc, docRoot, "ShowTimeTablePopupMenu",
+ showTimeTablePopupMenu() );
+
+ // the Shapes element
+ QDomElement shapesElement = doc.createElement( "Shapes" );
+ docRoot.appendChild( shapesElement );
+ QDomElement shapesEventElement = doc.createElement( "Event" );
+ shapesElement.appendChild( shapesEventElement );
+ KDGanttViewItem::Shape start, middle, end;
+ if( shapes( KDGanttViewItem::Event, start, middle, end ) ) {
+ KDGanttXML::createStringNode( doc, shapesEventElement, "Start",
+ KDGanttViewItem::shapeToString( start ) );
+ KDGanttXML::createStringNode( doc, shapesEventElement, "Middle",
+ KDGanttViewItem::shapeToString( middle ) );
+ KDGanttXML::createStringNode( doc, shapesEventElement, "End",
+ KDGanttViewItem::shapeToString( end ) );
+ } else {
+ KDGanttXML::createStringNode( doc, shapesEventElement, "Start",
+ "Undefined" );
+ KDGanttXML::createStringNode( doc, shapesEventElement, "Middle",
+ "Undefined" );
+ KDGanttXML::createStringNode( doc, shapesEventElement, "End",
+ "Undefined" );
+ }
+ QDomElement shapesTaskElement = doc.createElement( "Task" );
+ shapesElement.appendChild( shapesTaskElement );
+ if( shapes( KDGanttViewItem::Task, start, middle, end ) ) {
+ KDGanttXML::createStringNode( doc, shapesTaskElement, "Start",
+ KDGanttViewItem::shapeToString( start ) );
+ KDGanttXML::createStringNode( doc, shapesTaskElement, "Middle",
+ KDGanttViewItem::shapeToString( middle ) );
+ KDGanttXML::createStringNode( doc, shapesTaskElement, "End",
+ KDGanttViewItem::shapeToString( end ) );
+ } else {
+ KDGanttXML::createStringNode( doc, shapesTaskElement, "Start",
+ "Undefined" );
+ KDGanttXML::createStringNode( doc, shapesTaskElement, "Middle",
+ "Undefined" );
+ KDGanttXML::createStringNode( doc, shapesTaskElement, "End",
+ "Undefined" );
+ }
+ QDomElement shapesSummaryElement = doc.createElement( "Summary" );
+ shapesElement.appendChild( shapesSummaryElement );
+ if( shapes( KDGanttViewItem::Event, start, middle, end ) ) {
+ KDGanttXML::createStringNode( doc, shapesSummaryElement, "Start",
+ KDGanttViewItem::shapeToString( start ) );
+ KDGanttXML::createStringNode( doc, shapesSummaryElement, "Middle",
+ KDGanttViewItem::shapeToString( middle ) );
+ KDGanttXML::createStringNode( doc, shapesSummaryElement, "End",
+ KDGanttViewItem::shapeToString( end ) );
+ } else {
+ KDGanttXML::createStringNode( doc, shapesSummaryElement, "Start",
+ "Undefined" );
+ KDGanttXML::createStringNode( doc, shapesSummaryElement, "Middle",
+ "Undefined" );
+ KDGanttXML::createStringNode( doc, shapesSummaryElement, "End",
+ "Undefined" );
+ }
+
+ // the Colors element
+ QDomElement colorsElement = doc.createElement( "Colors" );
+ docRoot.appendChild( colorsElement );
+ QDomElement colorsEventElement = doc.createElement( "Event" );
+ colorsElement.appendChild( colorsEventElement );
+ QColor startColor, middleColor, endColor;
+ colors( KDGanttViewItem::Event, startColor, middleColor, endColor );
+ KDGanttXML::createColorNode( doc, colorsEventElement, "Start", startColor );
+ KDGanttXML::createColorNode( doc, colorsEventElement, "Middle", middleColor );
+ KDGanttXML::createColorNode( doc, colorsEventElement, "End", endColor );
+ QDomElement colorsTaskElement = doc.createElement( "Task" );
+ colorsElement.appendChild( colorsTaskElement );
+ colors( KDGanttViewItem::Task, startColor, middleColor, endColor );
+ KDGanttXML::createColorNode( doc, colorsTaskElement, "Start", startColor );
+ KDGanttXML::createColorNode( doc, colorsTaskElement, "Middle", middleColor );
+ KDGanttXML::createColorNode( doc, colorsTaskElement, "End", endColor );
+ QDomElement colorsSummaryElement = doc.createElement( "Summary" );
+ colorsElement.appendChild( colorsSummaryElement );
+ colors( KDGanttViewItem::Event, startColor, middleColor, endColor );
+ KDGanttXML::createColorNode( doc, colorsSummaryElement, "Start", startColor );
+ KDGanttXML::createColorNode( doc, colorsSummaryElement, "Middle", middleColor );
+ KDGanttXML::createColorNode( doc, colorsSummaryElement, "End", endColor );
+
+ // the DefaultColor element
+ QDomElement defaultColorsElement = doc.createElement( "DefaultColors" );
+ docRoot.appendChild( defaultColorsElement );
+ KDGanttXML::createColorNode( doc, defaultColorsElement, "Event",
+ defaultColor( KDGanttViewItem::Event ) );
+ KDGanttXML::createColorNode( doc, defaultColorsElement, "Task",
+ defaultColor( KDGanttViewItem::Task ) );
+ KDGanttXML::createColorNode( doc, defaultColorsElement, "Summary",
+ defaultColor( KDGanttViewItem::Summary ) );
+
+
+ // the HighlightColors element
+ QDomElement highlightColorsElement = doc.createElement( "HighlightColors" );
+ docRoot.appendChild( highlightColorsElement );
+ QDomElement highlightColorsEventElement = doc.createElement( "Event" );
+ highlightColorsElement.appendChild( highlightColorsEventElement );
+ highlightColors( KDGanttViewItem::Event, startColor, middleColor, endColor );
+ KDGanttXML::createColorNode( doc, highlightColorsEventElement, "Start", startColor );
+ KDGanttXML::createColorNode( doc, highlightColorsEventElement, "Middle", middleColor );
+ KDGanttXML::createColorNode( doc, highlightColorsEventElement, "End", endColor );
+ QDomElement highlightColorsTaskElement = doc.createElement( "Task" );
+ highlightColorsElement.appendChild( highlightColorsTaskElement );
+ highlightColors( KDGanttViewItem::Task, startColor, middleColor, endColor );
+ KDGanttXML::createColorNode( doc, highlightColorsTaskElement, "Start", startColor );
+ KDGanttXML::createColorNode( doc, highlightColorsTaskElement, "Middle", middleColor );
+ KDGanttXML::createColorNode( doc, highlightColorsTaskElement, "End", endColor );
+ QDomElement highlightColorsSummaryElement = doc.createElement( "Summary" );
+ highlightColorsElement.appendChild( highlightColorsSummaryElement );
+ highlightColors( KDGanttViewItem::Event, startColor, middleColor, endColor );
+ KDGanttXML::createColorNode( doc, highlightColorsSummaryElement, "Start", startColor );
+ KDGanttXML::createColorNode( doc, highlightColorsSummaryElement, "Middle", middleColor );
+ KDGanttXML::createColorNode( doc, highlightColorsSummaryElement, "End", endColor );
+
+
+ /*
+ if( highlightColors( KDGanttViewItem::Event, startColor, middleColor, endColor ) ) {
+ KDGanttXML::createColorNode( doc, highlightColorsSummaryElement, "Start", startColor );
+ KDGanttXML::createColorNode( doc, highlightColorsSummaryElement, "Middle", middleColor );
+ KDGanttXML::createColorNode( doc, highlightColorsSummaryElement, "End", endColor );
+ } else {
+ KDGanttXML::createColorNode( doc, highlightColorsSummaryElement, "Start", QColor() );
+ KDGanttXML::createColorNode( doc, highlightColorsSummaryElement, "Middle", QColor() );
+ KDGanttXML::createColorNode( doc, highlightColorsSummaryElement, "End", QColor() );
+ }
+ */
+ // the DefaultHighlightColor element
+ QDomElement defaultHighlightColorsElement = doc.createElement( "DefaultHighlightColors" );
+ docRoot.appendChild( defaultHighlightColorsElement );
+ KDGanttXML::createColorNode( doc, defaultHighlightColorsElement, "Event",
+ defaultHighlightColor( KDGanttViewItem::Event ) );
+ KDGanttXML::createColorNode( doc, defaultHighlightColorsElement, "Task",
+ defaultHighlightColor( KDGanttViewItem::Task ) );
+ KDGanttXML::createColorNode( doc, defaultHighlightColorsElement, "Summary",
+ defaultHighlightColor( KDGanttViewItem::Summary ) );
+
+
+ // the Items element
+ QDomElement itemsElement = doc.createElement( "Items" );
+ docRoot.appendChild( itemsElement );
+ KDGanttViewItem* currentItem = firstChild();
+ while( currentItem ) {
+ currentItem->createNode( doc, itemsElement );
+ currentItem = currentItem->nextSibling();
+ }
+
+ // the TaskLinks element
+ QDomElement taskLinksElement = doc.createElement( "TaskLinks" );
+ docRoot.appendChild( taskLinksElement );
+ QPtrList<KDGanttViewTaskLink> taskLinkList = taskLinks();
+ KDGanttViewTaskLink* currentTL = 0;
+ for( currentTL = taskLinkList.first(); currentTL;
+ currentTL = taskLinkList.next() )
+ currentTL->createNode( doc, taskLinksElement );
+
+ // the TaskLinkGroups element
+ QDomElement taskLinkGroupsElement = doc.createElement( "TaskLinkGroups" );
+ docRoot.appendChild( taskLinkGroupsElement );
+ QPtrList<KDGanttViewTaskLinkGroup> taskLinkGroupList = taskLinkGroups();
+ KDGanttViewTaskLinkGroup* currentTLG = 0;
+ for( currentTLG = taskLinkGroupList.first(); currentTLG;
+ currentTLG = taskLinkGroupList.next() )
+ currentTLG->createNode( doc, taskLinkGroupsElement );
+
+ // the ColumnBackgroundColors element
+ QDomElement columnBackgroundColorsElement =
+ doc.createElement( "ColumnBackgroundColors" );
+ docRoot.appendChild( columnBackgroundColorsElement );
+ KDTimeHeaderWidget::ColumnColorList ccList =
+ myTimeHeader->columnBackgroundColorList();
+ for( KDTimeHeaderWidget::ColumnColorList::iterator it = ccList.begin();
+ it != ccList.end(); ++it ) {
+ QDomElement columnBackgroundColorElement =
+ doc.createElement( "ColumnBackgroundColor" );
+ columnBackgroundColorsElement.appendChild( columnBackgroundColorElement );
+ KDGanttXML::createDateTimeNode( doc, columnBackgroundColorElement,
+ "DateTime", (*it).datetime );
+ KDGanttXML::createColorNode( doc, columnBackgroundColorElement,
+ "Color", (*it).color );
+ }
+
+ // the LegendItems element
+ QDomElement legendItemsElement =
+ doc.createElement( "LegendItems" );
+ docRoot.appendChild( legendItemsElement );
+ legendItem* current;
+ QPtrListIterator<legendItem> lit( *myLegendItems );
+ while( ( current = lit.current() ) ) {
+ ++lit;
+ QDomElement legendItemElement = doc.createElement( "LegendItem" );
+ legendItemsElement.appendChild( legendItemElement );
+ KDGanttXML::createStringNode( doc, legendItemElement, "Shape",
+ KDGanttViewItem::shapeToString( current->shape ) );
+ KDGanttXML::createColorNode( doc, legendItemElement, "Color",
+ current->color );
+ KDGanttXML::createStringNode( doc, legendItemElement, "Text",
+ current->text );
+ }
+
+ // the DragEnabled element
+ KDGanttXML::createBoolNode( doc, docRoot, "DragEnabled", isDragEnabled() );
+
+ // the DropEnabled element
+ KDGanttXML::createBoolNode( doc, docRoot, "DropEnabled", isDropEnabled() );
+
+ // the CalendarMode element
+ KDGanttXML::createBoolNode( doc, docRoot, "CalendarMode", calendarMode() );
+
+ return doc;
+}
+
+
+
+QString KDGanttView::scaleToString( Scale scale )
+{
+ switch( scale ) {
+ case Minute:
+ return "Minute";
+ case Hour:
+ return "Hour";
+ case Day:
+ return "Day";
+ case Week:
+ return "Week";
+ case Month:
+ return "Month";
+ case Auto:
+ return "Auto";
+ }
+ return "";
+}
+
+
+KDGanttView::Scale KDGanttView::stringToScale( const QString& string )
+{
+ if( string == "Minute" )
+ return Minute;
+ else if( string == "Hour" )
+ return Hour;
+ else if( string == "Day" )
+ return Day;
+ else if( string == "Week" )
+ return Week;
+ else if( string == "Month" )
+ return Month;
+ else if( string == "Auto" )
+ return Auto;
+
+ return Auto;
+}
+
+
+QString KDGanttView::yearFormatToString( YearFormat format )
+{
+ switch( format ) {
+ case FourDigit:
+ return "FourDigit";
+ case TwoDigit:
+ return "TwoDigit";
+ case TwoDigitApostrophe:
+ return "TwoDigitApostrophe";
+ case NoDate:
+ return "NoDate";
+ }
+ return "";
+}
+
+
+KDGanttView::YearFormat KDGanttView::stringToYearFormat( const QString& string )
+{
+ if( string == "FourDigit" )
+ return FourDigit;
+ else if( string == "TwoDigit" )
+ return TwoDigit;
+ else if( string == "TwoDigitApostrophe" )
+ return TwoDigitApostrophe;
+ else if( string == "NoDate" )
+ return NoDate;
+ else
+ return FourDigit;
+}
+
+
+QString KDGanttView::hourFormatToString( HourFormat format )
+{
+ switch( format ) {
+ case Hour_12:
+ return "Hour_12";
+ case Hour_24:
+ return "Hour_24";
+ case Hour_24_FourDigit:
+ return "Hour_24_FourDigit";
+ }
+ return "";
+}
+
+
+KDGanttView::HourFormat KDGanttView::stringToHourFormat( const QString& string )
+{
+ if( string == "Hour_12" )
+ return Hour_12;
+ else if( string == "Hour_24" )
+ return Hour_24;
+ else
+ return Hour_24;
+}
+
+
+void KDGanttView::addTaskLinkGroup(KDGanttViewTaskLinkGroup* group)
+{
+
+ if (myTaskLinkGroupList.isEmpty()) {
+ myTaskLinkGroupList.append(group);
+ return;
+ }
+ if (myTaskLinkGroupList.find(group) == -1)
+ myTaskLinkGroupList.append(group);
+}
+
+
+void KDGanttView::removeTaskLinkGroup(KDGanttViewTaskLinkGroup* group)
+{
+ myTaskLinkGroupList.remove(group);
+}
+
+
+/*!
+ This slot is called when a new item has been added to the Gantt
+ view. It will show the item attribute dialog in case the item is
+ editable. \a item is a pointer to the item that has been created.
+*/
+void KDGanttView::editItem( KDGanttViewItem* item)
+{
+ if ( ! item )
+ return;
+ if ( editorEnabled() ) {
+ if ( item->editable() ) {
+ myItemAttributeDialog->reset( item );
+ myItemAttributeDialog->show();
+ }
+ }
+}
+
+
+/*!
+ This method returns the pixmap used for a certain shape, in the
+ selected color and size.
+
+ \param shape the shape to generate
+ \param shapeColor the foreground color of the shape
+ \param backgroundColor the background color of the shape
+ \param itemSize the size of the shape
+ \return the generated shape pixmap
+*/
+QPixmap KDGanttView::getPixmap( KDGanttViewItem::Shape shape,
+ const QColor& shapeColor,
+ const QColor& backgroundColor, int itemSize)
+{
+ // 10 is a good value as size
+ int size = itemSize+2;
+ int hei = ( itemSize/3 ) / 2;
+ QPixmap p = QPixmap( size+4, size+4 );
+ p.fill( backgroundColor );
+ QPainter paint (&p);
+ QBrush b = QBrush ( Qt::SolidPattern );
+ b.setColor( shapeColor );
+ paint.setBrush( b );
+ QPen pen( Qt::black, 1 ) ;
+ paint.setPen( pen );
+ switch (shape) {
+ case KDGanttViewItem::TriangleDown:{
+ QPointArray arr = QPointArray(3);
+ arr.setPoint(0,-size/2,-hei);
+ arr.setPoint(1,size/2,-hei);
+ arr.setPoint(2,0,((size/2)-hei));
+ arr.translate( ( size/2 ) +2 , ( size/2 ) +2);
+ paint.drawPolygon( arr );
+ break;
+ }
+ case KDGanttViewItem::TriangleUp :{
+ QPointArray arr = QPointArray(3);
+ arr.setPoint(0,-size/2,hei);
+ arr.setPoint(1,size/2,hei);
+ arr.setPoint(2,0,(-size/2)+hei);
+ arr.translate( ( size/2 ) +2 , ( size/2 ) +2);
+ paint.drawPolygon( arr );
+ break;
+ }
+ case KDGanttViewItem::Diamond :{
+ QPointArray arr = QPointArray(4);
+ arr.setPoint(0,0,-size/2);
+ arr.setPoint(1,size/2,0);
+ arr.setPoint(2,0,size/2);
+ arr.setPoint(3,-size/2,0);
+ arr.translate( ( size/2 ) +2 , ( size/2 ) +2);
+ paint.drawPolygon( arr );
+ break;
+ }
+ case KDGanttViewItem::Square :{
+ QPointArray arr = QPointArray(4);
+ arr.setPoint(0,-size/2,-size/2);
+ arr.setPoint(1,size/2,-size/2);
+ arr.setPoint(2,size/2,size/2);
+ arr.setPoint(3,-size/2,size/2);
+ arr.translate( ( size/2 ) +2 , ( size/2 ) +2);
+ paint.drawPolygon( arr );
+ break;
+ }
+ case KDGanttViewItem::Circle :{
+ paint.drawEllipse( 2, 2, size, size);
+ break;
+ }
+ }
+ paint.end();
+ return p;
+}
+
+int KDGanttView::getIndex( KDGanttViewItem::Type type) const
+{
+ int index = -1;
+ switch (type) {
+ case (KDGanttViewItem::Event):
+ index = 0;
+ break;
+ case (KDGanttViewItem::Task):
+ index = 1;
+ break;
+ case (KDGanttViewItem::Summary):
+ index = 2;
+ break;
+ }
+ return index;
+}
+
+
+void KDGanttView::initDefaults()
+{
+ int i;
+ // We have 3 item types. Set all undefined to true.
+ for (i = 0;i<3;++i) {
+ undefinedShape[i] = true;
+ undefinedColor[i] = true;
+ undefinedColorHL[i] = true;
+ }
+ // setting the default colors
+ myDefaultColor [ getIndex( KDGanttViewItem::Event ) ] = Qt::blue; //event
+ myDefaultColorHL [ getIndex( KDGanttViewItem::Event ) ] = Qt::red;
+ myDefaultColor [ getIndex( KDGanttViewItem::Task ) ] = Qt::green;//task
+ myDefaultColorHL [ getIndex( KDGanttViewItem::Task ) ] = Qt::red;
+ myDefaultColor [ getIndex( KDGanttViewItem::Summary ) ] = Qt::cyan;//summary
+ myDefaultColorHL [ getIndex( KDGanttViewItem::Summary ) ] = Qt::red;
+
+ // setting the default shape types
+ // currently, we take for each item for all three shapes (start, middle, end) the same default shape
+ for (i = 0;i<3;++i) {
+ myDefaultShape [3*getIndex( KDGanttViewItem::Event )+ i] = KDGanttViewItem::Diamond; //event
+ myDefaultShape [3*getIndex( KDGanttViewItem::Task ) +i] = KDGanttViewItem::Square; //task
+ myDefaultShape [3*getIndex( KDGanttViewItem::Summary ) +i] = KDGanttViewItem::TriangleDown; //summary
+
+ }
+}
+
+
+
+/*!
+ Calls to this method are passed through to the underlying \a QListView.
+*/
+int KDGanttView::addColumn( const QString& label, int width )
+{
+ return myListView->addColumn( label, width );
+}
+
+
+/*!
+ Calls to this method are passed through to the underlying \a QListView.
+*/
+
+int KDGanttView::addColumn( const QIconSet& iconset, const QString& label,
+ int width )
+{
+ return myListView->addColumn( iconset, label, width );
+}
+
+
+/*!
+ Calls to this method are passed through to the underlying \a QListView.
+*/
+void KDGanttView::removeColumn( int index )
+{
+ myListView->removeColumn( index );
+}
+
+
+/*!
+ Calls to this method are passed through to the underlying \a QListView.
+*/
+KDGanttViewItem* KDGanttView::selectedItem() const
+{
+ return static_cast<KDGanttViewItem*>( myListView->selectedItem() );
+}
+
+
+/*!
+ Calls to this method are passed through to the underlying \a QListView.
+*/
+void KDGanttView::setSelected( KDGanttViewItem* item, bool selected )
+{
+ myListView->setSelected( item, selected );
+}
+
+
+/*!
+ Returns the pointer to the Gantt item with the name \a name.
+ If no item is found, the return value is 0.
+ If there is more than one item with the same name in the Gantt view,
+ the first item found will be returned. This may not necessarily be
+ the first item in the listview.
+
+ \param name the name of the Gantt item
+ \return the pointer to the item with name \a name. O, if there is no item
+ in the Gantt view with this name.
+
+*/
+KDGanttViewItem* KDGanttView::getItemByName( const QString& name ) const
+{
+ KDGanttViewItem* temp = firstChild(),* ret;
+ while (temp != 0) {
+ if ( (ret = temp->getChildByName( name ) ) )
+ return ret;
+ temp = temp->nextSibling();
+ }
+ return 0;
+}
+
+
+/*!
+ Returns the pointer to the Gantt item at the position \a pos in the
+ list view.
+ The position \a pos is a global position.
+ If no item is found, 0 is returned.
+
+ \param pos the (global) position of the Gantt item
+ \return the pointer to the item with position \a pos. O, if there is
+ no item in the list view at this position.
+
+*/
+KDGanttViewItem* KDGanttView::getItemByListViewPos( const QPoint& pos ) const
+{
+ return static_cast<KDGanttViewItem*>( myListView->itemAt(myListView->mapFromGlobal(pos) ));
+}
+
+
+/*!
+ Returns the pointer to the Gantt item at the position \a pos in the
+ Gantt view.
+ The position \a pos is a global position.
+ If no items are found, or the item is disabled, 0 is returned.
+ If there is more than one item with the same position in the Gantt view,
+ the first item found will be returned. This is not necessarily the
+ first item in the listview.
+
+ \param pos the (global) position of the Gantt item
+ \return the pointer to the item with position \a pos. O, if there is no item
+ in the Gantt view at this position.
+
+*/
+KDGanttViewItem* KDGanttView::getItemByGanttViewPos( const QPoint& pos ) const
+{
+ KDGanttViewItem* item;
+ QPoint local = myCanvasView->mapFromGlobal(pos);
+
+ QCanvasItemList il = myTimeTable->collisions( myCanvasView->viewportToContents( local ));
+ QCanvasItemList::Iterator it;
+ for ( it = il.begin(); it != il.end(); ++it ) {
+ if ( myCanvasView->getType(*it) == Type_is_KDGanttViewItem) {
+ item = myCanvasView->getItem(*it);
+ if ( item->enabled() )
+ return item;
+ }
+ }
+ return 0;
+}
+
+
+/*!
+ Returns the pointer to the Gantt item at the position \a pos in the
+ list view part of the Gantt view.
+ The position \a pos is a global position if parameter \a global is true.
+ If the vertical part (y coordinate) of \a pos
+ (mapped to local coordinates) is less than 0 or
+ larger than the height of the listview, 0 is returned.
+ The horizontal part (x coordinate) of \a pos is ignored.
+ \param pos the position of the Gantt item
+ \param global if true, pos is assumed to be global
+ \return the pointer to the item with position \a pos. O, if there is no item
+ in the Gantt view at this position.
+
+*/
+KDGanttViewItem* KDGanttView::getItemAt( const QPoint& pos, bool global ) const
+{
+ /* buggy code - commented out
+ QPoint myPos;
+ if ( global )
+ myPos = myListView->contentsToViewport( myListView->mapFromGlobal(pos) );
+ else
+ myPos = myListView->contentsToViewport( pos );
+ return (KDGanttViewItem*) myListView->itemAt( myPos );
+ */
+
+ KDGanttViewItem* item;
+ KDGanttViewItem* retItem = 0;
+ int y;
+ if ( global )
+ y = myCanvasView->mapFromGlobal(pos).y();
+ else
+ y = pos.y();
+ item = firstChild();
+ while ( item != 0 ) {
+ int yc = item->itemPos();
+ if ( yc <= y && y < yc + item->height()) {
+ retItem = item;
+ break;
+ }
+ item = item->itemBelow();
+ }
+ return retItem;
+
+}
+
+
+void KDGanttView::addTickRight()
+{
+ if ( !mFixedHorizon && _enableAdding && myCanvasView->horizontalScrollBar()->value() == myCanvasView->horizontalScrollBar()->maxValue()) {
+ //myCanvasView->horizontalScrollBar()->blockSignals( true );
+ myTimeHeader->addTickRight();
+ //myCanvasView->horizontalScrollBar()->blockSignals( false );
+ myCanvasView->updateHorScrollBar();
+ setTimelineToEnd();
+ }
+}
+
+
+void KDGanttView::addTickLeft()
+{
+ if ( !mFixedHorizon && _enableAdding && myCanvasView->horizontalScrollBar()->value() == 0 ) {
+ myCanvasView->horizontalScrollBar()->blockSignals( true );
+ myTimeHeader->addTickLeft();
+ myCanvasView->horizontalScrollBar()->blockSignals( false );
+ setTimelineToStart();
+ }
+}
+
+
+void KDGanttView::enableAdding( int val )
+{
+ _enableAdding = ( val == 0 || val == myCanvasView->horizontalScrollBar()->maxValue());
+}
+
+
+/*!
+ Returns the number of items in the Gantt view.
+
+ \return the number of items in the Gantt view.
+*/
+int KDGanttView::childCount() const
+{
+ return myListView->childCount();
+}
+
+
+/*!
+ Removes all items from the Gantt view.
+*/
+void KDGanttView::clear()
+{
+ bool block = myTimeTable->blockUpdating();
+ myTimeTable->setBlockUpdating( true );
+ myListView->clear();
+ myTimeTable->setBlockUpdating( false );
+ myTimeTable->updateMyContent();
+ myTimeTable->setBlockUpdating( block );
+}
+
+
+/*!
+ Passes on the signal from the list view.
+*/
+void KDGanttView::slot_lvDropped(QDropEvent* e, KDGanttViewItem* droppedItem, KDGanttViewItem* itemBelowMouse )
+{
+ emit dropped( e, droppedItem, itemBelowMouse);
+}
+
+/*!
+ Implements a pass-through to the list view.
+*/
+QDragObject * KDGanttView::dragObject ()
+{
+ return myListView->dragObject ();
+}
+
+
+/*!
+ Implements a pass-through to the list view.
+*/
+void KDGanttView::startDrag ()
+{
+ //myListView->pt_startDrag ();
+}
+
+
+/*!
+ This method is overridden for internal purposes.
+*/
+void KDGanttView::setPaletteBackgroundColor( const QColor& col)
+{
+ QWidget::setPaletteBackgroundColor( col );
+ timeHeaderSpacerWidget->setPaletteBackgroundColor( col );
+}
+
+
+/*!
+ Sets the background color of the Gantt view.
+
+ \param c the background color of the Gantt view.
+ \sa gvBackgroundColor()
+*/
+void KDGanttView::setGvBackgroundColor ( const QColor & c )
+{
+ myTimeTable->setBackgroundColor( c );
+}
+
+
+/*!
+ Sets the background color of the time header.
+
+ \param c the background color of the time header.
+ \sa timeHeaderBackgroundColor()
+*/
+void KDGanttView::setTimeHeaderBackgroundColor ( const QColor & c )
+{
+ myTimeHeader->setPaletteBackgroundColor( c );
+ //rightWidget->setPaletteBackgroundColor( c );
+ timeHeaderSpacerWidget->setPaletteBackgroundColor( c );
+}
+
+
+/*!
+ Sets the background color of the legend header.
+
+ \param c the background color of the legend header
+ \sa legendHeaderBackgroundColor()
+*/
+void KDGanttView::setLegendHeaderBackgroundColor ( const QColor & c )
+{
+ myLegend->setPaletteBackgroundColor( c );
+ leftWidget->setPaletteBackgroundColor( c );
+}
+
+
+/*!
+ Sets the background color of the list view.
+
+ \param c the background color of the list view
+ \sa lvBackgroundColor()
+*/
+void KDGanttView::setLvBackgroundColor ( const QColor & c )
+{
+ myListView->viewport()->setPaletteBackgroundColor( c );
+}
+
+
+/*!
+ Returns the background color of the list view.
+
+ \return the background color of the list view
+ \sa setLvBackgroundColor()
+*/
+QColor KDGanttView::lvBackgroundColor ( )const
+{
+ return myListView->viewport()->paletteBackgroundColor( );
+}
+
+
+/*!
+ Returns the background color of the Gantt view.
+
+ \return the background color of the Gantt view
+ \sa setGvBackgroundColor()
+*/
+QColor KDGanttView::gvBackgroundColor () const
+{
+ return myTimeTable->backgroundColor( );
+}
+
+
+/*!
+ Returns the background color of the time header.
+
+ \return the background color of the time header
+ \sa setTimeHeaderBackgroundColor()
+*/
+QColor KDGanttView::timeHeaderBackgroundColor () const
+{
+ return myTimeHeader->paletteBackgroundColor( );
+}
+
+
+/*!
+ Returns the background color of the legend header.
+
+ \return the background color of the legend header
+ \sa setLegendHeaderBackgroundColor()
+*/
+QColor KDGanttView::legendHeaderBackgroundColor () const
+{
+ return myLegend->paletteBackgroundColor( );
+}
+
+
+/*!
+ Adds a widget to the spacer widget above the list view part and
+ below the ShowLegendButton. To assign all the space above the
+ Listview to the spacer widget, hide the ShowLegendButton by calling
+ setShowLegendButton( false ). The spacer widget is a QHBox. You
+ may add as many widgets as you want. They are ordered horizontally
+ from left to right. To remove a widget from the spacer widget, call
+ widget->reparent(newParent,...) or delete the widget. Since the spacer
+ is a QHBox, the layout of the added widgets is managed by this
+ QHBox.
+
+ \param w A pointer to the widget to be added.
+ \sa setShowLegendButton( )
+*/
+void KDGanttView::addUserdefinedLegendHeaderWidget( QWidget * w )
+{
+ if ( w ) {
+ w->reparent ( spacerLeft, 0, QPoint(0,0) );
+ }
+}
+
+
+/*!
+ Specifies whether drag operations are allowed in the Gantt
+ view. Recurses over all items contained in the Gantt view and
+ enables or disabled them for dragging.
+
+ \param b true if dragging is enabled, false if dragging is disabled
+ \sa isDragEnabled(), setDropEnabled(), isDropEnabled(), setDragDropEnabled()
+*/
+void KDGanttView::setDragEnabled( bool b )
+{
+ fDragEnabled = b;
+ QListViewItemIterator it( myListView );
+ for ( ; it.current(); ++it ) {
+ (( KDGanttViewItem* )it.current())->setDragEnabled(b);
+ }
+
+}
+
+
+/*!
+ Specifies whether drop operations are allowed in the Gantt
+ view. Recurses over all items contained in the Gantt view and
+ enables or disabled them for dropping.
+
+ \param b true if dragging is enabled, false if dragging is disabled
+ \sa setDropEnabled(), setDragEnabled(), isDragEnabled(), setDragDropEnabled()
+*/
+void KDGanttView::setDropEnabled( bool b )
+{
+ fDropEnabled = b;
+
+ //myListView->setAcceptDrops( b );
+ QListViewItemIterator it( myListView );
+ for ( ; it.current(); ++it ) {
+ (( KDGanttViewItem* )it.current())->setDropEnabled(b);
+ }
+}
+
+
+/*!
+ Combines setDragEnabled() and setDropEnabled() in one convenient
+ method.
+
+ \param b true if dragging and dropping are enabled, false if
+ dragging and dropping are disabled
+ \sa setDragEnabled(), setDropEnabled()
+*/
+void KDGanttView::setDragDropEnabled( bool b )
+{
+ setDropEnabled( b );
+ setDragEnabled( b );
+}
+
+
+/*!
+ Returns whether dragging is enabled for this Gantt view.
+
+ \return true if dragging is enabled
+ \sa setDragEnabled(), setDragDropEnabled()
+*/
+bool KDGanttView::isDragEnabled() const
+{
+ return fDragEnabled;
+}
+
+
+/*!
+ Returns whether dropping is enabled for this Gantt view.
+
+ \return true if dropping is enabled
+ \sa setDropEnabled(), setDragDropEnabled()
+*/
+bool KDGanttView::isDropEnabled() const
+{
+ return fDropEnabled;
+}
+
+
+/*!
+ \deprecated Use isDragEnabled() instead
+*/
+bool KDGanttView::dragEnabled() const
+{
+ return isDragEnabled();
+}
+
+
+/*!
+ \deprecated Use isDropEnabled() instead
+*/
+bool KDGanttView::dropEnabled() const
+{
+ return isDropEnabled();
+}
+
+
+/*!
+ This virtual method makes it possible to specify user-defined drop
+ handling. The method is called directly before the internal drop
+ handling is executed. Return false to execute internal drop
+ handling. Return true to not execute internal drop handling. In
+ order to specify user-defined drop handling, subclass
+ KDGanttView and reimplement this method.
+
+ \param e The QDropEvent
+ Note: e->source() is a pointer to the KDGanttView from which the drag started.
+ I.e., if e->source() == this, this drag is an internal drag.
+ \param droppedItem 0, if this is a drag operation from another
+ KDGanttView instance.
+ If this drag is an internal drag (i.e., within the KDGanttView),
+ this parameter points to the dropped item.
+ \param itemBelowMouse a pointer to the item below the dragged
+ item (i.e., below the mouse).
+ If you accept, the dragged item may be inserted
+ in the KDGanttView as a child of this item.
+ The value is 0 if there is no item below the dragged item,
+ and the dragged item will be inserted as a root item.
+
+ \return false, when the internal drop handling should be executed
+ true, when the internal drop handling should not be executed
+ \sa lvDropEvent(), lvStartDrag()
+*/
+bool KDGanttView::lvDropEvent ( QDropEvent* e,
+ KDGanttViewItem* droppedItem,
+ KDGanttViewItem* itemBelowMouse )
+{
+ Q_UNUSED( e );
+ Q_UNUSED( droppedItem );
+ Q_UNUSED( itemBelowMouse );
+
+ // Example code for user defined behaviour:
+ // we want to accept the usual drags and the drags of files, which may be
+ // a saved Gantt file.
+ // Please uncomment the following lines for this behaviour
+ // You have to uncomment lines in lvDragMoveEvent() and llvDragEnterEvent() as well
+
+ // ************** begin example ************
+ /*
+ if ( QUriDrag::canDecode( e ) ) {
+ QStrList lst;
+ QUriDrag::decode( e, lst );
+ // we try the first file of icon-url-list
+ QString str = lst.at ( 0 );
+ // remove file: at beginning of string
+ str = str.right( str.length() - 5 );
+ QFileInfo info;
+ info.setFile( str ) ;
+ if ( info.isFile() ) {
+ if (!QMessageBox::information( this, "KDGantt Drag&Drop test",
+ "Try to insert file: "+ str + " ?",
+ "&Okay", "&Cancel",0,1 ) ) {
+ QFile file( str );
+ // store current updating status
+ bool uen = myTimeTable->blockUpdating();
+ // block updating while insertion of items
+ myTimeTable->setBlockUpdating();
+ loadProject( &file ) ;
+ // restore updating status and execute an update via setUpdateEnabled( true );
+ if ( !uen )
+ setUpdateEnabled( true );
+ }
+ }
+ return true;
+ }
+ */
+ // *********** end example ****************
+ return false;
+}
+
+
+/*!
+ This virtual method specifies whether a drag enter event may be
+ accepted or not.
+ To accept a drag enter event, call e->accept( true );
+ To not accept a drag enter evente, call e->accept( false );
+ This method does nothing but accepting the drag enter event, in case
+ decoding is possible.
+ In order to define accepting drops for particular items yourself,
+ subclass KDGanttView and reimplement this method.
+
+ \param e The QDragMoveEvent
+ Note: e->source() is a pointer to the KDGanttView, the drag started from.
+ I.e., if e->source() == this, this drag is an internal drag.
+
+ \sa lvDropEvent(), lvStartDrag(), lvDragMoveEvent()
+*/
+void KDGanttView::lvDragEnterEvent ( QDragEnterEvent * e)
+{
+ // the standard behaviour:
+ // accept drag enter events, if KDGanttViewItemDrag can decode the event
+ // e->accept(KDGanttViewItemDrag::canDecode(e) );
+
+ if ( KDGanttViewItemDrag::canDecode(e) ) {
+ e->accept( true);
+ return;
+ }
+
+ // example code for user defined behaviour:
+ // we want to accecpt the usual drags and the drags of files, which may be
+ // a saved Gantt file
+ // Please uncomment the following lines for this behaviour
+ // You have to uncomment lines in lvDragMoveEvent() and lvDropEvent () as well
+
+ // if ( QUriDrag::canDecode( e ) ) {
+ // e->accept(true);
+ // return;
+ // }
+
+ e->accept( false );
+}
+
+
+/*!
+ This virtual method specifies whether a drop event may be accepted or not.
+ To accept a drop event, call e->accept( true );
+ To not accept a drop event, call e->accept( false );
+ This method does nothing but allowing to execute the internal
+ drag move event handling.
+
+ In order to specify user-defined drop acceptance for particular
+ items, subclass KDGanttView and reimplement this method.
+
+ \param e The QDragMoveEvent
+ Note: e->source() is a pointer to the KDGanttView, the drag started from.
+ I.e. if e->source() == this, this drag is an internal drag.
+ draggedItem 0, if this is a drag operation from another KDGanttView instance.
+ If this drag is an internal drag (i.e., within the KDGanttView),
+ this parameter points to the dragged item.
+ itemBelowMouse a pointer to the item below the dragged item
+ (i.e., below the mouse).
+ If you accept the drop, the dragged item will be inserted
+ in the KDGanttView as a child of this item.
+ The value is 0 if there is no item below the dragged item,
+ and the dragged item will be inserted as a root item.
+ \return false, when the internal drag move event handling should be executed
+ true, when the internal drag move event handling should not
+ be executed; usually you should return true,
+ if you have called e->accept( true ) before.
+ \sa lvDropEvent(), lvStartDrag()
+*/
+bool KDGanttView::lvDragMoveEvent ( QDragMoveEvent* /*e*/,
+ KDGanttViewItem* /* draggedItem*/,
+ KDGanttViewItem* /*itemBelowMouse*/)
+{
+
+ // Example code 1:
+ // To generally block items to be inserted as root items, subclass KDGanttView
+ // and reimplement this method with to following code uncommented:
+
+ // if ( !itemBelowMouse ) {
+ // e->accept( false );
+ // return true;
+ //}
+ //return false;
+
+ // Example code 2:
+ // To allow the drags of files, which may be
+ // a saved Gantt file, subclass KDGanttView
+ // and reimplement this method with to following code uncommented:
+
+ // if ( QUriDrag::canDecode( e ) ) {
+ // e->accept(true);
+ // return true;
+ // }
+
+
+ // normal behaviour - the internal drag move event handling should be executed
+ return false;
+}
+
+
+/*!
+ This virtual method creates a QDragObject and starts a drag for a
+ KDGanttViewItem.
+ In order to prevent drags of particular items, subclass from
+ KDGanttView and reimplement this method.
+
+ \param item the KDGanttViewItem, which should be dragged
+ \sa lvDropEvent(), lvDragMoveEvent()
+*/
+void KDGanttView::lvStartDrag (KDGanttViewItem* item)
+{
+ QDragObject* d = new KDGanttViewItemDrag(item, this, "itemdrag" );
+ // call d->drag() to start the dragging
+ // d->drag() returns true, if a move was requested as a drag
+ // if a copy (by pressing the <Ctrl>-key) was performed, d->drag() returns false
+ // In order to avoid starting drags for particular items, subclass KDGanttView
+ // an reimplement this method.
+ // insert here some code like
+ // if ( item->parent() )
+ // return;
+ // This particular code will make it impossible to drag other items but root items.
+ if ( d->drag() ) {
+ delete item;
+ }
+}
+
+
+/*!
+ Sets the width of the list view. Space will be taken from or given
+ to the Gantt view.
+
+ \param w the width of the list view
+ \sa listViewWidth()
+*/
+void KDGanttView::setListViewWidth( int w )
+{
+ int sw = mySplitter->width();
+ QValueList<int> list;
+ list.append(w);
+ list.append(sw-w);
+ mySplitter->setSizes( list );
+}
+
+
+/*!
+ Returns the width of the list view.
+
+ \return the width of the list view
+ \sa setListViewWidth()
+*/
+int KDGanttView::listViewWidth( )
+{
+ return leftWidget->width();
+}
+
+
+/*!
+ Sets the scrollbar mode of the listview. The default is always off.
+ Possible values are always on, always off and auto.
+ It only makes sense to set this to always off
+ if setGvVScrollBarMode() is set to always on.
+
+ \param m the scrollbar mode.
+ \sa setGvVScrollBarMode( )
+*/
+void KDGanttView::setLvVScrollBarMode( QScrollView::ScrollBarMode m )
+{
+ myListView->setVScrollBarMode ( m );
+}
+
+
+/*!
+ Sets the scrollbar mode of the time table. The default is always on.
+ Possible values are always on and always off.
+ It only makes sense to set this to always off
+ if setLvVScrollBarMode() is set to always on or auto.
+
+ \param m The scrollbar mode.
+ \sa setLvVScrollBarMode( )
+*/
+void KDGanttView::setGvVScrollBarMode( QScrollView::ScrollBarMode m )
+{
+ if ( m == QScrollView::Auto )
+ qDebug("KDGanttView::setListViewVScrollBarMode: QScrollView::Auto not supported. Nothing changed. ");
+ else
+ {
+ myCanvasView->setVScrollBarMode ( m );
+ if ( m == QScrollView::AlwaysOn )
+ timeHeaderSpacerWidget->setFixedWidth(myCanvasView->verticalScrollBar()->width() );
+ else
+ timeHeaderSpacerWidget->setFixedWidth( 0 );
+ }
+}
+
+
+void KDGanttView::notifyEditdialog( KDGanttViewItem * item)
+{
+ if (myItemAttributeDialog->getItem() == item ) {
+ myItemAttributeDialog->reset( 0 );
+ }
+}
+
+/*!
+ \fn void KDGanttView::setLinkItemsEnabled( bool on );
+
+ This enables/disables the linking ui of KDGanttViewItems in KDGanttView.
+ A signal linkItems() is emitted when two items shall be linked and can
+ be used to create the actual link.
+*/
+void KDGanttView::setLinkItemsEnabled(bool on)
+{
+ myCanvasView->linkItemsEnabled = on;
+ myCanvasView->autoScrollEnabled = true;
+}
+
+/*!
+ \fn void KDGanttView::isLinkItemsEnabled();
+
+ Returns if the linking functionallity is enabled or disabled.
+*/
+bool KDGanttView::isLinkItemsEnabled() const
+{
+ return myCanvasView->linkItemsEnabled;
+}
+
+/*!
+ \fn void KDGanttView::timeIntervalSelected( const QDateTime& start, const QDateTime& end);
+
+ This signal is emitted when the user selects a time
+ interval with the mouse on the time header connect this signal to
+ the slot void zoomToSelection( const QDateTime& start, const
+ QDateTime& end) to obtain automatic zooming.
+*/
+
+
+/*!
+ \fn void KDGanttView::timeIntervallSelected( const QDateTime& start, const QDateTime& end);
+
+ \deprecated This signal is deprecated, do not use it in new code;
+ use timeIntervalSelected() instead. timeIntervallSelected() will be
+ removed in future versions.
+*/
+
+
+/*!
+ \fn void KDGanttView::rescaling( Scale )
+
+ This signal is emitted if another scale is choosen than the
+ specified one: i.e. if the horizon has a very wide range from
+ start to end and as scale is choosen minute it may be that the
+ size of the Gantt widget would become more than 32000 pixels. In
+ this case the scale is automatically changed to Hour and
+ rescaling( Hour ) is emitted. If the widget size would be still
+ more than 32000 pixels, the scale is automatically changed to day
+ and rescaling( Day ) is emitted. In the new scale, the
+ minortickcount is increased such that the horizon will fit in the
+ maximum size of 32000 pixels.
+*/
+
+
+/*!
+ \fn void KDGanttView::gvCurrentChanged( KDGanttViewItem* item )
+
+ This signal is emitted whenever the user clicks on the Gantt view
+ \a item parameter is 0, if no item was clicked
+*/
+
+
+/*!
+ \fn void KDGanttView::gvItemLeftClicked( KDGanttViewItem* )
+
+ This signal is emitted whenever the user clicks into the Gantt view
+ with the left mouse button.
+*/
+
+
+/*!
+ \fn void KDGanttView::gvItemMidClicked( KDGanttViewItem* )
+
+ This signal is emitted whenever the user clicks into the Gantt view
+ with the middle mouse button.
+*/
+
+/*!
+ \fn void KDGanttView::gvItemRightClicked( KDGanttViewItem* )
+
+ This signal is emitted whenever the user clicks into the Gantt view
+ with the right mouse button.
+*/
+
+/*!
+ \fn void KDGanttView::gvMouseButtonClicked ( int button, KDGanttViewItem* item, const QPoint & pos)
+
+ This signal is emitted when the user clicks into the Gantt view with
+ any mouse button. Notice that \a pos is the absolute mouse position.
+*/
+
+/*!
+ \fn void KDGanttView::gvItemDoubleClicked( KDGanttViewItem* )
+
+ This signal is emitted whenever the user double-clicks into the Gantt view.
+*/
+
+/*!
+ \fn void KDGanttView::gvContextMenuRequested ( KDGanttViewItem * item, const QPoint & pos )
+
+ This signal is emitted when the user requests a context menu in the
+ Gantt view. Notice that \a pos is the absolute mouse position.
+*/
+
+
+/*!
+ \fn void KDGanttView::linkItems ( KDGanttViewItem* from, KDGanttViewItem* to, int linkType )
+
+ This signal is emitted when the user wants to link two items in the Gantt view.
+*/
+
+
+/*!
+ \fn void KDGanttView::lvCurrentChanged( KDGanttViewItem* item )
+
+ This signal is emitted whenever the user clicks on the list view
+ \a item parameter is 0, if no item was clicked
+*/
+
+
+/*!
+ \fn void KDGanttView::lvItemLeftClicked( KDGanttViewItem* )
+
+ This signal is emitted whenever the user clicks into the list view
+ with the left mouse button.
+*/
+
+
+/*!
+ \fn void KDGanttView::lvItemMidClicked( KDGanttViewItem* )
+
+ This signal is emitted whenever the user clicks into the list view
+ with the middle mouse button.
+*/
+
+/*!
+ \fn void KDGanttView::lvItemRightClicked( KDGanttViewItem* )
+
+ This signal is emitted whenever the user clicks into the list view
+ with the right mouse button.
+*/
+
+/*!
+ \fn void KDGanttView::lvMouseButtonPressed ( int button,
+ KDGanttViewItem* item, const QPoint & pos, int col)
+
+ This signal is emitted when the user presses any mouse button in the
+ list view. Notice that \a pos is the absolute mouse position.
+*/
+
+/*!
+ \fn void KDGanttView::lvMouseButtonClicked ( int button,
+ KDGanttViewItem* item, const QPoint & pos, int col)
+
+ This signal is emitted when the user clicks into the
+ list view with any mouse button . Notice that \a pos is the absolute
+ mouse position.
+*/
+
+/*!
+ \fn void KDGanttView::lvItemDoubleClicked( KDGanttViewItem* )
+
+ This signal is emitted whenever the user double-clicks into the list view.
+*/
+
+/*!
+ \fn void KDGanttView::lvItemRenamed( KDGanttViewItem*, int col,
+ const QString& text )
+
+ This signal is emitted whenever the user changes the name of an item
+ in the list view using in-place editing. \a text contains the new
+ text in the list view.
+*/
+
+/*!
+ \fn void KDGanttView::lvContextMenuRequested( KDGanttViewItem *
+ item, const QPoint & pos, int col )
+
+ This signal is emitted when the user requests a context menu in the
+ list view. Notice that \a pos is the absolute mouse position.
+*/
+
+/*!
+ \fn void KDGanttView::lvSelectionChanged( KDGanttViewItem* )
+
+ This signal is emitted whenever the user changes the selection in
+ the list view.
+*/
+
+
+/*!
+ \fn void KDGanttView::dropped ( QDropEvent * e, KDGanttViewItem* droppedItem, KDGanttViewItem* itemBelowMouse)
+
+ This signal is emitted whenever a Gantt item is dropped onto the
+ Gantt view. \a droppedItem is 0, if this is a drag operation from
+ another KDGanttView instance. If this drag is an internal drag
+ (i.e. within the KDGanttView), this parameter points to the dropped item.
+ \a itemBelowMouse is a pointer to the item below the dragged
+ item (i.e., below the mouse). The dragged item may be inserted
+ in the KDGanttView as a child of this item.
+ If The value is 0, if there is no item below the dragged item,
+ and the dragged item will be inserted as a root item.
+
+ In order to get user-defined behavior for drop events, reimplement
+ KDGanttView::lvDropEvent()
+*/
+
+
+/*!
+ \enum KDGanttView::RepaintMode
+
+ Please see setRepaintMode() for a description of the values of this
+ enumeration.
+*/
+
diff --git a/kdgantt/KDGanttView.h b/kdgantt/KDGanttView.h
new file mode 100644
index 00000000..c0c9bbba
--- /dev/null
+++ b/kdgantt/KDGanttView.h
@@ -0,0 +1,502 @@
+/* -*- Mode: C++ -*-
+ $Id$
+ KDChart - a multi-platform charting engine
+*/
+
+/****************************************************************************
+ ** Copyright (C) 2001-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.
+ **
+ **********************************************************************/
+
+#ifndef KDGANTTVIEW_H
+#define KDGANTTVIEW_H
+
+#include <qptrlist.h>
+#include <qwidget.h>
+#include <qlistview.h>
+#include <qsplitter.h>
+#include <qlayout.h>
+#include <qfont.h>
+#include <qdom.h>
+#include <qvbox.h>
+
+
+#include "KDGanttViewItem.h"
+#include "KDGanttViewTaskLinkGroup.h"
+#include "KDGanttMinimizeSplitter.h"
+#include "KDGanttViewItemDrag.h"
+
+class KDIntervalColorRectangle;
+class KDGanttViewTaskLink;
+class QPrinter;
+class QIODevice;
+class itemAttributeDialog;
+class KDListView;
+class KDGanttViewItem;
+class KDGanttViewEventItem;
+class KDGanttViewTaskItem;
+class KDGanttViewSummaryItem;
+class KDTimeTableWidget;
+class KDTimeHeaderWidget;
+class KDLegendWidget;
+class KDGanttCanvasView;
+class KDGanttViewTaskLink;
+class KDGanttMinimizeSplitter;
+
+class KDGanttView : public KDGanttMinimizeSplitter
+{
+ Q_OBJECT
+
+ Q_PROPERTY( bool showLegend READ showLegend WRITE setShowLegend )
+ Q_PROPERTY( bool showListView READ showListView WRITE setShowListView )
+ Q_PROPERTY( bool showTaskLinks READ showTaskLinks WRITE setShowTaskLinks )
+ Q_PROPERTY( bool editorEnabled READ editorEnabled WRITE setEditorEnabled )
+ Q_PROPERTY( QDateTime horizonStart READ horizonStart WRITE setHorizonStart )
+ Q_PROPERTY( QDateTime horizonEnd READ horizonEnd WRITE setHorizonEnd )
+ Q_PROPERTY( Scale scale READ scale WRITE setScale )
+ Q_PROPERTY( YearFormat yearFormat READ yearFormat WRITE setYearFormat )
+ Q_PROPERTY( HourFormat hourFormat READ hourFormat WRITE setHourFormat )
+ Q_PROPERTY( bool showMinorTicks READ showMinorTicks WRITE setShowMinorTicks )
+ Q_PROPERTY( bool showMajorTicks READ showMajorTicks WRITE setShowMajorTicks )
+ Q_PROPERTY( bool editable READ editable WRITE setEditable )
+ Q_PROPERTY( QColor textColor READ textColor WRITE setTextColor )
+ Q_PROPERTY( int majorScaleCount READ majorScaleCount WRITE setMajorScaleCount )
+ Q_PROPERTY( int minorScaleCount READ minorScaleCount WRITE setMinorScaleCount )
+ Q_PROPERTY( int autoScaleMinorTickCount READ autoScaleMinorTickCount WRITE setAutoScaleMinorTickCount )
+ Q_PROPERTY( Scale maximumScale READ maximumScale WRITE setMaximumScale )
+ Q_PROPERTY( Scale minimumScale READ minimumScale WRITE setMinimumScale )
+ Q_PROPERTY( int minimumColumnWidth READ minimumColumnWidth WRITE setMinimumColumnWidth )
+ Q_PROPERTY( int ganttMaximumWidth READ ganttMaximumWidth WRITE setGanttMaximumWidth )
+ Q_PROPERTY( QColor weekendBackgroundColor READ weekendBackgroundColor WRITE setWeekendBackgroundColor )
+ Q_PROPERTY( QColor ganttViewBackgroundColor READ gvBackgroundColor WRITE setGvBackgroundColor )
+ Q_PROPERTY( QColor listViewBackgroundColor READ lvBackgroundColor WRITE setLvBackgroundColor )
+ Q_PROPERTY( QColor timeHeaderBackgroundColor READ timeHeaderBackgroundColor WRITE setTimeHeaderBackgroundColor )
+ Q_PROPERTY( QColor legendHeaderBackgroundColor READ legendHeaderBackgroundColor WRITE setLegendHeaderBackgroundColor )
+ Q_PROPERTY( double zoomFactor READ zoomFactor )
+ Q_PROPERTY( bool showHeaderPopupMenu READ showHeaderPopupMenu WRITE setShowHeaderPopupMenu )
+ Q_PROPERTY( bool showTimeTablePopupMenu READ showTimeTablePopupMenu WRITE setShowTimeTablePopupMenu )
+ Q_PROPERTY( bool headerVisible READ headerVisible WRITE setHeaderVisible )
+ Q_PROPERTY( bool showLegendButton READ showLegendButton WRITE setShowLegendButton )
+ Q_PROPERTY( bool legendIsDockwindow READ legendIsDockwindow WRITE setLegendIsDockwindow )
+ Q_PROPERTY( bool displayEmptyTasksAsLine READ displayEmptyTasksAsLine WRITE setDisplayEmptyTasksAsLine )
+ Q_PROPERTY( QBrush noInformationBrush READ noInformationBrush WRITE setNoInformationBrush )
+ Q_PROPERTY( bool dragEnabled READ dragEnabled WRITE setDragEnabled )
+ Q_PROPERTY( bool dropEnabled READ dropEnabled WRITE setDropEnabled )
+ Q_PROPERTY( bool calendarMode READ calendarMode WRITE setCalendarMode )
+
+ Q_ENUMS( Scale )
+ Q_ENUMS( YearFormat )
+ Q_ENUMS( HourFormat )
+
+public:
+ enum Scale { Minute, Hour, Day, Week, Month, Auto };
+ enum YearFormat { FourDigit, TwoDigit, TwoDigitApostrophe, NoDate };
+ enum HourFormat { Hour_24, Hour_12, Hour_24_FourDigit };
+ enum RepaintMode { No, Medium, Always };
+
+ KDGanttView( QWidget* parent = 0, const char* name = 0 );
+ ~KDGanttView();
+
+ virtual void show();
+ virtual bool close ( bool alsoDelete );
+ void setRepaintMode( RepaintMode mode );
+ void setUpdateEnabled( bool enable);
+ bool getUpdateEnabled( )const;
+
+ void setGanttMaximumWidth( int w );
+ int ganttMaximumWidth() const;
+ void setShowLegend( bool show );
+ bool showLegend() const;
+ void setLegendIsDockwindow( bool dock );
+ bool legendIsDockwindow( ) const;
+ QDockWindow* legendDockwindow( ) const;
+ void setShowListView( bool show );
+ bool showListView() const;
+ void setEditorEnabled( bool enable );
+ bool editorEnabled() const;
+ void setListViewWidth( int );
+ int listViewWidth();
+ void setEditable( bool editable );
+ bool editable() const;
+ void setCalendarMode( bool mode );
+ bool calendarMode() const;
+ void setDisplaySubitemsAsGroup( bool show );
+ bool displaySubitemsAsGroup() const;
+ void setDisplayEmptyTasksAsLine( bool show );
+ bool displayEmptyTasksAsLine() const;
+
+ void setHorBackgroundLines( int count = 2,
+ QBrush brush =
+ QBrush( QColor ( 200,200,200 ),
+ Qt::Dense6Pattern ));
+ int horBackgroundLines( QBrush& brush );
+ bool saveProject( QIODevice* );
+ bool loadProject( QIODevice* );
+ void print( QPrinter* printer = 0 ,
+ bool printListView = true, bool printTimeLine = true,
+ bool printLegend = false );
+ QSize drawContents( QPainter* p = 0,
+ bool drawListView = true, bool drawTimeLine = true,
+ bool drawLegend = false );
+ void setZoomFactor( double factor, bool absolute );
+ double zoomFactor() const;
+ void zoomToFit();
+ void ensureVisible( KDGanttViewItem* );
+ void center( KDGanttViewItem* );
+ void centerTimeline( const QDateTime& center );
+ void centerTimelineAfterShow( const QDateTime& center );
+ void setTimelineToStart();
+ void setTimelineToEnd();
+ void addTicksLeft( int num = 1 );
+ void addTicksRight( int num = 1 );
+ void setShowTaskLinks( bool show );
+ bool showTaskLinks() const;
+
+ void setFont(const QFont& f);
+ void setShowHeaderPopupMenu( bool show = true,
+ bool showZoom = true,
+ bool showScale = true,
+ bool showTime = true,
+ bool showYear = true,
+ bool showGrid = true,
+ bool showPrint = false);
+ bool showHeaderPopupMenu() const;
+ void setShowTimeTablePopupMenu( bool );
+ bool showTimeTablePopupMenu() const;
+ void setShapes( KDGanttViewItem::Type type,
+ KDGanttViewItem::Shape start,
+ KDGanttViewItem::Shape middle,
+ KDGanttViewItem::Shape end,
+ bool overwriteExisting = true );
+ bool shapes( KDGanttViewItem::Type type,
+ KDGanttViewItem::Shape& start,
+ KDGanttViewItem::Shape& middle,
+ KDGanttViewItem::Shape& end ) const;
+ void setColors( KDGanttViewItem::Type type,
+ const QColor& start, const QColor& middle,
+ const QColor& end,
+ bool overwriteExisting = true );
+ bool colors( KDGanttViewItem::Type type,
+ QColor& start, QColor& middle, QColor& end ) const;
+ void setDefaultColor( KDGanttViewItem::Type type,
+ const QColor&,
+ bool overwriteExisting = true );
+ QColor defaultColor( KDGanttViewItem::Type type ) const;
+ void setHighlightColors( KDGanttViewItem::Type type,
+ const QColor& start, const QColor& middle,
+ const QColor& end,
+ bool overwriteExisting = true );
+ bool highlightColors( KDGanttViewItem::Type type,
+ QColor& start, QColor& middle, QColor& end ) const;
+ void setDefaultHighlightColor( KDGanttViewItem::Type type,
+ const QColor&,
+ bool overwriteExisting = true );
+ QColor defaultHighlightColor( KDGanttViewItem::Type type ) const;
+ void setTextColor( const QColor& color );
+ QColor textColor() const;
+
+ void setNoInformationBrush( const QBrush& brush );
+ QBrush noInformationBrush() const;
+
+ // Link-related stuff
+ QPtrList<KDGanttViewTaskLink> taskLinks() const;
+ QPtrList<KDGanttViewTaskLinkGroup> taskLinkGroups() const;
+
+ // Legend-related stuff
+ void addLegendItem( KDGanttViewItem::Shape shape, const QColor& shapeColor, const QString& text );
+ void clearLegend();
+ // Header-related stuff
+ void setHorizonStart( const QDateTime& start );
+ QDateTime horizonStart() const;
+ void setHorizonEnd( const QDateTime& start );
+ QDateTime horizonEnd() const;
+ void setScale( Scale );
+ Scale scale() const;
+ void setMaximumScale( Scale );
+ Scale maximumScale() const;
+ void setMinimumScale( Scale );
+ Scale minimumScale() const;
+ void setAutoScaleMinorTickCount( int count );
+ int autoScaleMinorTickCount() const;
+ void setMajorScaleCount( int count );
+ int majorScaleCount() const;
+ void setMinorScaleCount( int count );
+ int minorScaleCount() const;
+ void setMinimumColumnWidth( int width );
+ int minimumColumnWidth() const;
+ void setYearFormat( YearFormat format );
+ YearFormat yearFormat() const;
+ void setHourFormat( HourFormat format );
+ HourFormat hourFormat() const;
+ void setShowMajorTicks( bool );
+ bool showMajorTicks() const;
+ void setShowMinorTicks( bool );
+ bool showMinorTicks() const;
+ void setColumnBackgroundColor( const QDateTime& column,
+ const QColor& color,
+ Scale mini = KDGanttView::Minute ,
+ Scale maxi = KDGanttView::Month);
+#if 0
+ // This API has been replaced with KDIntervalColorRectangle and addIntervalBackgroundColor
+ void setIntervalBackgroundColor( const QDateTime& start,
+ const QDateTime& end,
+ const QColor& color,
+ Scale mini = KDGanttView::Minute ,
+ Scale maxi = KDGanttView::Month);
+ bool changeBackgroundInterval( const QDateTime& oldstart,
+ const QDateTime& oldend,
+ const QDateTime& newstart,
+ const QDateTime& newend );
+ bool deleteBackgroundInterval( const QDateTime& start,
+ const QDateTime& end );
+#endif
+ void addIntervalBackgroundColor( KDIntervalColorRectangle* newItem );
+ void clearBackgroundColor();
+ QColor columnBackgroundColor( const QDateTime& column ) const;
+ void setWeekendBackgroundColor( const QColor& color );
+ QColor weekendBackgroundColor() const;
+ void setWeekdayBackgroundColor( const QColor& color, int weekday );
+ QColor weekdayBackgroundColor(int weekday) const;
+
+
+ void setPaletteBackgroundColor(const QColor& col);
+ void setGvBackgroundColor ( const QColor & );
+ void setLvBackgroundColor ( const QColor & );
+ void setTimeHeaderBackgroundColor ( const QColor & );
+ void setLegendHeaderBackgroundColor ( const QColor & );
+ QColor gvBackgroundColor () const ;
+ QColor lvBackgroundColor () const ;
+ QColor timeHeaderBackgroundColor () const ;
+ QColor legendHeaderBackgroundColor () const ;
+ void addUserdefinedLegendHeaderWidget( QWidget * w );
+
+ void setWeekendDays( int start, int end );
+ void weekendDays( int& start, int& end ) const;
+
+ static QPixmap getPixmap( KDGanttViewItem::Shape shape, const QColor& shapeColor,const QColor& backgroundColor, int itemSize);
+
+ void setHeaderVisible( bool );
+ bool headerVisible() const;
+
+ void setShowLegendButton( bool show );
+ bool showLegendButton() const;
+
+ // Pass-through methods from QListView
+ virtual int addColumn( const QString& label, int width = -1 );
+ virtual int addColumn( const QIconSet& iconset, const QString& label,
+ int width = -1 );
+ virtual void removeColumn( int index );
+ KDGanttViewItem* selectedItem() const;
+ void setSelected( KDGanttViewItem*, bool );
+ KDGanttViewItem* firstChild() const;
+ KDGanttViewItem* lastItem() const;
+ int childCount() const;
+ void clear();
+
+ void setDragEnabled( bool b );
+ void setDropEnabled( bool b );
+ void setDragDropEnabled( bool b );
+ bool dragEnabled() const;
+ bool dropEnabled() const;
+ bool isDragEnabled() const;
+ bool isDropEnabled() const;
+
+ virtual bool lvDropEvent ( QDropEvent *e, KDGanttViewItem*, KDGanttViewItem*);
+ virtual void lvStartDrag (KDGanttViewItem*);
+ virtual bool lvDragMoveEvent (QDragMoveEvent * e,KDGanttViewItem*, KDGanttViewItem*);
+ virtual void lvDragEnterEvent (QDragEnterEvent * e );
+ virtual QSize sizeHint() const;
+ KDGanttViewItem* getItemByName( const QString& name ) const;
+ QDateTime getDateTimeForCoordX(int coordX, bool global = true ) const;
+ KDGanttViewItem* getItemByListViewPos( const QPoint& pos ) const;
+ KDGanttViewItem* getItemByGanttViewPos( const QPoint& pos ) const;
+ KDGanttViewItem* getItemAt( const QPoint& pos , bool global = true ) const;
+
+ // setting the vertical scrollbars of the listview and the timetable
+ // default values: always off for the listview, always on for the timetable
+ void setLvVScrollBarMode( QScrollView::ScrollBarMode );
+ void setGvVScrollBarMode( QScrollView::ScrollBarMode );
+
+ void setLinkItemsEnabled(bool on);
+ bool isLinkItemsEnabled() const;
+
+ KDTimeTableWidget * timeTableWidget() { return myTimeTable; }
+ KDTimeHeaderWidget * timeHeaderWidget() { return myTimeHeader; }
+
+ void setFixedHorizon( bool f ) { mFixedHorizon = f; }
+
+public slots:
+ void editItem( KDGanttViewItem* );
+ void zoomToSelection( const QDateTime& start, const QDateTime& end);
+
+signals:
+ void timeIntervallSelected( const QDateTime& start, const QDateTime& end);
+ void timeIntervalSelected( const QDateTime& start, const QDateTime& end);
+ void rescaling( KDGanttView::Scale );
+ void intervalColorRectangleMoved( const QDateTime& start, const QDateTime& end );
+
+ // the following signals are emitted if an item is clicked in the
+ // listview (inclusive) or in the ganttview
+ void itemLeftClicked( KDGanttViewItem* );
+ void itemMidClicked( KDGanttViewItem* );
+ void itemRightClicked( KDGanttViewItem* );
+ void itemDoubleClicked( KDGanttViewItem* );
+
+ // The following signal is emitted when two items shall be linked
+ void linkItems( KDGanttViewItem* from, KDGanttViewItem* to, int linkType );
+
+ // the following signals are emitted if an item is clicked in the
+ // listview (exlusive) or in the ganttview
+ // gv... means item in ganttview clicked
+
+ void gvCurrentChanged( KDGanttViewItem* );
+ void gvItemLeftClicked( KDGanttViewItem* );
+ void gvItemMidClicked( KDGanttViewItem* );
+ void gvItemRightClicked( KDGanttViewItem* );
+ // the point is the global position!!
+ void gvMouseButtonClicked ( int button, KDGanttViewItem* item, const QPoint & pos);
+ void gvItemDoubleClicked( KDGanttViewItem* );
+ // the point is the global position!!
+ void gvContextMenuRequested ( KDGanttViewItem * item, const QPoint & pos );
+ void gvItemMoved( KDGanttViewItem* );
+
+ // lv... means item in listview clicked
+ void lvCurrentChanged( KDGanttViewItem* );
+ void lvItemRenamed( KDGanttViewItem* , int col, const QString & text );
+ void lvMouseButtonPressed( int button, KDGanttViewItem * item, const QPoint & pos, int c );
+ void lvItemLeftClicked( KDGanttViewItem* );
+ void lvItemMidClicked( KDGanttViewItem* );
+ void lvItemRightClicked( KDGanttViewItem* );
+ void lvContextMenuRequested ( KDGanttViewItem * item, const QPoint & pos, int col );
+ void lvMouseButtonClicked ( int button, KDGanttViewItem* item, const QPoint & pos, int c );
+ void lvItemDoubleClicked( KDGanttViewItem* );
+ void lvSelectionChanged( KDGanttViewItem* );
+
+ void itemConfigured( KDGanttViewItem* );
+
+ void taskLinkLeftClicked( KDGanttViewTaskLink* );
+ void taskLinkMidClicked( KDGanttViewTaskLink* );
+ void taskLinkRightClicked( KDGanttViewTaskLink* );
+ void taskLinkDoubleClicked( KDGanttViewTaskLink* );
+
+ void dateTimeDoubleClicked (const QDateTime& );
+
+ void dropped ( QDropEvent * e, KDGanttViewItem* droppedItem, KDGanttViewItem* itemBelowMouse);
+private slots:
+ void forceRepaint( int val = 0 );
+ void slotSelectionChanged( QListViewItem* item );
+ void slotCurrentChanged ( QListViewItem * item );
+ void slotItemRenamed ( QListViewItem * item, int col, const QString & text );
+ void slotMouseButtonPressed ( int button, QListViewItem * item, const QPoint & pos, int c );
+ void slotmouseButtonClicked ( int button, QListViewItem * item, const QPoint & pos, int c );
+ void slotcontextMenuRequested ( QListViewItem * item, const QPoint & pos, int col );
+ void slotHeaderSizeChanged();
+ void addTickRight();
+ void addTickLeft();
+ void enableAdding( int );
+ void slot_lvDropped(QDropEvent* e, KDGanttViewItem* droppedItem, KDGanttViewItem* itemBelowMouse );
+private:
+ struct legendItem {
+ KDGanttViewItem::Shape shape;
+ QColor color;
+ QString text;
+ };
+ bool loadXML( const QDomDocument& doc );
+ QDomDocument saveXML( bool withPI = true ) const;
+
+ void emptySpaceDoubleClicked( QMouseEvent* e );
+
+ static QString scaleToString( Scale scale );
+ static QString yearFormatToString( YearFormat format );
+ static QString hourFormatToString( HourFormat format );
+ static Scale stringToScale( const QString& string );
+ static YearFormat stringToYearFormat( const QString& string );
+ static HourFormat stringToHourFormat( const QString& string );
+
+ // PENDING(lutz) Review these
+ friend class KDGanttCanvasView;
+ friend class KDGanttViewEventItem;
+ friend class KDGanttViewItem;
+ friend class KDGanttViewTaskItem;
+ friend class KDGanttViewSummaryItem;
+ friend class KDGanttViewTaskLink;
+ friend class KDGanttViewCalendarItem;
+ friend class KDTimeTableWidget;
+ friend class KDTimeHeaderWidget;
+ friend class KDListView;
+ friend class KDGanttViewTaskLinkGroup;
+ friend class KDLegendWidget;
+
+ KDListView * myListView;
+ KDGanttCanvasView *myCanvasView;
+ KDTimeHeaderWidget * myTimeHeader;
+ KDTimeTableWidget * myTimeTable;
+ KDLegendWidget * myLegend;
+ itemAttributeDialog* myItemAttributeDialog;
+ QVBox * leftWidget, * rightWidget;
+ QHBox * spacerLeft;
+ QScrollView* myTimeHeaderScroll;
+ QHBox* myTimeHeaderContainer ;
+ QWidget* timeHeaderSpacerWidget;
+ QWidget *spacerRight;
+
+ bool listViewIsVisible;
+ bool chartIsEditable;
+ bool editorIsEnabled;
+ bool _displaySubitemsAsGroup;
+ bool _displayEmptyTasksAsLine;
+ bool _showLegendButton;
+ bool _showHeader;
+ bool _enableAdding;
+ bool fCenterTimeLineAfterShow;
+ bool fDragEnabled;
+ bool fDropEnabled;
+ bool closingBlocked;
+ QDateTime dtCenterTimeLineAfterShow;
+ KDGanttViewItem::Shape myDefaultShape [9];
+ QColor myColor[9],myColorHL[9];
+ bool undefinedShape[3],undefinedColor[3],undefinedColorHL[3];
+ QColor myTextColor;
+ QColor myDefaultColor[3],myDefaultColorHL[3];
+ QPtrList<KDGanttViewTaskLinkGroup> myTaskLinkGroupList;
+ QPtrList<legendItem> *myLegendItems;
+ void addTaskLinkGroup(KDGanttViewTaskLinkGroup*);
+ void removeTaskLinkGroup(KDGanttViewTaskLinkGroup*);
+ int getIndex( KDGanttViewItem::Type ) const;
+ void notifyEditdialog( KDGanttViewItem * );
+ void initDefaults();
+ KDGanttViewItem* myCurrentItem;
+ KDGanttMinimizeSplitter *mySplitter;
+ bool mFixedHorizon;
+protected:
+ virtual QDragObject * dragObject ();
+ virtual void startDrag ();
+};
+
+
+
+#endif
diff --git a/kdgantt/KDGanttViewEventItem.cpp b/kdgantt/KDGanttViewEventItem.cpp
new file mode 100644
index 00000000..aa6e707d
--- /dev/null
+++ b/kdgantt/KDGanttViewEventItem.cpp
@@ -0,0 +1,306 @@
+/* -*- 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 "KDGanttViewEventItem.h"
+#include "KDGanttViewSubwidgets.h"
+#include "itemAttributeDialog.h"
+
+/*!
+ \class KDGanttViewEventItem KDGanttViewEventItem.h
+ An event item in a Gantt chart.
+
+ This class represents event items in Gantt charts.
+*/
+
+/*!
+ Constructs an empty Gantt item of type event.
+
+ \param view the Gantt view to insert this item into
+ \param lvtext the text to show in the list view
+ \param name the name by which the item can be identified. If no name
+ is specified, a unique name will be generated
+*/
+KDGanttViewEventItem::KDGanttViewEventItem( KDGanttView* view,
+ const QString& lvtext,
+ const QString& name ) :
+ KDGanttViewItem( Event, view, lvtext, name )
+{
+ initItem();
+}
+
+
+/*!
+ Constructs an empty Gantt item of type event.
+
+ \param parent a parent item under which this one goes
+ \param lvtext the text to show in the list view
+ \param name the name by which the item can be identified. If no name
+ is specified, a unique name will be generated
+*/
+KDGanttViewEventItem::KDGanttViewEventItem( KDGanttViewItem* parent,
+ const QString& lvtext,
+ const QString& name ) :
+ KDGanttViewItem( Event, parent, lvtext, name )
+{
+ initItem();
+
+}
+
+
+/*!
+ Constructs an empty Gantt item of type event.
+
+ \param view the Gantt view to insert this item into
+ \param after another item at the same level behind which this one should go
+ \param lvtext the text to show in the list view
+ \param name the name by which the item can be identified. If no name
+ is specified, a unique name will be generated
+*/
+KDGanttViewEventItem::KDGanttViewEventItem( KDGanttView* view,
+ KDGanttViewItem* after,
+ const QString& lvtext,
+ const QString& name ) :
+ KDGanttViewItem( Event, view, after, lvtext, name )
+{
+
+ initItem();
+}
+
+
+/*!
+ Constructs an empty Gantt item of type event.
+
+ \param parent a parent item under which this one goes
+ \param after another item at the same level behind which this one should go
+ \param lvtext the text to show in the list view
+ \param name the name by which the item can be identified. If no name
+ is specified, a unique name will be generated
+*/
+KDGanttViewEventItem::KDGanttViewEventItem( KDGanttViewItem* parent,
+ KDGanttViewItem* after,
+ const QString& lvtext,
+ const QString& name ) :
+ KDGanttViewItem( Event, parent, after, lvtext, name )
+{
+
+ initItem();
+}
+
+
+/*!
+ The destructor. Nothing done here.
+*/
+KDGanttViewEventItem::~KDGanttViewEventItem()
+{
+
+
+}
+/*!
+ Specifies the start time of this item. The parameter must be valid
+ and non-null. If the parameter is invalid or null, no value is set.
+ If the start time is less than the lead time,
+ the lead time is set to this start time automatically.
+
+ \param start the start time
+ \sa startTime()
+*/
+void KDGanttViewEventItem::setStartTime( const QDateTime& start )
+{
+ if (! start.isValid() ) {
+ qDebug("KDGanttViewEventItem::setStartTime():Invalid parameter-no time set");
+ return;
+ }
+ myStartTime = start;
+ myEndTime = start;
+ if ( myStartTime < leadTime() )
+ setLeadTime( myStartTime );
+ else {
+ updateCanvasItems();
+ }
+
+}
+
+
+/*!
+ Specifies whether the event item should be shown with a lead time
+ line, and if yes, when the lead time starts.
+ If the start time is less than the lead time,
+ the start time is set to this lead time automatically.
+
+ \param leadTimeStart the start time of the lead time; pass an
+ invalid QDateTime object in order to turn the lead time off.
+ \sa leadTime()
+*/
+
+void KDGanttViewEventItem::setLeadTime( const QDateTime& leadTimeStart )
+{
+ if (!myLeadTime) myLeadTime = new QDateTime;
+ *myLeadTime = leadTimeStart;
+ if ( startTime() < leadTime() )
+ setStartTime( leadTimeStart );
+ else {
+ updateCanvasItems();
+ }
+
+}
+
+
+/*!
+ Returns whether the event item is shown with a lead time line and if
+ yes, when the lead time starts.
+
+ \return if the event item is shown with a lead time line, returns
+ the QDateTime object representing the start of the lead time,
+ otherwise returns an invalid QDateTime object
+ \sa setLeadTime()
+*/
+QDateTime KDGanttViewEventItem::leadTime() const
+{
+ if(myLeadTime)
+ return *myLeadTime;
+ return myStartTime;
+}
+
+
+void KDGanttViewEventItem::hideMe()
+{
+ startShape->hide();
+ startShapeBack->hide();
+ startLine->hide();
+ startLineBack->hide();
+ textCanvas->hide();
+ floatStartShape->hide();
+ floatEndShape->hide();
+}
+
+
+void KDGanttViewEventItem::showItem(bool show, int coordY)
+{
+ isVisibleInGanttView = show;
+ invalidateHeight () ;
+ if (!show) {
+ hideMe();
+ return;
+ }
+ float prio = ((float) ( priority() - 100 )) / 100.0;
+ startShape->setZ( prio + 0.0055 );
+ startShapeBack->setZ( prio + 0.003 );
+ startLine->setZ( prio + 0.0015 );
+ floatStartShape->setZ(prio + 0.004);
+ floatStartShape->hide();
+ floatEndShape->setZ(prio + 0.004);
+ floatEndShape->hide();
+ textCanvas->setZ( prio + 0.006 );
+ startLineBack->setZ( prio );
+
+ if ( displaySubitemsAsGroup() && firstChild() ) {
+ myStartTime = myChildStartTime();
+ myEndTime = myChildEndTime();
+ }
+ int startX, endX, allY;
+ if ( coordY )
+ allY = coordY;
+ else
+ allY = getCoordY();
+ startX = myGanttView->myTimeHeader->getCoordX(myStartTime);
+ if (myLeadTime) {
+ endX = myGanttView->myTimeHeader->getCoordX(*myLeadTime);
+ startLine->setPoints(startX,allY,endX,allY);
+ startLine->show();
+ startLineBack->setPoints(startX+1,allY,endX-1,allY);
+ startLineBack->show();
+ }
+ else {
+ startLine->hide();
+ startLineBack->hide();
+ }
+ startShape->move(startX,allY);
+ startShape->show();
+ startShapeBack->move(startX,allY);
+ startShapeBack->show();
+ if (myFloatStartTime.isValid()) {
+ KDCanvasRectangle* floatStartTemp = (KDCanvasRectangle*) floatStartShape;
+ int floatStartX = myGanttView->myTimeHeader->getCoordX(myFloatStartTime);
+ int hei = startShape->boundingRect().height();
+ // FIXME: Configurable colors
+ QBrush b(startShape->brush().color(), Dense4Pattern);
+ floatStartTemp->setBrush(b);
+ floatStartTemp->setPen(QPen(gray));
+ if (floatStartX < startX) {
+ floatStartTemp->setSize(startX - floatStartX, hei/2);
+ floatStartTemp->move(floatStartX, allY-hei/4);
+ } else {
+ floatStartTemp->setSize(floatStartX - startX, hei/2);
+ floatStartTemp->move(startX, allY-hei/4);
+ }
+ floatStartShape->show();
+ }
+ if (myFloatEndTime.isValid()) {
+ KDCanvasRectangle* floatEndTemp = (KDCanvasRectangle*) floatEndShape;
+ int floatEndX = myGanttView->myTimeHeader->getCoordX(myFloatEndTime);
+ int hei = startShape->boundingRect().height();
+ // FIXME: Configurable colors
+ QBrush b(startShape->brush().color(), Dense4Pattern);
+ floatEndTemp->setBrush(b);
+ floatEndTemp->setPen(QPen(gray));
+ if (floatEndX > startX) {
+ floatEndTemp->setSize(floatEndX - startX, hei/2);
+ floatEndTemp->move(startX, allY-hei/4);
+ } else {
+ floatEndTemp->setSize(startX - floatEndX, hei/2);
+ floatEndTemp->move(floatEndX, allY-hei/4);
+ }
+ floatEndShape->show();
+ }
+
+ moveTextCanvas(startX,allY);
+ textCanvas->show();
+ if (textCanvas->text().isEmpty())
+ textCanvas->hide();
+}
+
+
+void KDGanttViewEventItem::initItem()
+{
+ isVisibleInGanttView = false;
+ myLeadTime = 0;
+ showItem(true);
+ myGanttView->myTimeTable->updateMyContent();
+ setDragEnabled( myGanttView->dragEnabled() );
+ setDropEnabled( myGanttView->dropEnabled() );
+}
+
+
+
diff --git a/kdgantt/KDGanttViewEventItem.h b/kdgantt/KDGanttViewEventItem.h
new file mode 100644
index 00000000..5cd029ee
--- /dev/null
+++ b/kdgantt/KDGanttViewEventItem.h
@@ -0,0 +1,68 @@
+/* -*- Mode: C++ -*-
+ $Id$
+ KDGantt - a multi-platform charting engine
+*/
+
+/****************************************************************************
+ ** Copyright (C) 2001-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.
+ **
+ **********************************************************************/
+
+#ifndef KDGANTTVIEWEVENTITEM_H
+#define KDGANTTVIEWEVENTITEM_H
+
+#include "KDGanttViewItem.h"
+
+class KDGanttViewEventItem : public KDGanttViewItem
+{
+public:
+ KDGanttViewEventItem( KDGanttView* view,
+ const QString& lvtext = QString::null,
+ const QString& name = QString::null );
+ KDGanttViewEventItem( KDGanttViewItem* parent,
+ const QString& lvtext = QString::null,
+ const QString& name = QString::null );
+ KDGanttViewEventItem( KDGanttView* view, KDGanttViewItem* after,
+ const QString& lvtext = QString::null,
+ const QString& name = QString::null );
+ KDGanttViewEventItem( KDGanttViewItem* parent, KDGanttViewItem* after,
+ const QString& lvtext = QString::null,
+ const QString& name = QString::null );
+ virtual ~KDGanttViewEventItem();
+
+ void setLeadTime( const QDateTime& leadTimeStart );
+ void setStartTime( const QDateTime& start );
+ QDateTime leadTime() const;
+
+private:
+ void showItem( bool show = true, int coordY = 0 );
+ QDateTime* myLeadTime;
+ void initItem();
+ void hideMe();
+};
+
+#endif
diff --git a/kdgantt/KDGanttViewItem.cpp b/kdgantt/KDGanttViewItem.cpp
new file mode 100644
index 00000000..16665e5a
--- /dev/null
+++ b/kdgantt/KDGanttViewItem.cpp
@@ -0,0 +1,2571 @@
+/* -*- 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 "KDGanttViewTaskItem.h"
+#include "KDGanttViewSummaryItem.h"
+#include "KDGanttViewEventItem.h"
+#include "itemAttributeDialog.h"
+
+#include "qpainter.h"
+
+#include "KDGanttXMLTools.h"
+
+
+/*!
+ \class KDGanttViewItem KDGanttViewItem.h
+ This class represents an item in a Gantt chart.
+
+ This class is an abstract base class, it cannot be instantiated
+ directly. Instead, you should create items of one of the
+ subclasses. This class provides methods common to all Gantt items.
+
+ The initialization of the shapes/colors of the item works as follows:
+
+ Shapes:
+ When a new item is created, the shapes are set to the default values
+ for items of the type of this item, defined in the KDGanttView class with
+ void setShapes( KDGanttViewItem::Type type,
+ KDGanttViewItem::Shape start,
+ KDGanttViewItem::Shape middle,
+ KDGanttViewItem::Shape end );
+ If there is no default value defined for this type,
+ the shapes are set as follows:
+ For TaskViewItems all three shapes are set to Square.
+ For SummaryViewItems all three shapes are set to TriangleDown.
+ For EventViewItems all three shapes are set to Diamond.
+
+ Colors:
+ When a new item is created, the colors are set to the default values
+ for items of the type of this item, defined in the KDGanttView class with
+ void setColors( KDGanttViewItem::Type type,
+ const QColor& start,
+ const QColor& middle,
+ const QColor& end );
+ If there is no default value defined for this type,
+ the colors of the shapes are set to the default color for items of this type,
+ defined in the KDGanttView class with:
+ void setDefaultColor( KDGanttViewItem::Type type, const QColor& );
+ The initial default color in the KDGanttView class is set to
+ blue for KDGanttViewItem::Event,
+ green for KDGanttViewItem::Task,
+ cyan for KDGanttViewItem::Summary.
+
+ Highlight Colors:
+ When a new item is created, the highlight colors are set to the default
+ values for items of the type of this item,
+ defined in the KDGanttView class with:
+ void setHighlightColors( KDGanttViewItem::Type type,
+ const QColor& start,
+ const QColor& middle,
+ const QColor& end );
+ If there is no default value defined for this type,
+ the highlight colors of the shapes are set to the default color for
+ items of this type, defined in the KDGanttView class with:
+ void setDefaultHighlightColor( KDGanttViewItem::Type type, const QColor& );
+ The initial default highlight color in the KDGanttView class is set to red
+ for all types.
+
+ Start/End time:
+ When a new item is created, the start time and the end time is set
+ automatically. The time, which is currently displayed in the middle
+ of the Gantt View, is set as start/end time. At startup of a newly
+ created Gantt view, this is the current time.
+
+ The Priority:
+ The priority is set with \a setPriority().
+ The priority determines which items are painted over which other items.
+ The item with the highest priority is painted on top of all others.
+ The priority for an item can be between 1 and 199.
+ A priority less than 100 means that the item is painted below the
+ grid in the Gantt chart.
+ For Task items, the default priority is 50, for all other items it is 150.
+ This feature only makes sense for an item which is a child of another item,
+ for which \a displaySubitemsAsGroup() property is set to true.
+
+ The Display Mode:
+ The display mode is set with \a setDisplaySubitemsAsGroup().
+ In the normal view mode (set with setDisplaySubitemsAsGroup( false ); ),
+ an item is displayed in the same manner, when its child items are
+ shown or not.
+ In the other mode (set with setDisplaySubitemsAsGroup( true ); ),
+ called "calendar mode", the item is displayed as follows:
+ If the item has no children, it is displayed as usual.
+ If the item is opened (i.e., its children are displayed), the
+ start/end time of this item is computed automatically according to
+ the earliest start time/latest end time of its children. The item
+ and its children are displayed as usual.
+ If the item is closed (i.e., its children are hidden in the left
+ list view), the item itself is hidden, and its children are displayed
+ on the timeline of this item instead. To control the painting of
+ overlapping children, call \a setPriority() for the childs.
+
+ Blocking of user interaction to open item:
+ If you want to block users to open items used as parents of calendar items,
+ call \a KDGanttView::setCalendarMode( true );
+
+ Example 1, Color:
+ If you create an instance of a KDGanttView class and add a SummaryViewItem
+ without setting any color/shape values, you get an item with three shapes
+ of the form TriangleDown in the color magenta. If the item is highlighted,
+ the color will change to the highlight color red.
+
+ Example 2, Calender View:
+ To use a Gantt view as a calendar view, call
+ \a KDGanttView::setCalendarMode( true );
+ \a KDGanttView::setDisplaySubitemsAsGroup( true );
+ Insert root items in the Gantt view.
+ Insert items as children of these root item in the Gantt view.
+ You may use any item type as parent and child; there are no limitations.
+ It is, however, recommended to use KDGanttViewTaskItems
+ Actually, you may add child items to the children themselves.
+ Such a child behaves then like a parent.
+ Now set the start/end time of the children to specify a time
+ interval for these items.
+*/
+
+
+QDict<KDGanttViewItem> KDGanttViewItem::sItemDict;
+
+/*!
+ Constructs an empty Gantt item.
+
+ \param type the type of the item to insert
+ \param view the Gantt view to insert this item into
+ \param lvtext the text to show in the list view
+ \param name the name by which the item can be identified. If no name
+ is specified, a unique name will be generated
+*/
+KDGanttViewItem::KDGanttViewItem( Type type, KDGanttView* view,
+ const QString& lvtext,
+ const QString& name ) :
+ QListViewItem(view->myListView,lvtext)
+{
+ initColorAndShapes(type);
+ generateAndInsertName( name );
+}
+
+
+/*!
+ Constructs an empty Gantt item.
+
+ \param type the type of the item to insert
+ \param parentItem a parent item under which this one goes
+ \param lvtext the text to show in the list view
+ \param name the name by which the item can be identified. If no name
+ is specified, a unique name will be generated
+*/
+
+KDGanttViewItem::KDGanttViewItem( Type type, KDGanttViewItem* parentItem,
+ const QString& lvtext,
+ const QString& name ) :
+ QListViewItem(parentItem,lvtext)
+{
+ initColorAndShapes(type);
+ generateAndInsertName( name );
+}
+
+
+/*!
+ Constructs an empty Gantt item.
+
+ \param type the type of the item to insert
+ \param view the Gantt view to insert this item into
+ \param after another item at the same level behind which this one should go
+ \param lvtext the text to show in the list view
+ \param name the name by which the item can be identified. If no name
+ is specified, a unique name will be generated
+*/
+
+KDGanttViewItem::KDGanttViewItem( Type type, KDGanttView* view,
+ KDGanttViewItem* after,
+ const QString& lvtext,
+ const QString& name ) :
+ QListViewItem(view->myListView,after, lvtext)
+{
+ initColorAndShapes(type);
+ generateAndInsertName( name );
+}
+
+
+/*!
+ Constructs an empty Gantt item.
+
+ \param type the type of the item to insert
+ \param parentItem a parent item under which this one goes
+ \param after another item at the same level behind which this one should go
+ \param lvtext the text to show in the list view
+ \param name the name by which the item can be identified. If no name
+ is specified, a unique name will be generated
+*/
+
+KDGanttViewItem::KDGanttViewItem( Type type, KDGanttViewItem* parentItem,
+ KDGanttViewItem* after,
+ const QString& lvtext,
+ const QString& name ) :
+ QListViewItem( parentItem, after, lvtext )
+{
+ initColorAndShapes(type);
+ generateAndInsertName( name );
+}
+
+
+/*!
+ Destroys the object and frees any allocated resources.
+*/
+KDGanttViewItem::~KDGanttViewItem()
+{
+ myGanttView->notifyEditdialog( this );
+ if ( startLine ) delete startLine;
+ if ( endLine ) delete endLine ;
+ if ( startLineBack ) delete startLineBack ;
+ if ( endLineBack ) delete endLineBack ;
+ if ( actualEnd ) delete actualEnd ;
+ if ( textCanvas ) delete textCanvas ;
+ if ( startShape ) delete startShape ;
+ if ( midShape ) delete midShape ;
+ if ( endShape ) delete endShape ;
+ if ( startShapeBack ) delete startShapeBack ;
+ if ( midShapeBack ) delete midShapeBack ;
+ if ( endShapeBack ) delete endShapeBack ;
+ if ( progressShape ) delete progressShape ;
+ if ( floatStartShape ) delete floatStartShape ;
+ if ( floatEndShape ) delete floatEndShape ;
+ myGanttView->myTimeTable->removeItemFromTasklinks( this );
+ myGanttView->myCanvasView->resetCutPaste( this );
+ if ( listView() ) {
+ if ( isOpen() )
+ setOpen( false );
+ if ( parent() )
+ parent()->takeItem( this );
+ else
+ myGanttView->myListView->takeItem( this );
+ myGanttView->myTimeTable->updateMyContent();
+ }
+ // myGanttView->myTimeTable->removeItemFromTasklinks( this );
+ // myGanttView->myCanvasView->resetCutPaste( this );
+}
+
+
+/*!
+ Generates a unique name if necessary and inserts it into the item
+ dictionary.
+*/
+void KDGanttViewItem::generateAndInsertName( const QString& name )
+{
+ // First check if we already had a name. This can be the case if
+ // the item was reconstructed from an XML file.
+ if( !_name.isEmpty() )
+ // We had a name, remove it
+ sItemDict.remove( _name );
+
+ QString newName;
+ if ( name.isEmpty() || sItemDict.find( name ) ) {
+ // create unique name
+ newName.sprintf( "%p", (void* )this );
+ while( sItemDict.find( newName ) ) {
+ newName += "_0";
+ }
+ } else {
+ newName = name;
+ }
+ sItemDict.insert( newName, this );
+ _name = newName;
+}
+
+
+/*!
+ Returns the unique name that can identify the item.
+
+ \return the unique item name
+*/
+QString KDGanttViewItem::name() const
+{
+ return _name;
+}
+
+
+/*!
+ Returns the item with the specified name.
+
+ \param name the name to search for
+ \return the item with the specified name; 0 if no group
+ with that name exists
+*/
+
+KDGanttViewItem* KDGanttViewItem::find( const QString& name )
+{
+ if (name.isEmpty()) // avoid error msg from QDict
+ return 0;
+ return sItemDict.find( name );
+}
+
+
+
+/*!
+ Returns the type of the item.
+ This may be Event, Task, Summary.
+
+ \return the type of the item
+*/
+
+KDGanttViewItem::Type KDGanttViewItem::type() const
+{
+
+ return myType;
+}
+
+
+/*!
+ Specifies whether this item is enabled. If disabled, the item stays in the
+ Gantt view and the item is shown in gray to show that the item is disabled.
+ All signals of this item (like itemLeftClicked( this )) are blocked.
+ If the item displays its subitems (childs) as a group,
+ (displaySubitemsAsGroup() == true)
+ all changes apply to all subitems as well.
+
+ \param on pass true to make this item editable
+ \sa enabled ()
+*/
+void KDGanttViewItem::setEnabled( bool on )
+{
+ _enabled = on;
+ if ( displaySubitemsAsGroup() ) {
+ myGanttView->myTimeTable->inc_blockUpdating();
+ KDGanttViewItem* temp = (KDGanttViewItem*) firstChild();
+ while (temp != 0) {
+ temp->setEnabled( on );
+ temp = temp->nextSibling();
+ }
+ QListViewItem::setEnabled( on );
+ myGanttView->myTimeTable->dec_blockUpdating();
+ }
+ updateCanvasItems();
+}
+
+
+/*!
+ Returns whether this item is enabled.
+
+ \return true if this item is enabled, false otherwise
+ \sa setEnabled()
+*/
+bool KDGanttViewItem::enabled () const
+{
+ return _enabled;
+}
+
+
+// *********************************
+/*!
+ Specifies whether this item is visible.
+
+ \param on pass true to make this item visible
+ \sa itemVisible ()
+*/
+void KDGanttViewItem::setItemVisible( bool on )
+{
+ if ( on ) {
+ resetSubitemVisibility();
+ } else
+ setVisible( false );
+ //updateCanvasItems();
+ myGanttView->myTimeTable->updateMyContent();
+}
+
+
+/*!
+ Returns whether this item is visible.
+
+ \return true if this item is visible, false otherwise
+ \sa setItemVisible()
+*/
+bool KDGanttViewItem::itemVisible () const
+{
+ return QListViewItem::isVisible();
+}
+
+
+// *************************************
+
+/*!
+ Specifies whether this item is editable. The whole Gantt view needs
+ to be editable as well for this to have any effect.
+
+ \param editable pass true to make this item editable
+ \sa editable(), KDGanttView::setEditable(), KDGanttView::editable()
+*/
+void KDGanttViewItem::setEditable( bool editable )
+{
+ isEditable = editable;
+}
+
+
+/*!
+ Returns whether this item is editable.
+
+ \return true if this item is editable, false otherwise
+ \sa setEditable(), KDGanttView::setEditable(), KDGanttView::editable()
+*/
+
+bool KDGanttViewItem::editable() const
+{
+ return isEditable;
+}
+
+
+/*!
+ Specifies whether this item shows hidden subitems on its timeline.
+ Useful to get a so called "calendar view" with many items in one row.
+ When \a displaySubitemsAsGroup() is set to true, this item has a normal view,
+ when it is expanded. If it is not expanded (and has at least one child),
+ the item itself is hidden, and all children are displayed instead.
+ To manage the painting priority of the childs (if overlapping),
+ you may set \a priority() of these items.
+
+ \param show pass true to make this item displaying hidden subitems
+ \sa editable(), KDGanttView::setEditable(), KDGanttView::editable(), setPriority()
+*/
+void KDGanttViewItem::setDisplaySubitemsAsGroup( bool show )
+{
+ if ( !show && _displaySubitemsAsGroup)
+ isVisibleInGanttView = true;
+ _displaySubitemsAsGroup = show;
+ if ( parent() )
+ if ( parent()->isOpen() )
+ parent()->setOpen( true );
+ if ( isOpen() )
+ setOpen( true );
+ updateCanvasItems();
+}
+
+
+/*!
+ Returns whether this item displays hidden subitems.
+ Initial set to false.
+
+ \return true if this item displays hidden subitems, false otherwise
+ \sa setDisplaySubitemsAsGroup()
+*/
+bool KDGanttViewItem::displaySubitemsAsGroup() const
+{
+ return _displaySubitemsAsGroup;
+}
+
+
+/*!
+ Specifies the priority of this item.
+ Valid values are between 1 and 199.
+ A priority less than 100 means that the item is painted in the
+ Gantt chart below the grid. A priority more than 100 means
+ that the item is painted in the Gantt chart over the grid.
+ For a value of 100, the behavior is unspecified.
+ An item with a higher priority is painted over an item with a lower
+ priority in the Gantt chart. The painting order of items with the
+ same priority is unspecified.
+ For Calendar items, the default priority is 50, for all other items
+ it is 150.
+ This feature makes only sense for an item which is a child of
+ another item, which \a displaySubitemsAsGroup() property is set to
+ true.
+
+ \param prio the new priority of this item.
+ \sa priority(), displaySubitemsAsGroup()
+*/
+void KDGanttViewItem::setPriority( int prio )
+{
+ if ( prio < 1 )
+ prio = 1;
+ if (prio > 199 )
+ prio = 199;
+ _priority = prio;
+ updateCanvasItems();
+}
+
+
+/*!
+ Returns the priority of this item.
+ \return the priority of this item
+ \sa setDisplaySubitemsAsGroup()
+*/
+int KDGanttViewItem::priority()
+{
+ return _priority;
+}
+
+
+/*!
+ Specifies the start time of this item. The parameter must be valid
+ and non-null. If the parameter is invalid or null, no value is set.
+ Reimplemented in the subclasses.
+
+ \param start the start time
+ \sa startTime(), setEndTime(), endTime()
+*/
+void KDGanttViewItem::setStartTime( const QDateTime& )
+{
+}
+
+
+/*!
+ Returns the start time of this item.
+
+ \return the start time of this item
+ \sa setStartTime(), setEndTime(), endTime()
+*/
+QDateTime KDGanttViewItem::startTime() const
+{
+ return myStartTime;
+}
+
+
+/*!
+ Specifies the end time of this item. The parameter must be valid
+ and non-null. If the parameter is invalid or null, no value is set.
+ Reimplemented in the subclasses
+
+ \param end the end time
+ \sa endTime(), setStartTime(), startTime()
+*/
+void KDGanttViewItem::setEndTime( const QDateTime& end )
+{
+ switch( type() ) {
+ case Event:
+ qDebug( "KDGantt:Event Item has no end time" );
+ break;
+ case Summary:
+ ((KDGanttViewSummaryItem*)this)->setEndTime( end );
+ break;
+ case Task:
+ qDebug( "KDGantt:Task Item has no end time" );
+ break;
+ default:
+ qDebug( "Unknown type in KDGanttViewItem::typeToString()" );
+ }
+}
+
+
+/*!
+ Returns the end time of this item.
+
+ \return the end time of this item
+ \sa setEndTime(), setStartTime(), startTime()
+*/
+QDateTime KDGanttViewItem::endTime() const
+{
+ return myEndTime;
+}
+
+
+/*!
+ Sets the text to be shown in this item in the Gantt view.
+ For a KDGanttViewTaskItem witht displaySubitemsAsGroup() == true,
+ the text is shown in the item itself and
+ the text is truncated automatically, if it does not fit in the item.
+ For all other item types, the text is shown to the right of the item.
+
+ \param text the text to be shown
+ \sa text(), setTextColor(), textColor(), setListViewText(),
+ listViewText()
+*/
+void KDGanttViewItem::setText( const QString& text )
+{
+ textCanvas->setText(text);
+ textCanvasText = text;
+ updateCanvasItems();
+}
+
+
+/*!
+ Returns the text to be shown in this item in the Gantt view.
+
+ \return the text to be shown in this item
+ \sa setText(), setTextColor(), textColor(), setListViewText(),
+ listViewText()
+*/
+QString KDGanttViewItem::text() const
+{
+ return textCanvasText;
+}
+
+
+/*!
+ \deprecated Use setListViewTest( int, const QString& ) instead
+*/
+void KDGanttViewItem::setListViewText( const QString& text, int column )
+{
+ QListViewItem::setText( column, text );
+}
+
+
+/*!
+ Sets the text to be shown in this item in the list view.
+
+ \param column the column in which the text will be shown
+ \param text the text to be shown
+ \sa text(), setTextColor(), textColor(), setText(), listViewText()
+*/
+void KDGanttViewItem::setListViewText( int column, const QString& text )
+{
+ QListViewItem::setText( column, text );
+}
+
+
+/*!
+ Returns the text to be shown in this item in the list view.
+
+ \param column the column in which the text will be shown
+ \return the text to be shown in this item
+ \sa setText(), setTextColor(), textColor(), text(),
+ setListViewText()
+*/
+QString KDGanttViewItem::listViewText( int column ) const
+{
+ return QListViewItem::text( column );
+}
+
+
+/*!
+ Sets the font to be used for the text in this item.
+
+ \param font the font to be shown
+ \sa font()
+*/
+void KDGanttViewItem::setFont( const QFont& font )
+{
+ textCanvas->setFont(font);
+ updateCanvasItems();
+}
+
+
+/*!
+ Returns the font used for the text in this item.
+
+ \return the font used for the text in this item
+ \sa setFont()
+*/
+QFont KDGanttViewItem::font() const
+{
+ return textCanvas->font();
+}
+
+
+/*!
+ Sets the text to show in a tooltip for this item.
+
+ \param text the tooltip text
+ \sa tooltipText()
+*/
+void KDGanttViewItem::setTooltipText( const QString& text )
+{
+ myToolTipText = text;
+}
+
+
+/*!
+ Returns the tooltip text of this item
+
+ \return the tooltip text
+ \sa setTooltipText()
+*/
+QString KDGanttViewItem::tooltipText() const
+{
+
+ return myToolTipText;
+}
+
+
+/*!
+ Sets the text to show in a What's This window for this item.
+
+ \param text the what's this text
+ \sa whatsThisText()
+*/
+void KDGanttViewItem::setWhatsThisText( const QString& text )
+{
+ myWhatsThisText = text;
+}
+
+
+/*!
+ Returns the what's this text of this item
+
+ \return the what's this text
+ \sa setWhatsThisText()
+
+*/
+QString KDGanttViewItem::whatsThisText() const
+{
+ return myWhatsThisText;
+}
+
+
+/*!
+ Specifies whether this item should be shown highlighted. The user
+ can also highlight items with the mouse.
+ If the item displays its subitems (children) as a group
+ (displaySubitemsAsGroup() == true),
+ all changes apply to all subitems as well.
+
+ \param highlight true in order to highlight, false in order to turn
+ highlighting off for this item
+ \sa highlight()
+*/
+void KDGanttViewItem::setHighlight( bool highlight )
+{
+ isHighlighted = highlight;
+ if ( displaySubitemsAsGroup() ) {
+ myGanttView->myTimeTable->inc_blockUpdating();
+ KDGanttViewItem* temp = (KDGanttViewItem*) firstChild();
+ while (temp != 0) {
+ temp->setHighlight( highlight );
+ temp = temp->nextSibling();
+ }
+ myGanttView->myTimeTable->dec_blockUpdating();
+ }
+ updateCanvasItems();
+}
+
+
+/*!
+ Returns whether this item is highlighted, either programmatically
+ with setHighlight() or by the user with the mouse.
+
+ \return true if the item is highlighted
+ \sa setHighlight()
+*/
+bool KDGanttViewItem::highlight() const
+{
+ return isHighlighted;
+}
+
+
+/*!
+ Specifies the shapes to be used for this item.
+
+ It is advisable not to use this method, but rather set the shapes
+ for all items of a type with KDGanttView::setShapes() in order to
+ get a uniform Gantt view.
+
+ \param start the start shape
+ \param middle the middle shape
+ \param end the end shape
+ \sa shapes(), setColors(), colors()
+*/
+void KDGanttViewItem::setShapes( Shape start, Shape middle, Shape end )
+{
+
+ myStartShape = start;
+ myMiddleShape= middle;
+ myEndShape= end;
+ createShape(startShape,startShapeBack,start);
+ createShape(midShape,midShapeBack,middle);
+ midShape->setZ( 4 );
+ createShape(endShape,endShapeBack,end);
+ updateCanvasItems();
+}
+
+
+/*!
+ Creates shapes of the specified type \a shape.
+ The background shape color is set to black and the background shape
+ is slightly bit bigger than the foreground shape to have a black border
+ around the foreground shape.
+
+ \param itemShape the foreground shape
+ \param middle itemShapeBack the background shape
+ \param shape the type of the shape
+ (may be TriangleDown, TriangleUp, Diamond, Square, Circle)
+ \sa shapes(), setColors(), colors()
+*/
+void KDGanttViewItem::createShape( KDCanvasPolygonItem* &itemShape,
+ KDCanvasPolygonItem* &itemShapeBack,
+ Shape shape )
+{
+ if ( itemShape && type() == Task )
+ return;
+ if (itemShape) delete itemShape;
+ if (itemShapeBack) delete itemShapeBack;
+
+ QCanvasPolygonalItem * item;
+ QCanvasPolygonalItem * itemBack;
+ int size = myItemSize+2;
+ int hei = (myItemSize/3)/2;
+ switch (shape) {
+ case TriangleDown:
+ {
+ item = new KDCanvasPolygon(myGanttView->myTimeTable, this,Type_is_KDGanttViewItem);
+ QPointArray arr = QPointArray(3);
+ arr.setPoint(0,-size/2,-hei);
+ arr.setPoint(1,size/2,-hei);
+ arr.setPoint(2,0,((size/2)-hei));
+ ((QCanvasPolygon*)item)->setPoints(arr);
+ size += 4;hei +=1;
+ itemBack = new KDCanvasPolygon(myGanttView->myTimeTable, this,Type_is_KDGanttViewItem);
+ arr.setPoint(0,-size/2,-hei);
+ arr.setPoint(1,size/2,-hei);
+ arr.setPoint(2,0,((size/2)-hei));
+ ((QCanvasPolygon*)itemBack)->setPoints(arr);
+
+ break;
+ }
+ case TriangleUp:
+ {
+ // I really do not know why, but we get only an TriangleUp-icon
+ // of the same size as a TriangleDown-icon, if we increment the size by 2
+ size+=2;
+ item = new KDCanvasPolygon(myGanttView->myTimeTable, this,Type_is_KDGanttViewItem);
+ QPointArray arr = QPointArray(3);
+ arr.setPoint(0,-size/2,hei);
+ arr.setPoint(1,size/2,hei);
+ arr.setPoint(2,0,(-size/2)+hei);
+ ((QCanvasPolygon*)item)->setPoints(arr);
+ size += 4;hei +=1;
+ itemBack = new KDCanvasPolygon(myGanttView->myTimeTable, this,Type_is_KDGanttViewItem);
+ arr.setPoint(0,-size/2,hei);
+ arr.setPoint(1,size/2,hei);
+ arr.setPoint(2,0,(-size/2)+hei);
+ ((QCanvasPolygon*)itemBack)->setPoints(arr);
+
+ break;
+ }
+
+ case Diamond:
+ {
+ item = new KDCanvasPolygon(myGanttView->myTimeTable, this,Type_is_KDGanttViewItem);
+ QPointArray arr = QPointArray(4);
+ arr.setPoint(0,0,-size/2);
+ arr.setPoint(1,size/2,0);
+ arr.setPoint(2,0,size/2);
+ arr.setPoint(3,-size/2,0);
+ ((QCanvasPolygon*)item)->setPoints(arr);
+ size += 2;hei +=1;
+ itemBack = new KDCanvasPolygon(myGanttView->myTimeTable, this,Type_is_KDGanttViewItem);
+ arr.setPoint(0,0,-size/2);
+ arr.setPoint(1,size/2,0);
+ arr.setPoint(2,0,size/2);
+ arr.setPoint(3,-size/2,0);
+ ((QCanvasPolygon*)itemBack)->setPoints(arr);
+ break;
+ }
+
+ case Square:
+ {
+ size -=2;
+ item = new KDCanvasPolygon(myGanttView->myTimeTable, this,Type_is_KDGanttViewItem);
+ QPointArray arr = QPointArray(4);
+ arr.setPoint(0,-size/2,-size/2);
+ arr.setPoint(1,size/2,-size/2);
+ arr.setPoint(2,size/2,size/2);
+ arr.setPoint(3,-size/2,size/2);
+ ((QCanvasPolygon*)item)->setPoints(arr);
+ size += 2;hei +=1;
+ itemBack = new KDCanvasPolygon(myGanttView->myTimeTable, this,Type_is_KDGanttViewItem);
+ arr.setPoint(0,-size/2,-size/2);
+ arr.setPoint(1,size/2,-size/2);
+ arr.setPoint(2,size/2,size/2);
+ arr.setPoint(3,-size/2,size/2);
+ ((QCanvasPolygon*)itemBack)->setPoints(arr);
+ break;
+ }
+
+ case Circle:
+ {
+ size -= 2;
+ item = new KDCanvasEllipse(myGanttView->myTimeTable, this,Type_is_KDGanttViewItem);
+ ((KDCanvasEllipse*)item)->setSize(size,size);
+ size += 2;hei +=1;
+ itemBack = new KDCanvasEllipse(myGanttView->myTimeTable, this,Type_is_KDGanttViewItem);
+ ((KDCanvasEllipse*)itemBack)->setSize(size,size);
+ break;
+ }
+ default:
+ // Uninitialized shape, can e.g. be the case with free-busy
+ // items which don't have any shapes
+ return;
+ }
+ item->setBrush(Qt::SolidPattern);
+ item->setZ(5);
+ itemShape = (KDCanvasPolygonItem*) item;
+ itemBack->setBrush(Qt::SolidPattern);
+ itemBack->setZ(3);
+ itemShapeBack = (KDCanvasPolygonItem*) itemBack;
+
+}
+
+
+/*!
+ Returns the shapes used for this item
+
+ \param start returns the start shape
+ \param middle returns the middle shape
+ \param end returns the end shape
+ \sa setShapes(), setColors(), colors()
+*/
+void KDGanttViewItem::shapes( Shape& start, Shape& middle, Shape& end ) const
+{
+ start = myStartShape;
+ middle = myMiddleShape;
+ end = myEndShape;
+}
+
+
+/*!
+ Specifies the colors in which to draw the shapes of this item.
+
+ It is advisable not to use this method, but rather set the colors
+ for all items of a type with KDGanttView::setColors() in order to
+ get a uniform Gantt view.
+
+ \param start the color for the start shape
+ \param middle the color for the middle shape
+ \param end the color for the end shape
+ \sa colors(), setShapes(), shapes(), setDefaultColor(), defaultColor()
+*/
+void KDGanttViewItem::setColors( const QColor& start, const QColor& middle,
+ const QColor& end )
+{
+
+ myStartColor=start ;
+ myMiddleColor= middle;
+ myEndColor= end;
+ if ( displaySubitemsAsGroup() ) {
+ myGanttView->myTimeTable->inc_blockUpdating();
+ KDGanttViewItem* temp = (KDGanttViewItem*) firstChild();
+ while (temp != 0) {
+ temp->setColors( start, middle, end );
+ temp = temp->nextSibling();
+ }
+ myGanttView->myTimeTable->dec_blockUpdating();
+ }
+ updateCanvasItems();
+}
+
+
+/*!
+ Returns the colors used for this item
+
+ \param start returns the start color
+ \param middle returns the middle color
+ \param end returns the end color
+ \sa setColors(), setShapes(), shapes(), setDefaultColor(), defaultColor()
+*/
+void KDGanttViewItem::colors( QColor& start, QColor& middle, QColor& end ) const
+{
+ start = myStartColor ;
+ middle = myMiddleColor;
+ end = myEndColor;
+
+}
+
+
+/*!
+ Specifies the highlight colors in which to draw the shapes of this item.
+
+ It is advisable not to use this method, but rather set the highlight
+ colors for all items of a type with
+ KDGanttView::setHighlightColors() in order to get a uniform Gantt
+ view.
+
+ If the item displays its subitems (children) as a group,
+ (displaySubitemsAsGroup() == true)
+ all changes apply to all subitems as well.
+
+ \param start the highlight color for the start shape
+ \param middle the highlight color for the middle shape
+ \param end the highlight color for the end shape
+ \sa highlightColors(), setShapes(), shapes()
+*/
+void KDGanttViewItem::setHighlightColors( const QColor& start, const QColor& middle, const QColor& end )
+{
+ myStartColorHL=start ;
+ myMiddleColorHL= middle;
+ myEndColorHL= end;
+ if ( displaySubitemsAsGroup() ) {
+ myGanttView->myTimeTable->inc_blockUpdating();
+ KDGanttViewItem* temp = (KDGanttViewItem*) firstChild();
+ while (temp != 0) {
+ temp->setHighlightColors( start, middle, end );
+ temp = temp->nextSibling();
+ }
+ myGanttView->myTimeTable->dec_blockUpdating();
+ }
+ updateCanvasItems();
+}
+
+
+/*!
+ Returns the highlight colors used for this item
+
+ \param start returns the start highlight color
+ \param middle returns the middle highlight color
+ \param end returns the end highlight color
+ \sa setHighlightColors(), setShapes(), shapes()
+*/
+void KDGanttViewItem::highlightColors( QColor& start, QColor& middle, QColor& end ) const
+{
+ start = myStartColorHL ;
+ middle = myMiddleColorHL;
+ end = myEndColorHL;
+}
+
+
+/*!
+ Specifies the color to be used for the text of this item.
+
+ It is advisable not to use this method, but rather set the text color
+ for all items with KDGanttView::setTextColor() in order to get a
+ uniform Gantt view.
+ If the item displays its subitems (children) as a group,
+ (displaySubitemsAsGroup() == true)
+ all changes apply to all subitems as well.
+ \param color the text color
+ \sa textColor(), setText(), text()
+*/
+void KDGanttViewItem::setTextColor( const QColor& color )
+{
+
+ myTextColor = color;
+ if ( displaySubitemsAsGroup() ) {
+ myGanttView->myTimeTable->inc_blockUpdating();
+ KDGanttViewItem* temp = (KDGanttViewItem*) firstChild();
+ while (temp != 0) {
+ temp->setTextColor(color);
+ temp = temp->nextSibling();
+ }
+ myGanttView->myTimeTable->dec_blockUpdating();
+ }
+ updateCanvasItems();
+}
+
+
+/*!
+ Returns the color used for the text of this item.
+
+ \return the text color
+ \sa setTextColor(), setText(), text()
+*/
+QColor KDGanttViewItem::textColor() const
+{
+ return myTextColor;
+}
+
+
+/*!
+ \enum KDGanttViewItem::Shape
+
+ This enum is used in order to specify the shapes of a Gantt chart
+ item.
+*/
+
+
+/*!
+ \enum KDGanttViewItem::Type
+
+ This enum is used in order to return the type of a Gantt chart item.
+*/
+
+
+/*!
+ Sets the pixmap that is shown in the listview.
+
+ \param column the column in which the pixmap is shown
+ \param pixmap the pixmap to show
+ \sa pixmap()
+*/
+void KDGanttViewItem::setPixmap( int column, const QPixmap& pixmap )
+{
+ QListViewItem::setPixmap( column, pixmap );
+}
+
+/*!
+ \deprecated use setPixmap( int, const QPixmap& ) instead
+*/
+void KDGanttViewItem::setPixmap( const QPixmap& pixmap )
+{
+ QListViewItem::setPixmap( 0, pixmap );
+}
+
+
+/*!
+ Returns a pixmap that is shown in the listview.
+
+ \param column the column for which to query the pixmap
+ \return a pointer to the pixmap shown
+ \sa setPixmap()
+*/
+const QPixmap* KDGanttViewItem::pixmap( int column ) const
+{
+ return QListViewItem::pixmap( column );
+}
+
+
+/*!
+ Sets the default color that is used for the item if no specific
+ start, middle, or end colors are set.
+
+ It is advisable not to use this method, but rather set the colors
+ for all items of a type with KDGanttView::setDefaultColor() in order to
+ get a uniform Gantt view.
+
+ If the item displays its subitems (children) as a group,
+ (displaySubitemsAsGroup() == true)
+ all changes apply to all subitems as well.
+
+ \param color the default color to use
+ \sa defaultColor(), setColors(), colors()
+*/
+void KDGanttViewItem::setDefaultColor( const QColor& color )
+{
+ myDefaultColor = color;
+
+
+ if ( displaySubitemsAsGroup() ) {
+ myGanttView->myTimeTable->inc_blockUpdating();
+ KDGanttViewItem* temp = (KDGanttViewItem*) firstChild();
+ while (temp != 0) {
+ temp->setDefaultColor( color );
+ temp = temp->nextSibling();
+ }
+ myGanttView->myTimeTable->dec_blockUpdating();
+ }
+ updateCanvasItems();
+}
+
+
+
+/*!
+ Returns the default color that is used for the item if no specific
+ start, middle, or end colors are set.
+
+ \return color the default color used
+ \sa setDefaultColor(), setColors(), colors()
+*/
+QColor KDGanttViewItem::defaultColor() const
+{
+ return myDefaultColor;
+}
+
+
+/*!
+ Sets the default highlighting color that is used for the item if no
+ specific start, middle, or end colors are set.
+
+ It is advisable not to use this method, but rather set the colors
+ for all items of a type with KDGanttView::setDefaultHighlightColor()
+ in order to get a uniform Gantt view.
+
+ If the item displays its subitems (children) as a group,
+ (displaySubitemsAsGroup() == true)
+ all changes apply to all subitems as well.
+
+ \param color the default highlighting color to use
+ \sa defaultHighlightColor(), setHighlightColors(), highlightColors()
+*/
+void KDGanttViewItem::setDefaultHighlightColor( const QColor& color )
+{
+ myDefaultColorHL = color;
+ if ( displaySubitemsAsGroup() ) {
+ myGanttView->myTimeTable->inc_blockUpdating();
+ KDGanttViewItem* temp = (KDGanttViewItem*) firstChild();
+ while (temp != 0) {
+ temp->setDefaultHighlightColor( color );
+ temp = temp->nextSibling();
+ }
+ myGanttView->myTimeTable->dec_blockUpdating();
+ }
+ updateCanvasItems();
+}
+
+
+/*!
+ Returns the default highlighting color that is used for the item if
+ no specific start, middle, or end colors are set.
+
+ \return color the default highlighting color used
+ \sa setDefaultHighlightColor(), setHighlightColors(), highlightColors()
+*/
+QColor KDGanttViewItem::defaultHighlightColor() const
+{
+ return myDefaultColorHL;
+}
+
+
+/*!
+ Returns the first child of this item.
+
+ \return the first child of this item, 0 if this item has no children
+*/
+KDGanttViewItem* KDGanttViewItem::firstChild() const
+{
+
+ return (KDGanttViewItem* )QListViewItem::firstChild();
+}
+
+
+/*!
+ Returns the next sibling item of this item
+
+ \return the next sibling item of this item, 0 if this item has no
+ more siblings
+*/
+KDGanttViewItem* KDGanttViewItem::nextSibling() const
+{
+ return (KDGanttViewItem* )QListViewItem::nextSibling();
+}
+
+
+/*!
+ Returns the parent item of this item
+
+ \return the parent item of this item, 0 if this item is a top-level
+ item
+*/
+KDGanttViewItem* KDGanttViewItem::parent() const
+{
+ return (KDGanttViewItem*)QListViewItem::parent();
+}
+
+
+/*!
+ Returns the item above this item in the listview
+
+ \return the item above this item, 0 if this is the first item
+*/
+KDGanttViewItem* KDGanttViewItem::itemAbove()
+{
+ return (KDGanttViewItem* )QListViewItem::itemAbove();
+}
+
+
+/*!
+ Returns the item below this item in the listview.
+ It can be specified whether the disabled items are taken
+ into account as well.
+
+ \param includeDisabled if true, disabled items are considered as well
+ \return the item below this item, 0 if this is the last item
+*/
+KDGanttViewItem* KDGanttViewItem::itemBelow( bool includeDisabled )
+{
+
+ KDGanttViewItem* retItem = (KDGanttViewItem* )QListViewItem::itemBelow();
+ if ( !includeDisabled ) {
+ return retItem;
+ }
+ if ( retItem ) {
+ if (itemPos() + height() == retItem->itemPos() ) {
+ return retItem;
+ }
+ }
+ KDGanttViewItem* Item2 = (KDGanttViewItem* )QListViewItem::listView()->itemAt(QPoint (2, QListViewItem::itemPos() + QListViewItem::height() +2) );
+ if ( Item2 != 0 )
+ if (!Item2->enabled() )
+ return Item2;
+ return retItem;
+}
+
+
+/*!
+ Updates the colors of the item, but not the coordinates.
+*/
+void KDGanttViewItem::updateCanvasItems()
+{
+ if (blockUpdating) return;
+ QPen p,pBack;
+ QBrush b;
+ b.setStyle(Qt::SolidPattern);
+ if ( enabled() ) {
+ textCanvas->setColor(myTextColor);
+ if (isHighlighted) {
+ b.setStyle(Qt::SolidPattern);
+ b.setColor(myStartColorHL);
+ startShape->setBrush(b);
+ b.setColor(myMiddleColorHL);
+ midShape->setBrush(b);
+ b.setColor(myEndColorHL);
+ endShape->setBrush(b);
+ p.setWidth(myItemSize/3 -1);
+ p.setColor(myStartColorHL);
+ startLine->setPen(p);
+ p.setColor(myEndColorHL);
+ endLine->setPen(p);
+ } else {
+ b.setStyle(Qt::SolidPattern);
+ b.setColor(myStartColor);
+ // qDebug("update color %s %s", listViewText().latin1(),myStartColor.name().latin1() );
+ startShape->setBrush(b);
+ b.setColor(myMiddleColor);
+ midShape->setBrush(b);
+ b.setColor(myEndColor);
+ endShape->setBrush(b);
+ p.setWidth(myItemSize/3-1);
+ p.setColor(myStartColor);
+ startLine->setPen(p);
+ p.setColor(myEndColor);
+ endLine->setPen(p);
+ }
+ } else {
+ //QColor discol = Qt::lightGray;
+ QColor discol = QColor(232,232,232);
+ textCanvas->setColor( QColor(150,150,150) );
+ b.setStyle(Qt::SolidPattern);
+ b.setColor(discol);
+ startShape->setBrush(b);
+ midShape->setBrush(b);
+ endShape->setBrush(b);
+ p.setWidth(myItemSize/3 -1);
+ p.setColor(discol);
+ startLine->setPen(p);
+ endLine->setPen(p);
+ }
+ pBack.setWidth((myItemSize/3-1)+2);
+ startLineBack->setPen(pBack);
+ endLineBack->setPen(pBack);
+ QFont f = textCanvas->font();
+ f.setPixelSize(myItemSize);
+ textCanvas->setFont(f);
+ //if (isvisible) {
+ myGanttView->myTimeTable->updateMyContent();
+ //}
+}
+
+
+void KDGanttViewItem::initItem()
+{
+}
+
+
+/*!
+ This method is reimplemented for internal purposes.
+*/
+void KDGanttViewItem::setOpen( bool open )
+{
+ if ( _callListViewOnSetOpen ) {
+ // notify the listview about a programatically called setOpen()
+ if ( listView () )
+ listView ()->setOpen( this, open );
+
+ } else {
+
+ QListViewItem::setOpen( open );
+ }
+}
+
+
+void KDGanttViewItem::showItem( bool, int )
+{
+}
+
+
+QPoint KDGanttViewItem::getTaskLinkStartCoord(QPoint p)
+{
+ textCanvas->move(p.x()+myItemSize, itemPos() + height()/2-myItemSize/2);
+ return QPoint (myGanttView->myTimeHeader->getCoordX(myEndTime) +myItemSize/2,itemPos()+height()/2);
+}
+
+
+QPoint KDGanttViewItem::getTaskLinkEndCoord()
+{
+ return QPoint (myGanttView->myTimeHeader->getCoordX(myStartTime)-myItemSize/2 ,itemPos()-myItemSize/2+height()/2-2);
+}
+
+
+void KDGanttViewItem::hideSubtree()
+{
+ if (firstChild())
+ firstChild()->hideSubtree();
+ if ( nextSibling () )
+ nextSibling ()->hideSubtree();
+ showItem(false);
+}
+
+
+void KDGanttViewItem::setCallListViewOnSetOpen( bool call )
+{
+ _callListViewOnSetOpen = call;
+}
+
+
+void KDGanttViewItem::initColorAndShapes(Type t)
+{
+ _isMoveable = false;
+ _isResizeable = false;
+ setTextOffset(QPoint(0,0));
+ //_isCalendar = false;
+ _callListViewOnSetOpen = true;
+ myType = t;
+ myProgress = 0;
+ progressShape = 0;
+ floatStartShape = 0;
+ floatEndShape = 0;
+ blockUpdating = true;
+ isVisibleInGanttView = false;
+ startShape = 0;
+ midShape = 0;
+ endShape = 0;
+ startShapeBack = 0;
+ midShapeBack = 0;
+ endShapeBack = 0;
+
+ myItemSize = 10;
+ myGanttView = ((KDListView *)listView())->myGanttView;
+ myGanttView->myTimeHeader->saveCenterDateTime();
+ myStartTime = myGanttView->myTimeHeader->myCenterDateTime;
+ myEndTime = myStartTime;
+ myToolTipText =QListViewItem::text(0);
+ myWhatsThisText = QListViewItem::text(0);
+ isHighlighted = false;
+ isEditable = true;
+ _displaySubitemsAsGroup = myGanttView->displaySubitemsAsGroup();
+ startLine = new KDCanvasLine(myGanttView->myTimeTable,this,Type_is_KDGanttViewItem);//KDGanttViewItem );
+ endLine = new KDCanvasLine(myGanttView->myTimeTable,this,Type_is_KDGanttViewItem);
+ startLine->setZ(2);endLine->setZ(2);
+ startLineBack = new KDCanvasLine(myGanttView->myTimeTable,this,Type_is_KDGanttViewItem);//KDGanttViewItem );
+ endLineBack = new KDCanvasLine(myGanttView->myTimeTable,this,Type_is_KDGanttViewItem);
+ startLineBack->setZ(1);endLineBack->setZ(1);
+ actualEnd = new KDCanvasLine(myGanttView->myTimeTable,this,Type_is_KDGanttViewItem);
+ actualEnd->setZ(5);
+ actualEnd->setPen( QPen ( Qt::red, 3 ) );
+
+ textCanvas = new KDCanvasText(myGanttView->myTimeTable,this,Type_is_KDGanttViewItem);
+ textCanvas->setText("");
+ textCanvas->setZ(10);
+ // set textcolor
+ setTextColor( myGanttView->textColor());
+ // set default color
+ setDefaultColor( myGanttView->defaultColor(myType));
+ // set default highlight color
+ setDefaultHighlightColor(myGanttView->defaultHighlightColor(myType));
+ // set shapes
+ if (!( shapeDefined = (myGanttView->shapes(myType,myStartShape,myMiddleShape,myEndShape)))) {
+
+ //qDebug("KDGantt::KDGanttViewItem created with not user defined shapes");
+ };
+
+ setShapes(myStartShape,myMiddleShape,myEndShape);
+ if ( type() == Task ) {
+ //qDebug("new task %s ", listViewText().latin1());
+ if ( startShape )
+ delete startShape;
+ startShape = (KDCanvasPolygonItem*)new KDCanvasRectangle(myGanttView->myTimeTable,this,Type_is_KDGanttViewItem);
+ progressShape = (KDCanvasPolygonItem*)new KDCanvasRectangle(myGanttView->myTimeTable,this,Type_is_KDGanttViewItem);
+ }
+ floatStartShape = (KDCanvasPolygonItem*)new KDCanvasRectangle(myGanttView->myTimeTable,this,Type_is_KDGanttViewItem);
+ floatEndShape = (KDCanvasPolygonItem*)new KDCanvasRectangle(myGanttView->myTimeTable,this,Type_is_KDGanttViewItem);
+
+ // set color of shapes
+ if (!( colorDefined = (myGanttView->colors(myType,myStartColor,myMiddleColor,myEndColor)))) {
+
+ };
+ setColors(defaultColor(),defaultColor(), defaultColor());
+ // set highlight color of shapes
+ if (!( colorHLDefined = (myGanttView->highlightColors(myType,myStartColorHL,myMiddleColorHL,myEndColorHL)))) {
+
+ };
+ setHighlightColors(defaultHighlightColor(),defaultHighlightColor(), defaultHighlightColor());
+ setFont(myGanttView->font());
+ // if (type() == Task)
+ //setText(QListViewItem::text(0)); // testing only
+ //isvisible = true;
+ _priority = 150;
+ _showNoInformation = false;
+ _enabled = true;
+ blockUpdating = false;
+ updateCanvasItems();
+}
+
+
+QString KDGanttViewItem::shapeToString( Shape shape )
+{
+ switch( shape ) {
+ case TriangleDown:
+ return "TriangleDown";
+ case TriangleUp:
+ return "TriangleUp";
+ case Diamond:
+ return "Diamond";
+ case Square:
+ return "Square";
+ case Circle:
+ return "Circle";
+ }
+ return "";
+}
+
+
+KDGanttViewItem::Shape KDGanttViewItem::stringToShape( const QString& string )
+{
+ if( string == "TriangleDown" )
+ return TriangleDown;
+ else if( string == "TriangleUp" )
+ return TriangleUp;
+ else if( string == "Diamond" )
+ return Diamond;
+ else if( string == "Square" )
+ return Square;
+ else if( string == "Circle" )
+ return Circle;
+ else
+ return TriangleDown;
+}
+
+
+/*!
+ Creates a DOM node that describes this item.
+
+ \param doc the DOM document to which the node belongs
+ \param parentElement the element into which to insert this node
+*/
+void KDGanttViewItem::createNode( QDomDocument& doc,
+ QDomElement& parentElement )
+{
+ QDomElement itemElement = doc.createElement( "Item" );
+ parentElement.appendChild( itemElement );
+ itemElement.setAttribute( "Type", typeToString( type() ) );
+
+ KDGanttXML::createDateTimeNode( doc, itemElement, "StartTime", startTime() );
+ KDGanttXML::createDateTimeNode( doc, itemElement, "EndTime", endTime() );
+ KDGanttXML::createFontNode( doc, itemElement, "Font", font() );
+ KDGanttXML::createStringNode( doc, itemElement, "Text", text() );
+ KDGanttXML::createStringNode( doc, itemElement, "TooltipText", tooltipText() );
+ KDGanttXML::createStringNode( doc, itemElement, "WhatsThisText",
+ whatsThisText() );
+ if( pixmap() )
+ KDGanttXML::createPixmapNode( doc, itemElement, "Pixmap", *pixmap() );
+ if( !listViewText().isNull() )
+ KDGanttXML::createStringNode( doc, itemElement, "ListViewText",
+ listViewText() );
+ KDGanttXML::createBoolNode( doc, itemElement, "Open", isOpen() );
+ KDGanttXML::createBoolNode( doc, itemElement, "Highlight", highlight() );
+ Shape startShape, middleShape, endShape;
+ shapes( startShape, middleShape, endShape );
+ KDGanttXML::createStringNode( doc, itemElement, "StartShape",
+ shapeToString( startShape ) );
+ KDGanttXML::createStringNode( doc, itemElement, "MiddleShape",
+ shapeToString( middleShape ) );
+ KDGanttXML::createStringNode( doc, itemElement, "EndShape",
+ shapeToString( endShape ) );
+ KDGanttXML::createColorNode( doc, itemElement, "DefaultColor", defaultColor() );
+ QColor startColor, middleColor, endColor;
+ colors( startColor, middleColor, endColor );
+ KDGanttXML::createColorNode( doc, itemElement, "StartColor", startColor );
+ KDGanttXML::createColorNode( doc, itemElement, "MiddleColor", middleColor );
+ KDGanttXML::createColorNode( doc, itemElement, "EndColor", endColor );
+ KDGanttXML::createColorNode( doc, itemElement, "DefaultHighlightColor",
+ defaultHighlightColor() );
+ highlightColors( startColor, middleColor, endColor );
+ KDGanttXML::createColorNode( doc, itemElement, "StartHighlightColor",
+ startColor );
+ KDGanttXML::createColorNode( doc, itemElement, "MiddleHighlightColor",
+ middleColor );
+ KDGanttXML::createColorNode( doc, itemElement, "EndHighlightColor", endColor );
+ KDGanttXML::createColorNode( doc, itemElement, "TextColor", textColor() );
+ KDGanttXML::createStringNode( doc, itemElement, "Name", name() );
+ QDomElement itemsElement = doc.createElement( "Items" );
+ itemElement.appendChild( itemsElement );
+ KDGanttViewItem* currentItem = firstChild();
+ while( currentItem ) {
+ currentItem->createNode( doc, itemsElement );
+ currentItem = currentItem->nextSibling();
+ }
+
+}
+
+
+
+/*!
+ Creates a KDGanttViewItem according to the specification in a DOM
+ element.
+
+ \param view the view in which the item will be inserted
+ \param element the DOM element from which to read the specification
+ \return the newly created item
+*/
+KDGanttViewItem* KDGanttViewItem::createFromDomElement( KDGanttView* view,
+ QDomElement& element )
+{
+ QString typeString = element.attribute( "Type" );
+ Q_ASSERT( !typeString.isEmpty() );
+ KDGanttViewItem* item;
+ if( typeString == "Task" )
+ item = new KDGanttViewTaskItem( view );
+ else if( typeString == "Summary" )
+ item = new KDGanttViewSummaryItem( view );
+ else if( typeString == "Event" )
+ item = new KDGanttViewEventItem( view );
+ else {
+ qDebug( "Unknown item type %s in KDGanttViewItem::createFromDomElement()", typeString.latin1() );
+ return 0;
+ }
+
+ item->loadFromDomElement( element );
+ return item;
+}
+
+
+/*!
+ Creates a KDGanttViewItem according to the specification in a DOM
+ element.
+
+ \param view the view in which the item will be inserted
+ \param previous to item behind this one should appear
+ \param element the DOM element from which to read the specification
+ \return the newly created element
+*/
+KDGanttViewItem* KDGanttViewItem::createFromDomElement( KDGanttView* view,
+ KDGanttViewItem* previous,
+ QDomElement& element )
+{
+ QString typeString = element.attribute( "Type" );
+ Q_ASSERT( !typeString.isEmpty() );
+ KDGanttViewItem* item;
+ if( typeString == "Task" )
+ item = new KDGanttViewTaskItem( view, previous );
+ else if( typeString == "Summary" )
+ item = new KDGanttViewSummaryItem( view, previous );
+ else if( typeString == "Event" )
+ item = new KDGanttViewEventItem( view, previous );
+ else {
+ qDebug( "Unknown item type in KDGanttViewItem::createFromDomElement()" );
+ return 0;
+ }
+
+ item->loadFromDomElement( element );
+ return item;
+}
+
+
+
+
+/*!
+ Creates a KDGanttViewItem according to the specification in a DOM
+ element.
+
+ \param parent the parent item under which the item will be inserted
+ \param element the DOM element from which to read the specification
+ \return the newly created element
+*/
+KDGanttViewItem* KDGanttViewItem::createFromDomElement( KDGanttViewItem* parent,
+ QDomElement& element )
+{
+ QString typeString = element.attribute( "Type" );
+ Q_ASSERT( !typeString.isEmpty() );
+ KDGanttViewItem* item;
+ if( typeString == "Task" )
+ item = new KDGanttViewTaskItem( parent );
+ else if( typeString == "Summary" )
+ item = new KDGanttViewSummaryItem( parent );
+ else if( typeString == "Event" )
+ item = new KDGanttViewEventItem( parent );
+ else {
+ qDebug( "Unknown item type in KDGanttViewItem::createFromDomElement()" );
+ return 0;
+ }
+
+ item->loadFromDomElement( element );
+ return item;
+}
+
+
+/*!
+ Creates a KDGanttViewItem according to the specification in a DOM
+ element.
+
+ \param parent the parent item under which the item will be inserted
+ \param previous to item behind this one should appear
+ \param element the DOM element from which to read the specification
+ \return the newly created element
+*/
+KDGanttViewItem* KDGanttViewItem::createFromDomElement( KDGanttViewItem* parent,
+ KDGanttViewItem* previous,
+ QDomElement& element )
+{
+ QString typeString = element.attribute( "Type" );
+ Q_ASSERT( !typeString.isEmpty() );
+ KDGanttViewItem* item;
+ if( typeString == "Task" )
+ item = new KDGanttViewTaskItem( parent, previous );
+ else if( typeString == "Summary" )
+ item = new KDGanttViewSummaryItem( parent, previous );
+ else if( typeString == "Event" )
+ item = new KDGanttViewEventItem( parent, previous );
+ else {
+ qDebug( "Unknown item type in KDGanttViewItem::createFromDomElement()" );
+ return 0;
+ }
+
+ item->loadFromDomElement( element );
+ return item;
+}
+
+
+/*
+ Fills in the values in the item by reading the DOM element.
+*/
+void KDGanttViewItem::loadFromDomElement( QDomElement& element )
+{
+ QDomNode node = element.firstChild();
+ Shape startShape = TriangleDown, middleShape = TriangleDown,
+ endShape = TriangleDown;
+ QColor startColor, middleColor, endColor;
+ QColor startHighlightColor, middleHighlightColor, endHighlightColor;
+ QString tempName;
+ while( !node.isNull() ) {
+ QDomElement element = node.toElement();
+ if( !element.isNull() ) { // was really an element
+ QString tagName = element.tagName();
+ if( tagName == "StartTime" ) {
+ QDateTime value;
+ if( KDGanttXML::readDateTimeNode( element, value ) )
+ setStartTime( value );
+ } else if( tagName == "EndTime" ) {
+ QDateTime value;
+ if( KDGanttXML::readDateTimeNode( element, value ) )
+ setEndTime( value );
+ } else if( tagName == "Text" ) {
+ QString value;
+ if( KDGanttXML::readStringNode( element, value ) )
+ setText( value );
+ } else if( tagName == "Font" ) {
+ QFont value;
+ if( KDGanttXML::readFontNode( element, value ) )
+ setFont( value );
+ } else if( tagName == "TooltipText" ) {
+ QString value;
+ if( KDGanttXML::readStringNode( element, value ) )
+ setTooltipText( value );
+ } else if( tagName == "WhatsThisText" ) {
+ QString value;
+ if( KDGanttXML::readStringNode( element, value ) )
+ setWhatsThisText( value );
+ } else if( tagName == "Pixmap" ) {
+ QPixmap value;
+ if( KDGanttXML::readPixmapNode( element, value ) )
+ setPixmap( value );
+ } else if( tagName == "ListViewText" ) {
+ QString value;
+ if( KDGanttXML::readStringNode( element, value ) )
+ setListViewText( value );
+ } else if( tagName == "Open" ) {
+ bool value;
+ if( KDGanttXML::readBoolNode( element, value ) )
+ setOpen( value );
+ } else if( tagName == "Highlight" ) {
+ bool value;
+ if( KDGanttXML::readBoolNode( element, value ) )
+ setHighlight( value );
+ } else if( tagName == "StartShape" ) {
+ QString value;
+ if( KDGanttXML::readStringNode( element, value ) )
+ startShape = stringToShape( value );
+ } else if( tagName == "MiddleShape" ) {
+ QString value;
+ if( KDGanttXML::readStringNode( element, value ) )
+ middleShape = stringToShape( value );
+ } else if( tagName == "EndShape" ) {
+ QString value;
+ if( KDGanttXML::readStringNode( element, value ) )
+ endShape = stringToShape( value );
+ } else if( tagName == "DefaultColor" ) {
+ QColor value;
+ if( KDGanttXML::readColorNode( element, value ) )
+ setDefaultColor( value );
+ } else if( tagName == "StartColor" ) {
+ QColor value;
+ if( KDGanttXML::readColorNode( element, value ) )
+ startColor = value;
+ } else if( tagName == "MiddleColor" ) {
+ QColor value;
+ if( KDGanttXML::readColorNode( element, value ) )
+ middleColor = value;
+ } else if( tagName == "EndColor" ) {
+ QColor value;
+ if( KDGanttXML::readColorNode( element, value ) )
+ endColor = value;
+ } else if( tagName == "DefaultHighlightColor" ) {
+ QColor value;
+ if( KDGanttXML::readColorNode( element, value ) )
+ setDefaultHighlightColor( value );
+ } else if( tagName == "StartHighlightColor" ) {
+ QColor value;
+ if( KDGanttXML::readColorNode( element, value ) )
+ startHighlightColor = value;
+ } else if( tagName == "MiddleHighlightColor" ) {
+ QColor value;
+ if( KDGanttXML::readColorNode( element, value ) )
+ middleHighlightColor = value;
+ } else if( tagName == "EndHighlightColor" ) {
+ QColor value;
+ if( KDGanttXML::readColorNode( element, value ) )
+ endHighlightColor = value;
+ } else if( tagName == "TextColor" ) {
+ QColor value;
+ if( KDGanttXML::readColorNode( element, value ) )
+ setTextColor( value );
+ } else if( tagName == "Name" ) {
+ QString value;
+ if( KDGanttXML::readStringNode( element, value ) )
+ tempName = value;
+ } else if( tagName == "Items" ) {
+ QDomNode node = element.firstChild();
+ KDGanttViewItem* previous = 0;
+ while( !node.isNull() ) {
+ QDomElement element = node.toElement();
+ if( !element.isNull() ) { // was really an element
+ QString tagName = element.tagName();
+ if( tagName == "Item" ) {
+ KDGanttViewItem* newItem;
+ if( previous )
+ newItem =
+ KDGanttViewItem::createFromDomElement( this,
+ previous,
+ element );
+ else
+ newItem =
+ KDGanttViewItem::createFromDomElement( this,
+ element );
+ previous = newItem;
+ } else {
+ qDebug( "Unrecognized tag name: %s", tagName.latin1() );
+ Q_ASSERT( false );
+ }
+ }
+
+ node = node.nextSibling();
+ }
+ } else {
+ qDebug( "Unrecognized tag name: %s", tagName.latin1() );
+ Q_ASSERT( false );
+ }
+ }
+
+ node = node.nextSibling();
+ }
+
+ setColors( startColor, middleColor, endColor );
+ setHighlightColors( startHighlightColor, middleHighlightColor,
+ endHighlightColor );
+ setShapes( startShape, middleShape, endShape );
+ generateAndInsertName( tempName );
+}
+
+
+QString KDGanttViewItem::typeToString( Type type )
+{
+ switch( type ) {
+ case Event:
+ return "Event";
+ case Summary:
+ return "Summary";
+ case Task:
+ return "Task";
+ default:
+ qDebug( "Unknown type in KDGanttViewItem::typeToString()" );
+ return "Summary";
+ }
+ return "";
+}
+
+
+/*!
+ Returns the y coordinate of this item.
+
+ \return the y coordinate of this item
+*/
+int KDGanttViewItem::getCoordY()
+{
+ return itemPos() + height()/2;
+}
+
+
+void KDGanttViewItem::showSubItems()
+{
+ showSubitemTree( getCoordY() );
+}
+
+
+void KDGanttViewItem::showSubitemTree( int CoordY )
+{
+
+ KDGanttViewItem* temp = firstChild();
+ if (temp) {
+ while (temp != 0) {
+ if (temp->isOpen() || !temp->displaySubitemsAsGroup() ) {
+ temp->showItem( true, CoordY );
+ if ( temp->firstChild() )
+ temp->firstChild()->hideSubtree();
+ } else {
+ if ( temp->displaySubitemsAsGroup() && temp->firstChild() )
+ temp->hideSubtree();
+ else {
+ temp->showSubitemTree( CoordY );
+ }
+ }
+ temp = temp->nextSibling();
+ }
+ showItem( false );
+ } else {
+ showItem( true, CoordY );
+ }
+}
+
+
+/*!
+ Returns the start time of the children of this item.
+
+ \return the start time of the children of this item
+*/
+QDateTime KDGanttViewItem::myChildStartTime()
+{
+ QDateTime ret, tempTime;
+ bool set = true;
+ KDGanttViewItem* temp = (KDGanttViewItem*) firstChild();
+ if (temp) {
+ while (temp != 0) {
+ if ( !temp->displaySubitemsAsGroup() ) {
+ tempTime = temp->startTime();
+ } else {
+ tempTime = temp->myChildStartTime();
+ }
+ if ( set ) {
+ set = false;
+ ret = tempTime;
+ } else {
+ if ( tempTime < ret ) {
+ ret = tempTime;
+ }
+ }
+ temp = temp->nextSibling();
+ }
+ } else {
+ ret = startTime();
+ }
+ return ret;
+}
+
+
+/*!
+ Returns the end time of the children of this item.
+
+ \return the end time of the children of this item
+*/
+QDateTime KDGanttViewItem::myChildEndTime()
+{
+ QDateTime ret, tempTime;
+ bool set = true;
+ KDGanttViewItem* temp = (KDGanttViewItem*) firstChild();
+ if (temp) {
+ while (temp != 0) {
+ if ( !temp->displaySubitemsAsGroup() ) {
+ tempTime = temp->endTime();
+ } else {
+ tempTime = temp->myChildEndTime();
+ }
+ if ( set ) {
+ set = false;
+ ret = tempTime;
+ } else {
+ if ( tempTime > ret ) {
+ ret = tempTime;
+ }
+ }
+ temp = temp->nextSibling();
+ }
+ } else {
+ ret = endTime();
+ }
+ return ret;
+}
+
+
+/*!
+ Returns whether the 'showNoInformation' line should be shown for this item
+
+ \return true if showNoInformation line should be shown
+ \sa setShowNoInformation(), KDGanttView::setNoInformationBrush(), KDGanttView::noInformationBrush()
+*/
+bool KDGanttViewItem::showNoInformation()
+{
+ return _showNoInformation;
+}
+
+
+/*!
+ Specifies whether the 'showNoInformation' line should be shown for
+ this item.
+ The 'showNoInformation' line is drawn over the whole timeline.
+ The height of the line is the height of the item.
+ The brush of the line is specified by KDGanttView::setNoInformationBrush().
+ (i.e. the same brush for all items of the Gantt view).
+ The default brush is QBrush( QColor ( 100,100,100 ), Qt::FDiagPattern );
+ \param show if true, the 'showNoInformation' line is shown for this item
+ \sa showNoInformation(), KDGanttView::setNoInformationBrush(), KDGanttView::noInformationBrush()
+*/
+void KDGanttViewItem::setShowNoInformation( bool show )
+{
+ _showNoInformation = show;
+ myGanttView->myTimeTable->updateMyContent();
+}
+
+
+/*!
+ If the name of this item is \a name (i.e., listViewText() == name),
+ the pointer to this item is returned. Otherwise, it looks for an
+ item with name \a name in the set of children and subchildren of
+ this item.
+ \param name the name of the item
+ \return the pointer to the item with name \a name
+*/
+KDGanttViewItem* KDGanttViewItem::getChildByName( const QString& name )
+{
+ if ( listViewText() == name )
+ return this;
+ KDGanttViewItem* temp = firstChild(),* ret;
+ while (temp != 0) {
+ if ( (ret = temp->getChildByName( name )))
+ return ret;
+ temp = temp->nextSibling();
+ }
+ return 0;
+}
+
+
+/*
+void KDGanttViewItem::printinfo( QString s )
+{
+ KDGanttViewItem* temp = firstChild();
+ while (temp != 0) {
+ temp->printinfo(" "+s );
+ temp = temp->nextSibling();
+ }
+}
+*/
+
+
+/*!
+ Returns whether this item has at least one subitem that is a calendar.
+ A subitem is a calendar, if that item has at least one subitem or
+ displaySubitemAsGroup() is true for that item.
+
+ \return true if the item has at least one subitem that is a calendar.
+*/
+bool KDGanttViewItem::subitemIsCalendar() const
+{
+ KDGanttViewItem* temp = firstChild();
+ bool ret = false;
+ while (temp) {
+ if (temp->firstChild() || temp->displaySubitemsAsGroup() ) {
+ ret = true;
+ break;
+ }
+ temp = temp->nextSibling();
+ }
+ return ret;
+}
+
+
+int KDGanttViewItem::computeHeight()
+{
+ int hei = 0;
+ // if not visible, hide item and all subitems, return height = 0
+ if ( !isVisible() ) {
+ showItem( false );
+ if ( firstChild() )
+ firstChild()->hideSubtree();
+ // qDebug("KDGanttViewItem::computeHeight() %s returns 0 ", QListViewItem::text(0).latin1());
+ return 0;
+ }
+
+ KDGanttViewItem* temp;
+ bool show = true;
+
+ // explanation of terms:
+ // display opened item as usual:
+ // display this item opened, display Gantt part on the timeline of this item.
+ // the same for all subitems: display all subitems on its own timeline
+ // display closed item as usual:
+ // display this item closed, display Gantt part on the timeline of this item.
+ // do not display any subitem.
+
+ // desired behaviour:
+ // if not in calendar mode( GanttView is NOT in calendar mode ):
+ // opened:
+ // display opened item as usual
+ // closed:
+ // if not displaySubitemsAsGroup()
+ // display closed item as usual
+ // else ( displaySubitemsAsGroup() == true )
+ // display not this item, display subitems on the timeline of this item
+ // else ( GanttView is in calendar mode )
+ // 4 cases:
+ // opened && displaySubitemsAsGroup():
+ // display not this item, display subitems on the timeline of this item,
+ // which have the property displaySubitemsAsGroup() == false
+ // display the other items,
+ // which have the property displaySubitemsAsGroup() == true,
+ // as usual below this item on their own timeline
+ // opened && NOT displaySubitemsAsGroup():
+ // display opened item as usual
+ // closed && displaySubitemsAsGroup():
+ // display not this item, display subitems on the timeline of this item,
+ // which have the property displaySubitemsAsGroup() == false
+ // closed && NOT displaySubitemsAsGroup():
+ // display closed item as usual
+ //
+ if ( isOpen() ) {
+ //qDebug("KDGanttViewItem::computeHeight() %s is open ", QListViewItem::text(0).latin1());
+ temp = firstChild();
+ // if item opened, iterate over all subitems
+ int tempHeight;
+ // introduced special for performance reasons
+ bool special = displaySubitemsAsGroup() && myGanttView->calendarMode();
+ while (temp != 0) {
+ tempHeight = temp->computeHeight();
+ if ( special ) {
+ if ( temp->displaySubitemsAsGroup() ) {
+ hei += tempHeight;
+ //qDebug(" hei added ");
+ } else {
+ temp->showSubitemTree( getCoordY() );
+
+ }
+ } else {
+ hei += tempHeight;
+ //qDebug(" hei added ");
+ }
+ temp = temp->nextSibling();
+ }
+ } else { // closed!
+ //qDebug("KDGanttViewItem::computeHeight() %s is closed ", QListViewItem::text(0).latin1());
+
+ if ( !displaySubitemsAsGroup() ) {
+ if ( firstChild() ) {
+ firstChild()->hideSubtree();
+ }
+ } else {
+ if ( firstChild() ) {
+ showSubitemTree( getCoordY() );
+ show = false ;
+ }
+ }
+
+ }
+ if ( show )
+ showItem( true );
+
+ hei += height();
+ //qDebug("KDGanttViewItem::computeHeight() %s returns: %d ", QListViewItem::text(0).latin1(), hei);
+ return hei;
+}
+
+
+// if this item has at least one subitem which has the property displaySubitemsAsGroup(),
+// a false is returned
+bool KDGanttViewItem::showNoCross()
+{
+ KDGanttViewItem * temp = firstChild();
+ if ( !temp )
+ return false;
+ while ( temp ) {
+ if ( temp->displaySubitemsAsGroup() ) {
+ return false;
+ }
+ temp = temp->nextSibling();
+ }
+ return true;
+}
+
+
+void KDGanttViewItem::paintBranches ( QPainter* p, const QColorGroup& cg,
+ int w, int y, int h )
+{
+ QListViewItem::paintBranches ( p, cg, w, y, h);
+ if ( !myGanttView->calendarMode() )
+ return;
+ else {
+ KDGanttViewItem * temp = firstChild();
+ while ( temp ) {
+ if ( temp->showNoCross() ) {
+ //qDebug("paintNoCross %s ", temp->listViewText(0).latin1());
+ int y_coord = temp->itemPos() -height ()- itemPos();
+ int hei = temp->height();
+ //qDebug(" y %d w %d h %d ", y,w,h);
+ //qDebug("yc %d hei %d",y_coord,hei );
+ myGanttView->myListView->paintemptyarea( p, QRect( 0,y+y_coord,w,hei));
+ int x_c = w/2;
+ int y_c = y+y_coord+ temp->height ()/2;
+ int y_ce ;
+ if ( temp->itemBelow() && temp->itemBelow()->parent() == this )
+ y_ce =y+y_coord+ temp->height ();
+ else
+ y_ce = y_c;
+ int i;
+ for (i = y+y_coord+1; i <= y_ce; i+=2 ) {
+ p->drawPoint( x_c, i );
+ }
+ for (i = x_c+2; i < w; i+=2 ) {
+ p->drawPoint( i, y_c );
+ }
+ }
+ temp = temp->nextSibling();
+ }
+ }
+}
+
+
+// resets the visibility os the subitems according to the setting of calendar mode
+void KDGanttViewItem::resetSubitemVisibility()
+{
+ KDGanttViewItem* temp;
+ temp = firstChild();
+ bool allow = false;
+ if ( myGanttView->calendarMode() ) {
+ // in calendarmode only items can be opened which have subitems which have subitems
+ if ( ! temp ) {
+ if ( !parent() )
+ // has no parent, has no child : show!
+ setVisible( true );
+ else
+ // has parent, has no child : hide!
+ setVisible( false );
+ return;
+ }
+ setVisible( true );
+ while (temp) {
+ if (temp->firstChild()) {
+ allow = true;
+ temp->resetSubitemVisibility();
+ }
+ else {
+ temp->setVisible(false);
+ }
+ temp = temp->nextSibling();
+ }
+ } else {
+ setVisible( true );
+ // all items can be opened
+ allow = true;
+ while (temp != 0) {
+ temp->resetSubitemVisibility();
+ temp = temp->nextSibling();
+ }
+ }
+ if ( !allow && isOpen() )
+ setOpen( false );
+
+}
+
+
+/*!
+ Specifies whether this item should behave like a calendar.
+ In calendar mode, only those items can be opened
+ which have subitems which have subitems.
+ An item which has subitems which have no subitems is called a calendar.
+ I.e., an item that contains
+ multiple calendars can be opened, while a calendar item itself cannot.
+ But if all calendars of an item do not have any subitem (e.g at startup),
+ the program cannot detect automatically that it should be possible to open
+ this item.
+ To enable this, call setIsCalendar( true ); for at least one calendar
+
+ \param cal true in order behave this item like a calendar
+ highlighting off for this item
+ \sa isCalendar()
+*/
+
+/* removed
+void KDGanttViewItem::setIsCalendar( bool cal )
+{
+ _isCalendar = cal;
+ updateCanvasItems();
+}
+*/
+
+/*!
+ Returns whether this item behaves like a calendar,
+ even though it has no subitem which has subitems; when highlighting
+ with setHighlight() or by the user with the mouse.
+
+ \return true if the item behaves like a calendar
+ \sa setIsCalendar()
+*/
+/* removed
+bool KDGanttViewItem::isCalendar( ) const
+{
+ return _isCalendar;
+}
+*/
+
+
+/*!
+ \var KDGanttViewItem::startLine
+
+ the line at the beginning of the item
+*/
+
+/*!
+ \var KDGanttViewItem::endLine
+
+ the line at the end of the item
+*/
+
+
+/*!
+ \var KDGanttViewItem::startLineBack
+
+ the background line at the beginning of the item
+*/
+
+/*!
+ \var KDGanttViewItem::endLineBack
+
+ the background line at the end of the item
+*/
+
+
+/*!
+ \var KDGanttViewItem::actualEnd
+
+ the line at the actual end of the item
+*/
+
+/*!
+ \var KDGanttViewItem::startShape
+
+ the shape at the beginning of the item
+*/
+
+/*!
+ \var KDGanttViewItem::midShape
+
+ the shape in the middle of the item
+*/
+
+/*!
+ \var KDGanttViewItem::endShape
+
+ the shape at the end of the item
+*/
+
+/*!
+ \var KDGanttViewItem::startShapeBack
+
+ the background shape at the beginning of the item
+*/
+
+/*!
+ \var KDGanttViewItem::midShapeBack
+
+ the background shape in the middle of the item
+*/
+
+/*!
+ \var KDGanttViewItem::endShapeBack
+
+ the background shape at the end of the item
+*/
+
+
+/*!
+ \var KDGanttViewItem::myGanttView
+
+ a pointer to the KDGanttView object to which this item belongs
+*/
+
+/*!
+ \var KDGanttViewItem::textCanvas
+
+ the text object that is used for this item
+*/
+
+/*!
+ \var KDGanttViewItem::textCanvasText
+
+ the actual string that is displayed in the text object for this item
+*/
+
+/*!
+ \var KDGanttViewItem::myStartTime
+
+ the starting time of this item
+*/
+
+/*!
+ \var KDGanttViewItem::myEndTime
+
+ the ending time of this item
+*/
+
+/*!
+ \var KDGanttViewItem::isHighlighted
+
+ whether this item is currently highlighted or not
+*/
+
+/*!
+ \var KDGanttViewItem::isEditable
+
+ whether this item is currently editable or not
+*/
+
+/*!
+ \var KDGanttViewItem::myItemSize
+
+ the current size of this item
+*/
+
+/*!
+ \var KDGanttViewItem::blockUpdating
+
+ if true, updates to this item are currently blocked, to reduce
+ flicker or speed up redraws
+*/
+
+/*!
+ \var KDGanttViewItem::isVisibleInGanttView
+
+ this instance variable is true if the item is visible in the Gantt
+ view
+*/
+
+
+/*!
+ Returns the coordinate of this items middle left point
+*/
+QPoint KDGanttViewItem::middleLeft()
+{
+ return QPoint(myGanttView->myTimeHeader->getCoordX(myStartTime), itemPos()+height()/2);
+}
+/*!
+ Returns the coordinate of this items middle right point
+*/
+QPoint KDGanttViewItem::middleRight()
+{
+ return QPoint(myGanttView->myTimeHeader->getCoordX(myEndTime), itemPos()+height()/2);
+}
+/*!
+ Moves this items text.
+*/
+void KDGanttViewItem::moveTextCanvas(int x, int y)
+{
+ int mx = x + myTextOffset.x();
+ int my = y + myTextOffset.y();
+ if (myTextOffset.x() != 0)
+ mx -= 2*myItemSize; // keep old behaviour
+
+ textCanvas->move(mx+2*myItemSize,my-myItemSize/2);
+ //qDebug("%s: moveTextCanvas(%d,%d) offset: %d,%d moved to %d,%d",listViewText(0).latin1(),x,y,myTextOffset.x(),myTextOffset.y(),mx+2*myItemSize,my-myItemSize/2);
+}
+
+/*!
+ Moves this items text relative to the middle right end of the item
+ Used to move text away from link.
+*/
+void KDGanttViewItem::moveTextCanvas()
+{
+ QPoint m = myTextOffset+middleRight();
+ textCanvas->move(m.x(), m.y()-myItemSize/2);
+}
+
+/*!
+ Sets with how much the item text is offset.
+*/
+void KDGanttViewItem::setTextOffset(QPoint p)
+{
+ //qDebug("%s: setTextOffset() offset: %d,%d",listViewText(0).latin1(),p.x(),p.y());
+ myTextOffset.setX(p.x());
+ myTextOffset.setY(p.y());
+}
+
+bool KDGanttViewItem::isMyTextCanvas(QCanvasItem *tc)
+{
+ return tc == textCanvas;
+}
+
+/*!
+ Specifies the progress of this item in percent.
+ Progress is limited to minimum 0, maximum 100.
+
+ \param percent the progress in percent.
+*/
+
+void KDGanttViewItem::setProgress(int percent)
+{
+ myProgress = QMAX(0, percent);
+ myProgress = QMIN(100, myProgress);
+}
+
+/*!
+ Specifies the float start time of this item.
+ If the time is invalid, the start float is not shown.
+
+ \param start the float start time
+*/
+void KDGanttViewItem::setFloatStartTime(const QDateTime &start)
+{
+ myFloatStartTime = start;
+}
+
+/*!
+ Specifies the float end time of this item.
+ If the time is invalid, the end float is not shown.
+
+ \param end the float end time
+*/
+void KDGanttViewItem::setFloatEndTime(const QDateTime &end)
+{
+ myFloatEndTime = end;
+}
+
+void KDGanttViewItem::setMoveable(bool m)
+{
+ _isMoveable = m;
+}
+
+bool KDGanttViewItem::isMoveable() const
+{
+ return _isMoveable;
+}
+
+bool KDGanttViewItem::isResizeable() const
+{
+ return _isResizeable;
+}
+
+void KDGanttViewItem::setResizeable(bool r)
+{
+ _isResizeable = r;
+}
diff --git a/kdgantt/KDGanttViewItem.h b/kdgantt/KDGanttViewItem.h
new file mode 100644
index 00000000..e296db0a
--- /dev/null
+++ b/kdgantt/KDGanttViewItem.h
@@ -0,0 +1,254 @@
+/* -*- 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.
+ **
+ **********************************************************************/
+
+
+#ifndef KDGANTTVIEWITEM_H
+#define KDGANTTVIEWITEM_H
+
+#include <qdatetime.h>
+#include <qstring.h>
+#include <qcolor.h>
+#include <qpixmap.h>
+#include <qfont.h>
+#include <qlistview.h>
+#include <qcanvas.h>
+#include <qdom.h>
+#include <qdict.h>
+
+class KDGanttView;
+class KDTimeTableWidget;
+class KDTimeHeaderWidget;
+class KDGanttViewTaskLink;
+class KDCanvasLine;
+class KDCanvasText;
+class KDCanvasPolygonItem;
+class KDGanttViewTaskLinkGroup;
+
+class KDGanttViewItem : public QListViewItem
+{
+public:
+ enum Type { Event, Task, Summary };
+ enum Shape { TriangleDown, TriangleUp, Diamond, Square, Circle };
+
+protected:
+ KDGanttViewItem( Type type, KDGanttView* view,
+ const QString& lvtext = QString::null,
+ const QString& name = QString::null );
+ KDGanttViewItem( Type type, KDGanttViewItem* parent,
+ const QString& lvtext = QString::null,
+ const QString& name = QString::null );
+ KDGanttViewItem( Type type, KDGanttView* view, KDGanttViewItem* after,
+ const QString& lvtext = QString::null,
+ const QString& name = QString::null );
+ KDGanttViewItem( Type type, KDGanttViewItem* parent,
+ KDGanttViewItem* after,
+ const QString& lvtext = QString::null,
+ const QString& name = QString::null );
+
+ //bool _isCalendar;
+ bool isVisibleInGanttView;
+ void updateCanvasItems();
+ int getCoordY();
+ QDateTime myChildStartTime();
+ QDateTime myChildEndTime();
+ void generateAndInsertName( const QString& name );
+ KDCanvasLine * startLine, *endLine,
+ * startLineBack, *endLineBack, *actualEnd ;
+ KDCanvasPolygonItem* startShape,* midShape, *endShape, *progressShape,
+ * startShapeBack,* midShapeBack, *endShapeBack,
+ * floatStartShape, * floatEndShape;
+ KDGanttView* myGanttView;
+ KDCanvasText* textCanvas;
+ QString textCanvasText;
+ QDateTime myStartTime, myEndTime;
+ bool isHighlighted, isEditable;
+ int myItemSize;
+ bool blockUpdating;
+
+ void moveTextCanvas(int x, int y);
+ int myProgress;
+ QDateTime myFloatStartTime;
+ QDateTime myFloatEndTime;
+
+public:
+ virtual ~KDGanttViewItem();
+
+ Type type() const;
+ void setEnabled( bool on );
+ bool enabled () const;
+ virtual void setOpen( bool o );
+ void setItemVisible( bool on );
+ bool itemVisible () const;
+ void setEditable( bool editable );
+ bool editable() const;
+ void setShowNoInformation( bool show );
+ bool showNoInformation();
+ void setDisplaySubitemsAsGroup( bool show );
+ bool displaySubitemsAsGroup() const;
+ void setPriority( int prio );
+ int priority();
+ virtual void setStartTime( const QDateTime& start );
+ QDateTime startTime() const;
+ virtual void setEndTime( const QDateTime& end );
+ QDateTime endTime() const;
+
+ void setText( const QString& text );
+ QString text() const;
+ void setListViewText( const QString& text, int column = 0 );
+ void setListViewText( int column, const QString& text );
+ QString listViewText( int column = 0 ) const;
+ void setFont( const QFont& font );
+ QFont font() const;
+ void setTooltipText( const QString& text );
+ QString tooltipText() const;
+ void setWhatsThisText( const QString& text );
+ QString whatsThisText() const;
+ void setPixmap( int column, const QPixmap& pixmap );
+ void setPixmap( const QPixmap& pixmap );
+ const QPixmap* pixmap( int column = 0 ) const;
+
+ void setHighlight( bool );
+ bool highlight() const;
+
+ bool subitemIsCalendar() const;
+ //void setIsCalendar( bool );
+ //bool isCalendar( ) const;
+
+ void setShapes( Shape start, Shape middle, Shape end );
+ void shapes( Shape& start, Shape& middle, Shape& end ) const;
+ void setDefaultColor( const QColor& );
+ QColor defaultColor() const;
+ void setColors( const QColor& start, const QColor& middle,
+ const QColor& end );
+ void colors( QColor& start, QColor& middle, QColor& end ) const;
+ void setDefaultHighlightColor( const QColor& );
+ QColor defaultHighlightColor() const;
+ void setHighlightColors( const QColor& start, const QColor& middle,
+ const QColor& end );
+ void highlightColors( QColor& start, QColor& middle, QColor& end ) const;
+ void setTextColor( const QColor& color );
+ QColor textColor() const;
+
+ void setProgress(int percent);
+ void setFloatStartTime(const QDateTime &start);
+ void setFloatEndTime(const QDateTime &end);
+
+ KDGanttViewItem* firstChild() const;
+ KDGanttViewItem* nextSibling() const;
+ KDGanttViewItem* parent() const;
+ KDGanttViewItem* itemAbove();
+ KDGanttViewItem* itemBelow( bool includeDisabled = true );
+ KDGanttViewItem* getChildByName( const QString& name );
+ QString name() const;
+ static KDGanttViewItem* find( const QString& name );
+
+ void createNode( QDomDocument& doc,
+ QDomElement& parentElement );
+ static KDGanttViewItem* createFromDomElement( KDGanttView* view,
+ QDomElement& element );
+ static KDGanttViewItem* createFromDomElement( KDGanttView* view,
+ KDGanttViewItem* previous,
+ QDomElement& element );
+ static KDGanttViewItem* createFromDomElement( KDGanttViewItem* parent,
+ QDomElement& element );
+ static KDGanttViewItem* createFromDomElement( KDGanttViewItem* parent,
+ KDGanttViewItem* previous,
+ QDomElement& element );
+
+ void setMoveable( bool m );
+ bool isMoveable() const;
+ void setResizeable( bool r );
+ bool isResizeable() const;
+
+private:
+ friend class KDGanttView;
+ friend class KDTimeTableWidget;
+ friend class KDTimeHeaderWidget;
+ friend class KDListView;
+ friend class KDGanttViewTaskLink;
+ friend class KDGanttViewTaskLinkGroup;
+ friend class KDGanttCanvasView;
+ friend class KDGanttViewItemDrag;
+ friend class itemAttributeDialog;
+
+ static QString shapeToString( Shape shape );
+ static Shape stringToShape( const QString& string );
+ static QString typeToString( Type type );
+
+ Type myType;
+ void initColorAndShapes(Type t);
+ void resetSubitemVisibility();
+ virtual void showItem( bool show = true, int coordY = 0 );
+ virtual void initItem();
+ int computeHeight();
+ void showSubItems();
+ void showSubitemTree( int );
+ void hideSubtree();
+ void setCallListViewOnSetOpen( bool call );
+ bool showNoCross();
+ void createShape(KDCanvasPolygonItem* &,KDCanvasPolygonItem* &, Shape);
+ void loadFromDomElement( QDomElement& element );
+
+ //QFont myFont;
+ QString myToolTipText,myWhatsThisText;
+ void paintBranches ( QPainter * p, const QColorGroup & cg, int w, int y, int h );
+ bool _displaySubitemsAsGroup;
+ bool _showNoInformation;
+ bool _enabled;
+ bool _callListViewOnSetOpen;
+ Shape myStartShape,myMiddleShape,myEndShape;
+ QColor myStartColor,myMiddleColor,myEndColor;
+ QColor myStartColorHL,myMiddleColorHL,myEndColorHL;
+ QColor myDefaultColor,myDefaultColorHL;
+ QColor myTextColor;
+ bool colorDefined,colorHLDefined;
+ QPoint getTaskLinkStartCoord(QPoint);
+ QPoint getTaskLinkEndCoord();
+ QPoint middleLeft();
+ QPoint middleRight();
+ void moveTextCanvas();
+ void setTextOffset(QPoint p);
+ bool isMyTextCanvas(QCanvasItem *tc);
+ QPoint myTextOffset;
+ QString _name;
+ bool shapeDefined;
+ int _priority;
+ static QDict<KDGanttViewItem> sItemDict;
+
+ bool _isMoveable;
+ bool _isResizeable;
+};
+
+
+#endif
diff --git a/kdgantt/KDGanttViewItemDrag.cpp b/kdgantt/KDGanttViewItemDrag.cpp
new file mode 100644
index 00000000..bbc62914
--- /dev/null
+++ b/kdgantt/KDGanttViewItemDrag.cpp
@@ -0,0 +1,140 @@
+
+
+/****************************************************************************
+ ** 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 <KDGanttViewItemDrag.h>
+#include <KDGanttViewItem.h>
+#include <qpixmap.h>
+#include <KDGanttView.h>
+
+/*!
+ \class KDGanttViewItemDrag KDGanttViewItemDrag.h
+ \brief Drag and drop of KD Gantt items.
+
+ This class implements drag and drop of KD Gantt items within a Gantt
+ chart. It is mainly used for internal purposes, but made a part of
+ the public API nevertheless, as you may want to subclass it for some
+ specialized functionality.
+*/
+
+
+/*!
+ The constructor. Creates a KDGanttViewItemDrag object and
+ initializes the drag data in the form of an XML document.
+
+ \param item the item that is dragged
+ \param source the source widget
+ \param name the internal object name
+*/
+KDGanttViewItemDrag::KDGanttViewItemDrag( KDGanttViewItem* item , QWidget *source, const char * name ) : QStoredDrag("x-application/x-KDGanttViewItemDrag", source, name )
+{
+ myItem = item;
+
+ QPixmap pix;
+ if (item->pixmap() )
+ pix = *(item->pixmap()) ;
+ else {
+ KDGanttViewItem::Shape start, middle, end;
+ item->shapes( start, middle, end );
+ QColor st, mi, en;
+ item->colors( st, mi, en );
+ pix =item->myGanttView->getPixmap( start, st, item->myGanttView->lvBackgroundColor(), 11 );
+ }
+ setPixmap( pix , QPoint( -10,-10 ));
+ QDomDocument doc( "GanttView" );
+ QString docstart = "<GanttView/>";
+ doc.setContent( docstart );
+ QDomElement itemsElement = doc.createElement( "Items" );
+ doc.documentElement().appendChild( itemsElement );
+ item->createNode( doc, itemsElement );
+ QDataStream s( array, IO_WriteOnly );
+ s << doc.toString();
+}
+
+
+/*!
+ Returns the encoded data of the drag object.
+
+ \param c the format of the data
+ \return the encoded data of the drag object
+*/
+QByteArray KDGanttViewItemDrag::encodedData( const char * c) const
+{
+ QString s ( c );
+ if ( s == "x-application/x-KDGanttViewItemDrag" ) {
+ return array;
+ }
+ return QByteArray();
+}
+
+/*!
+ Returns the dragged item
+
+ \return the dragged item
+*/
+KDGanttViewItem* KDGanttViewItemDrag::getItem()
+{
+ return myItem;
+}
+
+
+/*!
+ Returns whether this drag object class can decode the data passed in \a e.
+
+ \param e the mime source that has been dragged
+ \return true if KDGanttViewItemDrag can decode the data in \a e.
+*/
+bool KDGanttViewItemDrag::canDecode ( const QMimeSource * e )
+{
+ if ( QString( e->format() ) == "x-application/x-KDGanttViewItemDrag" )
+ return true;
+
+ return false;
+}
+
+
+/*!
+ Decodes the data passed in \a e into an XML string that is written
+ into \a string.
+
+ \param e the data to decode
+ \param string the resulting XML string
+ \return true if the operation succeeded
+*/
+bool KDGanttViewItemDrag::decode ( const QMimeSource * e , QString & string)
+{
+ QByteArray arr;
+ arr = e->encodedData( "x-application/x-KDGanttViewItemDrag");
+ QDataStream s( arr, IO_ReadOnly );
+ s >> string;
+ return true;
+}
+
diff --git a/kdgantt/KDGanttViewItemDrag.h b/kdgantt/KDGanttViewItemDrag.h
new file mode 100644
index 00000000..c017720e
--- /dev/null
+++ b/kdgantt/KDGanttViewItemDrag.h
@@ -0,0 +1,61 @@
+
+/****************************************************************************
+ ** Copyright (C) 2001-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.
+ **
+ **********************************************************************/
+
+
+#ifndef KDGANTTVIEWITEMGRAG_H
+#define KDGANTTVIEWITEMGRAG_H
+
+#include <qwidget.h>
+#include <qcstring.h>
+#include <qdragobject.h>
+
+
+class KDGanttViewItem;
+
+class KDGanttViewItemDrag :public QStoredDrag
+{
+public:
+ KDGanttViewItemDrag(KDGanttViewItem* item, QWidget *source, const char * name ) ;
+
+ QByteArray encodedData( const char * c) const;
+ KDGanttViewItem* getItem();
+ static bool canDecode ( const QMimeSource * e );
+ static bool decode ( const QMimeSource * e, QString & );
+protected:
+
+private:
+ QByteArray array;
+ KDGanttViewItem* myItem;
+};
+
+
+
+
+#endif
diff --git a/kdgantt/KDGanttViewSubwidgets.cpp b/kdgantt/KDGanttViewSubwidgets.cpp
new file mode 100644
index 00000000..d35f7eba
--- /dev/null
+++ b/kdgantt/KDGanttViewSubwidgets.cpp
@@ -0,0 +1,4048 @@
+/* -*- 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 <qlabel.h>
+#include <qheader.h>
+#include <qpainter.h>
+#include <qrect.h>
+#include <qtooltip.h>
+#include <qapplication.h>
+#include <qdrawutil.h>
+#include <qpalette.h>
+#include <qdragobject.h>
+#include <qptrlist.h>
+#include <qpen.h>
+
+#include <kglobal.h>
+#include <klocale.h>
+#include <kcalendarsystem.h>
+#include <kdebug.h>
+
+KDTimeTableWidget:: KDTimeTableWidget( QWidget* parent,KDGanttView* myGantt)
+ : QCanvas (parent)
+{
+ myGanttView = myGantt;
+ taskLinksVisible = true;
+ flag_blockUpdating = false;
+ int_blockUpdating = 0;
+ gridPen.setStyle(Qt::DotLine);
+ gridPen.setColor(QColor(100,100,100));
+ maximumComputedGridHeight = 0;
+ denseLineCount = 0;
+ denseLineBrush = QBrush( QColor ( 240,240,240 ));
+ noInfoLineBrush = QBrush( QColor ( 100,100,100 ), Qt::FDiagPattern );
+ pendingHeight = 0;
+ pendingWidth = 0;
+ retune(256);
+ resize(1,1);
+}
+
+QPtrList<KDGanttViewTaskLink> KDTimeTableWidget::taskLinks()
+{
+ return myTaskLinkList;
+}
+
+void KDTimeTableWidget::clearTaskLinks()
+{
+ // cannot use clear() here, as tasklinks will remove themselves from my list when deleted!
+ QPtrListIterator<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 QBrush& brush )
+{
+ noInfoLineBrush = brush;
+ updateMyContent();
+}
+QBrush KDTimeTableWidget::noInformationBrush() const
+{
+ return noInfoLineBrush;
+}
+
+void KDTimeTableWidget::removeItemFromTasklinks( KDGanttViewItem* item)
+{
+ QPtrListIterator<KDGanttViewTaskLink> it((myTaskLinkList));
+ for ( ; it.current(); ++it ) {
+ it.current()->removeItemFromList( item );
+ }
+}
+
+void KDTimeTableWidget::expandItem( QListViewItem * item)
+{
+ item->invalidateHeight () ;
+ //qApp->processEvents();
+ updateMyContent();
+}
+void KDTimeTableWidget::collapseItem( QListViewItem * item)
+{
+ item->invalidateHeight () ;
+ //qApp->processEvents();
+ updateMyContent();
+}
+
+void KDTimeTableWidget::highlightItem( QListViewItem * item )
+{
+ static bool itemwashighlighted;
+ static KDGanttViewItem* highlightedItem = 0;
+ if (highlightedItem)
+ highlightedItem->setHighlight(itemwashighlighted);
+ highlightedItem = ( KDGanttViewItem*)item;
+ itemwashighlighted = highlightedItem->highlight();
+ highlightedItem->setHighlight(true);
+ item->invalidateHeight () ;
+ 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;
+ QColor colcol;
+ QPen colPen;
+ bool colorIterator = true;
+
+
+ if (myGanttView->showMinorTicks()){//minor
+ colPen.setWidth(cw);
+ QPtrListIterator<KDCanvasRectangle> itcol(columnColorList);
+ QPtrListIterator<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( QPen::NoPen );
+ itcol.current()->setBrush( QBrush( 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( QPen::NoPen );
+ temprect->setBrush( QBrush( 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( QPen::NoPen );
+ itcol.current()->setBrush( QBrush( 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( QPen::NoPen );
+ temprect->setBrush( QBrush( 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()) {
+ QValueList<int>::iterator intIt = myGanttView->myTimeHeader->majorTicks.begin();
+ QValueList<int>::iterator intItEnd = myGanttView->myTimeHeader->majorTicks.end();
+ QPtrListIterator<KDCanvasRectangle> itcol(columnColorList);
+ QPtrListIterator<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( QPen::NoPen );
+ itcol.current()->setBrush( QBrush( 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( QPen::NoPen );
+ temprect->setBrush( QBrush( 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( QPen::NoPen );
+ itcol.current()->setBrush( QBrush( 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( QPen::NoPen );
+ temprect->setBrush( QBrush( 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
+ QPtrListIterator<KDCanvasLine> itgrid(verGridList);
+ for ( ; itgrid.current(); ++itgrid ) {
+ itgrid.current()->hide();
+ }
+ QPtrListIterator<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;
+ QPtrListIterator<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() != QPoint(wid,posY ))
+ templine->setPoints(0,posY,wid,posY );
+ if ( !templine->isVisible() )
+ templine->show();
+ //QString 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();
+ QPtrListIterator<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() != QRect(0, temp->itemPos(),wid, temp->height()) ) {
+ denseLine->move( 0, temp->itemPos() );
+ denseLine->setSize( wid, temp->height());
+ }
+ if (denseLine->brush() != denseLineBrush ) {
+ denseLine->setPen( QPen( 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();
+ QPtrListIterator<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( QPen( Qt::NoPen ) );
+ noInfoLine->setBrush( noInfoLineBrush);
+ noInfoLine->show();
+ }
+ temp = temp->itemBelow ();
+ }
+ while ( itnoinfo.current() ) {
+ itnoinfo.current()->hide();
+ ++itnoinfo;
+ }
+
+}
+
+void KDTimeTableWidget::computeTaskLinks()
+{
+ //compute and show tasklinks
+ QPtrListIterator<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, QBrush brush )
+{
+ denseLineBrush = brush;
+ denseLineCount = 0;
+ if ( count > 1 )
+ denseLineCount = count;
+}
+
+
+int KDTimeTableWidget::horBackgroundLines( QBrush& brush )
+{
+ brush = denseLineBrush;
+ return denseLineCount;
+}
+
+int KDTimeTableWidget::getCoordX( QDateTime dt ) {
+ return myGanttView->myTimeHeader->getCoordX(dt);
+}
+
+/* ***************************************************************
+ KDTimeHeaderWidget:: KDTimeHeaderWidget
+ ***************************************************************** */
+KDTimeHeaderWidget:: KDTimeHeaderWidget( QWidget* parent,KDGanttView* gant )
+ : QWidget (parent)
+{
+ myToolTip = new KDTimeHeaderToolTip(this,this);
+ mySizeHint = 0;
+ myGanttView = gant;
+ flagDoNotRecomputeAfterChange = true;
+ QDateTime start = (QDateTime::currentDateTime ()).addSecs(-3600);
+ setHorizonStart(start);
+ setHorizonEnd( start.addSecs(3600*2));
+ flagStartTimeSet = false;
+ flagEndTimeSet = false;
+ myCenterDateTime = QDateTime::currentDateTime ();
+ 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(QColor(220,220,220) );
+ setWeekendDays( 6, 7 );
+ myGridMinorWidth = 0;
+ myPopupMenu = new QPopupMenu(this);
+ QPopupMenu * zoomPopupMenu = new QPopupMenu(this);
+ myPopupMenu->insertItem (i18n("Zoom"),zoomPopupMenu, 1);
+ zoomPopupMenu->insertItem( i18n("Zoom to 100%"),this, SLOT(setSettings(int)),0 ,21,21 );
+ zoomPopupMenu->insertItem( i18n("Zoom to Fit"),this, SLOT(setSettings(int)),0 ,20,20 );
+ zoomPopupMenu->insertItem( i18n("Zoom In (x 2)"),this, SLOT(setSettings(int)),0 ,22,22 );
+ zoomPopupMenu->insertItem( i18n("Zoom In (x 6)"),this, SLOT(setSettings(int)),0 ,24,24 );
+ zoomPopupMenu->insertItem( i18n("Zoom In (x 12)"),this, SLOT(setSettings(int)),0 ,26,26 );
+ zoomPopupMenu->insertItem( i18n("Zoom Out (x 1/2)"),this, SLOT(setSettings(int)),0 ,23,23 );
+ zoomPopupMenu->insertItem( i18n("Zoom Out (x 1/6)"),this, SLOT(setSettings(int)),0 ,25,25 );
+ zoomPopupMenu->insertItem( i18n("Zoom Out (x 1/12)"),this, SLOT(setSettings(int)),0 ,27,27 );
+ scalePopupMenu = new QPopupMenu(this);
+ myPopupMenu->insertItem (i18n("Scale"),scalePopupMenu, 2);
+ scalePopupMenu->insertItem( i18n("Minute"),this, SLOT(setSettings(int)),0 ,1,1 );
+ scalePopupMenu->insertItem( i18n("Hour"),this, SLOT(setSettings(int)),0 ,2,2 );
+ scalePopupMenu->insertItem( i18n("Day"),this, SLOT(setSettings(int)),0 ,3,3 );
+ scalePopupMenu->insertItem( i18n("Week"),this, SLOT(setSettings(int)),0 ,4,4 );
+ scalePopupMenu->insertItem( i18n("Month"),this, SLOT(setSettings(int)),0 ,5,5 );
+ scalePopupMenu->insertItem( i18n("Auto"),this, SLOT(setSettings(int)),0 ,6,6 );
+ scalePopupMenu->setCheckable ( true );
+ timePopupMenu = new QPopupMenu(this);
+ myPopupMenu->insertItem (i18n("Time Format"),timePopupMenu, 3);
+ timePopupMenu->insertItem( i18n("24 Hour"),this, SLOT(setSettings(int)),0 ,40,40 );
+ timePopupMenu->insertItem( i18n("12 PM Hour"),this, SLOT(setSettings(int)),0 ,41,41 );
+ timePopupMenu->insertItem( i18n("24:00 Hour"),this, SLOT(setSettings(int)),0 ,42,42 );
+ yearPopupMenu = new QPopupMenu(this);
+ myPopupMenu->insertItem (i18n("Year Format"),yearPopupMenu, 4);
+ yearPopupMenu->insertItem( i18n("Four Digit"),this, SLOT(setSettings(int)),0 ,50,50 );
+ yearPopupMenu->insertItem( i18n("Two Digit"),this, SLOT(setSettings(int)),0 ,51,51 );
+ yearPopupMenu->insertItem( i18n("Two Digit Apostrophe"),this, SLOT(setSettings(int)),0 ,52,52 );
+ yearPopupMenu->insertItem( i18n("No Date on Minute/Hour Scale"),this, SLOT(setSettings(int)),0 ,53,53 );
+
+ gridPopupMenu = new QPopupMenu(this);
+ myPopupMenu->insertItem (i18n("Grid"),gridPopupMenu,5);
+ gridPopupMenu->insertItem( i18n("Show Minor Grid"),this, SLOT(setSettings(int)),0 ,10,10 );
+ gridPopupMenu->insertItem( i18n("Show Major Grid"),this, SLOT(setSettings(int)),0 ,11,11 );
+ gridPopupMenu->insertItem( i18n("Show No Grid"),this, SLOT(setSettings(int)),0 ,12,12 );
+ myPopupMenu->insertItem( i18n("Print"),this, SLOT(setSettings(int)),0 ,30,30 );
+ connect(myPopupMenu, SIGNAL ( aboutToShow () ) , this, 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( QString::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()) );
+
+
+}
+
+QString KDTimeHeaderWidget::getToolTipText(QPoint p)
+{
+ return KGlobal::locale()->formatDateTime(getDateTimeForIndex(p.x()));
+}
+void KDTimeHeaderWidget::addTickRight( int num )
+{
+ int secs = ((num*getTickTime())-30);
+ setHorizonEnd(getDateTimeForIndex(width()).addSecs(secs));
+ //qApp->processEvents();
+}
+
+void KDTimeHeaderWidget::addTickLeft( int num )
+{
+ int secs = ((num*getTickTime())-30);
+ setHorizonStart(getDateTimeForIndex(0).addSecs(-secs));
+ //qApp->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 QScrollView scrollbar update)
+ if (myGanttView && myGanttView->myCanvasView)
+ myGanttView->myCanvasView->updateScrollBars();
+}
+
+bool KDTimeHeaderWidget::registerStartTime()
+{
+
+ QListViewItemIterator it( myGanttView->myListView );
+ if (!flagStartTimeSet) {
+ QDateTime 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) {
+ QDateTime temp , time;
+ KDGanttViewItem* item;
+ bool setNewTime = false;
+ item = (KDGanttViewItem*)myGanttView->myListView->firstChild();
+ if ( item ) {
+ temp = item->startTime();
+ time = temp;
+ QListViewItemIterator 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( QDateTime begin, QDateTime end )
+{
+ QDateTime 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( QDateTime start, QDateTime 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();
+ repaint();
+ 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 QDateTime& 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()
+*/
+QDateTime 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 QDateTime& 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()
+*/
+QDateTime 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 );
+ //repaintMe();
+ 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 QDateTime& column,
+ const QColor& 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)->layout( this, height );
+ }
+}
+
+void KDTimeHeaderWidget::addIntervalBackgroundColor( KDIntervalColorRectangle* newItem )
+{
+ icList.append(newItem);
+ updateTimeTable();
+}
+
+#if 0
+bool KDTimeHeaderWidget::changeBackgroundInterval( const QDateTime& oldstart,
+ const QDateTime& oldend,
+ const QDateTime& newstart,
+ const QDateTime& 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 QDateTime& start,
+ const QDateTime& 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 QDateTime& start,
+ const QDateTime& end,
+ const QColor& 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();
+}
+QDateTime KDTimeHeaderWidget::getDateTimeForIndex(int X, bool local )
+{
+ int coordX = X;
+ if ( !local ) {
+ QPoint p = QPoint ( 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(QColor& col,int coordLow, int coordHigh)
+{
+ if (!flagShowMajorTicks && !flagShowMinorTicks)
+ return false;
+ QDateTime 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()
+*/
+QColor KDTimeHeaderWidget::columnBackgroundColor( const QDateTime& column ) const
+{
+ QColor 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 QColor& color )
+{
+ myWeekendBackgroundColor = color ;
+ updateTimeTable();
+}
+
+
+/*!
+ Returns the background color for weekend days.
+
+ \return the background color for weekend days
+ \sa setWeekendBackgroundColor(), setWeekendDays(), weekendDays()
+*/
+QColor 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 QColor& 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()
+*/
+QColor 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 ( QResizeEvent * )
+{
+ // 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()) {
+ QValueList<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::repaintMe(int left,int paintwid, QPainter* painter)
+{
+ if (flagDoNotRecomputeAfterChange) return;
+ QColorGroup qcg =QColorGroup( white, black,white, darkGray,black,gray,gray) ;
+ QPainter* p;
+ int offsetLeft = 0;
+ if ( paintwid > paintPix.width()-100 )
+ paintPix.resize( paintwid+100, height () );
+ if ( painter )
+ p = painter;
+ else {
+ p = new QPainter( &paintPix );
+ offsetLeft = left-50;
+ }
+ if ( mouseDown ) {
+ p->fillRect( left-offsetLeft, 0, paintwid, height(), QBrush(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(), QBrush(paletteBackgroundColor().dark()) );
+ } else {
+ if (! painter )
+ p->fillRect( left-offsetLeft, 0, paintwid, height(), QBrush(paletteBackgroundColor()) );
+ }
+ p->setPen(QColor(40,40,40));
+ QFont tempFont = p->font();
+ tempFont.setWeight(63);
+ p->setFont(tempFont);
+ int hei1 = myMajorGridHeight,
+ hei2 = height(),
+ wid1 = myGridMinorWidth;
+ int xCoord;
+ int lwid = 1;
+
+ QValueList<QString>::iterator it;
+ QValueList<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
+
+QDateTime KDTimeHeaderWidget::getEvenTimeDate(QDateTime tempdatetime ,Scale sc)
+{
+ QDate 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 = QDateTime (tempdate, QTime (0,0));
+ break;
+ case KDGanttView::Week:
+ tempdate = tempdatetime.date();
+ while (tempdate.dayOfWeek ()!= KGlobal::locale()->weekStartDay())
+ tempdate = tempdate.addDays(-1);
+ //tempdate = tempdate.addDays(-7);
+ tempdatetime = QDateTime (tempdate, QTime (0,0));
+ break;
+ case KDGanttView::Day:
+ tempdatetime = QDateTime (tempdatetime.date(), QTime ( 0,0 ) );
+ break;
+ case KDGanttView::Hour:
+ hour = tempdatetime.time().hour();
+ while (24%tempMinorScaleCount > 0 && 24%tempMinorScaleCount < 24)
+ ++tempMinorScaleCount;
+ hour = ( hour /tempMinorScaleCount)*tempMinorScaleCount;
+ tempdatetime = QDateTime (tempdatetime.date(), QTime (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 = QDateTime (tempdatetime.date(), QTime (tempdatetime.time().hour(),min ));
+
+ break;
+ case KDGanttView::Auto:
+ break;
+ }
+ return tempdatetime;
+}
+
+
+void KDTimeHeaderWidget::computeRealScale(QDateTime 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);
+ QPainter p(this);
+ int Width, Height;
+ QString testTextMinor,testTextMajor, tempStr;
+ QRect itemRectMinor, itemRectMajor;
+ QDate 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(QDate::currentDate());
+ minorPerMajor = 2400;
+ break;
+ case KDGanttView::Day:
+ minorItems = minorItems/(60*24);
+ testTextMinor = "88";
+ testTextMajor = "Aug 30, x"+getYear(QDate::currentDate());
+ minorPerMajor = 700;
+ break;
+ case KDGanttView::Week:
+ minorItems = minorItems/(60*24*7);
+ testTextMinor = "88";
+ testTextMajor = "Aug x"+getYear(QDate::currentDate());
+ minorPerMajor = 435; // 435 = 365days/12months/7days * 100
+ break;
+ case KDGanttView::Month:
+ minorItems = (minorItems*12)/(60*24*365);
+ testTextMinor = "M";
+ testTextMajor = "x"+getYear(QDate::currentDate());
+ minorPerMajor = 1200;
+ break;
+ case KDGanttView::Auto:
+ qDebug("KDGanttView::Internal Error in KDTimeHeaderWidget::computeTicks() ");
+ qDebug(" RealScale == Auto : This may not be! ");
+ break;
+ }
+ itemRectMinor = p.boundingRect ( 10, 10, 2, 2, Qt::AlignLeft,testTextMinor);
+ itemRectMajor = p.boundingRect ( 10, 10, 2, 2, Qt::AlignLeft,testTextMajor);
+ p.end();
+ //qDebug(" tempMinorScaleCount %d ", tempMinorScaleCount);
+ Height = itemRectMinor.height()+itemRectMajor.height()+11;
+ Width = (itemRectMinor.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 < itemRectMajor.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 geometry
+ if (width() != Width || height() != Height )
+ {
+ resize( Width, Height );
+ emit sizeChanged( Width );
+ }
+ myMajorGridHeight = itemRectMajor.height()+5;
+ QTime tempTime = myRealStart.time();
+ QDateTime 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(QString::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);
+ repaint();
+}
+
+
+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 QDateTime& 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(QPaintEvent *p)
+{
+ repaintMe(p->rect().x(),p->rect().width());
+}
+
+
+int KDTimeHeaderWidget::getCoordX(QDate date)
+{
+ int wid = width();
+ int daysAll = myRealStart.daysTo(myRealEnd);
+ if (daysAll == 0) return 0;
+ int days = myRealStart.daysTo(QDateTime(date));
+ return (wid *days) /daysAll;
+}
+
+
+int KDTimeHeaderWidget::getCoordX(QDateTime 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));
+}
+
+
+QString KDTimeHeaderWidget::getYear(QDate date)
+{
+ QString 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;
+}
+
+
+QString KDTimeHeaderWidget::getHour(QTime time)
+{
+ QString 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 ( QMouseEvent * 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 ( QMouseEvent * )
+{
+ 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;
+ repaint();
+}
+
+
+void KDTimeHeaderWidget::mouseDoubleClickEvent ( QMouseEvent * )
+{
+
+}
+
+
+void KDTimeHeaderWidget::mouseMoveEvent ( QMouseEvent * e )
+{
+ if ( mouseDown ) {
+ if ( e->pos().y() < -height() || e->pos().y() > 2* height() ) {
+ mouseDown = false;
+ repaint();
+ return;
+ }
+ endMouseDown = e->pos().x();
+ //repaint;
+ int val = -1;
+ if (endMouseDown < -x() ) {
+ val = myGanttView->myCanvasView->horizontalScrollBar()->value() -
+ myGanttView->myCanvasView->horizontalScrollBar()->lineStep();
+ if ( val < 0 ) {
+ val = 0;
+ }
+ }
+ if (endMouseDown > -x() +parentWidget()->width() ) {
+ val = myGanttView->myCanvasView->horizontalScrollBar()->value() +
+ myGanttView->myCanvasView->horizontalScrollBar()->lineStep();
+
+ }
+ repaintMe(-x(),parentWidget()->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(),parentWidget()->width() , e->pos().y());
+ }
+}
+
+
+/* ***************************************************************
+ KDLegendWidget:: KDLegendWidget
+ ***************************************************************** */
+KDLegendWidget:: KDLegendWidget( QWidget* parent,
+ KDGanttMinimizeSplitter* legendParent ) :
+ KDGanttSemiSizingControl ( KDGanttSemiSizingControl::Before, Vertical,
+ parent)
+{
+ myLegendParent = legendParent;
+ dock = 0;
+ scroll = new QScrollView( legendParent );
+ setMaximizedWidget( scroll );
+
+ setMinimizedWidget( myLabel = new QLabel( 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 QDockWindow(QDockWindow:: 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 QScrollView( 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 QScrollView( myLegendParent );
+ clearLegend();
+ setMaximizedWidget( scroll );
+ showMe ( false );
+ }
+
+}
+
+
+bool KDLegendWidget::asDockwindow( )
+{
+ if ( dock )
+ return true;
+ return false;
+}
+
+
+QDockWindow* KDLegendWidget::dockwindow( )
+{
+ return dock;
+}
+
+
+void KDLegendWidget::setFont( QFont font)
+{
+ myLegend->setFont( font);
+ myLabel->setFont( font);
+ QWidget::setFont( font );
+}
+
+
+void KDLegendWidget::drawToPainter( QPainter *p )
+{
+ p->drawPixmap( 0, 0, QPixmap::grabWidget( myLegend ) );
+}
+
+
+QSize KDLegendWidget::legendSize()
+{
+ return myLegend->size();
+}
+
+
+QSize KDLegendWidget::legendSizeHint()
+{
+ QApplication::sendPostedEvents( 0, QEvent::LayoutHint );
+ return QSize( myLegend->sizeHint().width(), myLegend->sizeHint().height()+scroll->horizontalScrollBar()->height());
+}
+
+
+void KDLegendWidget::showMe ( bool show )
+{
+ minimize( !show );
+}
+
+
+void KDLegendWidget::clearLegend ( )
+{
+ if ( myLegend ) delete myLegend;
+ if ( dock )
+ myLegend = new QGroupBox( 1, Qt::Horizontal, scroll->viewport() );
+ else
+ myLegend = new QGroupBox( 1, Qt::Horizontal, i18n( "Legend" ), scroll->viewport() );
+ myLegend->setBackgroundColor( Qt::white );
+ myLegend->setFont( font() );
+ scroll->addChild( myLegend );
+ scroll->setResizePolicy( QScrollView::AutoOneFit );
+ myLegend->layout()->setMargin( 11 );
+ myLegend->setFrameStyle( QFrame::NoFrame );
+ if ( dock )
+ scroll->setMaximumHeight( 32000 );
+ else
+ scroll->setMaximumHeight( legendSizeHint().height() );
+}
+
+
+void KDLegendWidget::addLegendItem( KDGanttViewItem::Shape shape, const QColor& shapeColor, const QString& text )
+{
+ QLabel * temp;
+ QPixmap p = KDGanttView::getPixmap( shape, shapeColor, Qt::white, 10);
+ QWidget *w = new QWidget( myLegend );
+ w->setBackgroundColor( Qt::white );
+ QHBoxLayout *lay = new QHBoxLayout( w ,0, 6);
+ temp = new QLabel ( w );
+ lay->addWidget( temp, 0, Qt:: AlignRight);
+ temp->setPixmap(p);
+ temp = new QLabel ( 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(QWidget* parent, KDGanttView* gantView):QListView (parent)
+{
+ myGanttView = gantView;
+ setAcceptDrops(true);
+ new KDListViewWhatsThis(viewport(),this);
+ setRootIsDecorated( true );
+ setAllColumnsShowFocus( true );
+ addColumn( i18n( "Task Name" ) );
+ setSorting( -1 );
+ //setVScrollBarMode (QScrollView::AlwaysOn );
+ setHScrollBarMode (QScrollView::AlwaysOn );
+ setDefaultRenameAction(QListView::Accept);
+ setColumnWidthMode ( 0,Maximum );
+ _calendarMode = false;
+ // QObject::connect(this, SIGNAL ( pressed ( QListViewItem * )) , this, SLOT( dragItem( QListViewItem *))) ;
+}
+
+
+void KDListView::dragItem( QListViewItem * )
+{
+ // qDebug("drag ");
+ // startDrag();
+}
+QString KDListView::getWhatsThisText(QPoint 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(QListViewItem * item, bool open )
+{
+ if (! _calendarMode || ! open ) {
+ (( KDGanttViewItem*)item)->setCallListViewOnSetOpen( false );
+ QListView::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
+
+ QListViewItem* 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 );
+ QListView::setOpen ( item, open );
+ (( KDGanttViewItem*)item)->setCallListViewOnSetOpen( true );
+ }
+}
+
+
+void KDListView::contentsMouseDoubleClickEvent ( QMouseEvent * e )
+{
+ QListView::contentsMouseDoubleClickEvent ( e );
+ //if ( ! _calendarMode )
+ // QListView::contentsMouseDoubleClickEvent ( e );
+ // else
+ {
+
+ emit myGanttView->lvItemDoubleClicked ( (KDGanttViewItem*) itemAt(e->pos() ) );
+ emit myGanttView->itemDoubleClicked ( (KDGanttViewItem*) itemAt(e->pos() ) );
+ }
+
+}
+
+
+void KDListView::drawToPainter ( QPainter * p, bool drawHeader )
+{
+ // Draw list
+ drawAllContents ( p, 0, 0, contentsWidth(), contentsHeight() );
+ if (!drawHeader) {
+ return;
+ }
+ // Draw headers
+ QPen pen = QPen(Qt::lightGray, 1);
+ p->save();
+ QHeader *h = header();
+ for (int s = 0; s < h->count(); ++s) {
+ QRect 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(QPtrList<KDListView::DrawableItem> &lst, int level, int ypos, QListViewItem *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()) {
+ QListViewItem *child = item->firstChild();
+ for (; child; child = child->nextSibling()) {
+ y = buildDrawables(lst, level+1, y, child, ymin, ymax);
+ }
+ }
+ return y;
+}
+// This is a copy of QListView::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(QPainter * p, int cx, int cy, int cw, int ch) {
+ if ( columns() == 0 ) {
+ paintEmptyArea( p, QRect( cx, cy, cw, ch ) );
+ return;
+ }
+ //kdDebug()<<k_funcinfo<<QRect(cx, cy, cw, ch)<<endl;
+ QPtrList<KDListView::DrawableItem> drawables;
+ drawables.setAutoDelete(true);
+ QListViewItem *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() );
+
+ QPtrListIterator<KDListView::DrawableItem> it(drawables);
+
+ QRect 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 QColorGroup &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, colorGroup(), treeStepSize(),
+ rtop - crtop, r.height() );
+ p->restore();
+ }
+ }*/
+ }
+}
+
+void KDListView::resizeEvent(QResizeEvent *)
+{
+ triggerUpdate ();
+}
+void KDListView::dragEnterEvent ( QDragEnterEvent * e)
+{
+ if ( !myGanttView->dropEnabled() ) {
+ e->accept( false );
+ return;
+ }
+ myGanttView->lvDragEnterEvent(e);
+ //e->accept(KDGanttViewItemDrag::canDecode(e) );
+}
+
+void KDListView::dragMoveEvent ( QDragMoveEvent * 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 ( QDragLeaveEvent * )
+{
+ //qDebug("contentsDragLeaveEvent ");
+}
+void KDListView::dropEvent ( QDropEvent *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;
+ QString string;
+ KDGanttViewItemDrag::decode( e, string );
+ KDGanttViewItem* newItem = 0;
+
+ if ( gItem == myGanttView->myCanvasView->lastClickedItem && gItem != 0 ) {
+ qDebug("KDGanttView::Possible bug in drag&drop code ");
+ return;
+ }
+
+ QDomDocument doc( "GanttView" );
+ doc.setContent( string );
+ QDomElement docRoot = doc.documentElement(); // ChartParams element
+ QDomNode node = docRoot.firstChild();
+ bool enable = myGanttView->myTimeTable->blockUpdating( );
+ myGanttView->myTimeTable->setBlockUpdating( true );
+ while( !node.isNull() ) {
+ QDomElement element = node.toElement();
+ if( !element.isNull() ) { // was really an element
+ QString tagName = element.tagName();
+ if( tagName == "Items" ) {
+ QDomNode node = element.firstChild();
+ while( !node.isNull() ) {
+ QDomElement element = node.toElement();
+ if( !element.isNull() ) { // was really an element
+ QString 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;
+}
+
+QDragObject * KDListView::dragObject ()
+{
+ return QListView::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 ) :
+ QCanvasText(canvas)
+{
+ myParentType = type;
+ myParentItem = parentItem;
+}
+
+
+KDCanvasLine::KDCanvasLine( KDTimeTableWidget* canvas,
+ void* parentItem,
+ int type ) :
+ QCanvasLine(canvas)
+{
+ myParentType = type;
+ myParentItem = parentItem;
+}
+
+
+KDCanvasPolygonItem::KDCanvasPolygonItem( KDTimeTableWidget* canvas,
+ void* parentItem,
+ int type ) :
+ QCanvasPolygonalItem( canvas )
+{
+ myParentType = type;
+ myParentItem = parentItem;
+}
+
+
+KDCanvasPolygon::KDCanvasPolygon( KDTimeTableWidget* canvas,
+ void* parentItem,
+ int type ) :
+ QCanvasPolygon( canvas )
+{
+ myParentType = type;
+ myParentItem = parentItem;
+}
+
+
+KDCanvasEllipse::KDCanvasEllipse( KDTimeTableWidget* canvas,
+ void* parentItem,
+ int type ) :
+ QCanvasEllipse( canvas )
+{
+ myParentType = type;
+ myParentItem = parentItem;
+}
+
+
+KDCanvasRectangle::KDCanvasRectangle( KDTimeTableWidget* canvas,
+ void* parentItem,
+ int type ) :
+ QCanvasRectangle( canvas )
+{
+ myParentType = type;
+ myParentItem = parentItem;
+}
+
+
+
+
+KDGanttCanvasView::KDGanttCanvasView( KDGanttView* sender,QCanvas* canvas, QWidget* parent, const
+ char* name ) : QCanvasView ( canvas, parent, name ),
+ movingGVItem( 0 ),
+ scrollBarTimer( 0, "scrollBarTimer" )
+{
+ setHScrollBarMode (QScrollView::AlwaysOn );
+ setVScrollBarMode( QScrollView::AlwaysOn );
+ myToolTip = new KDCanvasToolTip(viewport(),this);
+ mySignalSender = sender;
+ currentItem = 0;
+ currentLink = 0;
+ cuttedItem = 0;
+ fromItem = 0;
+ fromArea = 0;
+ linkItemsEnabled = false;
+ mouseDown = false;
+ linkLine = new QCanvasLine(canvas);
+ linkLine->hide();
+ linkLine->setZ(1000);
+ set_Mouse_Tracking(true); // mouse cursor changes over KDIntervalColorRectangle borders
+ new KDCanvasWhatsThis(viewport(),this);
+ onItem = new QPopupMenu( this );
+ QPopupMenu * newMenu = new QPopupMenu( this );
+ QPopupMenu * onView = new QPopupMenu( this );
+ onView->insertItem( i18n( "Summary" ), this,
+ SLOT ( newRootItem( int ) ), 0, 0 );
+ onView->insertItem( i18n( "Event" ), this,
+ SLOT ( newRootItem( int ) ), 0, 1);
+ onView->insertItem( i18n( "Task" ), this,
+ SLOT ( newRootItem( int ) ), 0, 2 );
+
+ onItem->insertItem( i18n( "New Root" ), onView );
+ newMenu->insertItem( i18n( "Summary" ),
+ this, SLOT ( newChildItem( int) ), 0, 0 );
+ newMenu->insertItem( i18n( "Event" ),
+ this, SLOT ( newChildItem( int ) ), 0, 1 );
+ newMenu->insertItem( i18n( "Task" ),
+ this, SLOT ( newChildItem( int ) ), 0, 2 );
+
+ onItem->insertItem( i18n( "New Child" ), newMenu );
+ QPopupMenu * afterMenu = new QPopupMenu( this );
+ afterMenu->insertItem( i18n( "Summary" ),
+ this, SLOT ( newChildItem( int) ), 0, 0+4 );
+ afterMenu->insertItem( i18n( "Event" ),
+ this, SLOT ( newChildItem( int ) ), 0, 1+4 );
+ afterMenu->insertItem( i18n( "Task" ),
+ this, SLOT ( newChildItem( int ) ), 0, 2+4 );
+ onItem->insertItem( i18n( "New After" ), afterMenu );
+ QPopupMenu *pasteMenu = new QPopupMenu( this );
+ pasteMenu->insertItem( i18n( "As Root" ),
+ this, SLOT ( pasteItem( int ) ), 0, 0 );
+ pasteMenu->insertItem( i18n( "As Child" ),
+ this, SLOT ( pasteItem( int ) ), 0, 1 );
+ pasteMenu->insertItem( i18n( "After" ),
+ this, SLOT ( pasteItem( int ) ), 0, 2 );
+ onItem->insertItem( i18n( "Paste" ), pasteMenu, 3 );
+ onItem->insertItem( i18n( "Cut Item" ), this, SLOT ( cutItem() ) );
+ onItem->setItemEnabled( 3, false );
+ myMyContentsHeight = 0;
+ _showItemAddPopupMenu = false;
+
+ QObject *scrollViewTimer = child( "scrollview scrollbar timer", "QTimer", false );
+ Q_ASSERT( scrollViewTimer );
+ if ( scrollViewTimer ) {
+ disconnect( scrollViewTimer, SIGNAL(timeout()), this, SLOT(updateScrollBars() ) );
+ }
+ // If they needed a scrollbar timer in scrollview...
+ connect( &scrollBarTimer, SIGNAL(timeout()), this, SLOT(myUpdateScrollBars() ) );
+
+ myScrollTimer = new QTimer( this, "myScrollTimer" );
+ connect( myScrollTimer, SIGNAL( timeout() ), 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 ( QResizeEvent * e )
+{
+ int ho = e->oldSize().height();
+ int wo = e->oldSize().width();
+ int hi = height();
+ int wi = width();
+ //QScrollView::blockSignals( true );
+
+ verticalScrollBar()->setUpdatesEnabled( false );
+ QScrollView::resizeEvent ( e ) ;
+ if ( ho != hi )
+ emit heightResized( viewport()->height());
+ if ( wo != wi )
+ emit widthResized( viewport()->width() );
+ //setMyContentsHeight( 0 ); // via timer
+ //QScrollView::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 ( QPainter * p )
+{
+ drawContents ( p, 0, 0, canvas()->width(), canvas()->height() );
+}
+QString KDGanttCanvasView::getToolTipText(QPoint p)
+{
+ QCanvasItemList il = canvas()->collisions ( viewportToContents( p ));
+ QCanvasItemList::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 "";
+}
+
+QString KDGanttCanvasView::getWhatsThisText(QPoint p)
+{
+ QCanvasItemList il = canvas() ->collisions (viewportToContents( p ));
+ QCanvasItemList::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 QPoint &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 ( QMouseEvent * e )
+{
+ //qDebug("mousepress! %d ", this);
+ //qDebug("focus %d ",qApp->focusWidget());
+ setFocus();
+ currentLink = 0;
+ currentItem = 0;
+ movingItem = 0;
+ mouseDown = true;
+ if (e->button() == RightButton && mySignalSender->editable()) {
+ lastClickedItem = (KDGanttViewItem*) mySignalSender->myListView->itemAt( QPoint(2,e->pos().y()));
+ if ( lastClickedItem ) {
+ if ( lastClickedItem->displaySubitemsAsGroup() && ! lastClickedItem->isOpen() ) {
+ // findSub subitem
+ QCanvasItemList il = canvas() ->collisions ( e->pos() );
+ QCanvasItemList::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());
+ }
+ }
+ QCanvasItemList il = canvas() ->collisions ( e->pos() );
+ QCanvasItemList::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<QCanvasRectangle *>(*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 ( QMouseEvent * 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();
+ QCanvasItemList il = canvas() ->collisions ( e->pos() );
+ QCanvasItemList::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 ( QMouseEvent * e )
+{
+ QCanvasItemList il = canvas() ->collisions ( e->pos() );
+
+ if ( il.isEmpty() && e->button() == LeftButton ) {
+ //not directly sending a signal here (encapsulation and whatnot)
+ mySignalSender->emptySpaceDoubleClicked(e);
+ return;
+ }
+
+ QCanvasItemList::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 ( QMouseEvent *e )
+{
+ if ( !mouseDown ) {
+ // Update cursor
+ bool found = false;
+ QCanvasItemList il = canvas() ->collisions ( e->pos() );
+ QCanvasItemList::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 QPoint p = e->pos();
+ if ( movingItem ) {
+ int x = qRound( movingItem->x() );
+ int width = movingItem->width();
+ switch( movingOperation ) {
+ case Moving:
+ x += p.x() - movingStart.x();
+ break;
+ case ResizingLeft: {
+ width = qRound( 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 QDateTime newStart = mySignalSender->myTimeHeader->getDateTimeForIndex(x);
+ const QDateTime 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;
+ QDateTime 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()- QPoint(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 ( QPaintEvent * pe )
+{
+ QCanvasView::viewportPaintEvent ( pe );
+}
+void KDGanttCanvasView::set_Mouse_Tracking(bool on)
+{
+ viewport()->setMouseTracking(on);
+}
+int KDGanttCanvasView::getType(QCanvasItem* it)
+{
+ switch (it->rtti()) {
+ case QCanvasItem::Rtti_Line: return ((KDCanvasLine*)it)->myParentType;
+ case QCanvasItem::Rtti_Ellipse: return ((KDCanvasEllipse *)it)->myParentType;
+ case QCanvasItem::Rtti_Text: return ((KDCanvasText *)it)->myParentType;
+ case QCanvasItem::Rtti_Polygon: return ((KDCanvasPolygon *)it)->myParentType;
+ case QCanvasItem::Rtti_Rectangle:
+ case KDIntervalColorRectangle::RTTI:
+ return ((KDCanvasRectangle *)it)->myParentType;
+ }
+ return -1;
+}
+KDGanttViewItem* KDGanttCanvasView::getItem(QCanvasItem* it)
+{
+ switch (it->rtti()) {
+ case QCanvasItem::Rtti_Line: return (KDGanttViewItem*) ((KDCanvasLine*)it)->myParentItem;
+ case QCanvasItem::Rtti_Ellipse: return (KDGanttViewItem*) ((KDCanvasEllipse *)it)->myParentItem;
+ case QCanvasItem::Rtti_Text: return (KDGanttViewItem*) ((KDCanvasText *)it)->myParentItem;
+ case QCanvasItem::Rtti_Polygon: return (KDGanttViewItem*) ((KDCanvasPolygon *)it)->myParentItem;
+ case QCanvasItem::Rtti_Rectangle: return (KDGanttViewItem*) ((KDCanvasRectangle *)it)->myParentItem;
+
+ }
+ return 0;
+}
+KDGanttViewTaskLink* KDGanttCanvasView::getLink(QCanvasItem* it)
+{
+ switch (it->rtti()) {
+ case QCanvasItem::Rtti_Line: return (KDGanttViewTaskLink*) ((KDCanvasLine*)it)->myParentItem;
+ case QCanvasItem::Rtti_Ellipse: return (KDGanttViewTaskLink*) ((KDCanvasEllipse *)it)->myParentItem;
+ case QCanvasItem::Rtti_Text: return (KDGanttViewTaskLink*) ((KDCanvasText *)it)->myParentItem;
+ case QCanvasItem::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 QDateTime& start,
+ const QDateTime& end )
+{
+ mStart = start;
+ mEnd = end;
+ if ( mEnd < mStart )
+ qSwap( mStart, mEnd );
+}
+
+/*!
+ Sets the background color
+ \param color the background color
+*/
+void KDIntervalColorRectangle::setColor( const QColor& color )
+{
+ mColor = color;
+}
+
+/*!
+ \internal
+*/
+void KDIntervalColorRectangle::layout( KDTimeHeaderWidget* timeHeader, int height )
+{
+ int left = timeHeader->getCoordX(mStart);
+ int right = timeHeader->getCoordX(mEnd);
+ if ( right == left )
+ ++right;
+ setPen( QPen::NoPen );
+ setBrush( QBrush(mColor, SolidPattern) );
+ setSize( right - left, height );
+ move( left, 0 );
+ show();
+}
+
+/*!
+ \internal
+*/
+KDIntervalColorRectangle::HitTest KDIntervalColorRectangle::hitTest( KDTimeHeaderWidget* timeHeader, const QPoint& 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;
+}
diff --git a/kdgantt/KDGanttViewSubwidgets.h b/kdgantt/KDGanttViewSubwidgets.h
new file mode 100644
index 00000000..b8d9d57a
--- /dev/null
+++ b/kdgantt/KDGanttViewSubwidgets.h
@@ -0,0 +1,646 @@
+/* -*- 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.
+ **
+ **********************************************************************/
+
+
+#ifndef KDGANTTVIEWSUBWIDGETS_H
+#define KDGANTTVIEWSUBWIDGETS_H
+
+
+#include <qwidget.h>
+#include <qlistview.h>
+#include <qsplitter.h>
+#include <qevent.h>
+#include <qvaluelist.h>
+#include <qcanvas.h>
+#include <qwhatsthis.h>
+#include <qpopupmenu.h>
+#include <qtooltip.h>
+#include <qtimer.h>
+#include <qgroupbox.h>
+#include <qvgroupbox.h>
+#include <qlayout.h>
+#include <qlabel.h>
+#include <qbrush.h>
+#include <qvbox.h>
+#include <qdockwindow.h>
+#include <qtimer.h>
+
+#include "KDGanttView.h"
+#include "KDGanttViewTaskLink.h"
+#include "KDGanttViewTaskLinkGroup.h"
+#include "KDGanttViewSummaryItem.h"
+#include "KDGanttSemiSizingControl.h"
+#include "KDGanttViewItemDrag.h"
+
+#define Type_is_KDGanttGridItem 1
+#define Type_is_KDGanttViewItem 2
+#define Type_is_KDGanttTaskLink 3
+
+class KDIntervalColorRectangle;
+class KDCanvasWhatsThis;
+class KDToolTip;
+class KDCanvasRectangle;
+class KDTimeHeaderToolTip;
+
+class KDTimeHeaderWidget : public QWidget
+{
+ Q_OBJECT
+
+public:
+ typedef KDGanttView::Scale Scale;
+ typedef KDGanttView::YearFormat YearFormat;
+ typedef KDGanttView::HourFormat HourFormat;
+ struct DateTimeColor {
+ QDateTime datetime;
+ QDateTime end;
+ QColor color;
+ Scale minScaleView;
+ Scale maxScaleView;
+ //KDCanvasLine* canvasLine;
+ KDCanvasRectangle* canvasRect;
+ };
+ typedef QValueList<DateTimeColor> ColumnColorList;
+ typedef QValueList<KDIntervalColorRectangle *> IntervalColorList;
+ /*
+ enum Scale { Minute, Hour, Day, Week, Month, Auto };
+ enum YearFormat { FourDigit, TwoDigit, TwoDigitApostrophe };
+ enum HourFormat { Hour_24, Hour_12 };
+ */
+
+ KDTimeHeaderWidget (QWidget* parent,KDGanttView* gant);
+ ~KDTimeHeaderWidget();
+
+ QString getToolTipText(QPoint p);
+ void zoomToFit();
+ void zoom(double, bool absolute = true);
+ void zoomToSelection( QDateTime startTime, QDateTime endTime);
+ double zoomFactor();
+ void setAutoScaleMinorTickCount( int count );
+ int autoScaleMinorTickCount();
+ void setHorizonStart( const QDateTime& start );
+ QDateTime horizonStart() const;
+ void setHorizonEnd( const QDateTime& start );
+ QDateTime horizonEnd() const;
+
+ void setMaximumScale( Scale );
+ KDTimeHeaderWidget::Scale maximumScale() const;
+ void setMinimumScale( Scale );
+ KDTimeHeaderWidget::Scale minimumScale() const;
+ KDTimeHeaderWidget::Scale scale() const;
+ void setMajorScaleCount( int count );
+ int majorScaleCount() const;
+ void setMinorScaleCount( int count );
+ int minorScaleCount() const;
+ void setMinimumColumnWidth( int width );
+ int minimumColumnWidth() const;
+ void setYearFormat( YearFormat format );
+ KDTimeHeaderWidget::YearFormat yearFormat() const;
+ void setHourFormat( HourFormat format );
+ KDTimeHeaderWidget::HourFormat hourFormat() const;
+ void setShowMajorTicks( bool );
+ bool showMajorTicks() const;
+ void setShowMinorTicks( bool );
+ void setScale( Scale unit);
+ bool showMinorTicks() const;
+ void setColumnBackgroundColor( const QDateTime& column,
+ const QColor& color,
+ Scale mini = KDGanttView::Minute ,
+ Scale maxi = KDGanttView::Month);
+#if 0
+ // This API has been replaced with KDIntervalColorRectangle and addIntervalBackgroundColor
+ void setIntervalBackgroundColor( const QDateTime& start,
+ const QDateTime& end,
+ const QColor& color,
+ Scale mini = KDGanttView::Minute ,
+ Scale maxi = KDGanttView::Month);
+ bool changeBackgroundInterval( const QDateTime& oldstart,
+ const QDateTime& oldend,
+ const QDateTime& newstart,
+ const QDateTime& newend );
+ bool deleteBackgroundInterval( const QDateTime& start,
+ const QDateTime& end );
+#endif
+ void addIntervalBackgroundColor( KDIntervalColorRectangle* newItem );
+ void clearBackgroundColor();
+ QColor columnBackgroundColor( const QDateTime& column ) const;
+ void setWeekendBackgroundColor( const QColor& color );
+ QColor weekendBackgroundColor() const;
+ void setWeekdayBackgroundColor( const QColor& color, int weekday );
+ QColor weekdayBackgroundColor(int weekday) const;
+ void setWeekendDays( int start, int end );
+ void weekendDays( int& start, int& end ) const;
+ void computeTicks(bool doNotComputeRealScale = false);
+ void paintEvent(QPaintEvent *);
+ int getCoordX(QDate);
+ int getCoordX(QDateTime);
+ QDateTime getDateTimeForIndex(int coordX, bool local = true );
+ void setShowPopupMenu( bool show, bool showZoom, bool showScale,bool showTime,
+ bool showYear,bool showGrid, bool showPrint);
+ bool registerStartTime();
+ bool registerEndTime();
+ bool showPopupMenu() const;
+ ColumnColorList columnBackgroundColorList() const {
+ return ccList;
+ }
+ QColor weekdayColor[8];
+ void repaintMe(int left, int wid, QPainter *p = 0);
+
+ void centerDateTime( const QDateTime& center );
+
+public slots:
+ void setSettings(int);
+ void checkWidth( int );
+ void addTickRight( int num = 1 );
+ void addTickLeft( int num = 1 );
+ void preparePopupMenu();
+signals:
+ void sizeChanged( int );
+
+private:
+ friend class KDTimeTableWidget;
+ friend class KDGanttViewItem;
+ friend class KDGanttView;
+ friend class KDGanttCanvasView; // calls computeIntervals
+ virtual void mousePressEvent ( QMouseEvent * e );
+ virtual void mouseReleaseEvent ( QMouseEvent * e );
+ virtual void mouseDoubleClickEvent ( QMouseEvent * e );
+ virtual void mouseMoveEvent ( QMouseEvent * e );
+ double secsFromTo( QDateTime begin, QDateTime end );
+ void updateTimeTable();
+ void computeIntervals( int height );
+ bool getColumnColor(QColor& col,int coordLow, int coordHigh);
+ void moveTimeLineTo(int x);
+ //void mousePressEvent ( QMouseEvent * ) ;
+ void resizeEvent ( QResizeEvent * ) ;
+ QValueList<int> majorTicks;
+ QValueList<QString> minorText;
+ QValueList<QString> majorText;
+ QDateTime myHorizonStart, myHorizonEnd, myRealEnd,myRealStart;
+ QDateTime myCenterDateTime;
+ void saveCenterDateTime();
+ Scale myScale,myRealScale,myMaxScale,myMinScale;
+ YearFormat myYearFormat;
+ HourFormat myHourFormat;
+ int myMinimumColumWidth;
+ bool flagShowMajorTicks, flagShowMinorTicks, flagShowPopupMenu;
+ bool flagShowZoom, flagShowScale ,flagShowTime ,flagShowYear;
+ bool flagShowGrid ,flagShowPrint;
+ bool flagStartTimeSet,flagEndTimeSet;
+ QColor myWeekendBackgroundColor;
+ int myWeekendDaysStart, myWeekendDaysEnd;
+ ColumnColorList ccList;
+ IntervalColorList icList;
+ int myMinorScaleCount,myMajorScaleCount;
+ int myRealMinorScaleCount,myRealMajorScaleCount;
+ bool flagDoNotRecomputeAfterChange,flagDoNotRepaintAfterChange;
+ QString getYear(QDate);
+ QString getHour(QTime);
+ QDateTime getEvenTimeDate(QDateTime ,Scale);
+ void computeRealScale(QDateTime start);
+ int myGridMinorWidth;
+ int myMajorGridHeight;
+ QPopupMenu * myPopupMenu, *scalePopupMenu, *timePopupMenu;
+ QPopupMenu * yearPopupMenu, *gridPopupMenu;
+ KDGanttView* myGanttView;
+ double myZoomFactor;
+ int myAutoScaleMinorTickcount;
+ bool flagZoomToFit;
+ int mySizeHint;
+ int myMinimumWidth;
+ int getTickTime();
+ KDTimeHeaderToolTip* myToolTip;
+ bool mouseDown;
+ int beginMouseDown;
+ int endMouseDown;
+ bool autoComputeTimeLine;
+ QPixmap paintPix;
+};
+
+/* KDTimeTableWidget */
+class KDListView ;
+
+class KDTimeTableWidget : public QCanvas
+{
+ Q_OBJECT
+
+public:
+ KDTimeTableWidget (QWidget* parent,KDGanttView* my);
+
+ void setBlockUpdating( bool block = true );
+ bool blockUpdating();
+ void inc_blockUpdating();
+ void dec_blockUpdating();
+ void setShowTaskLinks( bool show );
+ bool showTaskLinks();
+ QPtrList<KDGanttViewTaskLink>taskLinks();
+ void clearTaskLinks();
+ void updateMyContent();
+ void removeItemFromTasklinks( KDGanttViewItem * );
+ void setHorBackgroundLines( int count, QBrush brush );
+ int horBackgroundLines( QBrush& brush );
+
+ void setNoInformationBrush( const QBrush& brush );
+ QBrush noInformationBrush() const;
+
+ int getCoordX( QDateTime dt );
+
+signals:
+ void heightComputed( int );
+
+public slots:
+ void expandItem(QListViewItem * );
+ void collapseItem(QListViewItem * );
+ void highlightItem(QListViewItem * );
+ void resetWidth( int );
+ void checkHeight( int );
+private:
+ friend class KDGanttViewTaskLink;
+ friend class KDTimeHeaderWidget;
+ friend class KDGanttView;
+ friend class KDGanttViewTaskItem;
+ KDGanttView* myGanttView;
+
+ bool taskLinksVisible;
+
+ QPtrList<KDGanttViewTaskLink> myTaskLinkList;
+
+ QPtrList<KDCanvasLine> verGridList;
+ QPtrList<KDCanvasLine> horGridList;
+ QPtrList<KDCanvasRectangle> horDenseList;
+ QPtrList<KDCanvasRectangle> showNoInfoList;
+ int denseLineCount;
+ QBrush denseLineBrush, noInfoLineBrush;
+ QPtrList<KDCanvasRectangle> columnColorList;
+
+ int computeHeight();
+ void computeVerticalGrid();
+ void computeHorizontalGrid();
+ void computeDenseLines();
+ void computeShowNoInformation();
+ void computeTaskLinks();
+ void computeMinorGrid();
+ void computeMajorGrid();
+
+ void showMajorGrid();
+ void showMinorGrid();
+ void hideGrid();
+
+ QPen gridPen;
+ int maximumComputedGridHeight;
+ int minimumHeight;
+ int int_blockUpdating;
+ bool flag_blockUpdating;
+ int pendingHeight;
+ int pendingWidth;
+
+};
+
+class KDLegendWidget : public KDGanttSemiSizingControl
+{
+ Q_OBJECT
+
+public:
+ KDLegendWidget ( QWidget* parent, KDGanttMinimizeSplitter* legendParent );
+ void showMe(bool);
+ bool isShown();
+ void addLegendItem( KDGanttViewItem::Shape shape, const QColor& shapeColor, const QString& text );
+ void clearLegend();
+ void setFont( QFont );
+ void drawToPainter( QPainter *p );
+ void setAsDockwindow( bool dockwin );
+ bool asDockwindow();
+ QDockWindow* dockwindow();
+ QSize legendSize();
+ QSize legendSizeHint();
+ private:
+ QGroupBox * myLegend;
+ QLabel* myLabel;
+ QScrollView * scroll;
+ QDockWindow* dock;
+ KDGanttMinimizeSplitter* myLegendParent;
+};
+
+class KDGanttView;
+class KDListView : public QListView
+{
+ Q_OBJECT
+
+public:
+ KDListView (QWidget* parent,KDGanttView* gv );
+ KDGanttView* myGanttView;
+ void drawToPainter( QPainter *p, bool drawHeader=false );
+ void setCalendarMode( bool mode );
+ bool calendarMode() { return _calendarMode; };
+ QString getWhatsThisText(QPoint p);
+ void setOpen ( QListViewItem * item, bool open );
+ void dragEnterEvent ( QDragEnterEvent * );
+ void dragMoveEvent ( QDragMoveEvent * );
+ void dragLeaveEvent ( QDragLeaveEvent * );
+ void dropEvent ( QDropEvent * );
+ QDragObject * dragObject ();
+ void startDrag ();
+ void paintemptyarea ( QPainter * p, const QRect & rect ){ QListView::paintEmptyArea( p, rect );};
+
+public:
+ class DrawableItem {
+ public:
+ DrawableItem(int level, int ypos, QListViewItem *item ) { y = ypos; l = level; i = item; };
+ int y;
+ int l;
+ QListViewItem * i;
+ };
+protected:
+ void drawAllContents(QPainter * p, int cx, int cy, int cw, int ch);
+ int buildDrawables(QPtrList<KDListView::DrawableItem> &lst, int level, int ypos, QListViewItem *item, int ymin, int ymax) const;
+
+private slots:
+ void dragItem( QListViewItem * );
+ private:
+ void resizeEvent ( QResizeEvent * ) ;
+ void contentsMouseDoubleClickEvent ( QMouseEvent * e );
+ bool _calendarMode;
+
+
+
+};
+
+
+class KDCanvasText : public QCanvasText
+{
+public:
+ KDCanvasText( KDTimeTableWidget* canvas, void* parentItem, int type );
+ int myParentType;
+ void* myParentItem;
+};
+
+
+class KDCanvasLine : public QCanvasLine
+{
+public:
+ KDCanvasLine( KDTimeTableWidget* canvas, void* parentItem, int type );
+ int myParentType;
+ void* myParentItem;
+};
+
+
+class KDCanvasPolygonItem: public QCanvasPolygonalItem
+{
+public:
+ KDCanvasPolygonItem( KDTimeTableWidget* canvas, void* parentItem,
+ int type );
+ int myParentType;
+ void* myParentItem;
+};
+
+
+class KDCanvasPolygon: public QCanvasPolygon
+{
+public:
+ KDCanvasPolygon( KDTimeTableWidget* canvas, void* parentItem, int type );
+ int myParentType;
+ void* myParentItem;
+};
+
+
+class KDCanvasEllipse: public QCanvasEllipse
+{
+public:
+ KDCanvasEllipse( KDTimeTableWidget* canvas, void* parentItem, int type );
+ int myParentType;
+ void* myParentItem;
+};
+
+
+class KDCanvasRectangle: public QCanvasRectangle
+{
+public:
+ KDCanvasRectangle( KDTimeTableWidget* canvas, void* parentItem, int type );
+ int myParentType;
+ void* myParentItem;
+};
+
+
+// Interval-color-rectangle, such as the one used in the freebusy view for the current event
+class KDIntervalColorRectangle: public KDCanvasRectangle
+{
+public:
+ KDIntervalColorRectangle( KDGanttView* view );
+
+ void setDateTimes( const QDateTime& start,
+ const QDateTime& end );
+ QDateTime start() const { return mStart; }
+ QDateTime end() const { return mEnd; }
+
+ void setColor( const QColor& color );
+
+ enum HitTest { Start, Middle, End };
+ HitTest hitTest( KDTimeHeaderWidget* timeHeader, const QPoint& pos ) const;
+
+ void layout( KDTimeHeaderWidget* timeHeader, int height );
+
+ static const int RTTI = 0x0c58;
+ /*reimp*/ int rtti() const { return RTTI; }
+
+private:
+ QColor mColor;
+ QDateTime mStart;
+ QDateTime mEnd;
+};
+
+class KDCanvasToolTip;
+
+class KDGanttCanvasView : public QCanvasView
+{
+ Q_OBJECT
+
+public:
+ KDGanttCanvasView(KDGanttView* sender, QCanvas* canvas = 0, QWidget* parent = 0, const char* name = 0 );
+ ~KDGanttCanvasView();
+ QString getToolTipText(QPoint p);
+ QString getWhatsThisText(QPoint p);
+ void drawToPainter ( QPainter * p );
+ void resetCutPaste( KDGanttViewItem* );
+ void setShowPopupMenu( bool show );
+ bool showPopupMenu();
+ void cutItem ( KDGanttViewItem* );
+ void insertItemAsRoot( KDGanttViewItem* );
+ void insertItemAsChild( KDGanttViewItem* , KDGanttViewItem* );
+ void insertItemAfter( KDGanttViewItem* , KDGanttViewItem* );
+protected:
+ friend class KDGanttView;
+ friend class KDListView;
+ virtual void contentsMousePressEvent ( QMouseEvent * ) ;
+ virtual void contentsMouseReleaseEvent ( QMouseEvent * );
+ virtual void contentsMouseDoubleClickEvent ( QMouseEvent * );
+ virtual void contentsMouseMoveEvent ( QMouseEvent * ) ;
+ virtual void viewportPaintEvent ( QPaintEvent * pe );
+ void resizeEvent ( QResizeEvent * ) ;
+ void set_MouseTracking(bool on);
+ int getType(QCanvasItem*);
+ KDGanttViewItem* getItem(QCanvasItem*);
+ KDGanttViewTaskLink* getLink(QCanvasItem*);
+ int getItemArea(KDGanttViewItem *item, int x);
+ int getLinkType(int from, int to);
+
+ KDGanttView* mySignalSender;
+ KDGanttViewItem* currentItem, *lastClickedItem, *cuttedItem;
+ QCanvasRectangle* movingItem;
+ KDGanttViewTaskItem* movingGVItem;
+ QPoint movingStart;
+ QDateTime movingStartDate;
+ enum MovingOperation { Moving, ResizingLeft, ResizingRight };
+ MovingOperation movingOperation;
+ KDGanttViewTaskLink* currentLink;
+ KDCanvasWhatsThis* myWhatsThis;
+ QPopupMenu* onItem;
+ bool _showItemAddPopupMenu;
+ int myMyContentsHeight;
+ KDGanttViewItem *fromItem;
+ bool linkItemsEnabled;
+ QCanvasLine *linkLine;
+ int fromArea;
+ bool autoScrollEnabled;
+ bool mouseDown;
+
+signals:
+ void heightResized( int );
+ void widthResized( int );
+
+public slots:
+ void set_Mouse_Tracking(bool on);
+ void moveMyContent( int, int );
+ void setMyContentsHeight( int );
+ void updateHorScrollBar();
+private slots:
+ void cutItem();
+ void pasteItem( int );
+ void newRootItem( int );
+ void newChildItem( int );
+ void slotScrollTimer();
+ void myUpdateScrollBars();
+
+private:
+ MovingOperation gvItemHitTest( KDGanttViewItem *item, KDTimeHeaderWidget* timeHeader, const QPoint &pos );
+private:
+ KDCanvasToolTip* myToolTip;
+ QTimer *myScrollTimer;
+ QPoint mousePos;
+ QTimer scrollBarTimer;
+};
+
+class KDTimeHeaderToolTip :public QToolTip
+{
+
+public:
+ KDTimeHeaderToolTip( QWidget *wid, KDTimeHeaderWidget* header ) : QToolTip( wid ), _wid(wid),_header (header) {
+
+};
+
+protected:
+ virtual void maybeTip( const QPoint& p)
+ {
+ static bool ishidden = true;
+ if (QToolTip::isGloballyEnabled () ) {
+ if (ishidden) {
+ tip( QRect( p.x(),p.y(),5,5), _header->getToolTipText(p));
+ }
+ else
+ hide();
+ ishidden = !ishidden;
+ }
+ }
+private:
+ QWidget* _wid;
+ KDTimeHeaderWidget * _header;
+};
+
+class KDCanvasToolTip :public QToolTip
+{
+
+public:
+ KDCanvasToolTip( QWidget *wid, KDGanttCanvasView* canview ) : QToolTip( wid ), _wid(wid),_canview (canview) {
+
+};
+
+protected:
+ virtual void maybeTip( const QPoint& p)
+ {
+ static bool ishidden = true;
+ if (QToolTip::isGloballyEnabled () ) {
+ if (ishidden) {
+ tip( QRect( p.x()-2,p.y()-2,5,5), _canview->getToolTipText(p));
+ }
+ else
+ hide();
+ ishidden = !ishidden;
+ }
+ }
+private:
+ QWidget* _wid;
+ KDGanttCanvasView * _canview;
+};
+
+class KDCanvasWhatsThis :public QWhatsThis
+{
+public:
+ KDCanvasWhatsThis( QWidget *wid, KDGanttCanvasView* canview ) : QWhatsThis( wid ), _wid(wid),_canview (canview) { };
+
+protected:
+ virtual QString text( const QPoint& p)
+ {
+ return _canview->getWhatsThisText(p) ;
+ }
+private:
+ QWidget* _wid;
+ KDGanttCanvasView * _canview;
+};
+
+class KDListViewWhatsThis :public QWhatsThis
+{
+public:
+ KDListViewWhatsThis( QWidget *wid, KDListView* view ) : QWhatsThis( wid ), _wid(wid),_view (view) { };
+
+protected:
+ virtual QString text( const QPoint& p)
+ {
+ return _view->getWhatsThisText(p) ;
+ }
+private:
+ QWidget* _wid;
+ KDListView * _view;
+};
+
+
+
+#endif
diff --git a/kdgantt/KDGanttViewSummaryItem.cpp b/kdgantt/KDGanttViewSummaryItem.cpp
new file mode 100644
index 00000000..a9cf23c6
--- /dev/null
+++ b/kdgantt/KDGanttViewSummaryItem.cpp
@@ -0,0 +1,377 @@
+/* -*- 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 "KDGanttViewSummaryItem.h"
+#include "KDGanttViewSubwidgets.h"
+
+#include "itemAttributeDialog.h"
+
+/*!
+ \class KDGanttViewSummaryItem KDGanttViewSummaryItem.h
+ A summary item in a Gantt chart.
+
+ This class represents summary items in Gantt charts.
+*/
+
+
+/*!
+ Constructs an empty Gantt item of type event.
+
+ \param view the Gantt view to insert this item into
+ \param lvtext the text to show in the list view
+ \param name the name by which the item can be identified. If no name
+ is specified, a unique name will be generated
+*/
+KDGanttViewSummaryItem::KDGanttViewSummaryItem( KDGanttView* view,
+ const QString& lvtext,
+ const QString& name ) :
+ KDGanttViewItem( Summary, view, lvtext, name )
+{
+ initItem();
+}
+
+
+/*!
+ Constructs an empty Gantt item of type event.
+
+ \param parent a parent item under which this one goes
+ \param lvtext the text to show in the list view
+ \param name the name by which the item can be identified. If no name
+ is specified, a unique name will be generated
+*/
+KDGanttViewSummaryItem::KDGanttViewSummaryItem( KDGanttViewItem* parent,
+ const QString& lvtext,
+ const QString& name ) :
+ KDGanttViewItem( Summary, parent, lvtext, name )
+{
+ initItem();
+}
+
+
+/*!
+ Constructs an empty Gantt item of type event.
+
+ \param view the Gantt view to insert this item into
+ \param after another item at the same level behind which this one should go
+ \param lvtext the text to show in the list view
+ \param name the name by which the item can be identified. If no name
+ is specified, a unique name will be generated
+*/
+KDGanttViewSummaryItem::KDGanttViewSummaryItem( KDGanttView* view,
+ KDGanttViewItem* after,
+ const QString& lvtext,
+ const QString& name ) :
+ KDGanttViewItem( Summary, view, after, lvtext, name )
+{
+ initItem();
+}
+
+
+/*!
+ Constructs an empty Gantt item of type event.
+
+ \param parent a parent item under which this one goes
+ \param after another item at the same level behind which this one should go
+ \param lvtext the text to show in the list view
+ \param name the name by which the item can be identified. If no name
+ is specified, a unique name will be generated
+*/
+KDGanttViewSummaryItem::KDGanttViewSummaryItem( KDGanttViewItem* parent,
+ KDGanttViewItem* after,
+ const QString& lvtext,
+ const QString& name ) :
+ KDGanttViewItem( Summary, parent, after, lvtext, name )
+{
+
+ initItem();
+
+}
+
+
+/*!
+ The destructor. Does nothing for the moment.
+*/
+KDGanttViewSummaryItem::~KDGanttViewSummaryItem()
+{
+
+}
+
+
+/*!
+ Specifies the middle time of this summary item. The parameter must be valid
+ and non-null. If the parameter is invalid or null, no value is set.
+
+ \param dateTime the middle time
+ \sa middleTime()
+*/
+void KDGanttViewSummaryItem::setMiddleTime( const QDateTime& dateTime )
+{
+ if (! dateTime.isValid() ) {
+ qDebug("KDGanttViewSummaryItem::setMiddleTime():Invalid parameter-no time set");
+ return;
+ }
+ if (!myMiddleTime) myMiddleTime = new QDateTime;
+ *myMiddleTime = dateTime;
+ if ( myEndTime < middleTime() )
+ setEndTime( middleTime() );
+ if ( myStartTime > middleTime() )
+ setStartTime( middleTime() );
+ updateCanvasItems();
+}
+
+
+/*!
+ Returns the middle time of this summary item. If there is no middle
+ time defined, the start time is returned.
+
+ \return the middle time of this summary item.
+ If there is no middle time defined, the start time is returned.
+*/
+QDateTime KDGanttViewSummaryItem::middleTime() const
+{
+ if(myMiddleTime)
+ return *myMiddleTime;
+ return myStartTime;
+}
+
+
+/*!
+ Specifies the end time of this item. The parameter must be valid
+ and non-null. If the parameter is invalid or null, no value is set.
+ If the end time is less the mid time,
+ the mid time is set to this end time automatically.
+ \param end the end time
+ \sa endTime(), setStartTime(), startTime()
+*/
+void KDGanttViewSummaryItem::setEndTime( const QDateTime& end )
+{
+ if (! end.isValid() ) {
+ qDebug("KDGanttViewSummaryItem::setEndTime():Invalid parameter-no time set");
+ return;
+ }
+ myEndTime = end;
+ if ( myEndTime < middleTime() )
+ setMiddleTime( myEndTime );
+ else
+ updateCanvasItems();
+}
+
+
+/*!
+ Specifies the start time of this item. The parameter must be valid
+ and non-null. If the parameter is invalid or null, no value is set.
+ If the start time is less the mid time,
+ the mid time is set to this start time automatically.
+
+ \param start the start time
+ \sa startTime(), setEndTime(), endTime()
+*/
+void KDGanttViewSummaryItem::setStartTime( const QDateTime& start )
+{
+ if (! start.isValid() ) {
+ qDebug("KDGanttViewSummaryItem::setStartTime():Invalid parameter-no time set");
+ return;
+ }
+ myStartTime = start;
+ if ( myStartTime > middleTime() ) {
+ setMiddleTime( myStartTime );
+ }
+ else
+ updateCanvasItems();
+}
+
+
+/*!
+ Specifies the actual end time of this item. The parameter must be valid
+ and non-null. Items with undefined start or end times lead to
+ undefined visual results.
+
+ \param end the actual end time
+ \sa actualEndTime()
+ startTime()
+*/
+void KDGanttViewSummaryItem::setActualEndTime( const QDateTime& end )
+{
+ if (!myActualEndTime) myActualEndTime = new QDateTime;
+ *myActualEndTime = end;
+
+ updateCanvasItems();
+
+}
+
+
+/*!
+ Returns the actual end time of this item.
+
+ \return the actual end time of this item
+ \sa setActualEndTime()
+
+*/
+QDateTime KDGanttViewSummaryItem::actualEndTime() const
+{
+ if(myActualEndTime)
+ return *myActualEndTime;
+ return myEndTime;
+}
+
+
+void KDGanttViewSummaryItem::hideMe()
+{
+ startShape->hide();
+ midShape->hide();
+ endShape->hide();
+ startShapeBack->hide();
+ midShapeBack->hide();
+ endShapeBack->hide();
+ startLine->hide();
+ endLine->hide();
+ textCanvas->hide();
+ startLineBack->hide();
+ endLineBack->hide();
+ actualEnd->hide();
+}
+
+// shows the item
+// if coordY >0, this is taken as the middle y-coordinate
+void KDGanttViewSummaryItem::showItem( bool show, int coordY )
+{
+ isVisibleInGanttView = show;
+ invalidateHeight () ;
+ if (!show) {
+ hideMe();
+ return;
+ }
+ if ( displaySubitemsAsGroup() && !parent() && !isOpen() ) {
+ hideMe();
+ return;
+ }
+ float prio = ((float) ( priority() - 100 )) / 100.0;
+ startShape->setZ( prio + 0.0055 );
+ midShape->setZ( prio + 0.004 );
+ endShape->setZ( prio + 0.005 );
+ startShapeBack->setZ( prio + 0.003 );
+ midShapeBack->setZ( prio + 0.003 );
+ endShapeBack->setZ( prio + 0.003 );
+ startLine->setZ( prio + 0.0015 );
+ endLine->setZ( prio + 0.001 );
+ textCanvas->setZ( prio + 0.006 );
+ startLineBack->setZ( prio );
+ endLineBack->setZ( prio );
+ actualEnd->setZ( prio + 0.007 );
+ if ( displaySubitemsAsGroup() && firstChild() ) {
+ myStartTime = myChildStartTime();
+ myEndTime = myChildEndTime();
+ }
+ int startX, endX, midX = 0,allY;
+ if ( coordY )
+ allY = coordY;
+ else
+ allY = getCoordY();
+ startX = myGanttView->myTimeHeader->getCoordX(myStartTime);
+ endX = myGanttView->myTimeHeader->getCoordX(myEndTime);
+ if (myMiddleTime)
+ midX = myGanttView->myTimeHeader->getCoordX(*myMiddleTime);
+ else
+ midX = endX;
+
+ startLine->setPoints(startX,allY,midX,allY);
+ startLine->show();
+ startLineBack->setPoints(startX-1,allY,midX+1,allY);
+ startLineBack->show();
+ startShape->move(startX,allY);
+ startShapeBack->move(startX,allY);
+
+ endShape->move(endX,allY);
+ endShapeBack->move(endX,allY);
+ moveTextCanvas(endX,allY);
+ startShape->show();
+ startShapeBack->show();
+ endShape->show();
+ endShapeBack->show();
+ textCanvas->show();
+ if (myMiddleTime) {
+ endLine->setPoints(midX,allY,endX,allY);
+ endLine->show();
+ endLineBack->setPoints(midX,allY,endX+1,allY);
+ endLineBack->show();
+ midShape->move(midX,allY);
+ midShape->show();
+ midShapeBack->move(midX,allY);
+ midShapeBack->show();
+ }
+ else {
+ endLine->hide();
+ endLineBack->hide();
+ midShape->hide();
+ midShapeBack->hide();
+ }
+ if (myActualEndTime) {
+ if ( *myActualEndTime == myEndTime ) {
+ actualEnd->hide();
+ }
+ else {
+ int actendX = myGanttView->myTimeHeader->getCoordX(*myActualEndTime);
+ actualEnd->setPoints(actendX,allY-5,actendX,allY+5);
+ actualEnd->show();
+ }
+ }
+ else {
+ actualEnd->hide();
+ }
+ if(myStartTime == myEndTime)
+ {
+ endShape->moveBy(myItemSize+4,0);
+ endShapeBack->moveBy(myItemSize+4,0);
+ textCanvas->moveBy(myItemSize+4,0);
+ midShape->hide();
+ midShapeBack->hide();
+ startLine->hide();
+ endLine->hide();
+ startLineBack->hide();
+ endLineBack->hide();
+ }
+ if (textCanvas->text().isEmpty())
+ textCanvas->hide();
+}
+void KDGanttViewSummaryItem::initItem()
+{
+ isVisibleInGanttView = false;
+ myActualEndTime = 0;
+ myMiddleTime = 0;
+ showItem(true);
+ myGanttView->myTimeTable->updateMyContent();
+ setDragEnabled( myGanttView->dragEnabled() );
+ setDropEnabled( myGanttView->dropEnabled() );
+}
+
diff --git a/kdgantt/KDGanttViewSummaryItem.h b/kdgantt/KDGanttViewSummaryItem.h
new file mode 100644
index 00000000..e8fcd618
--- /dev/null
+++ b/kdgantt/KDGanttViewSummaryItem.h
@@ -0,0 +1,72 @@
+/* -*- 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.
+ **
+ **********************************************************************/
+
+
+#ifndef KDGANTTVIEWSUMMARYITEM_H
+#define KDGANTTVIEWSUMMARYITEM_H
+
+#include "KDGanttViewItem.h"
+
+class KDGanttViewSummaryItem : public KDGanttViewItem
+{
+public:
+ KDGanttViewSummaryItem( KDGanttView* view,
+ const QString& lvtext = QString::null,
+ const QString& name = QString::null );
+ KDGanttViewSummaryItem( KDGanttViewItem* parent,
+ const QString& lvtext = QString::null,
+ const QString& name = QString::null );
+ KDGanttViewSummaryItem( KDGanttView* view, KDGanttViewItem* after,
+ const QString& lvtext = QString::null,
+ const QString& name = QString::null );
+ KDGanttViewSummaryItem( KDGanttViewItem* parent, KDGanttViewItem* after,
+ const QString& lvtext = QString::null,
+ const QString& name = QString::null );
+ virtual ~KDGanttViewSummaryItem();
+
+ void setMiddleTime( const QDateTime& );
+ QDateTime middleTime() const;
+ void setActualEndTime( const QDateTime& end );
+ QDateTime actualEndTime() const;
+ void setStartTime( const QDateTime& start );
+ void setEndTime( const QDateTime& end );
+private:
+ void showItem( bool show = true, int coordY = 0 );
+ QDateTime* myActualEndTime,*myMiddleTime;
+ void initItem();
+ void hideMe();
+
+
+};
+
+#endif
diff --git a/kdgantt/KDGanttViewTaskItem.cpp b/kdgantt/KDGanttViewTaskItem.cpp
new file mode 100644
index 00000000..a9f1bec9
--- /dev/null
+++ b/kdgantt/KDGanttViewTaskItem.cpp
@@ -0,0 +1,369 @@
+/* -*- 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 "KDGanttViewTaskItem.h"
+#include "KDGanttViewSubwidgets.h"
+
+#include "itemAttributeDialog.h"
+
+/*!
+ \class KDGanttViewTaskItem KDGanttViewTaskItem.h
+
+ This class represents calendar items in Gantt charts.
+
+ A calendar item in a Gantt chart has no start/end shape,
+ it is displayed as a rectangle.
+ You can set the colors as usual, where only the first argument of
+ setColors( col, col, col )
+ is important.
+ If the start time is equal to the end time, the item is displayed as
+ Ý, showing that there is no time interval set.
+
+ For a KDGanttViewTaskItem, the text, setted by \a setText(),
+ is shown in the item itself and the text is truncated automatically
+ to fit in the item.
+ For all other item types, the text is shown right of the item.
+*/
+
+
+/*!
+ Constructs an empty Gantt item of type event.
+
+ \param view the Gantt view to insert this item into
+ \param lvtext the text to show in the listview
+ \param name the name by which the item can be identified. If no name
+ is specified, a unique name will be generated
+*/
+KDGanttViewTaskItem::KDGanttViewTaskItem( KDGanttView* view,
+ const QString& lvtext,
+ const QString& name ) :
+ KDGanttViewItem( Task, view, lvtext, name )
+{
+
+ initItem();
+}
+
+
+/*!
+ Constructs an empty Gantt item of type event.
+
+ \param parent a parent item under which this one goes
+ \param lvtext the text to show in the list view
+ \param name the name by which the item can be identified. If no name
+ is specified, a unique name will be generated
+*/
+KDGanttViewTaskItem::KDGanttViewTaskItem( KDGanttViewItem* parent,
+ const QString& lvtext,
+ const QString& name ) :
+ KDGanttViewItem( Task, parent, lvtext, name )
+{
+ initItem();
+}
+
+
+/*!
+ Constructs an empty Gantt item of type event.
+
+ \param view the Gantt view to insert this item into
+ \param after another item at the same level behind which this one should go
+ \param lvtext the text to show in the list view
+ \param name the name by which the item can be identified. If no name
+ is specified, a unique name will be generated
+*/
+KDGanttViewTaskItem::KDGanttViewTaskItem( KDGanttView* view,
+ KDGanttViewItem* after,
+ const QString& lvtext,
+ const QString& name ) :
+ KDGanttViewItem( Task, view, after, lvtext, name )
+{
+ initItem();
+}
+
+
+/*!
+ Constructs an empty Gantt item of type event.
+
+ \param parent a parent item under which this one goes
+ \param after another item at the same level behind which this one should go
+ \param lvtext the text to show in the listview
+ \param name the name by which the item can be identified. If no name
+ is specified, a unique name will be generated
+*/
+KDGanttViewTaskItem::KDGanttViewTaskItem( KDGanttViewItem* parent,
+ KDGanttViewItem* after,
+ const QString& lvtext,
+ const QString& name ) :
+ KDGanttViewItem( Task, parent, after, lvtext, name )
+{
+ initItem();
+}
+
+
+/*!
+ The destructor.
+*/
+KDGanttViewTaskItem::~KDGanttViewTaskItem()
+{
+
+}
+
+
+/*!
+ Specifies the end time of this item. The parameter must be valid
+ and non-null. If the parameter is invalid or null, no value is set.
+ If the end time is less the start time,
+ the start time is set to this end time automatically.
+
+ \param end the end time
+ \sa setStartTime(), startTime(), endTime()
+*/
+void KDGanttViewTaskItem::setEndTime( const QDateTime& end )
+{
+ myEndTime = end;
+ if ( myEndTime < startTime() )
+ setStartTime( myEndTime );
+ else
+ updateCanvasItems();
+}
+
+
+/*!
+ Specifies the start time of this item. The parameter must be valid
+ and non-null. If the parameter is invalid or null, no value is set.
+ If the start time is greater than the end time,
+ the end time is set to this start time automatically.
+
+ \param start the start time
+ \sa startTime(), setEndTime(), endTime()
+*/
+void KDGanttViewTaskItem::setStartTime( const QDateTime& start )
+{
+ if (! start.isValid() ) {
+ qDebug("KDGanttViewTaskItem::setStartTime():Invalid parameter-no time set");
+ return;
+ }
+ myStartTime = start;
+ if ( myStartTime > endTime() )
+ setEndTime( myStartTime );
+ else
+ updateCanvasItems();
+}
+
+
+/*!
+ Hides all canvas items of this Gantt item
+ \sa showItem()
+*/
+void KDGanttViewTaskItem::hideMe()
+{
+ startShape->hide();
+ progressShape->hide();
+ textCanvas->hide();
+ floatStartShape->hide();
+ floatEndShape->hide();
+}
+
+
+void KDGanttViewTaskItem::showItem(bool show, int coordY)
+{
+
+ //qDebug("KDGanttViewTaskItem::showItem() %d %s ", (int) show, listViewText().latin1());
+ isVisibleInGanttView = show;
+ invalidateHeight () ;
+ if (!show) {
+ hideMe();
+ return;
+ }
+ bool takedefaultHeight = true ; // pending: make configureable
+ float prio = ((float) ( priority() - 100 )) / 100.0;
+ startShape->setZ( prio );
+ progressShape->setZ(startShape->z()+0.002); // less than textCanvas
+ progressShape->hide();
+ floatStartShape->setZ(startShape->z()+0.003); // less than textCanvas
+ floatStartShape->hide();
+ floatEndShape->setZ(startShape->z()+0.003); // less than textCanvas
+ floatEndShape->hide();
+ textCanvas->setZ( prio + 0.005 );
+ if ( displaySubitemsAsGroup() && !parent() && !isOpen() ) {
+ hideMe();
+ return;
+ }
+ if ( displaySubitemsAsGroup() && ( firstChild() || myGanttView->calendarMode() ) ) {
+ hideMe();//new
+ return;//new
+ myStartTime = myChildStartTime();
+ myEndTime = myChildEndTime();
+ }
+ //setExpandable(false);
+ KDCanvasRectangle* temp = (KDCanvasRectangle*) startShape;
+ KDCanvasRectangle* progtemp = (KDCanvasRectangle*) progressShape;
+ int startX, endX, midX = 0,allY, progX=0;
+ if ( coordY )
+ allY = coordY;
+ else
+ allY = getCoordY();
+ startX = myGanttView->myTimeHeader->getCoordX(myStartTime);
+ endX = myGanttView->myTimeHeader->getCoordX(myEndTime);
+ midX = endX;
+ if (myProgress > 0) {
+ progX = (endX - startX) * myProgress / 100;
+ }
+ int hei = height();
+ if ( ! isVisible() ) {
+ KDGanttViewItem * par = parent();
+ while ( par != 0 && !par->isVisible() )
+ par = par->parent();
+ if ( par )
+ hei = par->height();
+ }
+ if (myGanttView->myListView->itemAt( QPoint(2, allY)))
+ hei = myGanttView->myListView->itemAt( QPoint(2, allY))->height();
+ if ( takedefaultHeight )
+ hei = 16;
+ if ( myStartTime == myEndTime ) {
+ textCanvas->hide();
+ if ( showNoInformation() ) {
+ startShape->hide();
+ } else {
+ startShape->setZ( 1.01 );
+ if (myGanttView->displayEmptyTasksAsLine() ) {
+ hei = myGanttView->myTimeTable->height();
+ if (hei < myGanttView->myTimeTable->pendingHeight )
+ hei = myGanttView->myTimeTable->pendingHeight;
+ temp->setSize(5, hei );
+ temp->move(startX, 0);
+ temp->show();
+ } else {
+ temp->setSize( 1, hei -3 );
+ temp->move(startX, allY-hei/2 +2);
+ temp->show();
+ }
+ }
+ return;
+ }
+ if ( startX +3 >= endX )
+ temp->setSize( 3, hei-3 );
+ else
+ temp->setSize(endX-startX, hei-3 );
+ temp->move(startX, allY-hei/2 +2);
+ temp->show();
+ if (progX > 0) {
+ // FIXME: For now, just use inverted color for progress
+ QColor c = temp->brush().color();
+ int h, s, v;
+ c.getHsv(&h, &s, &v);
+ h > 359/2 ? h -= 359/2 : h += 359/2;
+ c.setHsv(h, s, v);
+ progtemp->setBrush(QBrush(c));
+
+ progtemp->setSize(progX, hei-3);
+ progtemp->move(temp->x(), temp->y());
+ progtemp->show();
+ }
+ if (myFloatStartTime.isValid()) {
+ KDCanvasRectangle* floatStartTemp = (KDCanvasRectangle*) floatStartShape;
+ int floatStartX = myGanttView->myTimeHeader->getCoordX(myFloatStartTime);
+ // FIXME: Configurable colors
+ QBrush b(temp->brush().color(), Dense4Pattern);
+ floatStartTemp->setBrush(b);
+ floatStartTemp->setPen(QPen(gray));
+ if (floatStartX < startX) {
+ floatStartTemp->setSize(startX - floatStartX, temp->size().height()/2);
+ floatStartTemp->move(floatStartX, temp->y() + temp->size().height()/4);
+ } else {
+ floatStartTemp->setSize(floatStartX - startX, temp->size().height()/2);
+ floatStartTemp->move(startX, temp->y() + temp->size().height()/4);
+ }
+ floatStartTemp->show();
+ }
+ if (myFloatEndTime.isValid()) {
+ KDCanvasRectangle* floatEndTemp = (KDCanvasRectangle*) floatEndShape;
+ int floatEndX = myGanttView->myTimeHeader->getCoordX(myFloatEndTime);
+ // FIXME: Configurable colors
+ QBrush b(temp->brush().color(), Dense4Pattern);
+ floatEndTemp->setBrush(b);
+ floatEndTemp->setPen(QPen(gray));
+ int ex = startX + temp->size().width();
+ if (floatEndX > ex) {
+ floatEndTemp->setSize(floatEndX - ex, temp->size().height()/2);
+ floatEndTemp->move(ex, temp->y() + temp->size().height()/4);
+ } else {
+ floatEndTemp->setSize(ex - floatEndX, temp->size().height()/2);
+ floatEndTemp->move(floatEndX, temp->y() + temp->size().height()/4);
+ }
+ floatEndTemp->show();
+ }
+
+ int wid = endX-startX - 4;
+ if ( !displaySubitemsAsGroup() && !myGanttView->calendarMode()) {
+ moveTextCanvas(endX,allY);
+ textCanvas->show();
+ } else {
+ if ( textCanvasText.isEmpty() || wid < 5)
+ textCanvas->hide();
+ else {
+ textCanvas->move(startX+3, allY-textCanvas->boundingRect().height()/2);
+ QString temp = textCanvasText;
+ textCanvas->setText(temp);
+ int len = temp.length();
+ while ( textCanvas->boundingRect().width() > wid ) {
+ temp.truncate(--len);
+ textCanvas->setText(temp);
+ }
+ if ( temp.isEmpty())
+ textCanvas->hide();
+ else {
+ textCanvas->show();
+ }
+ }
+ }
+}
+
+
+void KDGanttViewTaskItem::initItem()
+{
+ isVisibleInGanttView = false;
+
+ if ( myGanttView->calendarMode() && parent() ) {
+ setVisible( false );
+ parent()->setVisible( true );
+ } else
+ showItem(true);
+ //qDebug("initItem %s %s", listViewText().latin1(),startShape->brush().color().name().latin1() );
+ myGanttView->myTimeTable->updateMyContent();
+ setDragEnabled( myGanttView->dragEnabled() );
+ setDropEnabled( myGanttView->dropEnabled() );
+}
+
diff --git a/kdgantt/KDGanttViewTaskItem.h b/kdgantt/KDGanttViewTaskItem.h
new file mode 100644
index 00000000..d4a73cf0
--- /dev/null
+++ b/kdgantt/KDGanttViewTaskItem.h
@@ -0,0 +1,73 @@
+/* -*- 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.
+ **
+ **********************************************************************/
+
+
+#ifndef KDGANTTVIEWTASKITEM_H
+#define KDGANTTVIEWTASKITEM_H
+
+#include "KDGanttViewItem.h"
+class KDCanvasRectangle;
+class QBrush;
+
+class KDGanttViewTaskItem : public KDGanttViewItem
+{
+public:
+ KDGanttViewTaskItem( KDGanttView* view,
+ const QString& lvtext = QString::null,
+ const QString& name = QString::null );
+ KDGanttViewTaskItem( KDGanttViewItem* parent,
+ const QString& lvtext = QString::null,
+ const QString& name = QString::null );
+ KDGanttViewTaskItem( KDGanttView* view, KDGanttViewItem* after,
+ const QString& lvtext = QString::null,
+ const QString& name = QString::null );
+ KDGanttViewTaskItem( KDGanttViewItem* parent, KDGanttViewItem* after,
+ const QString& lvtext = QString::null,
+ const QString& name = QString::null );
+ virtual ~KDGanttViewTaskItem();
+
+ void setStartTime( const QDateTime& start );
+ void setEndTime( const QDateTime& end );
+
+protected:
+ void showItem( bool show = true, int coordY = 0 );
+
+private:
+ void initItem();
+ void hideMe();
+ QBrush myBrush, undefinedBrush;
+ bool _showUndefinedBrush;
+};
+
+#endif
diff --git a/kdgantt/KDGanttViewTaskLink.cpp b/kdgantt/KDGanttViewTaskLink.cpp
new file mode 100644
index 00000000..22a50b8a
--- /dev/null
+++ b/kdgantt/KDGanttViewTaskLink.cpp
@@ -0,0 +1,1007 @@
+/* -*- 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 "KDGanttViewTaskLink.h"
+#include "KDGanttViewTaskLinkGroup.h"
+#include "KDGanttViewSubwidgets.h"
+#include "KDGanttXMLTools.h"
+
+
+/*! \class KDGanttViewTaskLink KDGanttViewTaskLink.h
+ This class represents a link between a number of Gantt chart items.
+
+ It always connects source items with target items. Task links can
+ be grouped into KDGanttViewTaskLinkGroup objects.
+ If a Gantt view item is deleted, it is removed from the fromList or
+ from the toList.
+ If one of the lists becomes empty, the complete task link is deleted
+ as well.
+
+ The task link is deleted by KDGanttViews d'tor.
+ You may delete the task link yourself, if you do it
+ _before_ KDGanttViews d'tor is called.
+*/
+
+
+/*!
+ Creates a task link that connects all items in the source item list from
+ to all items in the destination item list to.
+
+ \param from the source items
+ \param to the target items
+ \param type the link type for the connection
+*/
+KDGanttViewTaskLink::KDGanttViewTaskLink( QPtrList<KDGanttViewItem> from,
+ QPtrList<KDGanttViewItem> to,
+ LinkType type )
+{
+ fromList= from;
+ toList = to;
+ myGroup = 0;
+ setLinkType(type);
+ initTaskLink();
+}
+
+
+/*!
+ \overload
+
+ Creates a task link that connects two items.
+ Note, that the from() and to() functions are returning a list,
+ in this case containing only one item.
+
+ \param from the source item
+ \param to the target item
+ \param type the link type for the connection
+*/
+KDGanttViewTaskLink::KDGanttViewTaskLink( KDGanttViewItem* from,
+ KDGanttViewItem* to,
+ LinkType type )
+{
+ fromList.append(from);
+ toList.append(to);
+ myGroup = 0;
+ setLinkType(type);
+ initTaskLink();
+
+}
+
+/*!
+ Creates a task link that connects all items in the source item list from
+ to all items in the destination item list to.
+ Inserts the link directly into a link group.
+
+ \param group the link group to insert this link into
+ \param from the source items
+ \param to the target items
+ \param type the link type for the connection
+*/
+
+KDGanttViewTaskLink::KDGanttViewTaskLink( KDGanttViewTaskLinkGroup* group,
+ QPtrList<KDGanttViewItem> from,
+ QPtrList<KDGanttViewItem> to,
+ LinkType type )
+{
+ fromList = from;
+ toList = to;
+ myGroup = 0;
+ setLinkType(type);
+ initTaskLink();
+ setGroup(group);
+}
+
+/*!
+ \overload
+
+ Creates a task link that connects two items and inserts the link
+ directly into a link group.
+ Note, that the from() and to() functions are returning a list,
+ in this case containing only one item.
+
+ \param group the link group to insert this link into
+ \param from the source item
+ \param to the target item
+ \param type the link type for the connection
+*/
+
+KDGanttViewTaskLink::KDGanttViewTaskLink( KDGanttViewTaskLinkGroup* group,
+ KDGanttViewItem* from,
+ KDGanttViewItem* to,
+ LinkType type )
+{
+ fromList.append(from);
+ toList.append(to);
+ myGroup = 0;
+ setLinkType(type);
+ initTaskLink();
+ setGroup(group);
+}
+
+
+KDGanttViewTaskLink::~KDGanttViewTaskLink( )
+{
+ setGroup(0);
+ myTimeTable->myTaskLinkList.remove(this);
+ delete horLineList;
+ delete verLineList;
+ delete horLineList2;
+ delete verLineList2;
+ delete horLineList3;
+ delete topList;
+ delete topLeftList;
+ delete topRightList;
+}
+
+
+void KDGanttViewTaskLink::initTaskLink()
+{
+ horLineList = new QPtrList<KDCanvasLine>;
+ verLineList = new QPtrList<KDCanvasLine>;
+ horLineList2 = new QPtrList<KDCanvasLine>;
+ verLineList2 = new QPtrList<KDCanvasLine>;
+ horLineList3 = new QPtrList<KDCanvasLine>;
+ topList = new QPtrList<KDCanvasPolygon>;
+ topLeftList = new QPtrList<KDCanvasPolygon>;
+ topRightList = new QPtrList<KDCanvasPolygon>;
+ horLineList->setAutoDelete( true );
+ verLineList->setAutoDelete( true );
+ horLineList2->setAutoDelete( true );
+ verLineList2->setAutoDelete( true );
+ horLineList3->setAutoDelete( true );
+ topList->setAutoDelete( true );
+ topLeftList->setAutoDelete( true );
+ topRightList->setAutoDelete( true );
+ myTimeTable = fromList.getFirst()->myGanttView->myTimeTable;
+ KDCanvasLine* horLine,*verLine;
+ KDCanvasLine* horLine2,*verLine2;
+ KDCanvasLine* horLine3;
+ KDCanvasPolygon* top;
+ KDCanvasPolygon* topLeft;
+ KDCanvasPolygon* topRight;
+ unsigned int i, j;
+ for ( i = 0;i < fromList.count();++i) {
+ for ( j = 0;j < toList.count();++j) {
+ horLine = new KDCanvasLine(myTimeTable,this,Type_is_KDGanttTaskLink);
+ verLine = new KDCanvasLine(myTimeTable,this,Type_is_KDGanttTaskLink);
+ horLine2 = new KDCanvasLine(myTimeTable,this,Type_is_KDGanttTaskLink);
+ verLine2 = new KDCanvasLine(myTimeTable,this,Type_is_KDGanttTaskLink);
+ horLine3 = new KDCanvasLine(myTimeTable,this,Type_is_KDGanttTaskLink);
+ top = new KDCanvasPolygon(myTimeTable,this,Type_is_KDGanttTaskLink);
+ topLeft = new KDCanvasPolygon(myTimeTable,this,Type_is_KDGanttTaskLink);
+ topRight = new KDCanvasPolygon(myTimeTable,this,Type_is_KDGanttTaskLink);
+ QPointArray arr = QPointArray(3);
+ arr.setPoint(0,-4,-5);
+ arr.setPoint(1,4,-5);
+ arr.setPoint(2,0,0);
+ top->setPoints(arr);
+ arr.setPoint(0,5,-5); // need an extra y pixel, canvas bug?
+ arr.setPoint(1,5,5); // need an extra y pixel, canvas bug?
+ arr.setPoint(2,0,0);
+ topLeft->setPoints(arr);
+ arr.setPoint(0,-5,-4);
+ arr.setPoint(1,-5,4);
+ arr.setPoint(2,0,0);
+ topRight->setPoints(arr);
+ horLineList->append(horLine);
+ verLineList->append(verLine);
+ horLineList2->append(horLine2);
+ verLineList2->append(verLine2);
+ horLineList3->append(horLine3);
+ topList->append(top);
+ topLeftList->append(topLeft);
+ topRightList->append(topRight);
+ horLine->setZ(1);
+ verLine->setZ(1);
+ horLine2->setZ(1);
+ verLine2->setZ(1);
+ horLine3->setZ(1);
+ top->setZ(1);
+ topLeft->setZ(1);
+ topRight->setZ(1);
+ }
+ }
+
+ setTooltipText( "Tasklink" );
+ setWhatsThisText( "Tasklink" );
+ myTimeTable->myTaskLinkList.append(this);
+ setHighlight( false);
+ setHighlightColor(Qt::red );
+ setColor(Qt::black);
+ setVisible(true);
+}
+
+
+/*!
+ Specifies whether this task link should be visible or not.
+
+ \param visible pass true to make this task link visible, and false
+ to hide it
+ \sa isVisible()
+*/
+
+void KDGanttViewTaskLink::setVisible( bool visible )
+{
+ showMe ( visible );
+ myTimeTable->updateMyContent();
+}
+void KDGanttViewTaskLink::showMe( bool visible )
+{
+ if (linkType() != None) {
+ showMeType(visible);
+ return;
+ }
+ hide();
+
+ isvisible = visible;
+ int wid = 1;
+ QPen p;
+ QBrush b;
+ p.setWidth(wid);
+ b.setStyle(Qt::SolidPattern);
+ if (ishighlighted) {
+ b.setColor(myColorHL);
+ p.setColor(myColorHL);
+
+ } else {
+ b.setColor(myColor);
+ p.setColor(myColor);
+ }
+ QPoint start, end;
+ QPtrListIterator<KDCanvasLine> horIt(*horLineList);
+ QPtrListIterator<KDCanvasLine> verIt(*verLineList);
+ QPtrListIterator<KDCanvasPolygon> topIt(*topList);
+ QPtrListIterator<KDGanttViewItem> fromIt(fromList);
+ QPtrListIterator<KDGanttViewItem> toIt(toList);
+ for ( ; fromIt.current(); ++fromIt ) {
+ (*fromIt)->setTextOffset(QPoint(0,0));
+ toIt.toFirst();
+ for ( ; toIt.current(); ++toIt ) {
+ (*toIt)->setTextOffset(QPoint(0,0));
+ if (!isvisible || ! (*fromIt)->isVisibleInGanttView || !(*toIt)->isVisibleInGanttView || !myTimeTable->taskLinksVisible) {
+ (*horIt)->hide();
+ (*verIt)->hide();
+ (*topIt)->hide();
+ ++horIt;
+ ++verIt;
+ ++topIt;
+ } else {
+ (*horIt)->setPen(p);
+ (*verIt)->setPen(p);
+ (*topIt)->setBrush(b);
+ end = (*toIt)->getTaskLinkEndCoord();
+ start = (*fromIt)->getTaskLinkStartCoord(end);
+ (*horIt)->setPoints(start.x(),start.y(),end.x()+wid,start.y());
+ (*verIt)->setPoints(end.x()+wid/2,start.y(),end.x()+wid/2,end.y()-2);
+ (*topIt)->move(end.x()+wid/2,end.y());
+ (*horIt)->show();
+ (*verIt)->show();
+ (*topIt)->show();
+ ++horIt;
+ ++verIt;
+ ++topIt;
+
+ }
+ }
+ }
+ while ( horIt.current() ) {
+ (*horIt)->hide();
+ (*verIt)->hide();
+ (*topIt)->hide();
+ ++horIt;
+ ++verIt;
+ ++topIt;
+ }
+}
+
+void KDGanttViewTaskLink::showMeType( bool visible )
+{
+ //qDebug("KDGanttViewTaskLink::showMeType %d",linkType());
+ hide();
+ isvisible = visible;
+ int wid = 1;
+ QPen p;
+ QBrush b;
+ p.setWidth(wid);
+ b.setStyle(Qt::SolidPattern);
+ if (ishighlighted) {
+ b.setColor(myColorHL);
+ p.setColor(myColorHL);
+
+ } else {
+ b.setColor(myColor);
+ p.setColor(myColor);
+ }
+ QPoint start, end;
+ QPtrListIterator<KDCanvasLine> horIt(*horLineList);
+ QPtrListIterator<KDCanvasLine> verIt(*verLineList);
+ QPtrListIterator<KDCanvasLine> horIt2(*horLineList2);
+ QPtrListIterator<KDCanvasLine> verIt2(*verLineList2);
+ QPtrListIterator<KDCanvasLine> horIt3(*horLineList3);
+ QPtrListIterator<KDCanvasPolygon> topIt(*topList);
+ QPtrListIterator<KDCanvasPolygon> topLeftIt(*topLeftList);
+ QPtrListIterator<KDCanvasPolygon> topRightIt(*topRightList);
+ QPtrListIterator<KDGanttViewItem> fromIt(fromList);
+ QPtrListIterator<KDGanttViewItem> toIt(toList);
+ for ( ; fromIt.current(); ++fromIt ) {
+ (*fromIt)->setTextOffset(QPoint(30,0));
+ (*fromIt)->moveTextCanvas();
+ toIt.toFirst();
+ for ( ; toIt.current(); ++toIt ) {
+ if (isvisible && (*fromIt)->isVisibleInGanttView &&
+ (*toIt)->isVisibleInGanttView && myTimeTable->taskLinksVisible) {
+ (*horIt)->setPen(p);
+ (*verIt)->setPen(p);
+ (*horIt2)->setPen(p);
+ (*verIt2)->setPen(p);
+ (*horIt3)->setPen(p);
+ (*topIt)->setBrush(b);
+ (*topLeftIt)->setBrush(b);
+ (*topRightIt)->setBrush(b);
+ (*toIt)->setTextOffset(QPoint(30,0));
+ (*toIt)->moveTextCanvas();
+ switch (linkType()) {
+ case StartStart: {
+ start = (*fromIt)->middleLeft();
+ end = (*toIt)->middleLeft()-QPoint(12,0);
+ bool down = start.y() < end.y();
+ (*horIt)->setPoints(start.x()-xOffset(*fromIt),start.y(),
+ start.x()-10, start.y());
+ (*verIt)->setPoints(
+ (*horIt)->endPoint().x(),
+ (*horIt)->endPoint().y(),
+ (*horIt)->endPoint().x(),
+ (down ? (*toIt)->itemPos()+1
+ : (*toIt)->itemPos()+(*toIt)->height()-1));
+ (*horIt2)->setPoints((*verIt)->endPoint().x(),
+ (*verIt)->endPoint().y(),
+ end.x()-12,
+ (*verIt)->endPoint().y());
+ (*verIt2)->setPoints((*horIt2)->endPoint().x(),
+ (*horIt2)->endPoint().y(),
+ (*horIt2)->endPoint().x(),
+ end.y());
+ (*horIt3)->setPoints((*verIt2)->endPoint().x(),
+ (*verIt2)->endPoint().y(),
+ end.x(),
+ end.y());
+ (*topRightIt)->move(end.x(),end.y());
+ (*topRightIt)->show();
+ break;
+ }
+ case FinishFinish: {
+ start = (*fromIt)->middleRight();
+ end = (*toIt)->middleRight()+QPoint(12,0);
+ bool down = start.y() < end.y();
+ (*horIt)->setPoints(start.x()+xOffset(*fromIt),start.y(),
+ start.x()+10, start.y());
+ (*verIt)->setPoints(
+ (*horIt)->endPoint().x(),
+ (*horIt)->endPoint().y(),
+ (*horIt)->endPoint().x(),
+ (down ? (*toIt)->itemPos()+1
+ : (*toIt)->itemPos()+(*toIt)->height()-1));
+ (*horIt2)->setPoints((*verIt)->endPoint().x(),
+ (*verIt)->endPoint().y(),
+ end.x()+12,
+ (*verIt)->endPoint().y());
+ (*verIt2)->setPoints((*horIt2)->endPoint().x(),
+ (*horIt2)->endPoint().y(),
+ (*horIt2)->endPoint().x(),
+ end.y());
+ (*horIt3)->setPoints((*verIt2)->endPoint().x(),
+ (*verIt2)->endPoint().y(),
+ end.x(),
+ end.y());
+ (*topLeftIt)->move(end.x(),end.y());
+ (*topLeftIt)->show();
+ break;
+ }
+ case FinishStart: {
+ start = (*fromIt)->middleRight();
+ end = (*toIt)->middleLeft() - QPoint(12,0);
+ bool down = start.y() < end.y();
+ (*horIt)->setPoints(start.x()+xOffset(*fromIt),start.y(),
+ start.x()+10,start.y());
+ (*verIt)->setPoints(
+ (*horIt)->endPoint().x(),
+ (*horIt)->endPoint().y(),
+ (*horIt)->endPoint().x(),
+ (down ? (*toIt)->itemPos()+1
+ : (*toIt)->itemPos()+(*toIt)->height()-1));
+ (*horIt2)->setPoints((*verIt)->endPoint().x(),
+ (*verIt)->endPoint().y(),
+ end.x()-12,
+ (*verIt)->endPoint().y());
+ (*verIt2)->setPoints((*horIt2)->endPoint().x(),
+ (*horIt2)->endPoint().y(),
+ (*horIt2)->endPoint().x(),
+ end.y());
+ (*horIt3)->setPoints((*verIt2)->endPoint().x(),
+ (*verIt2)->endPoint().y(),
+ end.x(),
+ end.y());
+ (*topRightIt)->move(end.x(),end.y());
+
+ (*topRightIt)->show();
+
+ break;
+ }
+ case StartFinish: {
+ start = (*fromIt)->middleRight();
+ end = (*toIt)->middleRight()+QPoint(12,0);
+ bool down = start.y() < end.y();
+ (*horIt)->setPoints(start.x()+xOffset(*fromIt),start.y(),
+ start.x()+10, start.y());
+ (*verIt)->setPoints(
+ (*horIt)->endPoint().x(),
+ (*horIt)->endPoint().y(),
+ (*horIt)->endPoint().x(),
+ (down ? (*toIt)->itemPos()+1
+ : (*toIt)->itemPos()+(*toIt)->height()-1));
+ (*horIt2)->setPoints((*verIt)->endPoint().x(),
+ (*verIt)->endPoint().y(),
+ end.x()-12,
+ (*verIt)->endPoint().y());
+ (*verIt2)->setPoints((*horIt2)->endPoint().x(),
+ (*horIt2)->endPoint().y(),
+ (*horIt2)->endPoint().x(),
+ end.y());
+ (*horIt3)->setPoints((*verIt2)->endPoint().x(),
+ (*verIt2)->endPoint().y(),
+ end.x(),
+ end.y());
+ (*topRightIt)->move(end.x(),end.y());
+ (*topRightIt)->show();
+ break;
+ }
+ default:
+ qWarning("KDGanttViewTaskLink: Unknown link type");
+ break;
+ }
+ (*horIt)->show();
+ (*verIt)->show();
+ (*horIt2)->show();
+ (*verIt2)->show();
+ (*horIt3)->show();
+ }
+ ++horIt;
+ ++verIt;
+ ++horIt2;
+ ++verIt2;
+ ++horIt3;
+ ++topIt;
+ ++topLeftIt;
+ ++topRightIt;
+ }
+ }
+}
+
+/*!
+ Returns whether this task link should be visible or not.
+
+ \return true if the task link is visible
+ \sa setVisible()
+*/
+bool KDGanttViewTaskLink::isVisible() const
+{
+
+ return isvisible;
+}
+
+
+/*!
+ Returns the group (if any) to which this task link belongs.
+
+ \return the group to which this task link belongs; 0 if it does not
+ belong to any group.
+ \sa KDGanttViewTaskLinkGroup
+*/
+KDGanttViewTaskLinkGroup* KDGanttViewTaskLink::group()
+{
+ return myGroup;
+}
+
+
+/*!
+ Inserts this task link in a group.
+ If the parameter is 0, the task link is removed from any group
+
+ \param group the group, this task link has to be inserted
+
+ \sa KDGanttViewTaskLinkGroup
+*/
+void KDGanttViewTaskLink::setGroup(KDGanttViewTaskLinkGroup* group)
+{
+
+ myTimeTable->myGanttView->addTaskLinkGroup(group);
+ if(myGroup == group)
+ return;
+ if (myGroup != 0)
+ myGroup->removeItem(this);
+ myGroup = group;
+ if (myGroup != 0)
+ myGroup->insertItem(this);
+}
+
+
+/*!
+ Specifies whether this task link should be shown highlighted. The
+ user can also highlight a task link with the mouse.
+
+ \param highlight pass true in order to highlight this task link
+ \sa highlight()
+*/
+void KDGanttViewTaskLink::setHighlight( bool highlight )
+{
+ ishighlighted = highlight ;
+ // if ( isvisible) setVisible(true );
+ myTimeTable->updateMyContent();
+}
+
+
+/*!
+ Returns whether this task link is highlighted, either
+ programmatically by setHighlight() or by the user with the mouse.
+
+ \return true if the task link is highlighted
+ \sa setHighlight()
+*/
+bool KDGanttViewTaskLink::highlight() const
+{
+ return ishighlighted;
+}
+
+
+/*!
+ Specifies the color to draw this task link in.
+
+ \param color the color to draw this task link in
+ \sa color()
+*/
+void KDGanttViewTaskLink::setColor( const QColor& color )
+{
+ myColor = color;
+ //if ( isvisible) setVisible(true );
+ myTimeTable->updateMyContent();
+}
+
+
+/*!
+ Returns the color in which this task link is drawn.
+
+ \return the color in which this task link is drawn
+ \sa setColor()
+*/
+QColor KDGanttViewTaskLink::color() const
+{
+ return myColor;
+}
+
+
+/*!
+ Specifies the highlight color to draw this task link in.
+
+ \param color the highlight color to draw this task link in
+ \sa highlightColor()
+*/
+void KDGanttViewTaskLink::setHighlightColor( const QColor& color )
+{
+ myColorHL = color;
+ //if ( isvisible) setVisible(true );
+ myTimeTable->updateMyContent();
+}
+
+
+/*!
+ Returns the highlight color in which this task link is drawn.
+
+ \return the highlight color in which this task link is drawn
+ \sa setHighlightColor()
+*/
+QColor KDGanttViewTaskLink::highlightColor() const
+{
+ return myColorHL;
+}
+
+
+/*!
+ Specifies the text to be shown as a tooltip for this task link.
+
+ \param text the tooltip text
+ \sa tooltipText()
+*/
+void KDGanttViewTaskLink::setTooltipText( const QString& text )
+{
+ myToolTipText = text;
+}
+
+
+/*!
+ Returns the tooltip text of this task link.
+
+ \return the tooltip text of this task link
+ \sa setTooltipText()
+*/
+QString KDGanttViewTaskLink::tooltipText() const
+{
+ return myToolTipText;
+}
+
+
+/*!
+ Specifies the text to be shown in a what's this window for this task link.
+
+ \param text the what's this text
+ \sa whatsThisText()
+*/
+void KDGanttViewTaskLink::setWhatsThisText( const QString& text )
+{
+ myWhatsThisText = text;
+
+}
+
+
+/*!
+ Returns the what's this text of this task link.
+
+ \return the what's this text of this task link
+ \sa setWhatsThisText()
+*/
+QString KDGanttViewTaskLink::whatsThisText() const
+{
+ return myWhatsThisText;
+}
+
+
+/*!
+ Returns the list of source item of this task link.
+
+ \return the ist of source item of this task link
+ \sa to()
+*/
+QPtrList<KDGanttViewItem> KDGanttViewTaskLink::from() const
+{
+ return fromList;
+}
+
+
+/*!
+ Removes a KDGanttViewItem from the lists.
+
+ \sa to() from()
+*/
+void KDGanttViewTaskLink::removeItemFromList( KDGanttViewItem* item )
+{
+ bool itemremoved = false;
+ if (fromList.remove( item )) {
+ itemremoved = true;
+ }
+ if ( toList.remove( item )) {
+ itemremoved = true;
+ }
+ if ( itemremoved ) {
+ setVisible( isvisible );
+ }
+}
+
+
+/*!
+ Returns the list of target items of this task link.
+
+ \return the list of target item of this task link
+ \sa from()
+*/
+QPtrList<KDGanttViewItem> KDGanttViewTaskLink::to() const
+{
+ return toList;
+}
+
+
+/*!
+ Creates a DOM node that describes this task link.
+
+ \param doc the DOM document to which the node belongs
+ \param parentElement the element into which to insert this node
+*/
+void KDGanttViewTaskLink::createNode( QDomDocument& doc,
+ QDomElement& parentElement )
+{
+ QDomElement taskLinkElement = doc.createElement( "TaskLink" );
+ parentElement.appendChild( taskLinkElement );
+
+ QDomElement fromItemsElement = doc.createElement( "FromItems" );
+ taskLinkElement.appendChild( fromItemsElement );
+ QPtrList<KDGanttViewItem> fromList = from();
+ KDGanttViewItem* item;
+ for( item = fromList.first(); item;
+ item = fromList.next() )
+ KDGanttXML::createStringNode( doc, fromItemsElement, "Item", item->name() );
+
+ QDomElement toItemsElement = doc.createElement( "ToItems" );
+ taskLinkElement.appendChild( toItemsElement );
+ QPtrList<KDGanttViewItem> toList = to();
+ for( item = toList.first(); item;
+ item = toList.next() )
+ KDGanttXML::createStringNode( doc, toItemsElement, "Item", item->name() );
+
+ KDGanttXML::createBoolNode( doc, taskLinkElement, "Highlight", highlight() );
+ KDGanttXML::createColorNode( doc, taskLinkElement, "Color", color() );
+ KDGanttXML::createColorNode( doc, taskLinkElement, "HighlightColor",
+ highlightColor() );
+ KDGanttXML::createStringNode( doc, taskLinkElement, "TooltipText",
+ tooltipText() );
+ KDGanttXML::createStringNode( doc, taskLinkElement, "WhatsThisText",
+ whatsThisText() );
+ if( group() )
+ KDGanttXML::createStringNode( doc, taskLinkElement, "Group",
+ group()->name() );
+ KDGanttXML::createBoolNode( doc, taskLinkElement, "Visible",
+ isVisible() );
+ KDGanttXML::createStringNode( doc, taskLinkElement, "Linktype",
+ linkTypeToString( myLinkType ) );
+}
+
+
+/*!
+ Creates a KDGanttViewTaskLink according to the specification in a DOM
+ element.
+
+ \param element the DOM element from which to read the specification
+ \return the newly created task link
+*/
+KDGanttViewTaskLink* KDGanttViewTaskLink::createFromDomElement( QDomElement& element )
+{
+ QDomNode node = element.firstChild();
+ QStringList fromList, toList;
+ bool highlight = false, visible = false;
+ QColor color, highlightColor;
+ QString tooltipText, whatsThisText, group;
+ LinkType linktype=None;
+ while( !node.isNull() ) {
+ QDomElement element = node.toElement();
+ if( !element.isNull() ) { // was really an element
+ QString tagName = element.tagName();
+ if( tagName == "FromItems" ) {
+ QDomNode node = element.firstChild();
+ while( !node.isNull() ) {
+ QDomElement element = node.toElement();
+ if( !element.isNull() ) { // was really an element
+ QString tagName = element.tagName();
+ if( tagName == "Item" ) {
+ QString value;
+ if( KDGanttXML::readStringNode( element, value ) )
+ fromList << value;
+ } else {
+ qDebug( "Unrecognized tag name: %s", tagName.latin1() );
+ Q_ASSERT( false );
+ }
+ }
+ node = node.nextSibling();
+ }
+ } else if( tagName == "ToItems" ) {
+ QDomNode node = element.firstChild();
+ while( !node.isNull() ) {
+ QDomElement element = node.toElement();
+ if( !element.isNull() ) { // was really an element
+ QString tagName = element.tagName();
+ if( tagName == "Item" ) {
+ QString value;
+ if( KDGanttXML::readStringNode( element, value ) )
+ toList << value;
+ } else {
+ qDebug( "Unrecognized tag name: %s", tagName.latin1() );
+ Q_ASSERT( false );
+ }
+ }
+ node = node.nextSibling();
+ }
+ } else if( tagName == "Highlight" ) {
+ bool value;
+ if( KDGanttXML::readBoolNode( element, value ) )
+ highlight = value;
+ } else if( tagName == "Visible" ) {
+ bool value;
+ if( KDGanttXML::readBoolNode( element, value ) )
+ visible = value;
+ } else if( tagName == "Color" ) {
+ QColor value;
+ if( KDGanttXML::readColorNode( element, value ) )
+ color = value;
+ } else if( tagName == "HighlightColor" ) {
+ QColor value;
+ if( KDGanttXML::readColorNode( element, value ) )
+ highlightColor = value;
+ } else if( tagName == "TooltipText" ) {
+ QString value;
+ if( KDGanttXML::readStringNode( element, value ) )
+ tooltipText = value;
+ } else if( tagName == "WhatsThisText" ) {
+ QString value;
+ if( KDGanttXML::readStringNode( element, value ) )
+ whatsThisText = value;
+ } else if( tagName == "Group" ) {
+ QString value;
+ if( KDGanttXML::readStringNode( element, value ) )
+ group = value;
+ } else if( tagName == "Linktype" ) {
+ QString value;
+ if( KDGanttXML::readStringNode( element, value ) )
+ linktype = stringToLinkType( value );
+ } else {
+ qDebug( "Unrecognized tag name: %s", tagName.latin1() );
+ Q_ASSERT( false );
+ }
+ }
+ node = node.nextSibling();
+ }
+
+ QPtrList<KDGanttViewItem> fromItemList;
+ QPtrList<KDGanttViewItem> toItemList;
+ for( QStringList::const_iterator fromIt = fromList.begin();
+ fromIt != fromList.end(); ++fromIt ) {
+ KDGanttViewItem* item = KDGanttViewItem::find( *fromIt );
+ if( item )
+ fromItemList.append( item );
+ }
+ for( QStringList::const_iterator toIt = toList.begin();
+ toIt != toList.end(); ++toIt ) {
+ KDGanttViewItem* item = KDGanttViewItem::find( *toIt );
+ if( item )
+ toItemList.append( item );
+ }
+ // safeguard aginst incorrect names
+ if (fromItemList.isEmpty()) {
+ qDebug("Cannot create link: fromItemList is empty");
+ return 0;
+ }
+ if (toItemList.isEmpty()) {
+ qDebug("Cannot create link: toItemList is empty");
+ return 0;
+ }
+ KDGanttViewTaskLink* tl = new KDGanttViewTaskLink( fromItemList,
+ toItemList );
+ tl->setLinkType( linktype );
+ tl->setVisible( visible );
+ tl->setHighlight( highlight );
+ tl->setColor( color );
+ tl->setHighlightColor( highlightColor );
+ tl->setTooltipText( tooltipText );
+ tl->setWhatsThisText( whatsThisText );
+ KDGanttViewTaskLinkGroup* gr = KDGanttViewTaskLinkGroup::find( group );
+ if( gr )
+ tl->setGroup( gr );
+
+ return tl;
+}
+
+int KDGanttViewTaskLink::linkType()
+{
+ return myLinkType;
+}
+
+void KDGanttViewTaskLink::setLinkType(int type)
+{
+ myLinkType = static_cast<LinkType>(type);
+}
+
+int KDGanttViewTaskLink::xOffset(KDGanttViewItem *item)
+{
+ switch (item->type()) {
+ case KDGanttViewItem::Task:
+ return 0;
+ break;
+ case KDGanttViewItem::Event:
+ return 4;
+ break;
+ case KDGanttViewItem::Summary:
+ return 4;
+ break;
+ default:
+ break;
+ }
+ return 0;
+}
+
+void KDGanttViewTaskLink::hide()
+{
+ QPtrListIterator<KDCanvasLine> horIt(*horLineList);
+ QPtrListIterator<KDCanvasLine> verIt(*verLineList);
+ QPtrListIterator<KDCanvasLine> horIt2(*horLineList2);
+ QPtrListIterator<KDCanvasLine> verIt2(*verLineList2);
+ QPtrListIterator<KDCanvasLine> horIt3(*horLineList3);
+ QPtrListIterator<KDCanvasPolygon> topIt(*topList);
+ QPtrListIterator<KDCanvasPolygon> topLeftIt(*topLeftList);
+ QPtrListIterator<KDCanvasPolygon> topRightIt(*topRightList);
+ QPtrListIterator<KDGanttViewItem> fromIt(fromList);
+ QPtrListIterator<KDGanttViewItem> toIt(toList);
+ for ( ; fromIt.current(); ++fromIt ) {
+ toIt.toFirst();
+ for ( ; toIt.current(); ++toIt ) {
+ (*horIt)->hide();
+ (*verIt)->hide();
+ (*horIt2)->hide();
+ (*verIt2)->hide();
+ (*horIt3)->hide();
+ (*topIt)->hide();
+ (*topLeftIt)->hide();
+ (*topRightIt)->hide();
+ ++horIt;
+ ++verIt;
+ ++horIt2;
+ ++verIt2;
+ ++horIt3;
+ ++topIt;
+ ++topLeftIt;
+ ++topRightIt;
+ }
+ }
+}
+
+QString KDGanttViewTaskLink::linkTypeToString( LinkType type )
+{
+ switch( type ) {
+ case None:
+ return "None";
+ break;
+ case FinishStart:
+ return "FinishStart";
+ break;
+ case FinishFinish:
+ return "FinishFinish";
+ break;
+ case StartStart:
+ return "StartStart";
+ break;
+ case StartFinish:
+ return "StartFinish";
+ break;
+ default:
+ break;
+ }
+ return "";
+}
+
+KDGanttViewTaskLink::LinkType KDGanttViewTaskLink::stringToLinkType( const QString type )
+{
+ if (type == "FinishStart")
+ return FinishStart;
+ if (type == "FinishFinish")
+ return FinishFinish;
+ if (type == "StartStart")
+ return StartStart;
+ if (type == "StartFinish")
+ return StartFinish;
+
+ return None;
+}
diff --git a/kdgantt/KDGanttViewTaskLink.h b/kdgantt/KDGanttViewTaskLink.h
new file mode 100644
index 00000000..efafb50f
--- /dev/null
+++ b/kdgantt/KDGanttViewTaskLink.h
@@ -0,0 +1,129 @@
+/* -*- 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.
+ **
+ **********************************************************************/
+
+#ifndef KDGANTTVIEWTASKLINK_H
+#define KDGANTTVIEWTASKLINK_H
+
+#include <qcolor.h>
+#include <qstring.h>
+#include <qptrlist.h>
+#include <qcanvas.h>
+
+#include "KDGanttViewItem.h"
+class KDGanttViewTaskLinkGroup;
+class KDCanvasPolygon;
+class KDCanvasLine;
+
+class KDGanttViewTaskLink
+{
+public:
+ enum LinkType { None, FinishStart, StartStart, FinishFinish, StartFinish };
+
+ KDGanttViewTaskLink( QPtrList<KDGanttViewItem> from,
+ QPtrList<KDGanttViewItem> to,
+ LinkType type=None );
+ KDGanttViewTaskLink( KDGanttViewTaskLinkGroup* group,
+ QPtrList<KDGanttViewItem> from,
+ QPtrList<KDGanttViewItem> to,
+ LinkType type=None );
+ KDGanttViewTaskLink( KDGanttViewTaskLinkGroup* group,
+ KDGanttViewItem* from,
+ KDGanttViewItem* to,
+ LinkType type=None );
+ KDGanttViewTaskLink( KDGanttViewItem* from,
+ KDGanttViewItem* to,
+ LinkType type=None );
+ ~KDGanttViewTaskLink();
+ QPtrList<KDGanttViewItem> from() const;
+ QPtrList<KDGanttViewItem> to() const;
+ void removeItemFromList( KDGanttViewItem* );
+
+ void setVisible( bool );
+ bool isVisible() const;
+
+ KDGanttViewTaskLinkGroup* group();
+ void setGroup( KDGanttViewTaskLinkGroup*) ;
+
+ void setHighlight( bool highlight );
+ bool highlight() const;
+
+ void setColor( const QColor& color );
+ QColor color() const;
+ void setHighlightColor( const QColor& color );
+ QColor highlightColor() const;
+
+ void setTooltipText( const QString& text );
+ QString tooltipText() const;
+ void setWhatsThisText( const QString& text );
+ QString whatsThisText() const;
+
+ void createNode( QDomDocument& doc,
+ QDomElement& parentElement );
+ static KDGanttViewTaskLink* createFromDomElement( QDomElement& );
+
+ int linkType();
+ void setLinkType(int type);
+
+private:
+ friend class KDGanttViewTaskLinkGroup;
+ friend class KDTimeTableWidget;
+ QPtrList<KDGanttViewItem> fromList,toList;
+ QPtrList<KDCanvasLine>* horLineList;
+ QPtrList<KDCanvasLine>* verLineList;
+ QPtrList<KDCanvasPolygon>* topList;
+
+ // also used when linkType != None
+ QPtrList<KDCanvasLine>* horLineList2;
+ QPtrList<KDCanvasLine>* verLineList2;
+ QPtrList<KDCanvasLine>* horLineList3;
+ QPtrList<KDCanvasPolygon>* topLeftList;
+ QPtrList<KDCanvasPolygon>* topRightList;
+
+ KDGanttViewTaskLinkGroup* myGroup;
+ bool isvisible,ishighlighted;
+ QColor myColor, myColorHL;
+ QString myToolTipText,myWhatsThisText;
+ KDTimeTableWidget* myTimeTable;
+ void initTaskLink();
+ void showMe( bool );
+ void showMeType( bool );
+ void hide();
+ int xOffset(KDGanttViewItem *item);
+
+ LinkType myLinkType;
+ static QString linkTypeToString( LinkType type );
+ static LinkType stringToLinkType( const QString type );
+};
+
+#endif
diff --git a/kdgantt/KDGanttViewTaskLinkGroup.cpp b/kdgantt/KDGanttViewTaskLinkGroup.cpp
new file mode 100644
index 00000000..c7142f67
--- /dev/null
+++ b/kdgantt/KDGanttViewTaskLinkGroup.cpp
@@ -0,0 +1,387 @@
+/* -*- 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 "KDGanttViewTaskLinkGroup.h"
+#include "KDGanttXMLTools.h"
+#include "KDGanttView.h"
+
+QDict<KDGanttViewTaskLinkGroup> KDGanttViewTaskLinkGroup::sGroupDict;
+
+/*! \class KDGanttViewTaskLinkGroup KDGanttViewTaskLinkGroup.h
+ A group of task links.
+
+ This class groups a number of task links together in order to
+ manipulate them uniformly.
+*/
+
+/*!
+ Constructs an empty task link group
+*/
+KDGanttViewTaskLinkGroup::KDGanttViewTaskLinkGroup()
+{
+ generateAndInsertName(QString());
+}
+
+/*!
+ Destructor
+ Removes this task link group from the list of task link groups in the
+ KDGanttView class.
+*/
+KDGanttViewTaskLinkGroup::~KDGanttViewTaskLinkGroup()
+{
+ if (!myTaskLinkList.isEmpty()) {
+ myTaskLinkList.first()->from().first()->myGanttView->removeTaskLinkGroup(this);
+ }
+}
+
+
+
+/*!
+ Constructs an empty task link group and records it under the name \a
+ name so that it can later be found again with
+ KDGanttViewTaskLinkGroup::find().
+
+ \param name the search name of this task link group
+*/
+KDGanttViewTaskLinkGroup::KDGanttViewTaskLinkGroup( const QString& name )
+{
+ generateAndInsertName( name );
+}
+
+/*!
+ Adds a task link LINK to this group. If the task link is already a member of
+ another group, it will be removed from it.
+ This function is equivalent to LINK->setGroup(this), where this is
+ a pointer to this TaskLinkGroup.
+ \param link a pointer to the task link to add to this task link group
+ visible, and false to hide them
+ \sa remove()
+*/
+void KDGanttViewTaskLinkGroup::insert (KDGanttViewTaskLink* link)
+{
+ link->setGroup(this);
+}
+
+
+/*!
+ Removes a task link LINK from this group.
+ You may remove a tasklink LINK from its group with LINK->setGroup(0).
+
+ \param link a pointer to the task link to remove from this task link group
+ \return true if the task link was a member of this group
+ \sa insert()
+*/
+bool KDGanttViewTaskLinkGroup::remove (KDGanttViewTaskLink* link)
+{
+ KDGanttViewTaskLinkGroup* g = link->group();
+ if ((g == this))
+ link->setGroup(0);
+ return (g == this);
+}
+
+
+/*!
+ Specifies whether the task links of this group should be visible or not.
+
+ \param show visible pass true to make the task links of this group
+ visible, and false to hide them
+ \sa isVisible()
+*/
+void KDGanttViewTaskLinkGroup::setVisible( bool show )
+{
+ isvisible = show;
+ QPtrListIterator<KDGanttViewTaskLink> it(myTaskLinkList);
+ for ( ; it.current(); ++it ) {
+ it.current()->setVisible(show);
+ }
+}
+
+
+/*!
+ Returns whether the task links of this group should be visible or not.
+
+ \return true if the task links of this group are visible
+ \sa setVisible()
+*/
+bool KDGanttViewTaskLinkGroup::visible() const
+{
+ return isvisible;
+}
+
+
+/*!
+ Specifies whether the task links of this group should be shown
+ highlighted. The user can also highlight a task link with the mouse.
+
+ \param highlight pass true in order to highlight the task links in
+ this group
+ \sa highlight()
+*/
+void KDGanttViewTaskLinkGroup::setHighlight( bool highlight )
+{
+ ishighlighted= highlight;
+ QPtrListIterator<KDGanttViewTaskLink> it(myTaskLinkList);
+ for ( ; it.current(); ++it )
+ it.current()->setHighlight(highlight );
+
+}
+
+
+/*!
+ Returns whether all task links in this group are highlighted, either
+ programmatically by setHighlight() or by the user with the
+ mouse. This method is not particularly useful and is mainly provided
+ for API uniformity reasons.
+
+ \return true if all the task links in this group are highlighted
+ \sa setHighlight()
+*/
+bool KDGanttViewTaskLinkGroup::highlight() const
+{
+ return ishighlighted;
+}
+
+
+/*!
+ Specifies the color to draw the task links in this group in.
+
+ \param color the color to draw the task links in this group in
+ \sa color()
+*/
+void KDGanttViewTaskLinkGroup::setColor( const QColor& color )
+{
+ myColor = color;
+ QPtrListIterator<KDGanttViewTaskLink> it(myTaskLinkList);
+ for ( ; it.current(); ++it )
+ it.current()->setColor(color);
+}
+
+
+/*!
+ Returns the color in which the task links in this group are
+ drawn. If task links have been assigned individual colors, the
+ return value of this method is undefined. This method is not
+ particularly useful and is mainly provided for API uniformity
+ reasons.
+
+ \return the color in which the task links in this group are drawn
+ \sa setColor()
+*/
+QColor KDGanttViewTaskLinkGroup::color() const
+{
+ return myColor;
+}
+
+
+/*!
+ Specifies the highlight color to draw the task links in this group in.
+
+ \param color the highlight color to draw the task links in this group in
+ \sa color()
+*/
+void KDGanttViewTaskLinkGroup::setHighlightColor( const QColor& color )
+{
+
+ myColorHL = color;
+ QPtrListIterator<KDGanttViewTaskLink> it(myTaskLinkList);
+ for ( ; it.current(); ++it )
+ it.current()->setHighlightColor(color);
+}
+
+
+/*!
+ Returns the highlight color in which the task links in this group are
+ drawn. If task links have been assigned individual highlight colors,
+ the return value of this method is undefined. This method is not
+ particularly useful and is mainly provided for API uniformity reasons.
+
+ \return the highlight color in which the task links in this group
+ are drawn
+ \sa setColor()
+*/
+QColor KDGanttViewTaskLinkGroup::highlightColor() const
+{
+ return myColorHL;
+}
+
+
+/*!
+ Adds a task link LINK to this group. If the task link is already a member of
+ another group, it will not be removed from it.
+ \param a pointer to the task link to add to this task link group
+ visible, and false to hide them
+ \sa removeItem()
+*/
+void KDGanttViewTaskLinkGroup::insertItem (KDGanttViewTaskLink* link)
+{
+ myTaskLinkList.append (link);
+}
+
+
+/*!
+ Removes a task link LINK from this group.
+
+ \param a pointer to the task link to remove from this task link group
+ \sa insertItem()
+*/
+void KDGanttViewTaskLinkGroup::removeItem (KDGanttViewTaskLink* link)
+{
+ myTaskLinkList.remove(link);
+}
+
+
+/*!
+ Returns the task link group with the specified name.
+
+ \param name the name to search for
+ \return the task link group with the specified name; 0 if no group
+ with that name exists
+*/
+KDGanttViewTaskLinkGroup* KDGanttViewTaskLinkGroup::find( const QString& name )
+{
+ if (name.isEmpty()) // avoid error msg from QDict
+ return 0;
+ return sGroupDict.find( name );
+}
+
+
+/*!
+ Creates a DOM node that describes this task link group.
+
+ \param doc the DOM document to which the node belongs
+ \param parentElement the element into which to insert this node
+*/
+void KDGanttViewTaskLinkGroup::createNode( QDomDocument& doc,
+ QDomElement& parentElement )
+{
+ QDomElement taskLinkGroupElement = doc.createElement( "TaskLink" );
+ parentElement.appendChild( taskLinkGroupElement );
+
+ KDGanttXML::createBoolNode( doc, taskLinkGroupElement, "Highlight",
+ highlight() );
+ KDGanttXML::createColorNode( doc, taskLinkGroupElement, "Color", color() );
+