/* This file is part of the KDE project Copyright (C) 2002 - 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; version 2 of the License. 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. */ #include "kptganttview.h" #include "kptappointment.h" #include "kptpart.h" #include "kptview.h" #include "kptcanvasitem.h" #include "kptnode.h" #include "kptpart.h" #include "kptproject.h" #include "kpttask.h" #include "kptresource.h" #include "kptdatetime.h" #include "kpttaskappointmentsview.h" #include "kptrelation.h" #include "kptcontext.h" #include "kptschedule.h" #include "KDGanttView.h" #include "KDGanttViewItem.h" #include "KDGanttViewTaskItem.h" #include "KDGanttViewSummaryItem.h" #include "KDGanttViewEventItem.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace KPlato { class MyKDGanttView : public KDGanttView { public: MyKDGanttView(TQWidget *parent, const char *name) : KDGanttView(parent, name) { } virtual TQSize sizeHint() const { return minimumSizeHint(); //HACK: koshell splitter minimumSize problem } }; GanttView::GanttView(TQWidget *parent, bool readWrite, const char* name) : TQSplitter(parent, name), m_readWrite(readWrite), m_currentItem(0), m_taskView(0), m_firstTime(true), m_project(0) { kdDebug() << " ---------------- KPlato: Creating GanttView ----------------" << endl; setOrientation(TQt::Vertical); m_gantt = new MyKDGanttView(this, "Gantt view"); m_showExpected = true; m_showOptimistic = false; m_showPessimistic = false; m_showResources = false; // FIXME m_showTaskName = false; // FIXME m_showTaskLinks = false; // FIXME m_showProgress = false; //FIXME m_showPositiveFloat = false; //FIXME m_showCriticalTasks = false; //FIXME m_showCriticalPath = false; //FIXME m_showNoInformation = false; //FIXME m_showAppointments = false; m_gantt->setHeaderVisible(true); m_gantt->addColumn(i18n("Work Breakdown Structure", "WBS")); // HACK: need changes to kdgantt KDGanttViewTaskItem *item = new KDGanttViewTaskItem(m_gantt); TQListView *lv = item->listView(); lv->header()->moveSection(1, 0); m_gantt->setScale(KDGanttView::Day); m_gantt->setShowLegendButton(false); m_gantt->setShowHeaderPopupMenu(); m_taskView = new TaskAppointmentsView(this); // hide TaskAppointmentsView TQValueList list = sizes(); list[0] += list[1]; list[1] = 0; setSizes(list); m_taskView->hide(); setReadWriteMode(readWrite); connect(m_gantt, TQ_SIGNAL(lvContextMenuRequested ( KDGanttViewItem *, const TQPoint &, int )), this, TQ_SLOT (popupMenuRequested(KDGanttViewItem *, const TQPoint &, int))); connect(m_gantt, TQ_SIGNAL(lvCurrentChanged(KDGanttViewItem*)), this, TQ_SLOT (currentItemChanged(KDGanttViewItem*))); // HACK: kdgantt emits 2 signals for each *double* click, so we go direct to listview connect(lv, TQ_SIGNAL(doubleClicked(TQListViewItem*, const TQPoint&, int)), this, TQ_SLOT (slotItemDoubleClicked(TQListViewItem*))); m_taskLinks.setAutoDelete(true); if (m_gantt->firstChild()) { m_gantt->firstChild()->listView()->setCurrentItem(m_gantt->firstChild()); m_gantt->firstChild()->listView()->setFocus(); } } void GanttView::setZoom(double zoom) { kdDebug() << "setting gantt zoom: " << zoom << endl; m_gantt->setZoomFactor(zoom,true); m_taskView->zoom( zoom ); } void GanttView::clear() { m_gantt->clear(); m_taskView->clear(); } void GanttView::draw(Project &project) { m_project = &project; //kdDebug()<id()); } //kdDebug()<typeToString():"None")<setUpdateEnabled(false); clear(); drawChildren(NULL, project); drawRelations(); if (m_firstTime) { m_gantt->centerTimelineAfterShow(project.startTime().addDays(-1)); m_firstTime = false; } m_gantt->setUpdateEnabled(true); currentItemChanged(m_currentItem); } void GanttView::drawChanges(Project &project) { m_project = &project; //FIXME Only draw changes on same project //kdDebug()<id()); } //kdDebug()<typeToString():"None")<setUpdateEnabled(false); resetDrawn(m_gantt->firstChild()); updateChildren(&project); // don't draw project removeNotDrawn(m_gantt->firstChild()); m_taskLinks.clear(); drawRelations(); m_gantt->setUpdateEnabled(true); if (m_currentItem == 0 && m_gantt->firstChild()) { m_gantt->firstChild()->listView()->setCurrentItem(m_gantt->firstChild()); currentItemChanged(m_gantt->firstChild()); //hmmm } currentItemChanged(m_currentItem); } void GanttView::drawOnPainter(TQPainter* painter, const TQRect rect) { // Assume clipping is allready set // Fill out the rect by adding ticks to right side of the timeline TQSize s = m_gantt->drawContents(0, false, true); while (s.width() < rect.width()) { m_gantt->addTicksRight(); m_gantt->setTimelineToEnd(); s = m_gantt->drawContents(0, false, true); } kdDebug()<save(); // TQValueList sizes = m_taskView->sizes(); // if (sizes.count() >= 2) // { // int first = sizes[0]; // int second = sizes[1]; // sizes.pop_front(); // sizes.pop_front(); // sizes.prepend(first+second); // sizes.prepend(0); // m_taskView->setSizes(sizes); // } // else // kdWarning() << "Apparently the task view splitter contains less than 2 parts!" << endl; // bool showlistview = m_gantt->showListView(); // int listviewwidth = m_gantt->listViewWidth(); // m_gantt->setShowListView(false); // m_gantt->setListViewWidth(0); // m_gantt->setGanttMaximumWidth(rect.x()); m_gantt->drawContents(painter,false,true); // m_gantt->setShowListView(showlistview); // m_gantt->setListViewWidth(listviewwidth); // m_taskView->drawContents(painter); //TODO doesn't seem to do very much painter->restore(); } KDGanttViewItem *GanttView::findItem(Node *node) { return findItem(node, m_gantt->firstChild()); } KDGanttViewItem *GanttView::findItem(Node *node, KDGanttViewItem *item) { for (; item; item = item->nextSibling()) { if (node == getNode(item)) { return item; } KDGanttViewItem *i = findItem(node, item->firstChild()); if (i) return i; } return 0; } Node *GanttView::getNode(KDGanttViewItem *item) const { if (item) { if (item->type() == KDGanttViewItem::Event){ return static_cast(item)->getTask(); } else if (item->type() == KDGanttViewItem::Task) { return static_cast(item)->getTask(); } else if (item->type() == KDGanttViewItem::Summary) { return static_cast(item)->getNode(); } } return 0; } bool GanttView::isDrawn(KDGanttViewItem *item) { if (item) { if (item->type() == KDGanttViewItem::Event){ return static_cast(item)->isDrawn(); } else if (item->type() == KDGanttViewItem::Task) { return static_cast(item)->isDrawn(); } else if (item->type() == KDGanttViewItem::Summary) { return static_cast(item)->isDrawn(); } else { kdWarning()<type()<type() == KDGanttViewItem::Event){ static_cast(item)->setDrawn(state); } else if (item->type() == KDGanttViewItem::Task) { static_cast(item)->setDrawn(state); } else if (item->type() == KDGanttViewItem::Summary) { static_cast(item)->setDrawn(state); } else { kdWarning()<type()<nextSibling(); setDrawn(item, false); resetDrawn(item->firstChild()); // then my children } } void GanttView::removeNotDrawn(KDGanttViewItem *_item) { KDGanttViewItem *nextItem, *item=_item; for (; item; item = nextItem) { nextItem = item->nextSibling(); if (!isDrawn(item)) { if (item == m_currentItem) m_currentItem = 0; deleteItem(item); } else { removeNotDrawn(item->firstChild()); // then my children } } } void GanttView::deleteItem(KDGanttViewItem *item) { //kdDebug()<listViewText()<parent()) item->parent()->takeItem(item); else item->listView()->takeItem(item); delete item; } KDGanttViewItem *GanttView::correctType(KDGanttViewItem *item, Node *node) { //kdDebug()<listViewText()<<": "<type()<<" node: "<type()<type()) { case Node::Type_Project: return item; break; case Node::Type_Summarytask: case Node::Type_Subproject: if (item->type() == KDGanttViewItem::Summary) return item; break; case Node::Type_Task: if (item->type() == KDGanttViewItem::Task) return item; break; case Node::Type_Milestone: if (item->type() == KDGanttViewItem::Event) return item; break; default: return item; break; } KDGanttViewItem *newItem = addNode(item->parent(), node, item); newItem->setOpen(item->isOpen()); deleteItem(item); return newItem; } void GanttView::correctPosition(KDGanttViewItem *item, Node *node) { KDGanttViewItem *after = findItem(node->siblingBefore()); if (after) { item->moveItem(after); } } KDGanttViewItem *GanttView::correctParent(KDGanttViewItem *item, Node *node) { KDGanttViewItem *p = findItem(node->getParent()); if (p == item->parent()) { return item; } KDGanttViewItem *newItem = addNode(p, node); newItem->setOpen(item->isOpen()); deleteItem(item); return newItem; } void GanttView::updateChildren(Node *parentNode) { //kdDebug()< nit(parentNode->childNodeIterator()); for (; nit.current(); ++nit ) { updateNode(nit.current()); } } void GanttView::updateNode(Node *node) { //kdDebug()<name()<getParent()), node, findItem(node->siblingBefore())); if (item && node->type() == Node::Type_Summarytask) updateChildren(node); return; } item = correctType(item, node); item = correctParent(item, node); correctPosition(item, node); modifyNode(node); if (node->type() == Node::Type_Summarytask) updateChildren(node); } void GanttView::modifyChildren(Node *node) { //kdDebug()< nit(node->childNodeIterator()); for ( nit.toLast(); nit.current(); --nit ) { modifyNode(nit.current()); modifyChildren(nit.current()); } } void GanttView::modifyNode(Node *node) { //kdDebug()<type() == Node::Type_Project) { return modifyProject(item, node); } if (node->type() == Node::Type_Subproject) { return modifyProject(item, node); } if (node->type() == Node::Type_Summarytask) { return modifySummaryTask(item, static_cast(node)); } if (node->type() == Node::Type_Task) { return modifyTask(item, static_cast(node)); } if (node->type() == Node::Type_Milestone) { return modifyMilestone(item, static_cast(node)); } return; } void GanttView::modifyProject(KDGanttViewItem *item, Node *node) { //kdDebug()<setListViewText(node->name()); item->setListViewText(1, node->wbs()); item->setStartTime(node->startTime()); item->setEndTime(node->endTime()); //item->setOpen(true); setDrawn(item, true); } void GanttView::modifySummaryTask(KDGanttViewItem *item, Task *task) { //kdDebug()<name()<<": "<currentSchedule()<<", "<notScheduled()<<", "<<(m_project ? m_project->notScheduled() : false)<currentSchedule() == 0) { item->setShowNoInformation(m_showNoInformation); item->setStartTime(task->projectNode()->startTime()); item->setEndTime(item->startTime().addDays(1)); } else { bool noinf = m_showNoInformation && (task->notScheduled() || (m_project ? m_project->notScheduled() : false /*hmmm, no project?*/)); item->setShowNoInformation(noinf); item->setStartTime(task->startTime()); item->setEndTime(task->endTime()); } item->setListViewText(task->name()); item->setListViewText(1, task->wbs()); //item->setOpen(true); if (m_showTaskName) { item->setText(task->name()); } else { item->setText(TQString()); } TQString w = i18n("Name: %1").arg(task->name()); if (!task->notScheduled()) { w += "\n" + i18n("Start: %1").arg(locale->formatDateTime(task->startTime())); w += "\n" + i18n("End: %1").arg(locale->formatDateTime(task->endTime())); } bool ok = true; if (task->notScheduled()) { w += "\n" + i18n("Not scheduled"); ok = false; } else { if (!m_showNoInformation && m_project && m_project->notScheduled()) { ok = false; } } if (ok) { TQColor c(cyan); item->setColors(c,c,c); } else { TQColor c(yellow); item->setColors(c,c,c); } item->setTooltipText(w); setDrawn(item, true); } void GanttView::modifyTask(KDGanttViewItem *item, Task *task) { //kdDebug()<name()<<": "<currentSchedule()<<", "<notScheduled()<<", "<<(m_project ? m_project->notScheduled() : false)<setListViewText(task->name()); item->setListViewText(1, task->wbs()); if (task->currentSchedule() == 0) { item->setShowNoInformation(m_showNoInformation); item->setStartTime(task->projectNode()->startTime()); item->setEndTime(item->startTime().addDays(1)); } else { bool noinf = m_showNoInformation && (task->notScheduled() || (m_project ? m_project->notScheduled() : false /*hmmm, no project?*/)); item->setShowNoInformation(noinf); item->setStartTime(task->startTime()); item->setEndTime(task->endTime()); } //item->setOpen(true); TQString text; if (m_showTaskName) { text = task->name(); } if (m_showResources && !task->notScheduled()) { TQPtrList lst = task->appointments(); if (lst.count() > 0) { if (!text.isEmpty()) text += ' '; text += '('; TQPtrListIterator it = lst; for (bool first=true; it.current(); ++it) { if (!first) text += ", "; text += it.current()->resource()->resource()->name(); first = false; } text += ')'; } } item->setText(text); if (m_showProgress) { item->setProgress(task->progress().percentFinished); } else { item->setProgress(0); } if (m_showPositiveFloat) { TQDateTime t = task->endTime() + task->positiveFloat(); if (t.isValid() && t > task->endTime()) { item->setFloatEndTime(t); } else { item->setFloatEndTime(TQDateTime()); } } else { item->setFloatStartTime(TQDateTime()); item->setFloatEndTime(TQDateTime()); } TQString w = i18n("Name: %1").arg(task->name()); if (!task->notScheduled()) { w += "\n"; w += i18n("Start: %1").arg(locale->formatDateTime(task->startTime())); w += "\n"; w += i18n("End: %1").arg(locale->formatDateTime(task->endTime())); if (m_showProgress) { w += "\n"; w += i18n("Completion: %1%").arg(task->progress().percentFinished); } if (task->positiveFloat() > Duration::zeroDuration) { w += "\n" + i18n("Float: %1").arg(task->positiveFloat().toString(Duration::Format_i18nDayTime)); } if (task->inCriticalPath()) { w += "\n" + i18n("Critical path"); } else if (task->isCritical()) { w += "\n" + i18n("Critical"); } } TQString sts; bool ok = true; if (task->notScheduled()) { sts += "\n" + i18n("Not scheduled"); ok = false; } else { if (task->resourceError()) { sts += "\n" + i18n("No resource assigned"); ok = false; } if (task->resourceNotAvailable()) { sts += "\n" + i18n("Resource not available"); ok = false; } if (task->schedulingError()) { sts += "\n" + i18n("Scheduling conflict"); ok = false; } if (task->effortMetError()) { sts += "\n" + i18n("Requested effort could not be met"); ok = false; } if (task->resourceOverbooked()) { ok = false; TQStringList rl = task->overbookedResources(); sts += "\n" + i18n("arg: list of resources", "Resource overbooked: %1").arg(rl.join(",")); } if (!m_showNoInformation && m_project && m_project->notScheduled()) { ok = false; } } if (ok) { TQColor c(green); item->setColors(c,c,c); } else { w += sts; TQColor c(yellow); item->setColors(c,c,c); } item->setHighlight(false); if (m_showCriticalTasks) { item->setHighlight(task->isCritical()); } else if (m_showCriticalPath) { item->setHighlight(task->inCriticalPath()); } item->setTooltipText(w); setDrawn(item, true); } void GanttView::modifyMilestone(KDGanttViewItem *item, Task *task) { //kdDebug()<name()<<": "<currentSchedule()<<", "<notScheduled()<<", "<<(m_project ? m_project->notScheduled() : false)<currentSchedule() == 0) { item->setShowNoInformation(m_showNoInformation); item->setStartTime(task->projectNode()->startTime()); } else { bool noinf = m_showNoInformation && (task->notScheduled() || (m_project ? m_project->notScheduled() : false /*hmmm, no project?*/)); item->setShowNoInformation(noinf); item->setStartTime(task->startTime()); } item->setListViewText(task->name()); item->setListViewText(1, task->wbs()); //item->setOpen(true); if (m_showTaskName) { item->setText(task->name()); } else { item->setText(TQString()); } if (m_showPositiveFloat) { DateTime t = task->startTime() + task->positiveFloat(); //kdDebug()<name()<<" float: "< task->startTime()) { item->setFloatEndTime(t); } else { item->setFloatEndTime(TQDateTime()); } } else { item->setFloatStartTime(TQDateTime()); item->setFloatEndTime(TQDateTime()); } //TODO: Show progress TQString w = i18n("Name: %1").arg(task->name()); if (!task->notScheduled()) { w += "\n" + i18n("Time: %1").arg(locale->formatDateTime(task->startTime())); if (task->positiveFloat() > Duration::zeroDuration) { w += "\n" + i18n("Float: %1").arg(task->positiveFloat().toString(Duration::Format_i18nDayTime)); } if (task->inCriticalPath()) { w += "\n" + i18n("Critical path"); } else if (task->isCritical()) { w += "\n" + i18n("Critical"); } } bool ok = true; if (task->notScheduled()) { w += "\n" + i18n("Not scheduled"); ok = false; } else { if (task->schedulingError()) { w += "\n" + i18n("Scheduling conflict"); ok = false; } if (!m_showNoInformation && m_project && m_project->notScheduled()) { ok = false; } } if (ok) { TQColor c(blue); item->setColors(c,c,c); } else { TQColor c(yellow); item->setColors(c,c,c); } item->setHighlight(false); if (m_showCriticalTasks) { item->setHighlight(task->isCritical()); } else if (m_showCriticalPath) { item->setHighlight(task->inCriticalPath()); } item->setTooltipText(w); setDrawn(item, true); } KDGanttViewItem *GanttView::addNode( KDGanttViewItem *parentItem, Node *node, KDGanttViewItem *after) { //kdDebug()<type() == Node::Type_Project) { return addProject(parentItem, node, after); } if (node->type() == Node::Type_Subproject) { return addSubProject(parentItem, node, after); } if (node->type() == Node::Type_Summarytask) { return addSummaryTask(parentItem, static_cast(node), after); } if (node->type() == Node::Type_Task) { return addTask(parentItem, static_cast(node), after); } if (node->type() == Node::Type_Milestone) { return addMilestone(parentItem, static_cast(node), after); } return 0; } KDGanttViewItem *GanttView::addProject(KDGanttViewItem *parentItem, Node *node, KDGanttViewItem *after) { //kdDebug()<moveItem(after); modifyProject(item, node); return item; } KDGanttViewItem *GanttView::addSubProject(KDGanttViewItem *parentItem, Node *node, KDGanttViewItem *after) { //kdDebug()<moveItem(after); modifySummaryTask(item, task); return item; } KDGanttViewItem *GanttView::addTask(KDGanttViewItem *parentItem, Task *task, KDGanttViewItem *after) { //kdDebug()<moveItem(after); modifyTask(item, task); return item; } KDGanttViewItem *GanttView::addMilestone(KDGanttViewItem *parentItem, Task *task, KDGanttViewItem *after) { //kdDebug()<moveItem(after); modifyMilestone(item, task); return item; } void GanttView::drawChildren(KDGanttViewItem *parentItem, Node &parentNode) { //kdDebug()< nit(parentNode.childNodeIterator()); for ( nit.toLast(); nit.current(); --nit ) { Node *n = nit.current(); if (n->type() == Node::Type_Project) drawProject(parentItem, n); else if (n->type() == Node::Type_Subproject) drawSubProject(parentItem, n); else if (n->type() == Node::Type_Summarytask) { Task *t = dynamic_cast(n); drawSummaryTask(parentItem, t); } else if (n->type() == Node::Type_Task) { Task *t = dynamic_cast(n); drawTask(parentItem, t); } else if (n->type() == Node::Type_Milestone) { Task *t = dynamic_cast(n); drawMilestone(parentItem, t); } else kdDebug()<type()<<" not implemented yet"<(addProject(parentItem, node)); drawChildren(item, *node); } void GanttView::drawSubProject(KDGanttViewItem *parentItem, Node *node) { //kdDebug()<(addSubProject(parentItem, node)); drawChildren(item, *node); } void GanttView::drawSummaryTask(KDGanttViewItem *parentItem, Task *task) { //kdDebug()<(addSummaryTask(parentItem, task)); drawChildren(item, *task); } void GanttView::drawTask(KDGanttViewItem *parentItem, Task *task) { //kdDebug()<firstChild(); //kdDebug()<listViewText() : "nil")<nextSibling()) { drawRelations(item); drawChildRelations(item->firstChild()); } } void GanttView::drawChildRelations(KDGanttViewItem *item) { //kdDebug()<listViewText() : "nil")<nextSibling()) { drawRelations(item); drawChildRelations(item->firstChild()); } } void GanttView::drawRelations(KDGanttViewItem *item) { //kdDebug()<(item); if (summaryItem) { //kdDebug()<listViewText()<insertRelations(this); return; } GanttViewTaskItem *taskItem = dynamic_cast(item); if (taskItem) { //kdDebug()<listViewText()<insertRelations(this); return; } GanttViewEventItem *milestoneItem = dynamic_cast(item); if (milestoneItem) { //kdDebug()<listViewText()<insertRelations(this); return; } kdDebug()<listViewText()<listViewText() : "null")<clear(); m_gantt->setSelected(m_currentItem, false); m_currentItem = item; if (item) { m_gantt->setSelected(item, true); if (m_showAppointments) { m_taskView->show(); GanttViewTaskItem *taskItem = dynamic_cast(item); if (taskItem) { m_taskView->draw(taskItem->getTask()); } else { GanttViewEventItem *msItem = dynamic_cast(item); if (msItem) m_taskView->draw(msItem->getTask()); } } else { m_taskView->hide(); } } emit enableActions(true); } Node *GanttView::currentNode() const { return getNode(m_currentItem); } void GanttView::popupMenuRequested(KDGanttViewItem * item, const TQPoint & pos, int) { //kdDebug()<listViewText(0):"0")<(n); if (t && (t->type() == Node::Type_Task || t->type() == Node::Type_Milestone)) { emit requestPopupMenu("task_popup",pos); // TQPopupMenu *menu = m_mainview->popupMenu("task_popup"); // if (menu) // { // /*int id =*/ menu->exec(pos); //kdDebug()<type() == Node::Type_Summarytask) { emit requestPopupMenu("summarytask_popup",pos); // TQPopupMenu *menu = m_mainview->popupMenu("summarytask_popup"); // if (menu) // { // /*int id =*/ menu->exec(pos); //kdDebug()<childCount() > 0) { // FIXME: How else to avoid interference wirh expanding/collapsing summary items? return; } emit itemDoubleClicked(); } //TODO: 1) make it koffice compliant, // 2) allow printing on multiple pages void GanttView::print(KPrinter &prt) { //kdDebug()<selectedItem(); if (selItem) selItem->setSelected(false); //Comment from KWord // We don't get valid metrics from the printer - and we want a better resolution // anyway (it's the PS driver that takes care of the printer resolution). //But KSpread uses fixed 300 dpis, so we can use it. TQPaintDeviceMetrics metrics( &prt ); uint top, left, bottom, right; prt.margins(&top, &left, &bottom, &right); //kdDebug()<drawContents(0); TQPainter p; p.begin( &prt ); p.setViewport(left, top, metrics.width()-left-right, metrics.height()-top-bottom); p.setClipRect(left, top, metrics.width()-left-right, metrics.height()-top-bottom); // Make a simple header p.drawRect(0,0,metrics.width(),metrics.height()); TQString text; int hei = 0; text = TDEGlobal::locale()->formatDateTime(TQDateTime::currentDateTime()); TQRect r = p.boundingRect(metrics.width()-1,0,0,0, TQt::AlignRight, text ); p.drawText( r, TQt::AlignRight, text ); hei = r.height(); //kdDebug()<<"Date r="<name() ); hei = r.height(); //kdDebug()<<"Project r="<drawContents(&p); // 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 (selItem) selItem->setSelected(true); } void GanttView::slotItemRenamed(KDGanttViewItem* item, int col, const TQString& str) { //kdDebug()<listViewText(col) : "null")<<": "<saveProject(device); } void GanttView::slotLinkItems(KDGanttViewItem* from, KDGanttViewItem* to, int linkType) { //kdDebug()<listViewText():"null")<<" to "<<(to?to->listViewText():"null")<<" linkType="<legalToLink(child))) { KMessageBox::sorry(this, i18n("Cannot link these nodes")); return; } Relation *rel = child->findRelation(par); if (rel) emit modifyRelation(rel, linkTypeToRelation(linkType)); else emit addRelation(par, child, linkTypeToRelation(linkType)); return; } int GanttView::linkTypeToRelation(int linkType) { switch (linkType) { case KDGanttViewTaskLink::FinishStart: return Relation::FinishStart; break; case KDGanttViewTaskLink::StartStart: return Relation::StartStart; break; case KDGanttViewTaskLink::FinishFinish: return Relation::FinishFinish; break; case KDGanttViewTaskLink::StartFinish: default: return -1; break; } } void GanttView::slotModifyLink(KDGanttViewTaskLink* link) { //kdDebug()<from().first()); Relation *rel = par->findRelation(getNode(link->to().first())); if (rel) emit modifyRelation(rel); } bool GanttView::setContext(Context::Ganttview &context, Project& /*project*/) { //kdDebug()< list = sizes(); list[0] = context.ganttviewsize; list[1] = context.taskviewsize; setSizes(list); //TODO this does not work yet! // currentItemChanged(findItem(project.findNode(context.currentNode))); m_showResources = context.showResources ; m_showTaskName = context.showTaskName; m_showTaskLinks = context.showTaskLinks; m_showProgress = context.showProgress; m_showPositiveFloat = context.showPositiveFloat; m_showCriticalTasks = context.showCriticalTasks; m_showCriticalPath = context.showCriticalPath; m_showNoInformation = context.showNoInformation; //TODO this does not work yet! // getContextClosedNodes(context, m_gantt->firstChild()); // for (TQStringList::ConstIterator it = context.closedNodes.begin(); it != context.closedNodes.end(); ++it) { // KDGanttViewItem *item = findItem(project.findNode(*it)); // if (item) { // item->setOpen(false); // } // } return true; } void GanttView::getContext(Context::Ganttview &context) const { //kdDebug()<id(); } context.showResources = m_showResources; context.showTaskName = m_showTaskName; context.showTaskLinks = m_showTaskLinks; context.showProgress = m_showProgress; context.showPositiveFloat = m_showPositiveFloat; context.showCriticalTasks = m_showCriticalTasks; context.showCriticalPath = m_showCriticalPath; context.showNoInformation = m_showNoInformation; getContextClosedNodes(context, m_gantt->firstChild()); } void GanttView::getContextClosedNodes(Context::Ganttview &context, KDGanttViewItem *item) const { if (item == 0) return; for (KDGanttViewItem *i = item; i; i = i->nextSibling()) { if (!i->isOpen()) { context.closedNodes.append(getNode(i)->id()); //kdDebug()<listViewText()<firstChild()); } } void GanttView::setReadWriteMode(bool on) { m_readWrite = on; disconnect(m_gantt, TQ_SIGNAL(linkItems(KDGanttViewItem*, KDGanttViewItem*, int)), this, TQ_SLOT(slotLinkItems(KDGanttViewItem*, KDGanttViewItem*, int))); disconnect(m_gantt, TQ_SIGNAL(taskLinkDoubleClicked(KDGanttViewTaskLink*)), this, TQ_SLOT(slotModifyLink(KDGanttViewTaskLink*))); m_gantt->setLinkItemsEnabled(on); if (on) { connect(m_gantt, TQ_SIGNAL(linkItems(KDGanttViewItem*, KDGanttViewItem*, int)), TQ_SLOT(slotLinkItems(KDGanttViewItem*, KDGanttViewItem*, int))); connect(m_gantt, TQ_SIGNAL(taskLinkDoubleClicked(KDGanttViewTaskLink*)), TQ_SLOT(slotModifyLink(KDGanttViewTaskLink*))); } setRenameEnabled(m_gantt->firstChild(), on); } void GanttView::setRenameEnabled(TQListViewItem *item, bool on) { if (item == 0) return; for (TQListViewItem *i = item; i; i = i->nextSibling()) { i->setRenameEnabled(0, on); setRenameEnabled(i->firstChild(), on); } } } //KPlato namespace #include "kptganttview.moc"