diff --git a/src/libs/ui/kptganttview.cpp b/src/libs/ui/kptganttview.cpp index 13dce3b4..4831c65c 100644 --- a/src/libs/ui/kptganttview.cpp +++ b/src/libs/ui/kptganttview.cpp @@ -1,1523 +1,1539 @@ /* This file is part of the KDE project Copyright (C) 2002 - 2007, 2012 Dag Andersen Copyright (C) 2006 Raphael Langerhorst Copyright (C) 2016 Dag Andersen This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ // clazy:excludeall=qstring-arg #include "kptganttview.h" #include "kptnodeitemmodel.h" #include "kptappointment.h" #include "kptnode.h" #include "kptproject.h" #include "kpttask.h" #include "kptresource.h" #include "kptrelation.h" #include "kptschedule.h" #include "kptviewbase.h" #include "kptitemviewsettup.h" #include "kptduration.h" #include "kptdatetime.h" #include "kptresourceappointmentsmodel.h" #include "Help.h" #include "kptdebug.h" #include "gantt/DateTimeTimeLine.h" #include "gantt/DateTimeGrid.h" #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /// The main namespace namespace KPlato { class GanttItemDelegate; //------------------------------------------------- GanttChartDisplayOptionsPanel::GanttChartDisplayOptionsPanel( GanttViewBase *gantt, GanttItemDelegate *delegate, QWidget *parent ) : QWidget( parent ) , m_delegate( delegate ) , m_gantt(gantt) { setupUi( this ); setValues( *delegate ); connect( ui_showTaskName, &QCheckBox::stateChanged, this, &GanttChartDisplayOptionsPanel::changed ); connect( ui_showResourceNames, &QCheckBox::stateChanged, this, &GanttChartDisplayOptionsPanel::changed ); connect( ui_showDependencies, &QCheckBox::stateChanged, this, &GanttChartDisplayOptionsPanel::changed ); connect( ui_showPositiveFloat, &QCheckBox::stateChanged, this, &GanttChartDisplayOptionsPanel::changed ); connect( ui_showNegativeFloat, &QCheckBox::stateChanged, this, &GanttChartDisplayOptionsPanel::changed ); connect( ui_showCriticalPath, &QCheckBox::stateChanged, this, &GanttChartDisplayOptionsPanel::changed ); connect( ui_showCriticalTasks, &QCheckBox::stateChanged, this, &GanttChartDisplayOptionsPanel::changed ); connect( ui_showCompletion, &QCheckBox::stateChanged, this, &GanttChartDisplayOptionsPanel::changed ); connect( ui_showSchedulingError, &QCheckBox::stateChanged, this, &GanttChartDisplayOptionsPanel::changed ); connect( ui_showTimeConstraint, &QCheckBox::stateChanged, this, &GanttChartDisplayOptionsPanel::changed ); } void GanttChartDisplayOptionsPanel::slotOk() { m_delegate->showTaskName = ui_showTaskName->checkState() == Qt::Checked; m_delegate->showResources = ui_showResourceNames->checkState() == Qt::Checked; m_delegate->showTaskLinks = ui_showDependencies->checkState() == Qt::Checked; m_delegate->showPositiveFloat = ui_showPositiveFloat->checkState() == Qt::Checked; m_delegate->showNegativeFloat = ui_showNegativeFloat->checkState() == Qt::Checked; m_delegate->showCriticalPath = ui_showCriticalPath->checkState() == Qt::Checked; m_delegate->showCriticalTasks = ui_showCriticalTasks->checkState() == Qt::Checked; m_delegate->showProgress = ui_showCompletion->checkState() == Qt::Checked; m_delegate->showSchedulingError = ui_showSchedulingError->checkState() == Qt::Checked; m_delegate->showTimeConstraint = ui_showTimeConstraint->checkState() == Qt::Checked; DateTimeTimeLine *timeline = m_gantt->timeLine(); timeline->setInterval(ui_timeLineInterval->value() * 60000); QPen pen; pen.setWidth(ui_timeLineStroke->value()); pen.setColor(ui_timeLineColor->color()); timeline->setPen(pen); DateTimeTimeLine::Options opt = timeline->options(); opt.setFlag(DateTimeTimeLine::Foreground, ui_timeLineForeground->isChecked()); opt.setFlag(DateTimeTimeLine::Background, ui_timeLineBackground->isChecked()); opt.setFlag(DateTimeTimeLine::UseCustomPen, ui_timeLineUseCustom->isChecked()); timeline->setOptions(opt); } void GanttChartDisplayOptionsPanel::setValues( const GanttItemDelegate &del ) { ui_showTaskName->setCheckState( del.showTaskName ? Qt::Checked : Qt::Unchecked ); ui_showResourceNames->setCheckState( del.showResources ? Qt::Checked : Qt::Unchecked ); ui_showDependencies->setCheckState( del.showTaskLinks ? Qt::Checked : Qt::Unchecked ); ui_showPositiveFloat->setCheckState( del.showPositiveFloat ? Qt::Checked : Qt::Unchecked ); ui_showNegativeFloat->setCheckState( del.showNegativeFloat ? Qt::Checked : Qt::Unchecked ); ui_showCriticalPath->setCheckState( del.showCriticalPath ? Qt::Checked : Qt::Unchecked ); ui_showCriticalTasks->setCheckState( del.showCriticalTasks ? Qt::Checked : Qt::Unchecked ); ui_showCompletion->setCheckState( del.showProgress ? Qt::Checked : Qt::Unchecked ); ui_showSchedulingError->setCheckState( del.showSchedulingError ? Qt::Checked : Qt::Unchecked ); ui_showTimeConstraint->setCheckState( del.showTimeConstraint ? Qt::Checked : Qt::Unchecked ); DateTimeTimeLine *timeline = m_gantt->timeLine(); ui_timeLineInterval->setValue(timeline->interval() / 60000); QPen pen = timeline->pen(); ui_timeLineStroke->setValue(pen.width()); ui_timeLineColor->setColor(pen.color()); ui_timeLineHide->setChecked(true); DateTimeTimeLine::Options opt = timeline->options(); ui_timeLineBackground->setChecked(opt & DateTimeTimeLine::Background); ui_timeLineForeground->setChecked(opt & DateTimeTimeLine::Foreground); ui_timeLineUseCustom->setChecked(opt & DateTimeTimeLine::UseCustomPen); } void GanttChartDisplayOptionsPanel::setDefault() { GanttItemDelegate del; setValues( del ); } //---- GanttViewSettingsDialog::GanttViewSettingsDialog( GanttViewBase *gantt, GanttItemDelegate *delegate, ViewBase *view, bool selectPrint ) : ItemViewSettupDialog( view, gantt->treeView(), true, view ), m_gantt( gantt ) { GanttChartDisplayOptionsPanel *panel = new GanttChartDisplayOptionsPanel( gantt, delegate ); /*KPageWidgetItem *page = */insertWidget( 1, panel, i18n( "Chart" ), i18n( "Gantt Chart Settings" ) ); QTabWidget *tab = new QTabWidget(); QWidget *w = ViewBase::createPageLayoutWidget( view ); tab->addTab( w, w->windowTitle() ); m_pagelayout = w->findChild(); Q_ASSERT( m_pagelayout ); m_printingoptions = new GanttPrintingOptionsWidget( this ); m_printingoptions->setOptions( gantt->printingOptions() ); tab->addTab( m_printingoptions, m_printingoptions->windowTitle() ); KPageWidgetItem *page = insertWidget( 2, tab, i18n( "Printing" ), i18n( "Printing Options" ) ); if (selectPrint) { setCurrentPage(page); } connect( this, SIGNAL(accepted()), this, SLOT(slotOk()) ); connect( this, &QDialog::accepted, panel, &GanttChartDisplayOptionsPanel::slotOk ); connect( button(QDialogButtonBox::RestoreDefaults), &QAbstractButton::clicked, panel, &GanttChartDisplayOptionsPanel::setDefault ); } void GanttViewSettingsDialog::slotOk() { debugPlan; m_gantt->setPrintingOptions( m_printingoptions->options()); ItemViewSettupDialog::slotOk(); } //------------------------- GanttPrintingOptions::GanttPrintingOptions() : printRowLabels( true ), singlePage( true ) { } bool GanttPrintingOptions::loadContext( const KoXmlElement &settings ) { KoXmlElement e = settings.namedItem( "print-options" ).toElement(); if ( ! e.isNull() ) { printRowLabels = (bool)( e.attribute( "print-rowlabels", "0" ).toInt() ); singlePage = (bool)( e.attribute( "print-singlepage", "0" ).toInt() ); } debugPlan <<"..........."<treeView()->header()->height(); // same header hight m_sceneRect = gantt->graphicsView()->sceneRect(); m_horPages = 1; qreal c = m_sceneRect.width() - printer().pageRect().width(); while ( c > 0 ) { ++m_horPages; c -= printer().pageRect().width(); } m_vertPages = 1; c = m_sceneRect.height() - printer().pageRect().height() - m_headerHeight; while ( c > 0 ) { ++m_vertPages; c -= printer().pageRect().height(); } debugPlan< pages; if ( printer().fromPage() > 0 ) { pages << printer().fromPage(); if ( ! m_gantt->m_printOptions.singlePage ) { int last = printer().toPage(); for ( int i = pages.first() + 1; i <= last; ++i ) { pages << i; } if (m_vertPages > 1) { m_image = QImage(m_sceneRect.width(), m_sceneRect.height() + m_headerHeight, QImage::Format_ARGB32); m_image.fill(Qt::white); QPainter p(&m_image); m_gantt->print(&p, m_image.rect(), m_gantt->m_printOptions.printRowLabels, true); } } } setPageRange( pages ); PrintingDialog::startPrinting( removePolicy ); } QList GanttPrintingDialog::createOptionWidgets() const { //debugPlan; GanttPrintingOptionsWidget *w = new GanttPrintingOptionsWidget(); w->setPrintRowLabels( m_gantt->m_printOptions.printRowLabels ); connect(w->ui_printRowLabels, &QAbstractButton::toggled, this, &GanttPrintingDialog::slotPrintRowLabelsToogled); w->setSinglePage( m_gantt->m_printOptions.singlePage ); connect(w->ui_singlePage, &QAbstractButton::toggled, this, &GanttPrintingDialog::slotSinglePageToogled); const_cast( this )->m_options = w; return QList() << createPageLayoutWidget() << m_options; } void GanttPrintingDialog::slotPrintRowLabelsToogled( bool on ) { m_gantt->m_printOptions.printRowLabels = on; } void GanttPrintingDialog::slotSinglePageToogled( bool on ) { m_gantt->m_printOptions.singlePage = on; printer().setFromTo( documentFirstPage(), documentLastPage() ); } int GanttPrintingDialog::documentLastPage() const { //debugPlan<m_printOptions.singlePage<m_printOptions.singlePage ? documentFirstPage() : m_horPages * m_vertPages; } void GanttPrintingDialog::printPage( int page, QPainter &painter ) { debugPlan<<"page:"<m_printOptions.singlePage; int vert = singlePage ? 0 : p / m_horPages; int hor = singlePage ? 0 : p % m_horPages; // painter.setClipRect( pageRect.adjusted( -1.0, -1.0, 1.0, 1.0 ) ); if (singlePage) { // single page: use KGantt m_gantt->print( &painter, m_sceneRect.left(), m_sceneRect.right(), pageRect, m_gantt->m_printOptions.printRowLabels, true ); } else if (m_vertPages == 1) { // single vertical page: use KGantt qreal hh = vert == 0 ? m_headerHeight : 0; qreal ho = vert > 0 ? m_headerHeight : 0; QRectF sourceRect = QRectF( m_sceneRect.x() + ( pageRect.width() * hor ), m_sceneRect.y() + ( ( pageRect.height() * vert ) - ho ), pageRect.width(), pageRect.height() - hh ); debugPlan<print( &painter, sourceRect.left(), sourceRect.right(), pageRect, hor == 0 && m_gantt->m_printOptions.printRowLabels, true ); } else { // print on multiple vertical pages: use pixmap // QT5TODO Make KGantt able to print multiple pages vertically QRectF sourceRect = m_image.rect(); qreal hh = vert == 0 ? m_headerHeight : 0; qreal ho = vert > 0 ? m_headerHeight : 0; sourceRect = QRectF( sourceRect.x() + ( pageRect.width() * hor ), sourceRect.y() + ( ( pageRect.height() * vert ) - ho ), pageRect.width(), pageRect.height() - hh ); debugPlan<setContextMenuPolicy( Qt::CustomContextMenu ); connect( header(), SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(slotHeaderContextMenuRequested(QPoint)) ); } //------------------------------------------- GanttZoomWidget::GanttZoomWidget( QWidget *parent ) : QSlider( parent ), m_hide( true ), m_grid( 0 ) { setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ); setGeometry( 0, 0, 200, minimumSizeHint().height() ); setContextMenuPolicy( Qt::PreventContextMenu ); setOrientation( Qt::Horizontal ); setPageStep( 5 ); setMaximum( 125 ); connect(this, &QAbstractSlider::valueChanged, this, &GanttZoomWidget::sliderValueChanged); } void GanttZoomWidget::setEnableHideOnLeave( bool hide ) { m_hide = hide; } void GanttZoomWidget::setGrid( KGantt::DateTimeGrid *grid ) { m_grid = grid; if ( grid ) { int pos = -1; // daywidth always >= 0.1 for ( qreal dw = grid->dayWidth(); dw >= 0.1 && pos < maximum(); ++pos ) { dw *= 1.0 / 1.1; } blockSignals( true ); setValue( pos ); blockSignals( false ); } } void GanttZoomWidget::leaveEvent( QEvent *e ) { if ( m_hide ) { setVisible( false ); } QSlider::leaveEvent( e ); } void GanttZoomWidget::sliderValueChanged( int value ) { //debugPlan<setDayWidth( v ); } } //------------------------------------------- GanttViewBase::GanttViewBase( QWidget *parent ) : KGantt::View( parent ) { setGrid(new DateTimeGrid()); DateTimeGrid *g = static_cast( grid() ); g->setUserDefinedUpperScale( new KGantt::DateTimeScaleFormatter(KGantt::DateTimeScaleFormatter::Month, QString::fromLatin1("yyyy-MMMM"))); g->setUserDefinedLowerScale( new KGantt::DateTimeScaleFormatter(KGantt::DateTimeScaleFormatter::Day, QString::fromLatin1("ddd"))); g->timeNow()->setInterval(5000); QLocale locale; g->setWeekStart( locale.firstDayOfWeek() ); const QList weekdays = locale.weekdays(); QSet fd; for ( int i = Qt::Monday; i <= Qt::Sunday; ++i ) { if (!weekdays.contains(static_cast(i))) { fd << static_cast( i ); } } g->setFreeDays( fd ); m_zoomwidget = new GanttZoomWidget( graphicsView() ); m_zoomwidget->setGrid( g ); m_zoomwidget->setEnableHideOnLeave( true ); m_zoomwidget->hide(); m_zoomwidget->move( 6, 6 ); graphicsView()->installEventFilter(this); graphicsView()->setMouseTracking(true); } GanttViewBase::~GanttViewBase() { // HACK: avoid crash due to access of graphicsview scrollbar after death // KGantt tries to sync leftview scrollbar with graphicsview scrollbar // and seems sometimes graphicsview has already been deleted. // Note: this will be fixed in next KGantt release leftView()->verticalScrollBar()->disconnect(); } DateTimeTimeLine *GanttViewBase::timeLine() const { DateTimeGrid *g = static_cast( grid() ); return g->timeNow(); } GanttTreeView *GanttViewBase::treeView() const { GanttTreeView *tv = qobject_cast(const_cast(leftView())); Q_ASSERT(tv); return tv; } bool GanttViewBase::eventFilter(QObject *obj, QEvent *event) { if (obj != graphicsView()) { return false; } if (event->type() == QEvent::HoverMove) { QHoverEvent *e = static_cast( event ); if (e->pos().y() > 7 && e->pos().y() < m_zoomwidget->height() + 5 && e->pos().x() > 7 && e->pos().x() < m_zoomwidget->width() + 5 ) { if ( !m_zoomwidget->isVisible()) { m_zoomwidget->show(); m_zoomwidget->setFocus(); } return true; } } return false; } bool GanttViewBase::loadContext( const KoXmlElement &settings ) { KGantt::DateTimeGrid *g = static_cast( grid() ); g->setScale( static_cast( settings.attribute( "chart-scale", "0" ).toInt() ) ); g->setDayWidth( settings.attribute( "chart-daywidth", "30" ).toDouble() ); DateTimeTimeLine::Options opt; opt.setFlag(DateTimeTimeLine::Foreground, settings.attribute("timeline-foreground").toInt()); opt.setFlag(DateTimeTimeLine::Background, settings.attribute("timeline-background").toInt()); opt.setFlag(DateTimeTimeLine::UseCustomPen, settings.attribute("timeline-custom").toInt()); timeLine()->setOptions(opt); timeLine()->setInterval(settings.attribute("timeline-interval", 0).toInt() * 60000); QPen pen; pen.setWidth(settings.attribute("timeline-width").toInt()); pen.setColor(QColor(settings.attribute("timeline-color"))); timeLine()->setPen(pen); return true; } void GanttViewBase::saveContext( QDomElement &settings ) const { KGantt::DateTimeGrid *g = static_cast( grid() ); settings.setAttribute( "chart-scale", QString::number(g->scale()) ); settings.setAttribute( "chart-daywidth", QString::number(g->dayWidth()) ); settings.setAttribute("timeline-foreground", timeLine()->options() & DateTimeTimeLine::Foreground); settings.setAttribute("timeline-background", timeLine()->options() & DateTimeTimeLine::Background); settings.setAttribute("timeline-interval", timeLine()->interval() / 60000); settings.setAttribute("timeline-custom", timeLine()->options() & DateTimeTimeLine::UseCustomPen); settings.setAttribute("timeline-width", timeLine()->pen().width()); settings.setAttribute("timeline-color", timeLine()->pen().color().name()); } //------------------------------------------- NodeGanttViewBase::NodeGanttViewBase( QWidget *parent ) : GanttViewBase( parent ), m_project( 0 ), m_ganttdelegate( new GanttItemDelegate( this ) ) { debugPlan<<"------------------- create NodeGanttViewBase -----------------------"; graphicsView()->setItemDelegate( m_ganttdelegate ); GanttTreeView *tv = new GanttTreeView( this ); tv->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn); tv->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); tv->setVerticalScrollMode( QAbstractItemView::ScrollPerPixel ); // needed since qt 4.2 setLeftView( tv ); m_rowController = new KGantt::TreeViewRowController( tv, ganttProxyModel() ); setRowController( m_rowController ); tv->header()->setStretchLastSection( true ); - NodeSortFilterProxyModel *m = new NodeSortFilterProxyModel( &m_defaultModel, this ); + NodeSortFilterProxyModel *m = new NodeSortFilterProxyModel(&m_defaultModel, this, true); KGantt::View::setModel( m ); } NodeGanttViewBase::~NodeGanttViewBase() { delete m_rowController; } NodeSortFilterProxyModel *NodeGanttViewBase::sfModel() const { return static_cast( KGantt::View::model() ); } void NodeGanttViewBase::setItemModel( ItemModelBase *model ) { sfModel()->setSourceModel( model ); } ItemModelBase *NodeGanttViewBase::model() const { return sfModel()->itemModel(); } void NodeGanttViewBase::setProject( Project *project ) { model()->setProject( project ); m_project = project; } bool NodeGanttViewBase::loadContext( const KoXmlElement &settings ) { treeView()->loadContext( model()->columnMap(), settings ); KoXmlElement e = settings.namedItem( "ganttchart" ).toElement(); if ( ! e.isNull() ) { m_ganttdelegate->showTaskLinks = (bool)( e.attribute( "show-dependencies", "0" ).toInt() ); m_ganttdelegate->showTaskName = (bool)( e.attribute( "show-taskname", "0" ).toInt() ); m_ganttdelegate->showResources = (bool)( e.attribute( "show-resourcenames", "0" ).toInt() ); m_ganttdelegate->showProgress = (bool)( e.attribute( "show-completion", "0" ).toInt() ); m_ganttdelegate->showCriticalPath = (bool)( e.attribute( "show-criticalpath", "0" ).toInt() ); m_ganttdelegate->showCriticalTasks = (bool)( e.attribute( "show-criticaltasks", "0" ).toInt() ); m_ganttdelegate->showPositiveFloat = (bool)( e.attribute( "show-positivefloat", "0" ).toInt() ); m_ganttdelegate->showSchedulingError = (bool)( e.attribute( "show-schedulingerror", "0" ).toInt() ); m_ganttdelegate->showTimeConstraint = (bool)( e.attribute( "show-timeconstraint", "0" ).toInt() ); m_ganttdelegate->showNegativeFloat = (bool)( e.attribute( "show-negativefloat", "0" ).toInt() ); GanttViewBase::loadContext( e ); m_printOptions.loadContext( e ); } return true; } void NodeGanttViewBase::saveContext( QDomElement &settings ) const { debugPlan; treeView()->saveContext( model()->columnMap(), settings ); QDomElement e = settings.ownerDocument().createElement( "ganttchart" ); settings.appendChild( e ); e.setAttribute( "show-dependencies", QString::number(m_ganttdelegate->showTaskLinks) ); e.setAttribute( "show-taskname", QString::number(m_ganttdelegate->showTaskName) ); e.setAttribute( "show-resourcenames", QString::number(m_ganttdelegate->showResources) ); e.setAttribute( "show-completion", QString::number(m_ganttdelegate->showProgress) ); e.setAttribute( "show-criticalpath", QString::number(m_ganttdelegate->showCriticalPath) ); e.setAttribute( "show-criticaltasks",QString::number(m_ganttdelegate->showCriticalTasks) ); e.setAttribute( "show-positivefloat", QString::number(m_ganttdelegate->showPositiveFloat) ); e.setAttribute( "show-schedulingerror", QString::number(m_ganttdelegate->showSchedulingError) ); e.setAttribute( "show-timeconstraint", QString::number(m_ganttdelegate->showTimeConstraint) ); e.setAttribute( "show-negativefloat", QString::number(m_ganttdelegate->showNegativeFloat) ); GanttViewBase::saveContext( e ); m_printOptions.saveContext( e ); } +void NodeGanttViewBase::setShowUnscheduledTasks(bool show) +{ + NodeSortFilterProxyModel *m = qobject_cast(KGantt::View::model()); + if (m) { + m->setFilterUnscheduled(!show); + } +} + //------------------------------------------- MyKGanttView::MyKGanttView( QWidget *parent ) : NodeGanttViewBase( parent ), m_manager( 0 ) { debugPlan<<"------------------- create MyKGanttView -----------------------"; GanttItemModel *gm = new GanttItemModel( this ); setItemModel( gm ); treeView()->createItemDelegates( gm ); QList show; show << NodeModel::NodeName << NodeModel::NodeCompleted << NodeModel::NodeStartTime << NodeModel::NodeEndTime; treeView()->setDefaultColumns( show ); for ( int i = 0; i < model()->columnCount(); ++i ) { if ( ! show.contains( i ) ) { treeView()->hideColumn( i ); } } setConstraintModel( new KGantt::ConstraintModel( this ) ); KGantt::ProxyModel *m = static_cast( ganttProxyModel() ); m->setRole( KGantt::ItemTypeRole, KGantt::ItemTypeRole ); // To provide correct format m->setRole( KGantt::StartTimeRole, Qt::EditRole ); // To provide correct format m->setRole( KGantt::EndTimeRole, Qt::EditRole ); // To provide correct format m->removeColumn( Qt::DisplayRole ); m->setColumn( KGantt::ItemTypeRole, NodeModel::NodeType ); m->setColumn( KGantt::StartTimeRole, NodeModel::NodeStartTime ); m->setColumn( KGantt::EndTimeRole, NodeModel::NodeEndTime ); m->setColumn( KGantt::TaskCompletionRole, NodeModel::NodeCompleted ); KGantt::DateTimeGrid *g = static_cast( grid() ); g->setDayWidth( 30 ); // TODO: extend QLocale/KGantt to support formats for hourly time display // see bug #349030 // removed custom code here connect( model(), &NodeItemModel::nodeInserted, this, &MyKGanttView::slotNodeInserted ); } GanttItemModel *MyKGanttView::model() const { return static_cast( NodeGanttViewBase::model() ); } void MyKGanttView::setProject( Project *proj ) { clearDependencies(); if ( project() ) { disconnect( project(), &Project::relationToBeModified, this, &MyKGanttView::removeDependency); disconnect( project(), &Project::relationModified, this, &MyKGanttView::addDependency); disconnect( project(), &Project::relationAdded, this, &MyKGanttView::addDependency ); disconnect( project(), &Project::relationToBeRemoved, this, &MyKGanttView::removeDependency ); disconnect( project(), &Project::projectCalculated, this, &MyKGanttView::slotProjectCalculated ); } NodeGanttViewBase::setProject( proj ); if ( proj ) { connect( project(), &Project::relationToBeModified, this, &MyKGanttView::removeDependency); connect( project(), &Project::relationModified, this, &MyKGanttView::addDependency); connect( proj, &Project::relationAdded, this, &MyKGanttView::addDependency ); connect( proj, &Project::relationToBeRemoved, this, &MyKGanttView::removeDependency ); connect( proj, &Project::projectCalculated, this, &MyKGanttView::slotProjectCalculated ); } createDependencies(); } void MyKGanttView::slotProjectCalculated( ScheduleManager *sm ) { if ( m_manager == sm ) { setScheduleManager( sm ); } } void MyKGanttView::setScheduleManager( ScheduleManager *sm ) { clearDependencies(); m_manager = sm; KGantt::DateTimeGrid *g = static_cast( grid() ); if ( sm && project() ) { QDateTime start = project()->startTime( sm->scheduleId() ); if ( start.isValid() && g->startDateTime() != start ) { g->setStartDateTime( start ); } } if ( ! g->startDateTime().isValid() ) { g->setStartDateTime( QDateTime::currentDateTime() ); } model()->setScheduleManager( sm ); createDependencies(); } void MyKGanttView::slotNodeInserted( Node *node ) { foreach( Relation *r, node->dependChildNodes() ) { addDependency( r ); } foreach( Relation *r, node->dependParentNodes() ) { addDependency( r ); } } void MyKGanttView::addDependency( Relation *rel ) { QModelIndex par = sfModel()->mapFromSource( model()->index( rel->parent() ) ); QModelIndex ch = sfModel()->mapFromSource( model()->index( rel->child() ) ); // debugPlan<<"addDependency() "<( rel->type() )/*NOTE!!*/ ); if ( ! constraintModel()->hasConstraint( con ) ) { constraintModel()->addConstraint( con ); } } } void MyKGanttView::removeDependency( Relation *rel ) { QModelIndex par = sfModel()->mapFromSource( model()->index( rel->parent() ) ); QModelIndex ch = sfModel()->mapFromSource( model()->index( rel->child() ) ); KGantt::Constraint con( par, ch, KGantt::Constraint::TypeSoft, static_cast( rel->type() )/*NOTE!!*/ ); constraintModel()->removeConstraint( con ); } void MyKGanttView::clearDependencies() { constraintModel()->clear(); // Remove old deps from view // NOTE: This should be handled by KGantt graphicsView()->updateScene(); } void MyKGanttView::createDependencies() { clearDependencies(); if ( project() == 0 || m_manager == 0 ) { return; } foreach ( Node* n, project()->allNodes() ) { foreach ( Relation *r, n->dependChildNodes() ) { addDependency( r ); } } } //------------------------------------------ GanttView::GanttView(KoPart *part, KoDocument *doc, QWidget *parent, bool readWrite) : ViewBase(part, doc, parent), m_readWrite( readWrite ), m_project( 0 ) { debugPlan <<" ---------------- KPlato: Creating GanttView ----------------"; QVBoxLayout *l = new QVBoxLayout( this ); l->setMargin( 0 ); m_splitter = new QSplitter( this ); l->addWidget( m_splitter ); m_splitter->setOrientation( Qt::Vertical ); m_gantt = new MyKGanttView( m_splitter ); connect(this, &ViewBase::expandAll, m_gantt->treeView(), &TreeViewBase::slotExpand); connect(this, &ViewBase::collapseAll, m_gantt->treeView(), &TreeViewBase::slotCollapse); setupGui(); updateReadWrite( readWrite ); //connect( m_gantt->constraintModel(), SIGNAL(constraintAdded(Constraint)), this, SLOT(update()) ); debugPlan <constraintModel(); connect( m_gantt->treeView(), &TreeViewBase::contextMenuRequested, this, &GanttView::slotContextMenuRequested ); connect( m_gantt->treeView(), &TreeViewBase::headerContextMenuRequested, this, &ViewBase::slotHeaderContextMenuRequested ); Help::add(this, xi18nc("@info:whatsthis", "Gantt View" "" "Displays scheduled tasks in a Gantt diagram." " The chart area can be zoomed in and out with a slider" " positioned in the upper left corner of the time scale." " You need to hoover over it with the mouse for it to show." "" "This view supports configuration and printing using the context menu of the tree view." "More..." "", Help::page("Manual/Task_Gantt_View"))); } KoPrintJob *GanttView::createPrintJob() { return new GanttPrintingDialog( this, m_gantt ); } void GanttView::setZoom( double ) { //debugPlan <<"setting gantt zoom:" << zoom; //m_gantt->setZoomFactor(zoom,true); NO!!! setZoomFactor() is something else } void GanttView::setupGui() { // create context menu actions actionShowProject = new KToggleAction( i18n( "Show Project" ), this ); // FIXME: Dependencies depend on these methods being called in the correct order connect(actionShowProject, &QAction::triggered, m_gantt, &MyKGanttView::clearDependencies); connect(actionShowProject, &QAction::triggered, m_gantt->model(), &NodeItemModel::setShowProject); connect(actionShowProject, &QAction::triggered, m_gantt, &MyKGanttView::createDependencies); addContextAction( actionShowProject ); + actionShowUnscheduled = new KToggleAction( i18n( "Show Unscheduled Tasks" ), this ); + connect(actionShowUnscheduled, &QAction::triggered, m_gantt, &MyKGanttView::setShowUnscheduledTasks); + addContextAction(actionShowUnscheduled); + createOptionActions(ViewBase::OptionAll); } void GanttView::slotOptions() { debugPlan; GanttViewSettingsDialog *dlg = new GanttViewSettingsDialog( m_gantt, m_gantt->delegate(), this, sender()->objectName() == "print options" ); connect(dlg, SIGNAL(finished(int)), SLOT(slotOptionsFinished(int))); dlg->show(); dlg->raise(); dlg->activateWindow(); } void GanttView::slotOptionsFinished( int result ) { GanttViewSettingsDialog *dlg = qobject_cast( sender() ); if ( dlg && result == QDialog::Accepted ) { m_gantt->graphicsView()->updateScene(); } ViewBase::slotOptionsFinished( result ); } void GanttView::clear() { // m_gantt->clear(); } void GanttView::setShowResources( bool on ) { m_gantt->delegate()->showResources = on; } void GanttView::setShowTaskName( bool on ) { m_gantt->delegate()->showTaskName = on; } void GanttView::setShowProgress( bool on ) { m_gantt->delegate()->showProgress = on; } void GanttView::setShowPositiveFloat( bool on ) { m_gantt->delegate()->showPositiveFloat = on; } void GanttView::setShowCriticalTasks( bool on ) { m_gantt->delegate()->showCriticalTasks = on; } void GanttView::setShowCriticalPath( bool on ) { m_gantt->delegate()->showCriticalPath = on; } void GanttView::setShowNoInformation( bool on ) { m_gantt->delegate()->showNoInformation = on; } void GanttView::setShowAppointments( bool on ) { m_gantt->delegate()->showAppointments = on; } void GanttView::setShowTaskLinks( bool on ) { m_gantt->delegate()->showTaskLinks = on; } void GanttView::setProject( Project *project ) { m_gantt->setProject( project ); } void GanttView::setScheduleManager( ScheduleManager *sm ) { if (!sm && scheduleManager()) { // we should only get here if the only schedule manager is scheduled, // or when last schedule manager is deleted m_domdoc.clear(); QDomElement element = m_domdoc.createElement("expanded"); m_domdoc.appendChild(element); m_gantt->treeView()->saveExpanded(element); } bool tryexpand = sm && !scheduleManager(); bool expand = sm && scheduleManager() && sm != scheduleManager(); QDomDocument doc; if (expand) { QDomElement element = doc.createElement("expanded"); doc.appendChild(element); m_gantt->treeView()->saveExpanded(element); } ViewBase::setScheduleManager(sm); m_gantt->setScheduleManager( sm ); if (expand) { m_gantt->treeView()->doExpand(doc); } else if (tryexpand) { m_gantt->treeView()->doExpand(m_domdoc); } } void GanttView::draw( Project &project ) { setProject( &project ); } void GanttView::drawChanges( Project &project ) { if ( m_project != &project ) { setProject( &project ); } } Node *GanttView::currentNode() const { QModelIndex idx = m_gantt->treeView()->selectionModel()->currentIndex(); return m_gantt->model()->node( m_gantt->sfModel()->mapToSource( idx ) ); } void GanttView::slotContextMenuRequested( const QModelIndex &idx, const QPoint &pos ) { debugPlan; QString name; Node *node = m_gantt->model()->node( m_gantt->sfModel()->mapToSource( idx ) ); if ( node ) { switch ( node->type() ) { case Node::Type_Task: name = "taskview_popup"; break; case Node::Type_Milestone: name = "taskview_milestone_popup"; break; case Node::Type_Summarytask: name = "taskview_summary_popup"; break; default: break; } } else debugPlan<<"No node"; m_gantt->treeView()->setContextMenuIndex(idx); if ( name.isEmpty() ) { slotHeaderContextMenuRequested( pos ); m_gantt->treeView()->setContextMenuIndex(QModelIndex()); debugPlan<<"No menu"; return; } emit requestPopupMenu( name, pos ); m_gantt->treeView()->setContextMenuIndex(QModelIndex()); } bool GanttView::loadContext( const KoXmlElement &settings ) { debugPlan; ViewBase::loadContext( settings ); bool show = (bool)(settings.attribute( "show-project", "0" ).toInt() ); actionShowProject->setChecked( show ); m_gantt->model()->setShowProject( show ); // why is this not called by the action? + show = (bool)(settings.attribute( "show-unscheduled", "1" ).toInt() ); + actionShowUnscheduled->setChecked(show); + m_gantt->setShowUnscheduledTasks(show); return m_gantt->loadContext( settings ); } void GanttView::saveContext( QDomElement &settings ) const { debugPlan; ViewBase::saveContext( settings ); settings.setAttribute( "show-project", QString::number(actionShowProject->isChecked()) ); + settings.setAttribute( "show-unscheduled", QString::number(actionShowUnscheduled->isChecked()) ); m_gantt->saveContext( settings ); } void GanttView::updateReadWrite( bool on ) { // TODO: KGanttView needs read/write mode m_readWrite = on; } //---- MilestoneGanttViewSettingsDialog::MilestoneGanttViewSettingsDialog( GanttViewBase *gantt, ViewBase *view, bool selectPrint ) : ItemViewSettupDialog( view, gantt->treeView(), true, view ), m_gantt( gantt ) { QTabWidget *tab = new QTabWidget(); QWidget *w = ViewBase::createPageLayoutWidget( view ); tab->addTab( w, w->windowTitle() ); m_pagelayout = w->findChild(); Q_ASSERT( m_pagelayout ); m_printingoptions = new GanttPrintingOptionsWidget( this ); m_printingoptions->setOptions( gantt->printingOptions() ); tab->addTab( m_printingoptions, m_printingoptions->windowTitle() ); KPageWidgetItem *page = insertWidget( -1, tab, i18n( "Printing" ), i18n( "Printing Options" ) ); if (selectPrint) { setCurrentPage(page); } connect( this, SIGNAL(accepted()), this, SLOT(slotOk()) ); } void MilestoneGanttViewSettingsDialog::slotOk() { debugPlan; m_gantt->setPrintingOptions( m_printingoptions->options()); ItemViewSettupDialog::slotOk(); } //------------------------ MilestoneKGanttView::MilestoneKGanttView( QWidget *parent ) : NodeGanttViewBase( parent ), m_manager( 0 ) { debugPlan<<"------------------- create MilestoneKGanttView -----------------------"; MilestoneItemModel *mm = new MilestoneItemModel( this ); setItemModel( mm ); treeView()->createItemDelegates( mm ); sfModel()->setFilterRole ( Qt::EditRole ); sfModel()->setFilterFixedString( QString::number( Node::Type_Milestone ) ); sfModel()->setFilterKeyColumn( NodeModel::NodeType ); QList show; show << NodeModel::NodeWBSCode << NodeModel::NodeName << NodeModel::NodeStartTime; treeView()->setDefaultColumns( show ); for ( int i = 0; i < model()->columnCount(); ++i ) { if ( ! show.contains( i ) ) { treeView()->hideColumn( i ); } } treeView()->header()->moveSection(NodeModel::NodeWBSCode, show.indexOf(NodeModel::NodeWBSCode)); treeView()->setRootIsDecorated ( false ); KGantt::ProxyModel *m = static_cast( ganttProxyModel() ); m->setRole( KGantt::ItemTypeRole, KGantt::ItemTypeRole ); // To provide correct format m->setRole( KGantt::StartTimeRole, Qt::EditRole ); // To provide correct format m->setRole( KGantt::EndTimeRole, Qt::EditRole ); // To provide correct format m->removeColumn( Qt::DisplayRole ); m->setColumn( KGantt::ItemTypeRole, NodeModel::NodeType ); m->setColumn( KGantt::StartTimeRole, NodeModel::NodeStartTime ); m->setColumn( KGantt::EndTimeRole, NodeModel::NodeEndTime ); m->setColumn( KGantt::TaskCompletionRole, NodeModel::NodeCompleted ); KGantt::DateTimeGrid *g = static_cast( grid() ); g->setDayWidth( 30 ); // TODO: extend QLocale/KGantt to support formats for hourly time display // see bug #349030 // removed custom code here // TODO: add to context treeView()->sortByColumn(NodeModel::NodeWBSCode, Qt::AscendingOrder); treeView()->setSortingEnabled(true); Help::add(this, xi18nc("@info:whatsthis", "Milestone Gantt View" "" "Displays scheduled milestones in a Gantt diagram." " The chart area can be zoomed in and out with a slider" " positioned in the upper left corner of the time scale." " You need to hoover over it with the mouse for it to show." "" "This view supports configuration and printing using the context menu." "More..." "", Help::page("Manual/Milestone_Gantt_View"))); } MilestoneItemModel *MilestoneKGanttView::model() const { return static_cast( NodeGanttViewBase::model() ); } void MilestoneKGanttView::setProject( Project *proj ) { if ( project() ) { disconnect( project(), &Project::projectCalculated, this, &MilestoneKGanttView::slotProjectCalculated ); } NodeGanttViewBase::setProject( proj ); if ( proj ) { connect( proj, &Project::projectCalculated, this, &MilestoneKGanttView::slotProjectCalculated ); } } void MilestoneKGanttView::slotProjectCalculated( ScheduleManager *sm ) { if ( m_manager == sm ) { setScheduleManager( sm ); } } void MilestoneKGanttView::setScheduleManager( ScheduleManager *sm ) { //debugPlan<setScheduleManager( 0 ); m_manager = sm; KGantt::DateTimeGrid *g = static_cast( grid() ); if ( sm && m_project ) { QDateTime start; foreach ( const Node *n, model()->mileStones() ) { QDateTime nt = n->startTime( sm->scheduleId() ); if ( ! nt.isValid() ) { continue; } if ( ! start.isValid() || start > nt ) { start = nt; debugPlan<name()<startTime( sm->scheduleId() ); } if ( g->startDateTime() != start ) { g->setStartDateTime( start ); } } if ( ! g->startDateTime().isValid() ) { g->setStartDateTime( QDateTime::currentDateTime() ); } model()->setScheduleManager( sm ); } //------------------------------------------ MilestoneGanttView::MilestoneGanttView(KoPart *part, KoDocument *doc, QWidget *parent, bool readWrite) : ViewBase(part, doc, parent), m_readWrite( readWrite ), m_project( 0 ) { debugPlan <<" ---------------- Plan: Creating Milesone GanttView ----------------"; QVBoxLayout *l = new QVBoxLayout( this ); l->setMargin( 0 ); m_splitter = new QSplitter( this ); l->addWidget( m_splitter ); m_splitter->setOrientation( Qt::Vertical ); setupGui(); m_gantt = new MilestoneKGanttView( m_splitter ); m_showTaskName = false; // FIXME m_showProgress = false; //FIXME m_showPositiveFloat = false; //FIXME m_showCriticalTasks = false; //FIXME m_showNoInformation = false; //FIXME updateReadWrite( readWrite ); connect( m_gantt->treeView(), &TreeViewBase::contextMenuRequested, this, &MilestoneGanttView::slotContextMenuRequested ); connect( m_gantt->treeView(), &TreeViewBase::headerContextMenuRequested, this, &ViewBase::slotHeaderContextMenuRequested ); } void MilestoneGanttView::setZoom( double ) { //debugPlan <<"setting gantt zoom:" << zoom; //m_gantt->setZoomFactor(zoom,true); NO!!! setZoomFactor() is something else } void MilestoneGanttView::show() { } void MilestoneGanttView::clear() { } void MilestoneGanttView::setProject( Project *project ) { m_gantt->setProject( project ); } void MilestoneGanttView::setScheduleManager( ScheduleManager *sm ) { //debugPlan<setScheduleManager( sm ); } void MilestoneGanttView::draw( Project &project ) { setProject( &project ); } void MilestoneGanttView::drawChanges( Project &project ) { if ( m_project != &project ) { setProject( &project ); } } Node *MilestoneGanttView::currentNode() const { QModelIndex idx = m_gantt->treeView()->selectionModel()->currentIndex(); return m_gantt->model()->node( m_gantt->sfModel()->mapToSource( idx ) ); } void MilestoneGanttView::setupGui() { createOptionActions(ViewBase::OptionAll); } void MilestoneGanttView::slotContextMenuRequested( const QModelIndex &idx, const QPoint &pos ) { debugPlan; QString name; Node *node = m_gantt->model()->node( m_gantt->sfModel()->mapToSource( idx ) ); if ( node ) { switch ( node->type() ) { case Node::Type_Task: name = "taskview_popup"; break; case Node::Type_Milestone: name = "taskview_milestone_popup"; break; case Node::Type_Summarytask: name = "taskview_summary_popup"; break; default: break; } } else debugPlan<<"No node"; m_gantt->treeView()->setContextMenuIndex(idx); if ( name.isEmpty() ) { debugPlan<<"No menu"; slotHeaderContextMenuRequested( pos ); m_gantt->treeView()->setContextMenuIndex(QModelIndex()); return; } emit requestPopupMenu( name, pos ); m_gantt->treeView()->setContextMenuIndex(QModelIndex()); } void MilestoneGanttView::slotOptions() { debugPlan; MilestoneGanttViewSettingsDialog *dlg = new MilestoneGanttViewSettingsDialog( m_gantt, this, sender()->objectName() == "print options" ); connect(dlg, SIGNAL(finished(int)), SLOT(slotOptionsFinished(int))); dlg->show(); dlg->raise(); dlg->activateWindow(); } bool MilestoneGanttView::loadContext( const KoXmlElement &settings ) { debugPlan; ViewBase::loadContext( settings ); return m_gantt->loadContext( settings ); } void MilestoneGanttView::saveContext( QDomElement &settings ) const { debugPlan; ViewBase::saveContext( settings ); return m_gantt->saveContext( settings ); } void MilestoneGanttView::updateReadWrite( bool on ) { m_readWrite = on; } KoPrintJob *MilestoneGanttView::createPrintJob() { return new GanttPrintingDialog( this, m_gantt ); } //-------------------- ResourceAppointmentsGanttViewSettingsDialog::ResourceAppointmentsGanttViewSettingsDialog( GanttViewBase *gantt, ViewBase *view, bool selectPrint ) : ItemViewSettupDialog( view, gantt->treeView(), true, view ) , m_gantt(gantt) { QTabWidget *tab = new QTabWidget(); QWidget *w = ViewBase::createPageLayoutWidget( view ); tab->addTab( w, w->windowTitle() ); m_pagelayout = w->findChild(); Q_ASSERT( m_pagelayout ); m_printingoptions = new GanttPrintingOptionsWidget( this ); m_printingoptions->setOptions( gantt->printingOptions() ); tab->addTab( m_printingoptions, m_printingoptions->windowTitle() ); KPageWidgetItem *page = insertWidget( -1, tab, i18n( "Printing" ), i18n( "Printing Options" ) ); if (selectPrint) { setCurrentPage(page); } connect( this, SIGNAL(accepted()), this, SLOT(slotOk()) ); } void ResourceAppointmentsGanttViewSettingsDialog::slotOk() { debugPlan; m_gantt->setPrintingOptions( m_printingoptions->options()); ItemViewSettupDialog::slotOk(); } //------------------------------------------ ResourceAppointmentsGanttView::ResourceAppointmentsGanttView(KoPart *part, KoDocument *doc, QWidget *parent, bool readWrite) : ViewBase(part, doc, parent), m_project( 0 ), m_model( new ResourceAppointmentsGanttModel( this ) ) { debugPlan <<" ---------------- KPlato: Creating ResourceAppointmentsGanttView ----------------"; m_gantt = new GanttViewBase( this ); m_gantt->graphicsView()->setItemDelegate( new ResourceGanttItemDelegate( m_gantt ) ); GanttTreeView *tv = new GanttTreeView( m_gantt ); tv->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn); tv->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); tv->setVerticalScrollMode( QAbstractItemView::ScrollPerPixel ); // needed since qt 4.2 m_gantt->setLeftView( tv ); connect(this, &ViewBase::expandAll, tv, &TreeViewBase::slotExpand); connect(this, &ViewBase::collapseAll, tv, &TreeViewBase::slotCollapse); m_rowController = new KGantt::TreeViewRowController( tv, m_gantt->ganttProxyModel() ); m_gantt->setRowController( m_rowController ); tv->header()->setStretchLastSection( true ); tv->setTreePosition(-1); KGantt::ProxyModel *m = static_cast( m_gantt->ganttProxyModel() ); m->setRole( KGantt::ItemTypeRole, KGantt::ItemTypeRole ); m->setRole( KGantt::StartTimeRole, KGantt::StartTimeRole ); m->setRole( KGantt::EndTimeRole, KGantt::EndTimeRole ); m->setRole( KGantt::TaskCompletionRole, KGantt::TaskCompletionRole ); m_gantt->setModel( m_model ); QVBoxLayout *l = new QVBoxLayout( this ); l->setMargin( 0 ); l->addWidget( m_gantt ); setupGui(); updateReadWrite( readWrite ); connect( m_gantt->leftView(), SIGNAL(contextMenuRequested(QModelIndex,QPoint,QModelIndexList)), SLOT(slotContextMenuRequested(QModelIndex,QPoint)) ); connect( m_gantt->leftView(), SIGNAL(headerContextMenuRequested(QPoint)), SLOT(slotHeaderContextMenuRequested(QPoint)) ); Help::add(this, xi18nc("@info:whatsthis", "Resource Assignments (Gantt)" "" "Displays the scheduled resource - task assignments in a Gantt diagram." " The chart area can be zoomed in and out with a slider" " positioned in the upper left corner of the time scale." " You need to hoover over it with the mouse for it to show." "" "This view supports configuration and printing using the context menu." "More..." "", Help::page("Manual/Resource_Assignment_Gantt_View"))); } ResourceAppointmentsGanttView::~ResourceAppointmentsGanttView() { delete m_rowController; } void ResourceAppointmentsGanttView::setZoom( double ) { //debugPlan <<"setting gantt zoom:" << zoom; //m_gantt->setZoomFactor(zoom,true); NO!!! setZoomFactor() is something else } Project *ResourceAppointmentsGanttView::project() const { return m_model->project(); } void ResourceAppointmentsGanttView::setProject( Project *project ) { m_model->setProject( project ); } void ResourceAppointmentsGanttView::setScheduleManager( ScheduleManager *sm ) { //debugPlan<saveExpanded(element); } bool tryexpand = sm && !scheduleManager(); bool expand = sm && scheduleManager() && sm != scheduleManager(); QDomDocument doc; if (expand) { QDomElement element = doc.createElement("expanded"); doc.appendChild(element); treeView()->saveExpanded(element); } ViewBase::setScheduleManager(sm); m_model->setScheduleManager( sm ); if (expand) { treeView()->doExpand(doc); } else if (tryexpand) { treeView()->doExpand(m_domdoc); } } void ResourceAppointmentsGanttView::setupGui() { createOptionActions(ViewBase::OptionAll); } Node *ResourceAppointmentsGanttView::currentNode() const { QModelIndex idx = treeView()->selectionModel()->currentIndex(); return m_model->node( idx ); } void ResourceAppointmentsGanttView::slotContextMenuRequested( const QModelIndex &idx, const QPoint &pos ) { debugPlan<node( idx ); if ( n ) { name = "taskview_popup"; } } m_gantt->treeView()->setContextMenuIndex(idx); if ( name.isEmpty() ) { slotHeaderContextMenuRequested( pos ); m_gantt->treeView()->setContextMenuIndex(QModelIndex()); return; } emit requestPopupMenu( name, pos ); m_gantt->treeView()->setContextMenuIndex(QModelIndex()); } void ResourceAppointmentsGanttView::slotOptions() { debugPlan; ItemViewSettupDialog *dlg = new ResourceAppointmentsGanttViewSettingsDialog(m_gantt, this, sender()->objectName() == "print options"); connect(dlg, SIGNAL(finished(int)), SLOT(slotOptionsFinished(int))); dlg->show(); dlg->raise(); dlg->activateWindow(); } bool ResourceAppointmentsGanttView::loadContext( const KoXmlElement &settings ) { debugPlan; ViewBase::loadContext( settings ); m_gantt->loadContext( settings ); return treeView()->loadContext( m_model->columnMap(), settings ); } void ResourceAppointmentsGanttView::saveContext( QDomElement &settings ) const { debugPlan; ViewBase::saveContext( settings ); m_gantt->saveContext( settings ); treeView()->saveContext( m_model->columnMap(), settings ); } void ResourceAppointmentsGanttView::updateReadWrite( bool on ) { m_readWrite = on; } KoPrintJob *ResourceAppointmentsGanttView::createPrintJob() { return new GanttPrintingDialog( this, m_gantt ); } } //KPlato namespace #include "moc_kptganttview.cpp" diff --git a/src/libs/ui/kptganttview.h b/src/libs/ui/kptganttview.h index 162d3673..c2f049ac 100644 --- a/src/libs/ui/kptganttview.h +++ b/src/libs/ui/kptganttview.h @@ -1,481 +1,485 @@ /* This file is part of the KDE project Copyright (C) 2005 Dag Andersen Copyright (C) 2006 Raphael Langerhorst This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KPTGANTTVIEW_H #define KPTGANTTVIEW_H #include "planui_export.h" #include "kptviewbase.h" #include "kptitemviewsettup.h" #include "kptnodeitemmodel.h" #include "kptganttitemdelegate.h" #include "ui_kptganttprintingoptions.h" #include "ui_kptganttchartdisplayoptions.h" #include #include #include class KoDocument; class QPoint; class QSplitter; class KoPrintJob; namespace KGantt { class TreeViewRowController; } namespace KPlato { class Node; class MilestoneItemModel; class GanttItemModel; class ResourceAppointmentsGanttModel; class Task; class Project; class Relation; class ScheduleManager; class MyKGanttView; class GanttPrintingOptions; class GanttViewBase; class NodeGanttViewBase; class GanttPrintingOptionsWidget; class DateTimeTimeLine; //--------------------------------------- class GanttChartDisplayOptionsPanel : public QWidget, public Ui::GanttChartDisplayOptions { Q_OBJECT public: explicit GanttChartDisplayOptionsPanel( GanttViewBase *gantt, GanttItemDelegate *delegate, QWidget *parent = 0 ); void setValues( const GanttItemDelegate &del ); public Q_SLOTS: void slotOk(); void setDefault(); Q_SIGNALS: void changed(); private: GanttItemDelegate *m_delegate; GanttViewBase *m_gantt; }; class GanttViewSettingsDialog : public ItemViewSettupDialog { Q_OBJECT public: explicit GanttViewSettingsDialog( GanttViewBase *gantt, GanttItemDelegate *delegate, ViewBase *view, bool selectPrint = false ); protected Q_SLOTS: void slotOk(); private: GanttViewBase *m_gantt; GanttPrintingOptionsWidget *m_printingoptions; }; //-------------------- class GanttPrintingOptions { public: GanttPrintingOptions(); bool loadContext( const KoXmlElement &settings ); void saveContext( QDomElement &settings ) const; bool printRowLabels; bool singlePage; }; class PLANUI_EXPORT GanttPrintingOptionsWidget : public QWidget, public Ui::GanttPrintingOptionsWidget { Q_OBJECT public: explicit GanttPrintingOptionsWidget( QWidget *parent = 0 ); GanttPrintingOptions options() const; void setPrintRowLabels( bool value ) { ui_printRowLabels->setChecked( value ); } bool printRowLabels() const { return ui_printRowLabels->isChecked(); } void setSinglePage( bool value ) { value ? ui_singlePage->setChecked( false ) : ui_multiplePages->setChecked( true ); } bool singlePage() const { return ui_singlePage->isChecked(); } public Q_SLOTS: void setOptions(const KPlato::GanttPrintingOptions &opt); }; class GanttPrintingDialog : public PrintingDialog { Q_OBJECT public: GanttPrintingDialog( ViewBase *view, GanttViewBase *gantt ); void startPrinting( RemovePolicy removePolicy ); QList createOptionWidgets() const; void printPage( int page, QPainter &painter ); int documentLastPage() const; protected Q_SLOTS: void slotPrintRowLabelsToogled( bool on ); void slotSinglePageToogled( bool on ); protected: GanttViewBase *m_gantt; QRectF m_sceneRect; int m_horPages; int m_vertPages; double m_headerHeight; GanttPrintingOptionsWidget *m_options; QImage m_image; }; class PLANUI_EXPORT GanttTreeView : public TreeViewBase { Q_OBJECT public: explicit GanttTreeView(QWidget *parent); }; class GanttZoomWidget : public QSlider { Q_OBJECT public: explicit GanttZoomWidget( QWidget *parent ); void setGrid( KGantt::DateTimeGrid *grid ); void setEnableHideOnLeave( bool hide ); protected: void leaveEvent( QEvent *event ); private Q_SLOTS: void sliderValueChanged( int value ); private: bool m_hide; KGantt::DateTimeGrid *m_grid; }; class PLANUI_EXPORT GanttViewBase : public KGantt::View { Q_OBJECT public: explicit GanttViewBase(QWidget *parent); ~GanttViewBase(); GanttTreeView *treeView() const; GanttPrintingOptions printingOptions() const { return m_printOptions; } virtual bool loadContext( const KoXmlElement &settings ); virtual void saveContext( QDomElement &settings ) const; DateTimeTimeLine *timeLine() const; public Q_SLOTS: void setPrintingOptions(const KPlato::GanttPrintingOptions &opt) { m_printOptions = opt; } protected: bool eventFilter(QObject *obj, QEvent *event); friend class GanttPrintingDialog; GanttPrintingOptions m_printOptions; private: GanttZoomWidget *m_zoomwidget; }; class NodeGanttViewBase : public GanttViewBase { Q_OBJECT public: explicit NodeGanttViewBase(QWidget *parent); ~NodeGanttViewBase(); NodeSortFilterProxyModel *sfModel() const; void setItemModel( ItemModelBase *model ); ItemModelBase *model() const; void setProject( Project *project ); Project *project() const { return m_project; } GanttItemDelegate *delegate() const { return m_ganttdelegate; } bool loadContext( const KoXmlElement &settings ); void saveContext( QDomElement &settings ) const; +public Q_SLOTS: + void setShowUnscheduledTasks(bool show); + protected: Project *m_project; GanttItemDelegate *m_ganttdelegate; NodeItemModel m_defaultModel; KGantt::TreeViewRowController *m_rowController; }; class PLANUI_EXPORT MyKGanttView : public NodeGanttViewBase { Q_OBJECT public: explicit MyKGanttView(QWidget *parent); GanttItemModel *model() const; void setProject( Project *project ); void setScheduleManager( ScheduleManager *sm ); public Q_SLOTS: void clearDependencies(); void createDependencies(); void addDependency(KPlato::Relation *rel); void removeDependency(KPlato::Relation *rel); void slotProjectCalculated(KPlato::ScheduleManager *sm); void slotNodeInserted(KPlato::Node *node); protected: ScheduleManager *m_manager; }; class PLANUI_EXPORT GanttView : public ViewBase { Q_OBJECT public: GanttView(KoPart *part, KoDocument *doc, QWidget *parent, bool readWrite = true); //~GanttView(); virtual void setZoom( double zoom ); void setupGui(); Project *project() const { return m_gantt->project(); } virtual void setProject( Project *project ); using ViewBase::draw; virtual void draw( Project &project ); virtual void drawChanges( Project &project ); Node *currentNode() const; void clear(); virtual bool loadContext( const KoXmlElement &context ); virtual void saveContext( QDomElement &context ) const; void updateReadWrite( bool on ); KoPrintJob *createPrintJob(); void setShowSpecialInfo( bool on ) { m_gantt->model()->setShowSpecial( on ); } bool showSpecialInfo() const { return m_gantt->model()->showSpecial(); } Q_SIGNALS: void modifyRelation(KPlato::Relation *rel) ; void addRelation(KPlato::Node *par, KPlato::Node *child); void modifyRelation(KPlato::Relation *rel, int linkType) ; void addRelation(KPlato::Node *par, KPlato::Node *child, int linkType); void itemDoubleClicked(); public Q_SLOTS: void setScheduleManager(KPlato::ScheduleManager *sm); void setShowResources( bool on ); void setShowTaskName( bool on ); void setShowTaskLinks( bool on ); void setShowProgress( bool on ); void setShowPositiveFloat( bool on ); void setShowCriticalTasks( bool on ); void setShowCriticalPath( bool on ); void setShowNoInformation( bool on ); void setShowAppointments( bool on ); protected Q_SLOTS: void slotContextMenuRequested( const QModelIndex&, const QPoint &pos ); virtual void slotOptions(); virtual void slotOptionsFinished( int result ); private: bool m_readWrite; int m_defaultFontSize; QSplitter *m_splitter; MyKGanttView *m_gantt; Project *m_project; QAction *actionShowProject; + QAction *actionShowUnscheduled; QDomDocument m_domdoc; }; class MilestoneGanttViewSettingsDialog : public ItemViewSettupDialog { Q_OBJECT public: MilestoneGanttViewSettingsDialog( GanttViewBase *gantt, ViewBase *view, bool selectPrint = false ); protected Q_SLOTS: virtual void slotOk(); private: GanttViewBase *m_gantt; GanttPrintingOptionsWidget *m_printingoptions; }; class PLANUI_EXPORT MilestoneKGanttView : public NodeGanttViewBase { Q_OBJECT public: explicit MilestoneKGanttView(QWidget *parent); MilestoneItemModel *model() const; void setProject( Project *project ); void setScheduleManager( ScheduleManager *sm ); public Q_SLOTS: void slotProjectCalculated(KPlato::ScheduleManager *sm); protected: ScheduleManager *m_manager; }; class PLANUI_EXPORT MilestoneGanttView : public ViewBase { Q_OBJECT public: MilestoneGanttView(KoPart *part, KoDocument *doc, QWidget *parent, bool readWrite = true); virtual void setZoom( double zoom ); void show(); virtual void setProject( Project *project ); Project *project() const { return m_gantt->project(); } using ViewBase::draw; virtual void draw( Project &project ); virtual void drawChanges( Project &project ); void setupGui(); Node *currentNode() const; void clear(); virtual bool loadContext( const KoXmlElement &context ); virtual void saveContext( QDomElement &context ) const; void updateReadWrite( bool on ); bool showNoInformation() const { return m_showNoInformation; } KoPrintJob *createPrintJob(); Q_SIGNALS: void itemDoubleClicked(); public Q_SLOTS: void setScheduleManager(KPlato::ScheduleManager *sm); void setShowTaskName( bool on ) { m_showTaskName = on; } void setShowProgress( bool on ) { m_showProgress = on; } void setShowPositiveFloat( bool on ) { m_showPositiveFloat = on; } void setShowCriticalTasks( bool on ) { m_showCriticalTasks = on; } void setShowNoInformation( bool on ) { m_showNoInformation = on; } protected Q_SLOTS: void slotContextMenuRequested( const QModelIndex&, const QPoint &pos ); virtual void slotOptions(); private: bool m_readWrite; int m_defaultFontSize; QSplitter *m_splitter; MilestoneKGanttView *m_gantt; bool m_showTaskName; bool m_showProgress; bool m_showPositiveFloat; bool m_showCriticalTasks; bool m_showNoInformation; Project *m_project; }; class ResourceAppointmentsGanttViewSettingsDialog : public ItemViewSettupDialog { Q_OBJECT public: ResourceAppointmentsGanttViewSettingsDialog(GanttViewBase *gantt, ViewBase *view, bool selectPrint = false); public Q_SLOTS: void slotOk(); private: GanttViewBase *m_gantt; GanttPrintingOptionsWidget *m_printingoptions; }; class PLANUI_EXPORT ResourceAppointmentsGanttView : public ViewBase { Q_OBJECT public: ResourceAppointmentsGanttView(KoPart *part, KoDocument *doc, QWidget *parent, bool readWrite = true); ~ResourceAppointmentsGanttView(); virtual void setZoom( double zoom ); virtual void setProject( Project *project ); Project *project() const; void setupGui(); virtual bool loadContext( const KoXmlElement &context ); virtual void saveContext( QDomElement &context ) const; void updateReadWrite( bool on ); KoPrintJob *createPrintJob(); GanttTreeView *treeView() const { return static_cast( m_gantt->leftView() ); } Node *currentNode() const; Q_SIGNALS: void itemDoubleClicked(); public Q_SLOTS: void setScheduleManager(KPlato::ScheduleManager *sm); protected Q_SLOTS: void slotContextMenuRequested( const QModelIndex&, const QPoint &pos ); virtual void slotOptions(); private: GanttViewBase *m_gantt; Project *m_project; ResourceAppointmentsGanttModel *m_model; KGantt::TreeViewRowController *m_rowController; QDomDocument m_domdoc; }; } //KPlato namespace #endif