File indexing completed on 2024-04-28 16:24:39
0001 /* This file is part of the KDE project 0002 Copyright (C) 1998, 1999, 2000 Torben Weis <weis@kde.org> 0003 Copyright (C) 2002 - 2011 Dag Andersen <danders@get2net.dk> 0004 Copyright (C) 2012 Dag Andersen <danders@get2net.dk> 0005 Copyright (C) 2019 Dag Andersen <danders@get2net.dk> 0006 0007 This library is free software; you can redistribute it and/or 0008 modify it under the terms of the GNU Library General Public 0009 License as published by the Free Software Foundation; either 0010 version 2 of the License, or (at your option) any later version. 0011 0012 This library is distributed in the hope that it will be useful, 0013 but WITHOUT ANY WARRANTY; without even the implied warranty of 0014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0015 Library General Public License for more details. 0016 0017 You should have received a copy of the GNU Library General Public License 0018 along with this library; see the file COPYING.LIB. If not, write to 0019 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0020 * Boston, MA 02110-1301, USA. 0021 */ 0022 0023 // clazy:excludeall=qstring-arg 0024 #include "kptview.h" 0025 0026 #include <kmessagebox.h> 0027 #include <KRecentFilesAction> 0028 0029 #include "KoDocumentInfo.h" 0030 #include "KoMainWindow.h" 0031 #include <KoIcon.h> 0032 #include <KoResourcePaths.h> 0033 #include <KoFileDialog.h> 0034 0035 #include <QAction> 0036 #include <QApplication> 0037 #include <QLabel> 0038 #include <QString> 0039 #include <QStringList> 0040 #include <QStackedWidget> 0041 #include <QVBoxLayout> 0042 #include <QPrintDialog> 0043 #include <QDomDocument> 0044 #include <QDomElement> 0045 #include <kundo2command.h> 0046 #include <QTimer> 0047 #include <QDockWidget> 0048 #include <QMenu> 0049 #include <QTemporaryFile> 0050 #include <QFileDialog> 0051 #include <QStatusBar> 0052 0053 #include <kactioncollection.h> 0054 #include <kactionmenu.h> 0055 #include <kstandardaction.h> 0056 #include <ktoolbar.h> 0057 #include <kxmlguifactory.h> 0058 #include <ktoggleaction.h> 0059 #include <ktoolinvocation.h> 0060 #include <krun.h> 0061 #include <khelpclient.h> 0062 0063 #include <KoPart.h> 0064 #include <KoComponentData.h> 0065 #include <KoPluginLoader.h> 0066 0067 #include "kptlocale.h" 0068 #include "kptviewbase.h" 0069 #include "kptaccountsview.h" 0070 #include "kptaccountseditor.h" 0071 #include "kptcalendareditor.h" 0072 #include "kptfactory.h" 0073 #include "kptmilestoneprogressdialog.h" 0074 #include "kpttaskdescriptiondialog.h" 0075 #include "kptdocumentsdialog.h" 0076 #include "kptnode.h" 0077 #include "kptmaindocument.h" 0078 #include "kptproject.h" 0079 #include "kptmainprojectdialog.h" 0080 #include "kpttask.h" 0081 #include "kptsummarytaskdialog.h" 0082 #include "kpttaskdialog.h" 0083 #include "kpttaskprogressdialog.h" 0084 #include "kptganttview.h" 0085 #include "kpttaskeditor.h" 0086 #include "kptdependencyeditor.h" 0087 #include "kptperteditor.h" 0088 #include "kptdatetime.h" 0089 #include "kptcommand.h" 0090 #include "kptrelation.h" 0091 #include "kptrelationdialog.h" 0092 #include "kptresourceappointmentsview.h" 0093 #include "kptresourceeditor.h" 0094 #include "kptscheduleeditor.h" 0095 #include "kptresourcedialog.h" 0096 #include "kptresource.h" 0097 #include "kptstandardworktimedialog.h" 0098 #include "kptwbsdefinitiondialog.h" 0099 #include "kptresourceassignmentview.h" 0100 #include "kpttaskstatusview.h" 0101 #include "kptsplitterview.h" 0102 #include "kptpertresult.h" 0103 #include "kptinsertfiledlg.h" 0104 #include "kptloadsharedprojectsdialog.h" 0105 #include "kptlocaleconfigmoneydialog.h" 0106 #include "kptflatproxymodel.h" 0107 #include "kpttaskstatusmodel.h" 0108 #include "kptworkpackagemergedialog.h" 0109 #include "Help.h" 0110 0111 #include "performance/PerformanceStatusView.h" 0112 #include "performance/ProjectStatusView.h" 0113 0114 #include "reportsgenerator/ReportsGeneratorView.h" 0115 0116 #ifdef PLAN_USE_KREPORT 0117 #include "reports/reportview.h" 0118 #include "reports/reportdata.h" 0119 #endif 0120 0121 #include "kptviewlistdialog.h" 0122 #include "kptviewlistdocker.h" 0123 #include "kptviewlist.h" 0124 #include "kptschedulesdocker.h" 0125 #include "kptpart.h" 0126 #include "kptdebug.h" 0127 0128 #include "calligraplansettings.h" 0129 #include "kptprintingcontrolprivate.h" 0130 0131 // #include "KPtViewAdaptor.h" 0132 0133 #include <assert.h> 0134 0135 using namespace KPlato; 0136 0137 View::View(KoPart *part, MainDocument *doc, QWidget *parent) 0138 : KoView(part, doc, parent), 0139 m_currentEstimateType(Estimate::Use_Expected), 0140 m_scheduleActionGroup(new QActionGroup(this)), 0141 m_readWrite(false), 0142 m_defaultView(1), 0143 m_partpart (part) 0144 { 0145 //debugPlan; 0146 new Help(KPlatoSettings::contextPath(), KPlatoSettings::contextLanguage()); 0147 0148 doc->registerView(this); 0149 0150 setComponentName(Factory::global().componentName(), Factory::global().componentDisplayName()); 0151 if (!doc->isReadWrite()) 0152 setXMLFile("calligraplan_readonly.rc"); 0153 else 0154 setXMLFile("calligraplan.rc"); 0155 0156 // new ViewAdaptor(this); 0157 0158 m_sp = new QSplitter(this); 0159 QVBoxLayout *layout = new QVBoxLayout(this); 0160 layout->setMargin(0); 0161 layout->addWidget(m_sp); 0162 0163 ViewListDocker *docker = 0; 0164 if (mainWindow() == 0) { 0165 // Don't use docker if embedded 0166 m_viewlist = new ViewListWidget(doc, m_sp); 0167 m_viewlist->setProject(&(getProject())); 0168 connect(m_viewlist, &ViewListWidget::selectionChanged, this, &View::slotSelectionChanged); 0169 connect(this, &View::currentScheduleManagerChanged, m_viewlist, &ViewListWidget::setSelectedSchedule); 0170 connect(m_viewlist, &ViewListWidget::updateViewInfo, this, &View::slotUpdateViewInfo); 0171 } else { 0172 ViewListDockerFactory vl(this); 0173 docker = static_cast<ViewListDocker *>(mainWindow()->createDockWidget(&vl)); 0174 if (docker->view() != this) { 0175 docker->setView(this); 0176 } 0177 m_viewlist = docker->viewList(); 0178 #if 0 //SchedulesDocker 0179 SchedulesDockerFactory sdf; 0180 SchedulesDocker *sd = dynamic_cast<SchedulesDocker*>(createDockWidget(&sdf)); 0181 Q_ASSERT(sd); 0182 0183 sd->setProject(&getProject()); 0184 connect(sd, SIGNAL(selectionChanged(KPlato::ScheduleManager*)), SLOT(slotSelectionChanged(KPlato::ScheduleManager*))); 0185 connect(this, &View::currentScheduleManagerChanged, sd, SLOT(setSelectedSchedule(KPlato::ScheduleManager*))); 0186 #endif 0187 } 0188 0189 m_tab = new QStackedWidget(m_sp); 0190 0191 //////////////////////////////////////////////////////////////////////////////////////////////////// 0192 0193 // Add sub views 0194 0195 // The menu items 0196 // ------ File 0197 actionCreateTemplate = new QAction(koIcon("document-save-as-template"), i18n("Create Project Template..."), this); 0198 actionCollection()->addAction("file_createtemplate", actionCreateTemplate); 0199 connect(actionCreateTemplate, SIGNAL(triggered(bool)), SLOT(slotCreateTemplate())); 0200 0201 actionCreateNewProject = new QAction(i18n("Create New Project..."), this); 0202 actionCollection()->addAction("file_createnewproject", actionCreateNewProject); 0203 connect(actionCreateNewProject, &QAction::triggered, this, &View::slotCreateNewProject); 0204 0205 // ------ Edit 0206 actionCut = actionCollection()->addAction(KStandardAction::Cut, "edit_cut", this, SLOT(slotEditCut())); 0207 actionCopy = actionCollection()->addAction(KStandardAction::Copy, "edit_copy", this, SLOT(slotEditCopy())); 0208 actionPaste = actionCollection()->addAction(KStandardAction::Paste, "edit_paste", this, SLOT(slotEditPaste())); 0209 0210 // ------ View 0211 actionCollection()->addAction(KStandardAction::Redisplay, "view_refresh" , this, SLOT(slotRefreshView())); 0212 0213 actionViewSelector = new KToggleAction(i18n("Show Selector"), this); 0214 actionCollection()->addAction("view_show_selector", actionViewSelector); 0215 connect(actionViewSelector, &QAction::triggered, this, &View::slotViewSelector); 0216 0217 // ------ Insert 0218 0219 // ------ Project 0220 actionEditMainProject = new QAction(koIcon("view-time-schedule-edit"), i18n("Edit..."), this); 0221 actionCollection()->addAction("project_edit", actionEditMainProject); 0222 connect(actionEditMainProject, &QAction::triggered, this, &View::slotProjectEdit); 0223 0224 actionEditStandardWorktime = new QAction(koIcon("configure"), i18n("Define Estimate Conversions..."), this); 0225 actionCollection()->addAction("project_worktime", actionEditStandardWorktime); 0226 connect(actionEditStandardWorktime, &QAction::triggered, this, &View::slotProjectWorktime); 0227 0228 actionDefineWBS = new QAction(koIcon("configure"), i18n("Define WBS Pattern..."), this); 0229 actionCollection()->addAction("tools_define_wbs", actionDefineWBS); 0230 connect(actionDefineWBS, &QAction::triggered, this, &View::slotDefineWBS); 0231 0232 actionCurrencyConfig = new QAction(koIcon("configure"), i18n("Define Currency..."), this); 0233 actionCollection()->addAction("config_currency", actionCurrencyConfig); 0234 connect(actionCurrencyConfig, &QAction::triggered, this, &View::slotCurrencyConfig); 0235 0236 QAction *actionProjectDescription = new QAction(koIcon("document-edit"), i18n("Edit Description..."), this); 0237 actionCollection()->addAction("edit_project_description", actionProjectDescription); 0238 connect(actionProjectDescription, &QAction::triggered, this, &View::slotOpenProjectDescription); 0239 0240 // ------ Tools 0241 actionInsertFile = new QAction(koIcon("document-import"), i18n("Insert Project File..."), this); 0242 actionCollection()->addAction("insert_file", actionInsertFile); 0243 connect(actionInsertFile, &QAction::triggered, this, &View::slotInsertFile); 0244 0245 actionLoadSharedProjects = new QAction(koIcon("document-import"), i18n("Load Shared Projects..."), this); 0246 actionCollection()->addAction("load_shared_projects", actionLoadSharedProjects); 0247 connect(actionLoadSharedProjects, &QAction::triggered, this, &View::slotLoadSharedProjects); 0248 0249 #ifdef PLAN_USE_KREPORT 0250 actionOpenReportFile = new QAction(koIcon("document-open"), i18n("Open Report Definition File..."), this); 0251 actionCollection()->addAction("reportdesigner_open_file", actionOpenReportFile); 0252 connect(actionOpenReportFile, QAction::triggered, this, &View::slotOpenReportFile); 0253 #endif 0254 0255 // ------ Popup 0256 actionOpenNode = new QAction(koIcon("document-edit"), i18n("Edit..."), this); 0257 actionCollection()->addAction("node_properties", actionOpenNode); 0258 connect(actionOpenNode, &QAction::triggered, this, &View::slotOpenCurrentNode); 0259 actionTaskProgress = new QAction(koIcon("document-edit"), i18n("Progress..."), this); 0260 actionCollection()->addAction("task_progress", actionTaskProgress); 0261 connect(actionTaskProgress, &QAction::triggered, this, &View::slotTaskProgress); 0262 actionDeleteTask = new QAction(koIcon("edit-delete"), i18n("Delete Task"), this); 0263 actionCollection()->addAction("delete_task", actionDeleteTask); 0264 connect(actionDeleteTask, &QAction::triggered, this, &View::slotDeleteCurrentTask); 0265 actionTaskDescription = new QAction(koIcon("document-edit"), i18n("Description..."), this); 0266 actionCollection()->addAction("task_description", actionTaskDescription); 0267 connect(actionTaskDescription, &QAction::triggered, this, &View::slotTaskDescription); 0268 actionDocuments = new QAction(koIcon("document-edit"), i18n("Documents..."), this); 0269 actionCollection()->addAction("task_documents", actionDocuments); 0270 connect(actionDocuments, &QAction::triggered, this, &View::slotDocuments); 0271 actionIndentTask = new QAction(koIcon("format-indent-more"), i18n("Indent Task"), this); 0272 actionCollection()->addAction("indent_task", actionIndentTask); 0273 connect(actionIndentTask, &QAction::triggered, this, &View::slotIndentTask); 0274 actionUnindentTask= new QAction(koIcon("format-indent-less"), i18n("Unindent Task"), this); 0275 actionCollection()->addAction("unindent_task", actionUnindentTask); 0276 connect(actionUnindentTask, &QAction::triggered, this, &View::slotUnindentTask); 0277 actionMoveTaskUp = new QAction(koIcon("arrow-up"), i18n("Move Task Up"), this); 0278 actionCollection()->addAction("move_task_up", actionMoveTaskUp); 0279 connect(actionMoveTaskUp, &QAction::triggered, this, &View::slotMoveTaskUp); 0280 actionMoveTaskDown = new QAction(koIcon("arrow-down"), i18n("Move Task Down"), this); 0281 actionCollection()->addAction("move_task_down", actionMoveTaskDown); 0282 connect(actionMoveTaskDown, &QAction::triggered, this, &View::slotMoveTaskDown); 0283 0284 actionEditResource = new QAction(koIcon("document-edit"), i18n("Edit Resource..."), this); 0285 actionCollection()->addAction("edit_resource", actionEditResource); 0286 connect(actionEditResource, &QAction::triggered, this, &View::slotEditCurrentResource); 0287 0288 actionEditRelation = new QAction(koIcon("document-edit"), i18n("Edit Dependency..."), this); 0289 actionCollection()->addAction("edit_dependency", actionEditRelation); 0290 connect(actionEditRelation, &QAction::triggered, this, &View::slotModifyCurrentRelation); 0291 actionDeleteRelation = new QAction(koIcon("edit-delete"), i18n("Delete Dependency"), this); 0292 actionCollection()->addAction("delete_dependency", actionDeleteRelation); 0293 connect(actionDeleteRelation, &QAction::triggered, this, &View::slotDeleteRelation); 0294 0295 // Viewlist popup 0296 connect(m_viewlist, &ViewListWidget::createView, this, &View::slotCreateView); 0297 0298 m_workPackageButton = new QToolButton(this); 0299 m_workPackageButton->hide(); 0300 m_workPackageButton->setIcon(koIcon("application-x-vnd.kde.plan.work")); 0301 m_workPackageButton->setText(i18n("Work Packages...")); 0302 m_workPackageButton->setToolTip(i18nc("@info:tooltip", "Work packages available")); 0303 m_workPackageButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); 0304 connect(m_workPackageButton, &QToolButton::clicked, this, &View::openWorkPackageMergeDialog); 0305 m_estlabel = new QLabel("", 0); 0306 if (statusBar()) { 0307 addStatusBarItem(m_estlabel, 0, true); 0308 } 0309 0310 connect(&getProject(), &Project::scheduleManagerAdded, this, &View::slotScheduleAdded); 0311 connect(&getProject(), &Project::scheduleManagerRemoved, this, &View::slotScheduleRemoved); 0312 connect(&getProject(), &Project::scheduleManagersSwapped, this, &View::slotScheduleSwapped); 0313 connect(&getProject(), &Project::sigCalculationFinished, this, &View::slotScheduleCalculated); 0314 slotPlugScheduleActions(); 0315 0316 connect(doc, &MainDocument::changed, this, &View::slotUpdate); 0317 0318 connect(m_scheduleActionGroup, &QActionGroup::triggered, this, &View::slotViewSchedule); 0319 0320 0321 connect(getPart(), &MainDocument::workPackageLoaded, this, &View::slotWorkPackageLoaded); 0322 0323 // views take time for large projects 0324 QTimer::singleShot(0, this, &View::initiateViews); 0325 0326 const QList<KPluginFactory *> pluginFactories = 0327 KoPluginLoader::instantiatePluginFactories(QStringLiteral("calligraplan/extensions")); 0328 0329 foreach (KPluginFactory* factory, pluginFactories) { 0330 QObject *object = factory->create<QObject>(this, QVariantList()); 0331 KXMLGUIClient *clientPlugin = dynamic_cast<KXMLGUIClient*>(object); 0332 if (clientPlugin) { 0333 insertChildClient(clientPlugin); 0334 } else { 0335 // not our/valid plugin, so delete the created object 0336 object->deleteLater(); 0337 } 0338 } 0339 //debugPlan<<" end"; 0340 } 0341 0342 View::~View() 0343 { 0344 // Disconnect and delete so we do not get called by destroyed() signal 0345 const QMap<QAction*, ScheduleManager*> map = m_scheduleActions; // clazy:exclude=qmap-with-pointer-key 0346 QMap<QAction*, ScheduleManager*>::const_iterator it; 0347 for (it = map.constBegin(); it != map.constEnd(); ++it) { 0348 disconnect(it.key(), &QObject::destroyed, this, &View::slotActionDestroyed); 0349 m_scheduleActionGroup->removeAction(it.key()); 0350 delete it.key(); 0351 } 0352 ViewBase *view = currentView(); 0353 if (view) { 0354 // deactivate view to remove dockers etc 0355 slotGuiActivated(view, false); 0356 } 0357 /* removeStatusBarItem(m_estlabel); 0358 delete m_estlabel;*/ 0359 } 0360 0361 void View::initiateViews() 0362 { 0363 QApplication::setOverrideCursor(Qt::WaitCursor); 0364 createViews(); 0365 0366 connect(m_viewlist, &ViewListWidget::activated, this, &View::slotViewActivated); 0367 // after createViews() !! 0368 connect(m_viewlist, &ViewListWidget::viewListItemRemoved, this, &View::slotViewListItemRemoved); 0369 // after createViews() !! 0370 connect(m_viewlist, &ViewListWidget::viewListItemInserted, this, &View::slotViewListItemInserted); 0371 0372 ViewListDocker *docker = qobject_cast<ViewListDocker*>(m_viewlist->parent()); 0373 if (docker) { 0374 // after createViews() !! 0375 connect(m_viewlist, &ViewListWidget::modified, docker, &ViewListDocker::slotModified); 0376 connect(m_viewlist, &ViewListWidget::modified, getPart(), &MainDocument::slotViewlistModified); 0377 connect(getPart(), &MainDocument::viewlistModified, docker, &ViewListDocker::updateWindowTitle); 0378 } 0379 connect(m_tab, &QStackedWidget::currentChanged, this, &View::slotCurrentChanged); 0380 0381 slotSelectDefaultView(); 0382 0383 loadContext(); 0384 0385 QApplication::restoreOverrideCursor(); 0386 } 0387 0388 void View::slotCreateNewProject() 0389 { 0390 debugPlan; 0391 if (KMessageBox::Continue == KMessageBox::warningContinueCancel(this, 0392 xi18nc("@info", 0393 "<note>This action cannot be undone.</note><nl/><nl/>" 0394 "Create a new Project from the current project " 0395 "with new project- and task identities.<nl/>" 0396 "Resource- and calendar identities are not changed.<nl/>" 0397 "All scheduling information is removed.<nl/>" 0398 "<nl/>Do you want to continue?"))) 0399 { 0400 emit currentScheduleManagerChanged(0); 0401 getPart()->createNewProject(); 0402 slotOpenNode(&getProject()); 0403 } 0404 } 0405 0406 void View::slotCreateTemplate() 0407 { 0408 debugPlan; 0409 KoFileDialog dlg(nullptr, KoFileDialog::SaveFile, "Create Template"); 0410 dlg.setNameFilters(QStringList()<<"Plan Template (*.plant)"); 0411 QString file = dlg.filename(); 0412 if (!file.isEmpty()) { 0413 QTemporaryDir dir; 0414 dir.setAutoRemove(false); 0415 QString tmpfile = dir.path() + '/' + QUrl(file).fileName(); 0416 tmpfile.replace(".plant", ".plan"); 0417 Part *part = new Part(this); 0418 MainDocument *doc = new MainDocument(part); 0419 part->setDocument(doc); 0420 doc->disconnect(); // doc shall not handle feedback from openUrl() 0421 doc->setAutoSave(0); //disable 0422 bool ok = koDocument()->exportDocument(QUrl::fromUserInput("file:/" + tmpfile)); 0423 ok &= doc->loadNativeFormat(tmpfile); 0424 if (ok) { 0425 // strip unused data 0426 Project *project = doc->project(); 0427 for (ScheduleManager *sm : project->scheduleManagers()) { 0428 DeleteScheduleManagerCmd c(*project, sm); 0429 c.redo(); 0430 } 0431 } 0432 ok &= doc->saveNativeFormat(file); 0433 0434 part->deleteLater(); 0435 } 0436 } 0437 0438 void View::createViews() 0439 { 0440 Context *ctx = getPart()->context(); 0441 if (ctx && ctx->isLoaded()) { 0442 debugPlan<<"isLoaded"; 0443 KoXmlNode n = ctx->context().namedItem("categories"); 0444 if (n.isNull()) { 0445 warnPlan<<"No categories"; 0446 } else { 0447 n = n.firstChild(); 0448 for (; ! n.isNull(); n = n.nextSibling()) { 0449 if (! n.isElement()) { 0450 continue; 0451 } 0452 KoXmlElement e = n.toElement(); 0453 if (e.tagName() != "category") { 0454 continue; 0455 } 0456 debugPlan<<"category: "<<e.attribute("tag"); 0457 ViewListItem *cat; 0458 QString cn = e.attribute("name"); 0459 QString ct = e.attribute("tag"); 0460 if (cn.isEmpty()) { 0461 cn = defaultCategoryInfo(ct).name; 0462 } 0463 cat = m_viewlist->addCategory(ct, cn); 0464 KoXmlNode n1 = e.firstChild(); 0465 for (; ! n1.isNull(); n1 = n1.nextSibling()) { 0466 if (! n1.isElement()) { 0467 continue; 0468 } 0469 KoXmlElement e1 = n1.toElement(); 0470 if (e1.tagName() != "view") { 0471 continue; 0472 } 0473 ViewBase *v = 0; 0474 QString type = e1.attribute("viewtype"); 0475 QString tag = e1.attribute("tag"); 0476 QString name = e1.attribute("name"); 0477 QString tip = e1.attribute("tooltip"); 0478 v = createView(cat, type, tag, name, tip); 0479 //KoXmlNode settings = e1.namedItem("settings "); ???? 0480 KoXmlNode settings = e1.firstChild(); 0481 for (; ! settings.isNull(); settings = settings.nextSibling()) { 0482 if (settings.nodeName() == "settings") { 0483 break; 0484 } 0485 } 0486 if (v && settings.isElement()) { 0487 debugPlan<<" settings"; 0488 v->loadContext(settings.toElement()); 0489 } 0490 } 0491 } 0492 } 0493 } else { 0494 debugPlan<<"Default"; 0495 ViewBase *v = 0; 0496 ViewListItem *cat; 0497 QString ct = "Editors"; 0498 cat = m_viewlist->addCategory(ct, defaultCategoryInfo(ct).name); 0499 0500 createCalendarEditor(cat, "CalendarEditor", QString(), TIP_USE_DEFAULT_TEXT); 0501 0502 createAccountsEditor(cat, "AccountsEditor", QString(), TIP_USE_DEFAULT_TEXT); 0503 0504 v = createResourceEditor(cat, "ResourceEditor", QString(), TIP_USE_DEFAULT_TEXT); 0505 0506 v = createTaskEditor(cat, "TaskEditor", QString(), TIP_USE_DEFAULT_TEXT); 0507 m_defaultView = m_tab->count() - 1; 0508 v->showColumns(QList<int>() << NodeModel::NodeName 0509 << NodeModel::NodeType 0510 << NodeModel::NodeAllocation 0511 << NodeModel::NodeEstimateCalendar 0512 << NodeModel::NodeEstimate 0513 << NodeModel::NodeOptimisticRatio 0514 << NodeModel::NodePessimisticRatio 0515 << NodeModel::NodeRisk 0516 << NodeModel::NodeResponsible 0517 << NodeModel::NodeDescription 0518 ); 0519 0520 v = createTaskEditor(cat, "TaskConstraintEditor", i18n("Task Constraints"), i18n("Edit task scheduling constraints")); 0521 v->showColumns(QList<int>() << NodeModel::NodeName 0522 << NodeModel::NodeType 0523 << NodeModel::NodePriority 0524 << NodeModel::NodeConstraint 0525 << NodeModel::NodeConstraintStart 0526 << NodeModel::NodeConstraintEnd 0527 << NodeModel::NodeDescription 0528 ); 0529 0530 v = createTaskEditor(cat, "TaskCostEditor", i18n("Task Cost"), i18n("Edit task cost")); 0531 v->showColumns(QList<int>() << NodeModel::NodeName 0532 << NodeModel::NodeType 0533 << NodeModel::NodeRunningAccount 0534 << NodeModel::NodeStartupAccount 0535 << NodeModel::NodeStartupCost 0536 << NodeModel::NodeShutdownAccount 0537 << NodeModel::NodeShutdownCost 0538 << NodeModel::NodeDescription 0539 ); 0540 0541 createDependencyEditor(cat, "DependencyEditor", QString(), TIP_USE_DEFAULT_TEXT); 0542 0543 // Do not show by default 0544 // createPertEditor(cat, "PertEditor", QString(), TIP_USE_DEFAULT_TEXT); 0545 0546 createScheduleHandler(cat, "ScheduleHandlerView", QString(), TIP_USE_DEFAULT_TEXT); 0547 0548 ct = "Views"; 0549 cat = m_viewlist->addCategory(ct, defaultCategoryInfo(ct).name); 0550 0551 createGanttView(cat, "GanttView", QString(), TIP_USE_DEFAULT_TEXT); 0552 0553 createMilestoneGanttView(cat, "MilestoneGanttView", QString(), TIP_USE_DEFAULT_TEXT); 0554 0555 createResourceAppointmentsView(cat, "ResourceAppointmentsView", QString(), TIP_USE_DEFAULT_TEXT); 0556 0557 createResourceAppointmentsGanttView(cat, "ResourceAppointmentsGanttView", QString(), TIP_USE_DEFAULT_TEXT); 0558 0559 createAccountsView(cat, "AccountsView", QString(), TIP_USE_DEFAULT_TEXT); 0560 0561 ct = "Execution"; 0562 cat = m_viewlist->addCategory(ct, defaultCategoryInfo(ct).name); 0563 0564 createProjectStatusView(cat, "ProjectStatusView", QString(), TIP_USE_DEFAULT_TEXT); 0565 0566 createPerformanceStatusView(cat, "PerformanceStatusView", QString(), TIP_USE_DEFAULT_TEXT); 0567 0568 v = createTaskStatusView(cat, "TaskStatusView", QString(), TIP_USE_DEFAULT_TEXT); 0569 0570 v = createTaskView(cat, "TaskView", QString(), TIP_USE_DEFAULT_TEXT); 0571 0572 v = createTaskWorkPackageView(cat, "TaskWorkPackageView", QString(), TIP_USE_DEFAULT_TEXT); 0573 0574 ct = "Reports"; 0575 cat = m_viewlist->addCategory(ct, defaultCategoryInfo(ct).name); 0576 0577 createReportsGeneratorView(cat, "ReportsGeneratorView", i18n("Generate reports"), TIP_USE_DEFAULT_TEXT); 0578 0579 #ifdef PLAN_USE_KREPORT 0580 // Let user add reports explicitly, we prefer reportsgenerator now 0581 // A little hack to get the user started... 0582 #if 0 0583 ReportView *rv = qobject_cast<ReportView*>(createReportView(cat, "ReportView", i18n("Task Status Report"), TIP_USE_DEFAULT_TEXT)); 0584 if (rv) { 0585 QDomDocument doc; 0586 doc.setContent(standardTaskStatusReport()); 0587 rv->loadXML(doc); 0588 } 0589 #endif 0590 #endif 0591 } 0592 } 0593 0594 ViewBase *View::createView(ViewListItem *cat, const QString &type, const QString &tag, const QString &name, const QString &tip, int index) 0595 { 0596 ViewBase *v = 0; 0597 //NOTE: type is the same as classname (so if it is changed...) 0598 if (type == "CalendarEditor") { 0599 v = createCalendarEditor(cat, tag, name, tip, index); 0600 } else if (type == "AccountsEditor") { 0601 v = createAccountsEditor(cat, tag, name, tip, index); 0602 } else if (type == "ResourceEditor") { 0603 v = createResourceEditor(cat, tag, name, tip, index); 0604 } else if (type == "TaskEditor") { 0605 v = createTaskEditor(cat, tag, name, tip, index); 0606 } else if (type == "DependencyEditor") { 0607 v = createDependencyEditor(cat, tag, name, tip, index); 0608 } else if (type == "PertEditor") { 0609 v = createPertEditor(cat, tag, name, tip, index); 0610 } else if (type == "ScheduleEditor") { 0611 v = createScheduleEditor(cat, tag, name, tip, index); 0612 } else if (type == "ScheduleHandlerView") { 0613 v = createScheduleHandler(cat, tag, name, tip, index); 0614 } else if (type == "ProjectStatusView") { 0615 v = createProjectStatusView(cat, tag, name, tip, index); 0616 } else if (type == "TaskStatusView") { 0617 v = createTaskStatusView(cat, tag, name, tip, index); 0618 } else if (type == "TaskView") { 0619 v = createTaskView(cat, tag, name, tip, index); 0620 } else if (type == "TaskWorkPackageView") { 0621 v = createTaskWorkPackageView(cat, tag, name, tip, index); 0622 } else if (type == "GanttView") { 0623 v = createGanttView(cat, tag, name, tip, index); 0624 } else if (type == "MilestoneGanttView") { 0625 v = createMilestoneGanttView(cat, tag, name, tip, index); 0626 } else if (type == "ResourceAppointmentsView") { 0627 v = createResourceAppointmentsView(cat, tag, name, tip, index); 0628 } else if (type == "ResourceAppointmentsGanttView") { 0629 v = createResourceAppointmentsGanttView(cat, tag, name, tip, index); 0630 } else if (type == "AccountsView") { 0631 v = createAccountsView(cat, tag, name, tip, index); 0632 } else if (type == "PerformanceStatusView") { 0633 v = createPerformanceStatusView(cat, tag, name, tip, index); 0634 } else if (type == "ReportsGeneratorView") { 0635 v = createReportsGeneratorView(cat, tag, name, tip, index); 0636 } else if (type == "ReportView") { 0637 #ifdef PLAN_USE_KREPORT 0638 v = createReportView(cat, tag, name, tip, index); 0639 #endif 0640 } else { 0641 warnPlan<<"Unknown viewtype: "<<type; 0642 } 0643 return v; 0644 } 0645 0646 void View::slotUpdateViewInfo(ViewListItem *itm) 0647 { 0648 if (itm->type() == ViewListItem::ItemType_SubView) { 0649 itm->setViewInfo(defaultViewInfo(itm->viewType())); 0650 } else if (itm->type() == ViewListItem::ItemType_Category) { 0651 ViewInfo vi = defaultCategoryInfo(itm->tag()); 0652 itm->setViewInfo(vi); 0653 } 0654 } 0655 0656 ViewInfo View::defaultViewInfo(const QString &type) const 0657 { 0658 ViewInfo vi; 0659 if (type == "CalendarEditor") { 0660 vi.name = i18n("Work & Vacation"); 0661 vi.tip = xi18nc("@info:tooltip", "Edit working- and vacation days for resources"); 0662 } else if (type == "AccountsEditor") { 0663 vi.name = i18n("Cost Breakdown Structure"); 0664 vi.tip = xi18nc("@info:tooltip", "Edit cost breakdown structure."); 0665 } else if (type == "ResourceEditor") { 0666 vi.name = i18n("Resources"); 0667 vi.tip = xi18nc("@info:tooltip", "Edit resource breakdown structure"); 0668 } else if (type == "TaskEditor") { 0669 vi.name = i18n("Tasks"); 0670 vi.tip = xi18nc("@info:tooltip", "Edit work breakdown structure"); 0671 } else if (type == "DependencyEditor") { 0672 vi.name = i18n("Dependencies (Graphic)"); 0673 vi.tip = xi18nc("@info:tooltip", "Edit task dependencies"); 0674 } else if (type == "PertEditor") { 0675 vi.name = i18n("Dependencies (List)"); 0676 vi.tip = xi18nc("@info:tooltip", "Edit task dependencies"); 0677 } else if (type == "ScheduleEditor") { 0678 // This view is not used stand-alone atm 0679 vi.name = i18n("Schedules"); 0680 } else if (type == "ScheduleHandlerView") { 0681 vi.name = i18n("Schedules"); 0682 vi.tip = xi18nc("@info:tooltip", "Calculate and analyze project schedules"); 0683 } else if (type == "ProjectStatusView") { 0684 vi.name = i18n("Project Performance Chart"); 0685 vi.tip = xi18nc("@info:tooltip", "View project status information"); 0686 } else if (type == "TaskStatusView") { 0687 vi.name = i18n("Task Status"); 0688 vi.tip = xi18nc("@info:tooltip", "View task progress information"); 0689 } else if (type == "TaskView") { 0690 vi.name = i18n("Task Execution"); 0691 vi.tip = xi18nc("@info:tooltip", "View task execution information"); 0692 } else if (type == "TaskWorkPackageView") { 0693 vi.name = i18n("Work Package View"); 0694 vi.tip = xi18nc("@info:tooltip", "View task work package information"); 0695 } else if (type == "GanttView") { 0696 vi.name = i18n("Gantt"); 0697 vi.tip = xi18nc("@info:tooltip", "View Gantt chart"); 0698 } else if (type == "MilestoneGanttView") { 0699 vi.name = i18n("Milestone Gantt"); 0700 vi.tip = xi18nc("@info:tooltip", "View milestone Gantt chart"); 0701 } else if (type == "ResourceAppointmentsView") { 0702 vi.name = i18n("Resource Assignments"); 0703 vi.tip = xi18nc("@info:tooltip", "View resource assignments in a table"); 0704 } else if (type == "ResourceAppointmentsGanttView") { 0705 vi.name = i18n("Resource Assignments (Gantt)"); 0706 vi.tip = xi18nc("@info:tooltip", "View resource assignments in Gantt chart"); 0707 } else if (type == "AccountsView") { 0708 vi.name = i18n("Cost Breakdown"); 0709 vi.tip = xi18nc("@info:tooltip", "View planned and actual cost"); 0710 } else if (type == "PerformanceStatusView") { 0711 vi.name = i18n("Tasks Performance Chart"); 0712 vi.tip = xi18nc("@info:tooltip", "View tasks performance status information"); 0713 } else if (type == "ReportsGeneratorView") { 0714 vi.name = i18n("Reports Generator"); 0715 vi.tip = xi18nc("@info:tooltip", "Generate reports"); 0716 } else if (type == "ReportView") { 0717 vi.name = i18n("Report"); 0718 vi.tip = xi18nc("@info:tooltip", "View report"); 0719 } else { 0720 warnPlan<<"Unknown viewtype: "<<type; 0721 } 0722 return vi; 0723 } 0724 0725 ViewInfo View::defaultCategoryInfo(const QString &type) const 0726 { 0727 ViewInfo vi; 0728 if (type == "Editors") { 0729 vi.name = i18n("Editors"); 0730 } else if (type == "Views") { 0731 vi.name = i18n("Views"); 0732 } else if (type == "Execution") { 0733 vi.name = i18nc("Project execution views", "Execution"); 0734 } else if (type == "Reports") { 0735 vi.name = i18n("Reports"); 0736 } 0737 return vi; 0738 } 0739 0740 ViewBase *View::createResourceAppointmentsGanttView(ViewListItem *cat, const QString &tag, const QString &name, const QString &tip, int index) 0741 { 0742 ResourceAppointmentsGanttView *v = new ResourceAppointmentsGanttView(getKoPart(), getPart(), m_tab); 0743 m_tab->addWidget(v); 0744 0745 ViewListItem *i = m_viewlist->addView(cat, tag, name, v, getPart(), "", index); 0746 ViewInfo vi = defaultViewInfo("ResourceAppointmentsGanttView"); 0747 if (name.isEmpty()) { 0748 i->setText(0, vi.name); 0749 } 0750 if (tip == TIP_USE_DEFAULT_TEXT) { 0751 i->setToolTip(0, vi.tip); 0752 } else { 0753 i->setToolTip(0, tip); 0754 } 0755 0756 0757 connect(v, &ViewBase::guiActivated, this, &View::slotGuiActivated); 0758 0759 connect(this, &View::currentScheduleManagerChanged, v, &ResourceAppointmentsGanttView::setScheduleManager); 0760 0761 connect(v, &ResourceAppointmentsGanttView::requestPopupMenu, this, &View::slotPopupMenuRequested); 0762 0763 v->setProject(&(getProject())); 0764 v->setScheduleManager(currentScheduleManager()); 0765 v->updateReadWrite(m_readWrite); 0766 return v; 0767 } 0768 0769 0770 ViewBase *View::createResourceAppointmentsView(ViewListItem *cat, const QString &tag, const QString &name, const QString &tip, int index) 0771 { 0772 ResourceAppointmentsView *v = new ResourceAppointmentsView(getKoPart(), getPart(), m_tab); 0773 m_tab->addWidget(v); 0774 0775 ViewListItem *i = m_viewlist->addView(cat, tag, name, v, getPart(), "", index); 0776 ViewInfo vi = defaultViewInfo("ResourceAppointmentsView"); 0777 if (name.isEmpty()) { 0778 i->setText(0, vi.name); 0779 } 0780 if (tip == TIP_USE_DEFAULT_TEXT) { 0781 i->setToolTip(0, vi.tip); 0782 } else { 0783 i->setToolTip(0, tip); 0784 } 0785 0786 connect(v, &ViewBase::guiActivated, this, &View::slotGuiActivated); 0787 0788 connect(this, &View::currentScheduleManagerChanged, v, &ResourceAppointmentsView::setScheduleManager); 0789 0790 connect(v, &ResourceAppointmentsView::requestPopupMenu, this, &View::slotPopupMenuRequested); 0791 0792 v->setProject(&(getProject())); 0793 v->setScheduleManager(currentScheduleManager()); 0794 v->updateReadWrite(m_readWrite); 0795 return v; 0796 } 0797 0798 ViewBase *View::createResourceEditor(ViewListItem *cat, const QString &tag, const QString &name, const QString &tip, int index) 0799 { 0800 ResourceEditor *resourceeditor = new ResourceEditor(getKoPart(), getPart(), m_tab); 0801 resourceeditor->setViewSplitMode(false); 0802 m_tab->addWidget(resourceeditor); 0803 resourceeditor->setProject(&(getProject())); 0804 0805 ViewListItem *i = m_viewlist->addView(cat, tag, name, resourceeditor, getPart(), "", index); 0806 ViewInfo vi = defaultViewInfo("ResourceEditor"); 0807 if (name.isEmpty()) { 0808 i->setText(0, vi.name); 0809 } 0810 if (tip == TIP_USE_DEFAULT_TEXT) { 0811 i->setToolTip(0, vi.tip); 0812 } else { 0813 i->setToolTip(0, tip); 0814 } 0815 0816 connect(resourceeditor, &ViewBase::guiActivated, this, &View::slotGuiActivated); 0817 0818 connect(resourceeditor, &ResourceEditor::deleteObjectList, this, &View::slotDeleteResourceObjects); 0819 0820 connect(resourceeditor, &ResourceEditor::requestPopupMenu, this, &View::slotPopupMenuRequested); 0821 resourceeditor->updateReadWrite(m_readWrite); 0822 return resourceeditor; 0823 } 0824 0825 ViewBase *View::createTaskEditor(ViewListItem *cat, const QString &tag, const QString &name, const QString &tip, int index) 0826 { 0827 TaskEditor *taskeditor = new TaskEditor(getKoPart(), getPart(), m_tab); 0828 taskeditor->setViewSplitMode(false); 0829 m_tab->addWidget(taskeditor); 0830 0831 ViewListItem *i = m_viewlist->addView(cat, tag, name, taskeditor, getPart(), "", index); 0832 ViewInfo vi = defaultViewInfo("TaskEditor"); 0833 if (name.isEmpty()) { 0834 i->setText(0, vi.name); 0835 } 0836 if (tip == TIP_USE_DEFAULT_TEXT) { 0837 i->setToolTip(0, vi.tip); 0838 } else { 0839 i->setToolTip(0, tip); 0840 } 0841 0842 taskeditor->setProject(&(getProject())); 0843 taskeditor->setScheduleManager(currentScheduleManager()); 0844 0845 connect(this, &View::currentScheduleManagerChanged, taskeditor, &TaskEditor::setScheduleManager); 0846 0847 connect(taskeditor, &ViewBase::guiActivated, this, &View::slotGuiActivated); 0848 0849 connect(taskeditor, &TaskEditor::addTask, this, &View::slotAddTask); 0850 connect(taskeditor, &TaskEditor::addMilestone, this, &View::slotAddMilestone); 0851 connect(taskeditor, &TaskEditor::addSubtask, this, &View::slotAddSubTask); 0852 connect(taskeditor, &TaskEditor::addSubMilestone, this, &View::slotAddSubMilestone); 0853 connect(taskeditor, &TaskEditor::deleteTaskList, this, &View::slotDeleteTaskList); 0854 connect(taskeditor, &TaskEditor::moveTaskUp, this, &View::slotMoveTaskUp); 0855 connect(taskeditor, &TaskEditor::moveTaskDown, this, &View::slotMoveTaskDown); 0856 connect(taskeditor, &TaskEditor::indentTask, this, &View::slotIndentTask); 0857 connect(taskeditor, &TaskEditor::unindentTask, this, &View::slotUnindentTask); 0858 0859 connect(taskeditor, &TaskEditor::saveTaskModule, this, &View::saveTaskModule); 0860 connect(taskeditor, &TaskEditor::removeTaskModule, this, &View::removeTaskModule); 0861 connect(taskeditor, &ViewBase::openDocument, static_cast<KPlato::Part*>(m_partpart), &Part::openTaskModule); 0862 0863 connect(taskeditor, &TaskEditor::requestPopupMenu, this, &View::slotPopupMenuRequested); 0864 connect(taskeditor, &TaskEditor::openTaskDescription, this, &View::slotOpenTaskDescription); 0865 taskeditor->updateReadWrite(m_readWrite); 0866 0867 return taskeditor; 0868 } 0869 0870 ViewBase *View::createAccountsEditor(ViewListItem *cat, const QString &tag, const QString &name, const QString &tip, int index) 0871 { 0872 AccountsEditor *ae = new AccountsEditor(getKoPart(), getPart(), m_tab); 0873 m_tab->addWidget(ae); 0874 0875 ViewListItem *i = m_viewlist->addView(cat, tag, name, ae, getPart(), "", index); 0876 ViewInfo vi = defaultViewInfo("AccountsEditor"); 0877 if (name.isEmpty()) { 0878 i->setText(0, vi.name); 0879 } 0880 if (tip == TIP_USE_DEFAULT_TEXT) { 0881 i->setToolTip(0, vi.tip); 0882 } else { 0883 i->setToolTip(0, tip); 0884 } 0885 0886 ae->draw(getProject()); 0887 0888 connect(ae, &ViewBase::guiActivated, this, &View::slotGuiActivated); 0889 ae->updateReadWrite(m_readWrite); 0890 return ae; 0891 } 0892 0893 ViewBase *View::createCalendarEditor(ViewListItem *cat, const QString &tag, const QString &name, const QString &tip, int index) 0894 { 0895 CalendarEditor *calendareditor = new CalendarEditor(getKoPart(), getPart(), m_tab); 0896 m_tab->addWidget(calendareditor); 0897 0898 ViewListItem *i = m_viewlist->addView(cat, tag, name, calendareditor, getPart(), "", index); 0899 ViewInfo vi = defaultViewInfo("CalendarEditor"); 0900 if (name.isEmpty()) { 0901 i->setText(0, vi.name); 0902 } 0903 if (tip == TIP_USE_DEFAULT_TEXT) { 0904 i->setToolTip(0, vi.tip); 0905 } else { 0906 i->setToolTip(0, tip); 0907 } 0908 0909 calendareditor->draw(getProject()); 0910 0911 connect(calendareditor, &ViewBase::guiActivated, this, &View::slotGuiActivated); 0912 0913 connect(calendareditor, &CalendarEditor::requestPopupMenu, this, &View::slotPopupMenuRequested); 0914 calendareditor->updateReadWrite(m_readWrite); 0915 return calendareditor; 0916 } 0917 0918 ViewBase *View::createScheduleHandler(ViewListItem *cat, const QString &tag, const QString &name, const QString &tip, int index) 0919 { 0920 ScheduleHandlerView *handler = new ScheduleHandlerView(getKoPart(), getPart(), m_tab); 0921 m_tab->addWidget(handler); 0922 0923 ViewListItem *i = m_viewlist->addView(cat, tag, name, handler, getPart(), "", index); 0924 ViewInfo vi = defaultViewInfo("ScheduleHandlerView"); 0925 if (name.isEmpty()) { 0926 i->setText(0, vi.name); 0927 } 0928 if (tip == TIP_USE_DEFAULT_TEXT) { 0929 i->setToolTip(0, vi.tip); 0930 } else { 0931 i->setToolTip(0, tip); 0932 } 0933 0934 connect(handler->scheduleEditor(), &ScheduleEditor::addScheduleManager, this, &View::slotAddScheduleManager); 0935 connect(handler->scheduleEditor(), &ScheduleEditor::deleteScheduleManager, this, &View::slotDeleteScheduleManager); 0936 connect(handler->scheduleEditor(), &ScheduleEditor::moveScheduleManager, this, &View::slotMoveScheduleManager); 0937 0938 connect(handler->scheduleEditor(), &ScheduleEditor::calculateSchedule, this, &View::slotCalculateSchedule); 0939 0940 connect(handler->scheduleEditor(), &ScheduleEditor::baselineSchedule, this, &View::slotBaselineSchedule); 0941 0942 0943 connect(handler, &ViewBase::guiActivated, this, &View::slotGuiActivated); 0944 0945 connect(this, &View::currentScheduleManagerChanged, handler, &ScheduleHandlerView::currentScheduleManagerChanged); 0946 0947 connect(handler, &ScheduleHandlerView::requestPopupMenu, this, &View::slotPopupMenuRequested); 0948 0949 connect(handler, &ScheduleHandlerView::editNode, this, &View::slotOpenNode); 0950 connect(handler, &ScheduleHandlerView::editResource, this, &View::slotEditResource); 0951 0952 handler->draw(getProject()); 0953 handler->updateReadWrite(m_readWrite); 0954 return handler; 0955 } 0956 0957 ScheduleEditor *View::createScheduleEditor(QWidget *parent) 0958 { 0959 ScheduleEditor *scheduleeditor = new ScheduleEditor(getKoPart(), getPart(), parent); 0960 0961 connect(scheduleeditor, &ScheduleEditor::addScheduleManager, this, &View::slotAddScheduleManager); 0962 connect(scheduleeditor, &ScheduleEditor::deleteScheduleManager, this, &View::slotDeleteScheduleManager); 0963 0964 connect(scheduleeditor, &ScheduleEditor::calculateSchedule, this, &View::slotCalculateSchedule); 0965 0966 connect(scheduleeditor, &ScheduleEditor::baselineSchedule, this, &View::slotBaselineSchedule); 0967 0968 scheduleeditor->updateReadWrite(m_readWrite); 0969 return scheduleeditor; 0970 } 0971 0972 ViewBase *View::createScheduleEditor(ViewListItem *cat, const QString &tag, const QString &name, const QString &tip, int index) 0973 { 0974 ScheduleEditor *scheduleeditor = new ScheduleEditor(getKoPart(), getPart(), m_tab); 0975 m_tab->addWidget(scheduleeditor); 0976 0977 ViewListItem *i = m_viewlist->addView(cat, tag, name, scheduleeditor, getPart(), "", index); 0978 ViewInfo vi = defaultViewInfo("ScheduleEditor"); 0979 if (name.isEmpty()) { 0980 i->setText(0, vi.name); 0981 } 0982 if (tip == TIP_USE_DEFAULT_TEXT) { 0983 i->setToolTip(0, vi.tip); 0984 } else { 0985 i->setToolTip(0, tip); 0986 } 0987 0988 scheduleeditor->setProject(&(getProject())); 0989 0990 connect(scheduleeditor, &ViewBase::guiActivated, this, &View::slotGuiActivated); 0991 0992 connect(scheduleeditor, &ScheduleEditor::addScheduleManager, this, &View::slotAddScheduleManager); 0993 0994 connect(scheduleeditor, &ScheduleEditor::deleteScheduleManager, this, &View::slotDeleteScheduleManager); 0995 0996 connect(scheduleeditor, &ScheduleEditor::calculateSchedule, this, &View::slotCalculateSchedule); 0997 0998 connect(scheduleeditor, &ScheduleEditor::baselineSchedule, this, &View::slotBaselineSchedule); 0999 1000 scheduleeditor->updateReadWrite(m_readWrite); 1001 return scheduleeditor; 1002 } 1003 1004 1005 ViewBase *View::createDependencyEditor(ViewListItem *cat, const QString &tag, const QString &name, const QString &tip, int index) 1006 { 1007 DependencyEditor *editor = new DependencyEditor(getKoPart(), getPart(), m_tab); 1008 m_tab->addWidget(editor); 1009 1010 ViewListItem *i = m_viewlist->addView(cat, tag, name, editor, getPart(), "", index); 1011 ViewInfo vi = defaultViewInfo("DependencyEditor"); 1012 if (name.isEmpty()) { 1013 i->setText(0, vi.name); 1014 } 1015 if (tip == TIP_USE_DEFAULT_TEXT) { 1016 i->setToolTip(0, vi.tip); 1017 } else { 1018 i->setToolTip(0, tip); 1019 } 1020 1021 editor->draw(getProject()); 1022 1023 connect(editor, &ViewBase::guiActivated, this, &View::slotGuiActivated); 1024 1025 connect(editor, &DependencyEditor::addRelation, this, &View::slotAddRelation); 1026 connect(editor, &DependencyEditor::modifyRelation, this, &View::slotModifyRelation); 1027 connect(editor, &DependencyEditor::editRelation, this, &View::slotEditRelation); 1028 1029 connect(editor, &DependencyEditor::editNode, this, &View::slotOpenNode); 1030 connect(editor, &DependencyEditor::addTask, this, &View::slotAddTask); 1031 connect(editor, &DependencyEditor::addMilestone, this, &View::slotAddMilestone); 1032 connect(editor, &DependencyEditor::addSubMilestone, this, &View::slotAddSubMilestone); 1033 connect(editor, &DependencyEditor::addSubtask, this, &View::slotAddSubTask); 1034 connect(editor, &DependencyEditor::deleteTaskList, this, &View::slotDeleteTaskList); 1035 1036 connect(this, &View::currentScheduleManagerChanged, editor, &DependencyEditor::setScheduleManager); 1037 1038 connect(editor, &DependencyEditor::requestPopupMenu, this, &View::slotPopupMenuRequested); 1039 editor->updateReadWrite(m_readWrite); 1040 editor->setScheduleManager(currentScheduleManager()); 1041 return editor; 1042 } 1043 1044 ViewBase *View::createPertEditor(ViewListItem *cat, const QString &tag, const QString &name, const QString &tip, int index) 1045 { 1046 PertEditor *perteditor = new PertEditor(getKoPart(), getPart(), m_tab); 1047 m_tab->addWidget(perteditor); 1048 1049 ViewListItem *i = m_viewlist->addView(cat, tag, name, perteditor, getPart(), "", index); 1050 ViewInfo vi = defaultViewInfo("PertEditor"); 1051 if (name.isEmpty()) { 1052 i->setText(0, vi.name); 1053 } 1054 if (tip == TIP_USE_DEFAULT_TEXT) { 1055 i->setToolTip(0, vi.tip); 1056 } else { 1057 i->setToolTip(0, tip); 1058 } 1059 1060 perteditor->draw(getProject()); 1061 1062 connect(perteditor, &ViewBase::guiActivated, this, &View::slotGuiActivated); 1063 m_updatePertEditor = true; 1064 perteditor->updateReadWrite(m_readWrite); 1065 return perteditor; 1066 } 1067 1068 ViewBase *View::createProjectStatusView(ViewListItem *cat, const QString &tag, const QString &name, const QString &tip, int index) 1069 { 1070 ProjectStatusView *v = new ProjectStatusView(getKoPart(), getPart(), m_tab); 1071 m_tab->addWidget(v); 1072 1073 ViewListItem *i = m_viewlist->addView(cat, tag, name, v, getPart(), "", index); 1074 ViewInfo vi = defaultViewInfo("ProjectStatusView"); 1075 if (name.isEmpty()) { 1076 i->setText(0, vi.name); 1077 } 1078 if (tip == TIP_USE_DEFAULT_TEXT) { 1079 i->setToolTip(0, vi.tip); 1080 } else { 1081 i->setToolTip(0, tip); 1082 } 1083 1084 connect(v, &ViewBase::guiActivated, this, &View::slotGuiActivated); 1085 1086 connect(this, &View::currentScheduleManagerChanged, v, &ProjectStatusView::setScheduleManager); 1087 1088 v->updateReadWrite(m_readWrite); 1089 v->setProject(&getProject()); 1090 v->setScheduleManager(currentScheduleManager()); 1091 return v; 1092 } 1093 1094 ViewBase *View::createPerformanceStatusView(ViewListItem *cat, const QString &tag, const QString &name, const QString &tip, int index) 1095 { 1096 PerformanceStatusView *v = new PerformanceStatusView(getKoPart(), getPart(), m_tab); 1097 m_tab->addWidget(v); 1098 1099 ViewListItem *i = m_viewlist->addView(cat, tag, name, v, getPart(), "", index); 1100 ViewInfo vi = defaultViewInfo("PerformanceStatusView"); 1101 if (name.isEmpty()) { 1102 i->setText(0, vi.name); 1103 } 1104 if (tip == TIP_USE_DEFAULT_TEXT) { 1105 i->setToolTip(0, vi.tip); 1106 } else { 1107 i->setToolTip(0, tip); 1108 } 1109 1110 connect(v, &ViewBase::guiActivated, this, &View::slotGuiActivated); 1111 1112 connect(this, &View::currentScheduleManagerChanged, v, &PerformanceStatusView::setScheduleManager); 1113 1114 connect(v, &PerformanceStatusView::requestPopupMenu, this, &View::slotPopupMenuRequested); 1115 1116 v->updateReadWrite(m_readWrite); 1117 v->setProject(&getProject()); 1118 v->setScheduleManager(currentScheduleManager()); 1119 return v; 1120 } 1121 1122 1123 ViewBase *View::createTaskStatusView(ViewListItem *cat, const QString &tag, const QString &name, const QString &tip, int index) 1124 { 1125 TaskStatusView *taskstatusview = new TaskStatusView(getKoPart(), getPart(), m_tab); 1126 taskstatusview->setViewSplitMode(false); 1127 m_tab->addWidget(taskstatusview); 1128 1129 ViewListItem *i = m_viewlist->addView(cat, tag, name, taskstatusview, getPart(), "", index); 1130 ViewInfo vi = defaultViewInfo("TaskStatusView"); 1131 if (name.isEmpty()) { 1132 i->setText(0, vi.name); 1133 } 1134 if (tip == TIP_USE_DEFAULT_TEXT) { 1135 i->setToolTip(0, vi.tip); 1136 } else { 1137 i->setToolTip(0, tip); 1138 } 1139 1140 connect(taskstatusview, &ViewBase::guiActivated, this, &View::slotGuiActivated); 1141 1142 connect(this, &View::currentScheduleManagerChanged, taskstatusview, &TaskStatusView::setScheduleManager); 1143 1144 connect(taskstatusview, &TaskStatusView::requestPopupMenu, this, &View::slotPopupMenuRequested); 1145 connect(taskstatusview, &TaskStatusView::openTaskDescription, this, &View::slotOpenTaskDescription); 1146 1147 taskstatusview->updateReadWrite(m_readWrite); 1148 taskstatusview->draw(getProject()); 1149 taskstatusview->setScheduleManager(currentScheduleManager()); 1150 return taskstatusview; 1151 } 1152 1153 ViewBase *View::createTaskView(ViewListItem *cat, const QString &tag, const QString &name, const QString &tip, int index) 1154 { 1155 TaskView *v = new TaskView(getKoPart(), getPart(), m_tab); 1156 v->setViewSplitMode(false); 1157 m_tab->addWidget(v); 1158 1159 ViewListItem *i = m_viewlist->addView(cat, tag, name, v, getPart(), "", index); 1160 ViewInfo vi = defaultViewInfo("TaskView"); 1161 if (name.isEmpty()) { 1162 i->setText(0, vi.name); 1163 } 1164 if (tip == TIP_USE_DEFAULT_TEXT) { 1165 i->setToolTip(0, vi.tip); 1166 } else { 1167 i->setToolTip(0, tip); 1168 } 1169 1170 v->draw(getProject()); 1171 v->setScheduleManager(currentScheduleManager()); 1172 1173 connect(this, &View::currentScheduleManagerChanged, v, &TaskView::setScheduleManager); 1174 1175 connect(v, &ViewBase::guiActivated, this, &View::slotGuiActivated); 1176 1177 connect(v, &TaskView::requestPopupMenu, this, &View::slotPopupMenuRequested); 1178 connect(v, &TaskView::openTaskDescription, this, &View::slotOpenTaskDescription); 1179 v->updateReadWrite(m_readWrite); 1180 return v; 1181 } 1182 1183 ViewBase *View::createTaskWorkPackageView(ViewListItem *cat, const QString &tag, const QString &name, const QString &tip, int index) 1184 { 1185 TaskWorkPackageView *v = new TaskWorkPackageView(getKoPart(), getPart(), m_tab); 1186 v->setViewSplitMode(false); 1187 m_tab->addWidget(v); 1188 1189 ViewListItem *i = m_viewlist->addView(cat, tag, name, v, getPart(), "", index); 1190 ViewInfo vi = defaultViewInfo("TaskWorkPackageView"); 1191 if (name.isEmpty()) { 1192 i->setText(0, vi.name); 1193 } 1194 if (tip == TIP_USE_DEFAULT_TEXT) { 1195 i->setToolTip(0, vi.tip); 1196 } else { 1197 i->setToolTip(0, tip); 1198 } 1199 1200 v->setProject(&getProject()); 1201 v->setScheduleManager(currentScheduleManager()); 1202 1203 connect(this, &View::currentScheduleManagerChanged, v, &TaskWorkPackageView::setScheduleManager); 1204 1205 connect(v, &ViewBase::guiActivated, this, &View::slotGuiActivated); 1206 1207 connect(v, &TaskWorkPackageView::requestPopupMenu, this, &View::slotPopupMenuRequested); 1208 1209 connect(v, &TaskWorkPackageView::mailWorkpackage, this, &View::slotMailWorkpackage); 1210 connect(v, &TaskWorkPackageView::publishWorkpackages, this, &View::slotPublishWorkpackages); 1211 connect(v, &TaskWorkPackageView::openWorkpackages, this, &View::openWorkPackageMergeDialog); 1212 connect(this, &View::workPackagesAvailable, v, &TaskWorkPackageView::slotWorkpackagesAvailable); 1213 connect(v, &TaskWorkPackageView::checkForWorkPackages, getPart(), &MainDocument::checkForWorkPackages); 1214 connect(v, &TaskWorkPackageView::loadWorkPackageUrl, this, &View::loadWorkPackage); 1215 connect(v, &TaskWorkPackageView::openTaskDescription, this, &View::slotOpenTaskDescription); 1216 v->updateReadWrite(m_readWrite); 1217 1218 return v; 1219 } 1220 1221 ViewBase *View::createGanttView(ViewListItem *cat, const QString &tag, const QString &name, const QString &tip, int index) 1222 { 1223 GanttView *ganttview = new GanttView(getKoPart(), getPart(), m_tab, koDocument()->isReadWrite()); 1224 m_tab->addWidget(ganttview); 1225 1226 ViewListItem *i = m_viewlist->addView(cat, tag, name, ganttview, getPart(), "", index); 1227 ViewInfo vi = defaultViewInfo("GanttView"); 1228 if (name.isEmpty()) { 1229 i->setText(0, vi.name); 1230 } 1231 if (tip == TIP_USE_DEFAULT_TEXT) { 1232 i->setToolTip(0, vi.tip); 1233 } else { 1234 i->setToolTip(0, tip); 1235 } 1236 1237 ganttview->setProject(&(getProject())); 1238 ganttview->setScheduleManager(currentScheduleManager()); 1239 1240 connect(ganttview, &ViewBase::guiActivated, this, &View::slotGuiActivated); 1241 /* TODO: Review these 1242 connect(ganttview, SIGNAL(addRelation(KPlato::Node*,KPlato::Node*,int)), SLOT(slotAddRelation(KPlato::Node*,KPlato::Node*,int))); 1243 connect(ganttview, SIGNAL(modifyRelation(KPlato::Relation*,int)), SLOT(slotModifyRelation(KPlato::Relation*,int))); 1244 connect(ganttview, SIGNAL(modifyRelation(KPlato::Relation*)), SLOT(slotModifyRelation(KPlato::Relation*))); 1245 connect(ganttview, SIGNAL(itemDoubleClicked()), SLOT(slotOpenNode())); 1246 connect(ganttview, SIGNAL(itemRenamed(KPlato::Node*,QString)), this, SLOT(slotRenameNode(KPlato::Node*,QString)));*/ 1247 1248 connect(this, &View::currentScheduleManagerChanged, ganttview, &GanttView::setScheduleManager); 1249 1250 connect(ganttview, &GanttView::requestPopupMenu, this, &View::slotPopupMenuRequested); 1251 connect(ganttview, &GanttView::openTaskDescription, this, &View::slotOpenTaskDescription); 1252 ganttview->updateReadWrite(m_readWrite); 1253 1254 return ganttview; 1255 } 1256 1257 ViewBase *View::createMilestoneGanttView(ViewListItem *cat, const QString &tag, const QString &name, const QString &tip, int index) 1258 { 1259 MilestoneGanttView *ganttview = new MilestoneGanttView(getKoPart(), getPart(), m_tab, koDocument()->isReadWrite()); 1260 m_tab->addWidget(ganttview); 1261 1262 ViewListItem *i = m_viewlist->addView(cat, tag, name, ganttview, getPart(), "", index); 1263 ViewInfo vi = defaultViewInfo("MilestoneGanttView"); 1264 if (name.isEmpty()) { 1265 i->setText(0, vi.name); 1266 } 1267 if (tip == TIP_USE_DEFAULT_TEXT) { 1268 i->setToolTip(0, vi.tip); 1269 } else { 1270 i->setToolTip(0, tip); 1271 } 1272 1273 ganttview->setProject(&(getProject())); 1274 ganttview->setScheduleManager(currentScheduleManager()); 1275 1276 connect(ganttview, &ViewBase::guiActivated, this, &View::slotGuiActivated); 1277 1278 connect(this, &View::currentScheduleManagerChanged, ganttview, &MilestoneGanttView::setScheduleManager); 1279 1280 connect(ganttview, &MilestoneGanttView::requestPopupMenu, this, &View::slotPopupMenuRequested); 1281 connect(ganttview, &MilestoneGanttView::openTaskDescription, this, &View::slotOpenTaskDescription); 1282 ganttview->updateReadWrite(m_readWrite); 1283 1284 return ganttview; 1285 } 1286 1287 1288 ViewBase *View::createAccountsView(ViewListItem *cat, const QString &tag, const QString &name, const QString &tip, int index) 1289 { 1290 AccountsView *accountsview = new AccountsView(getKoPart(), &getProject(), getPart(), m_tab); 1291 m_tab->addWidget(accountsview); 1292 1293 ViewListItem *i = m_viewlist->addView(cat, tag, name, accountsview, getPart(), "", index); 1294 ViewInfo vi = defaultViewInfo("AccountsView"); 1295 if (name.isEmpty()) { 1296 i->setText(0, vi.name); 1297 } 1298 if (tip == TIP_USE_DEFAULT_TEXT) { 1299 i->setToolTip(0, vi.tip); 1300 } else { 1301 i->setToolTip(0, tip); 1302 } 1303 1304 accountsview->setScheduleManager(currentScheduleManager()); 1305 1306 connect(this, &View::currentScheduleManagerChanged, accountsview, &AccountsView::setScheduleManager); 1307 1308 connect(accountsview, &ViewBase::guiActivated, this, &View::slotGuiActivated); 1309 accountsview->updateReadWrite(m_readWrite); 1310 return accountsview; 1311 } 1312 1313 ViewBase *View::createResourceAssignmentView(ViewListItem *cat, const QString &tag, const QString &name, const QString &tip, int index) 1314 { 1315 ResourceAssignmentView *resourceAssignmentView = new ResourceAssignmentView(getKoPart(), getPart(), m_tab); 1316 m_tab->addWidget(resourceAssignmentView); 1317 m_updateResourceAssignmentView = true; 1318 1319 ViewListItem *i = m_viewlist->addView(cat, tag, name, resourceAssignmentView, getPart(), "", index); 1320 ViewInfo vi = defaultViewInfo("ResourceAssignmentView"); 1321 if (name.isEmpty()) { 1322 i->setText(0, vi.name); 1323 } 1324 if (tip == TIP_USE_DEFAULT_TEXT) { 1325 i->setToolTip(0, vi.tip); 1326 } else { 1327 i->setToolTip(0, tip); 1328 } 1329 1330 resourceAssignmentView->draw(getProject()); 1331 1332 connect(resourceAssignmentView, &ViewBase::guiActivated, this, &View::slotGuiActivated); 1333 1334 connect(resourceAssignmentView, &ResourceAssignmentView::requestPopupMenu, this, &View::slotPopupMenuRequested); 1335 resourceAssignmentView->updateReadWrite(m_readWrite); 1336 return resourceAssignmentView; 1337 } 1338 1339 ViewBase *View::createReportsGeneratorView(ViewListItem *cat, const QString &tag, const QString &name, const QString &tip, int index) 1340 { 1341 ReportsGeneratorView *v = new ReportsGeneratorView(getKoPart(), getPart(), m_tab); 1342 m_tab->addWidget(v); 1343 1344 ViewListItem *i = m_viewlist->addView(cat, tag, name, v, getPart(), "", index); 1345 ViewInfo vi = defaultViewInfo("ReportsGeneratorView"); 1346 if (name.isEmpty()) { 1347 i->setText(0, vi.name); 1348 } 1349 if (tip == TIP_USE_DEFAULT_TEXT) { 1350 i->setToolTip(0, vi.tip); 1351 } else { 1352 i->setToolTip(0, tip); 1353 } 1354 1355 v->setProject(&getProject()); 1356 1357 connect(this, &View::currentScheduleManagerChanged, v, &ViewBase::setScheduleManager); 1358 connect(this, &View::currentScheduleManagerChanged, v, &ViewBase::slotRefreshView); 1359 v->setScheduleManager(currentScheduleManager()); 1360 1361 connect(v, &ViewBase::guiActivated, this, &View::slotGuiActivated); 1362 connect(v, &ReportsGeneratorView::requestPopupMenu, this, &View::slotPopupMenuRequested); 1363 1364 v->updateReadWrite(m_readWrite); 1365 return v; 1366 } 1367 1368 ViewBase *View::createReportView(ViewListItem *cat, const QString &tag, const QString &name, const QString &tip, int index) 1369 { 1370 #ifdef PLAN_USE_KREPORT 1371 ReportView *v = new ReportView(getKoPart(), getPart(), m_tab); 1372 m_tab->addWidget(v); 1373 1374 ViewListItem *i = m_viewlist->addView(cat, tag, name, v, getPart(), "", index); 1375 ViewInfo vi = defaultViewInfo("ReportView"); 1376 if (name.isEmpty()) { 1377 i->setText(0, vi.name); 1378 } 1379 if (tip == TIP_USE_DEFAULT_TEXT) { 1380 i->setToolTip(0, vi.tip); 1381 } else { 1382 i->setToolTip(0, tip); 1383 } 1384 1385 v->setProject(&getProject()); 1386 1387 connect(this, &View::currentScheduleManagerChanged, v, &ReportView::setScheduleManager); 1388 connect(this, &View::currentScheduleManagerChanged, v, SLOT(slotRefreshView())); 1389 v->setScheduleManager(currentScheduleManager()); 1390 1391 connect(v, &ReportView::guiActivated, this, &View::slotGuiActivated); 1392 v->updateReadWrite(m_readWrite); 1393 return v; 1394 #else 1395 Q_UNUSED(cat) 1396 Q_UNUSED(tag) 1397 Q_UNUSED(name) 1398 Q_UNUSED(tip) 1399 Q_UNUSED(index) 1400 return 0; 1401 #endif 1402 } 1403 1404 Project& View::getProject() const 1405 { 1406 return getPart() ->getProject(); 1407 } 1408 1409 KoPrintJob * View::createPrintJob() 1410 { 1411 KoView *v = qobject_cast<KoView*>(canvas()); 1412 if (v == 0) { 1413 return 0; 1414 } 1415 return v->createPrintJob(); 1416 } 1417 1418 ViewBase *View::currentView() const 1419 { 1420 return qobject_cast<ViewBase*>(m_tab->currentWidget()); 1421 } 1422 1423 void View::slotEditCut() 1424 { 1425 ViewBase *v = currentView(); 1426 if (v) { 1427 v->slotEditCut(); 1428 } 1429 } 1430 1431 void View::slotEditCopy() 1432 { 1433 ViewBase *v = currentView(); 1434 if (v) { 1435 v->slotEditCopy(); 1436 } 1437 } 1438 1439 void View::slotEditPaste() 1440 { 1441 ViewBase *v = currentView(); 1442 if (v) { 1443 v->slotEditPaste(); 1444 } 1445 } 1446 1447 void View::slotRefreshView() 1448 { 1449 ViewBase *v = currentView(); 1450 if (v) { 1451 debugPlan<<v; 1452 v->slotRefreshView(); 1453 } 1454 } 1455 1456 void View::slotViewSelector(bool show) 1457 { 1458 //debugPlan; 1459 m_viewlist->setVisible(show); 1460 } 1461 1462 void View::slotInsertResourcesFile(const QString &file, const QUrl &projects) 1463 { 1464 getPart()->insertResourcesFile(QUrl(file), projects); 1465 } 1466 1467 void View::slotInsertFile() 1468 { 1469 InsertFileDialog *dlg = new InsertFileDialog(getProject(), currentTask(), this); 1470 connect(dlg, &QDialog::finished, this, &View::slotInsertFileFinished); 1471 dlg->open(); 1472 } 1473 1474 void View::slotInsertFileFinished(int result) 1475 { 1476 InsertFileDialog *dlg = qobject_cast<InsertFileDialog*>(sender()); 1477 if (dlg == 0) { 1478 return; 1479 } 1480 if (result == QDialog::Accepted) { 1481 getPart()->insertFile(dlg->url(), dlg->parentNode(), dlg->afterNode()); 1482 } 1483 dlg->deleteLater(); 1484 } 1485 1486 void View::slotLoadSharedProjects() 1487 { 1488 LoadSharedProjectsDialog *dlg = new LoadSharedProjectsDialog(getProject(), getPart()->url(), this); 1489 connect(dlg, &QDialog::finished, this, &View::slotLoadSharedProjectsFinished); 1490 dlg->open(); 1491 } 1492 1493 void View::slotLoadSharedProjectsFinished(int result) 1494 { 1495 LoadSharedProjectsDialog *dlg = qobject_cast<LoadSharedProjectsDialog*>(sender()); 1496 if (dlg == 0) { 1497 return; 1498 } 1499 if (result == QDialog::Accepted) { 1500 getPart()->insertSharedProjects(dlg->urls()); 1501 } 1502 dlg->deleteLater(); 1503 } 1504 1505 void View::slotProjectEdit() 1506 { 1507 slotOpenNode(&getProject()); 1508 } 1509 1510 void View::slotProjectWorktime() 1511 { 1512 StandardWorktimeDialog *dia = new StandardWorktimeDialog(getProject(), this); 1513 connect(dia, &QDialog::finished, this, &View::slotProjectWorktimeFinished); 1514 dia->open(); 1515 } 1516 1517 void View::slotProjectWorktimeFinished(int result) 1518 { 1519 StandardWorktimeDialog *dia = qobject_cast<StandardWorktimeDialog*>(sender()); 1520 if (dia == 0) { 1521 return; 1522 } 1523 if (result == QDialog::Accepted) { 1524 KUndo2Command * cmd = dia->buildCommand(); 1525 if (cmd) { 1526 //debugPlan<<"Modifying calendar(s)"; 1527 getPart() ->addCommand(cmd); //also executes 1528 } 1529 } 1530 dia->deleteLater(); 1531 } 1532 1533 void View::slotSelectionChanged(ScheduleManager *sm) { 1534 debugPlan<<sm; 1535 if (sm == 0) { 1536 return; 1537 } 1538 QAction *a = m_scheduleActions.key(sm); 1539 if (!a) { 1540 debugPlan<<sm<<"could not find action for schedule:"<<sm; 1541 return; 1542 } 1543 a->setChecked(true); // this doesn't trigger QActionGroup 1544 slotViewSchedule(a); 1545 } 1546 1547 QList<QAction*> View::sortedActionList() 1548 { 1549 QMap<QString, QAction*> lst; 1550 const QMap<QAction*, ScheduleManager*> map = m_scheduleActions; // clazy:exclude=qmap-with-pointer-key 1551 QMap<QAction*, ScheduleManager*>::const_iterator it; 1552 for (it = map.constBegin(); it != map.constEnd(); ++it) { 1553 lst.insert(it.key()->objectName(), it.key()); 1554 } 1555 return lst.values(); 1556 } 1557 1558 void View::slotScheduleSwapped(ScheduleManager *from, ScheduleManager *to) 1559 { 1560 if (currentScheduleManager() == from) { 1561 QAction *a = m_scheduleActions.key(to); 1562 if (a) { 1563 a->setChecked(true); 1564 } 1565 } 1566 } 1567 1568 void View::slotScheduleRemoved(const ScheduleManager *sch) 1569 { 1570 debugPlan<<sch<<sch->name(); 1571 QAction *a = 0; 1572 QAction *checked = m_scheduleActionGroup->checkedAction(); 1573 QMapIterator<QAction*, ScheduleManager*> i(m_scheduleActions); 1574 while (i.hasNext()) { 1575 i.next(); 1576 if (i.value() == sch) { 1577 a = i.key(); 1578 break; 1579 } 1580 } 1581 if (a) { 1582 unplugActionList("view_schedule_list"); 1583 delete a; 1584 plugActionList("view_schedule_list", sortedActionList()); 1585 if (checked && checked != a) { 1586 checked->setChecked(true); 1587 } else if (! m_scheduleActions.isEmpty()) { 1588 m_scheduleActions.firstKey()->setChecked(true); 1589 } 1590 } 1591 slotViewSchedule(m_scheduleActionGroup->checkedAction()); 1592 } 1593 1594 void View::slotScheduleAdded(const ScheduleManager *sch) 1595 { 1596 ScheduleManager *s = const_cast<ScheduleManager*>(sch); 1597 QAction *checked = m_scheduleActionGroup->checkedAction(); 1598 unplugActionList("view_schedule_list"); 1599 QAction *act = addScheduleAction(s); 1600 plugActionList("view_schedule_list", sortedActionList()); 1601 if (!currentScheduleManager()) { 1602 if (act) { 1603 act->setChecked(true); 1604 } else if (! m_scheduleActions.isEmpty()) { 1605 m_scheduleActions.firstKey()->setChecked(true); 1606 } 1607 slotViewSchedule(m_scheduleActionGroup->checkedAction()); 1608 } 1609 } 1610 1611 void View::slotScheduleCalculated(Project *project, ScheduleManager *manager) 1612 { 1613 Q_UNUSED(project); 1614 if (manager == currentScheduleManager()) { 1615 slotViewScheduleManager(manager); 1616 } 1617 } 1618 1619 QAction *View::addScheduleAction(ScheduleManager *sch) 1620 { 1621 QAction *act = 0; 1622 QString n = sch->name(); 1623 act = new KToggleAction(n, this); 1624 actionCollection()->addAction(n, act); 1625 m_scheduleActions.insert(act, sch); 1626 m_scheduleActionGroup->addAction(act); 1627 //debugPlan<<"Add:"<<n; 1628 connect(act, &QObject::destroyed, this, &View::slotActionDestroyed); 1629 return act; 1630 } 1631 1632 void View::slotViewScheduleManager(ScheduleManager *sm) 1633 { 1634 QApplication::setOverrideCursor(Qt::WaitCursor); 1635 setLabel(sm); 1636 emit currentScheduleManagerChanged(sm); 1637 QApplication::restoreOverrideCursor(); 1638 } 1639 1640 void View::slotViewSchedule(QAction *act) 1641 { 1642 //debugPlan<<act; 1643 ScheduleManager *sm = 0; 1644 if (act != 0) { 1645 ScheduleManager *sch = m_scheduleActions.value(act, 0); 1646 sm = m_scheduleActions.value(act, 0); 1647 } 1648 setLabel(0); 1649 slotViewScheduleManager(sm); 1650 } 1651 1652 void View::slotActionDestroyed(QObject *o) 1653 { 1654 //debugPlan<<o->name(); 1655 m_scheduleActions.remove(static_cast<QAction*>(o)); 1656 } 1657 1658 void View::slotPlugScheduleActions() 1659 { 1660 ScheduleManager *current = currentScheduleManager(); 1661 unplugActionList("view_schedule_list"); 1662 const QMap<QAction*, ScheduleManager*> map = m_scheduleActions; // clazy:exclude=qmap-with-pointer-key 1663 QMap<QAction*, ScheduleManager*>::const_iterator it; 1664 for (it = map.constBegin(); it != map.constEnd(); ++it) { 1665 m_scheduleActionGroup->removeAction(it.key()); 1666 delete it.key(); 1667 } 1668 m_scheduleActions.clear(); 1669 QAction *ca = 0; 1670 foreach(ScheduleManager *sm, getProject().allScheduleManagers()) { 1671 QAction *act = addScheduleAction(sm); 1672 if (sm == current) { 1673 ca = act; 1674 } 1675 } 1676 plugActionList("view_schedule_list", sortedActionList()); 1677 if (ca == 0 && m_scheduleActionGroup->actions().count() > 0) { 1678 ca = m_scheduleActionGroup->actions().constFirst(); 1679 } 1680 if (ca) { 1681 ca->setChecked(true); 1682 } 1683 slotViewSchedule(ca); 1684 } 1685 1686 void View::slotCalculateSchedule(Project *project, ScheduleManager *sm) 1687 { 1688 if (project == 0 || sm == 0) { 1689 return; 1690 } 1691 if (sm->parentManager() && ! sm->parentManager()->isScheduled()) { 1692 // the parent must be scheduled 1693 return; 1694 } 1695 CalculateScheduleCmd *cmd = new CalculateScheduleCmd(*project, sm, kundo2_i18nc("@info:status 1=schedule name", "Calculate %1", sm->name())); 1696 getPart() ->addCommand(cmd); 1697 slotUpdate(); 1698 } 1699 1700 void View::slotRemoveCommands() 1701 { 1702 while (! m_undocommands.isEmpty()) { 1703 m_undocommands.last()->undo(); 1704 delete m_undocommands.takeLast(); 1705 } 1706 } 1707 1708 void View::slotBaselineSchedule(Project *project, ScheduleManager *sm) 1709 { 1710 if (project == 0 || sm == 0) { 1711 return; 1712 } 1713 if (! sm->isBaselined() && project->isBaselined()) { 1714 KMessageBox::sorry(this, i18n("Cannot baseline. The project is already baselined.")); 1715 return; 1716 } 1717 MacroCommand *cmd = nullptr; 1718 if (sm->isBaselined()) { 1719 KMessageBox::ButtonCode res = KMessageBox::warningContinueCancel(this, i18n("This schedule is baselined. Do you want to remove the baseline?")); 1720 if (res == KMessageBox::Cancel) { 1721 return; 1722 } 1723 cmd = new MacroCommand(kundo2_i18n("Reset baseline %1", sm->name())); 1724 cmd->addCommand(new ResetBaselineScheduleCmd(*sm)); 1725 } else { 1726 cmd = new MacroCommand(kundo2_i18n("Baseline %1", sm->name())); 1727 if (sm->schedulingMode() == ScheduleManager::AutoMode) { 1728 cmd->addCommand(new ModifyScheduleManagerSchedulingModeCmd(*sm, ScheduleManager::ManualMode)); 1729 } 1730 cmd->addCommand(new BaselineScheduleCmd(*sm, kundo2_i18n("Baseline %1", sm->name()))); 1731 } 1732 getPart() ->addCommand(cmd); 1733 } 1734 1735 void View::slotAddScheduleManager(Project *project) 1736 { 1737 if (project == 0) { 1738 return; 1739 } 1740 ScheduleManager *sm = project->createScheduleManager(); 1741 AddScheduleManagerCmd *cmd = new AddScheduleManagerCmd(*project, sm, -1, kundo2_i18n("Add schedule %1", sm->name())); 1742 getPart() ->addCommand(cmd); 1743 } 1744 1745 void View::slotDeleteScheduleManager(Project *project, ScheduleManager *sm) 1746 { 1747 if (project == 0 || sm == 0) { 1748 return; 1749 } 1750 DeleteScheduleManagerCmd *cmd = new DeleteScheduleManagerCmd(*project, sm, kundo2_i18n("Delete schedule %1", sm->name())); 1751 getPart() ->addCommand(cmd); 1752 } 1753 1754 void View::slotMoveScheduleManager(ScheduleManager *sm, ScheduleManager *parent, int index) 1755 { 1756 if (sm == 0) { 1757 return; 1758 } 1759 MoveScheduleManagerCmd *cmd = new MoveScheduleManagerCmd(sm, parent, index, kundo2_i18n("Move schedule %1", sm->name())); 1760 getPart() ->addCommand(cmd); 1761 } 1762 1763 void View::slotAddSubTask() 1764 { 1765 Task * node = getProject().createTask(getPart() ->config().taskDefaults()); 1766 SubTaskAddDialog *dia = new SubTaskAddDialog(getProject(), *node, currentNode(), getProject().accounts(), this); 1767 connect(dia, &QDialog::finished, this, &View::slotAddSubTaskFinished); 1768 dia->open(); 1769 } 1770 1771 void View::slotAddSubTaskFinished(int result) 1772 { 1773 SubTaskAddDialog *dia = qobject_cast<SubTaskAddDialog*>(sender()); 1774 if (dia == 0) { 1775 return; 1776 } 1777 if (result == QDialog::Accepted) { 1778 KUndo2Command *m = dia->buildCommand(); 1779 getPart() ->addCommand(m); // add task to project 1780 } 1781 dia->deleteLater(); 1782 } 1783 1784 void View::slotAddTask() 1785 { 1786 Task * node = getProject().createTask(getPart() ->config().taskDefaults()); 1787 TaskAddDialog *dia = new TaskAddDialog(getProject(), *node, currentNode(), getProject().accounts(), this); 1788 connect(dia, &QDialog::finished, this, &View::slotAddTaskFinished); 1789 dia->open(); 1790 } 1791 1792 void View::slotAddTaskFinished(int result) 1793 { 1794 TaskAddDialog *dia = qobject_cast<TaskAddDialog*>(sender()); 1795 if (dia == 0) { 1796 return; 1797 } 1798 if (result == QDialog::Accepted) { 1799 KUndo2Command *m = dia->buildCommand(); 1800 getPart() ->addCommand(m); // add task to project 1801 } 1802 dia->deleteLater(); 1803 } 1804 1805 void View::slotAddMilestone() 1806 { 1807 Task * node = getProject().createTask(); 1808 node->estimate() ->clear(); 1809 1810 TaskAddDialog *dia = new TaskAddDialog(getProject(), *node, currentNode(), getProject().accounts(), this); 1811 connect(dia, &QDialog::finished, this, &View::slotAddMilestoneFinished); 1812 dia->open(); 1813 } 1814 1815 void View::slotAddMilestoneFinished(int result) 1816 { 1817 TaskAddDialog *dia = qobject_cast<TaskAddDialog*>(sender()); 1818 if (dia == 0) { 1819 return; 1820 } 1821 if (result == QDialog::Accepted) { 1822 MacroCommand *c = new MacroCommand(kundo2_i18n("Add milestone")); 1823 c->addCommand(dia->buildCommand()); 1824 getPart() ->addCommand(c); // add task to project 1825 } 1826 dia->deleteLater(); 1827 } 1828 1829 void View::slotAddSubMilestone() 1830 { 1831 Task * node = getProject().createTask(); 1832 node->estimate() ->clear(); 1833 1834 SubTaskAddDialog *dia = new SubTaskAddDialog(getProject(), *node, currentNode(), getProject().accounts(), this); 1835 connect(dia, &QDialog::finished, this, &View::slotAddSubMilestoneFinished); 1836 dia->open(); 1837 } 1838 1839 void View::slotAddSubMilestoneFinished(int result) 1840 { 1841 SubTaskAddDialog *dia = qobject_cast<SubTaskAddDialog*>(sender()); 1842 if (dia == 0) { 1843 return; 1844 } 1845 if (result == QDialog::Accepted) { 1846 MacroCommand *c = new MacroCommand(kundo2_i18n("Add sub-milestone")); 1847 c->addCommand(dia->buildCommand()); 1848 getPart() ->addCommand(c); // add task to project 1849 } 1850 dia->deleteLater(); 1851 } 1852 1853 void View::slotDefineWBS() 1854 { 1855 //debugPlan; 1856 Project &p = getProject(); 1857 WBSDefinitionDialog *dia = new WBSDefinitionDialog(p, p.wbsDefinition(), this); 1858 connect(dia, &QDialog::finished, this, &View::slotDefineWBSFinished); 1859 dia->open(); 1860 } 1861 1862 void View::slotDefineWBSFinished(int result) 1863 { 1864 //debugPlan; 1865 WBSDefinitionDialog *dia = qobject_cast<WBSDefinitionDialog*>(sender()); 1866 if (dia == 0) { 1867 return; 1868 } 1869 if (result == QDialog::Accepted) { 1870 KUndo2Command *cmd = dia->buildCommand(); 1871 if (cmd) { 1872 getPart()->addCommand(cmd); 1873 } 1874 } 1875 dia->deleteLater(); 1876 } 1877 1878 Calendar *View::currentCalendar() 1879 { 1880 ViewBase *v = dynamic_cast<ViewBase*>(m_tab->currentWidget()); 1881 if (v == 0) { 1882 return 0; 1883 } 1884 return v->currentCalendar(); 1885 } 1886 1887 Node *View::currentNode() const 1888 { 1889 ViewBase *v = dynamic_cast<ViewBase*>(m_tab->currentWidget()); 1890 if (v == 0) { 1891 return 0; 1892 } 1893 Node * task = v->currentNode(); 1894 if (0 != task) { 1895 return task; 1896 } 1897 return &(getProject()); 1898 } 1899 1900 Task *View::currentTask() const 1901 { 1902 ViewBase *v = dynamic_cast<ViewBase*>(m_tab->currentWidget()); 1903 if (v == 0) { 1904 return 0; 1905 } 1906 Node * task = v->currentNode(); 1907 if (task) { 1908 return dynamic_cast<Task*>(task); 1909 } 1910 return 0; 1911 } 1912 1913 Resource *View::currentResource() 1914 { 1915 ViewBase *v = dynamic_cast<ViewBase*>(m_tab->currentWidget()); 1916 if (v == 0) { 1917 return 0; 1918 } 1919 return v->currentResource(); 1920 } 1921 1922 ResourceGroup *View::currentResourceGroup() 1923 { 1924 ViewBase *v = dynamic_cast<ViewBase*>(m_tab->currentWidget()); 1925 if (v == 0) { 1926 return 0; 1927 } 1928 return v->currentResourceGroup(); 1929 } 1930 1931 1932 void View::slotOpenCurrentNode() 1933 { 1934 //debugPlan; 1935 Node * node = currentNode(); 1936 slotOpenNode(node); 1937 } 1938 1939 void View::slotOpenNode(Node *node) 1940 { 1941 //debugPlan; 1942 if (!node) 1943 return ; 1944 1945 switch (node->type()) { 1946 case Node::Type_Project: { 1947 Project * project = static_cast<Project *>(node); 1948 MainProjectDialog *dia = new MainProjectDialog(*project, this); 1949 connect(dia, &MainProjectDialog::dialogFinished, this, &View::slotProjectEditFinished); 1950 connect(dia, &MainProjectDialog::sigLoadSharedResources, this, &View::slotInsertResourcesFile); 1951 connect(dia, &MainProjectDialog::loadResourceAssignments, getPart(), &MainDocument::loadResourceAssignments); 1952 connect(dia, &MainProjectDialog::clearResourceAssignments, getPart(), &MainDocument::clearResourceAssignments); 1953 dia->open(); 1954 break; 1955 } 1956 case Node::Type_Subproject: 1957 //TODO 1958 break; 1959 case Node::Type_Task: { 1960 Task *task = static_cast<Task *>(node); 1961 TaskDialog *dia = new TaskDialog(getProject(), *task, getProject().accounts(), this); 1962 connect(dia, &QDialog::finished, this, &View::slotTaskEditFinished); 1963 dia->open(); 1964 break; 1965 } 1966 case Node::Type_Milestone: { 1967 // Use the normal task dialog for now. 1968 // Maybe milestone should have it's own dialog, but we need to be able to 1969 // enter a duration in case we accidentally set a tasks duration to zero 1970 // and hence, create a milestone 1971 Task *task = static_cast<Task *>(node); 1972 TaskDialog *dia = new TaskDialog(getProject(), *task, getProject().accounts(), this); 1973 connect(dia, &QDialog::finished, this, &View::slotTaskEditFinished); 1974 dia->open(); 1975 break; 1976 } 1977 case Node::Type_Summarytask: { 1978 Task *task = dynamic_cast<Task *>(node); 1979 Q_ASSERT(task); 1980 SummaryTaskDialog *dia = new SummaryTaskDialog(*task, this); 1981 connect(dia, &QDialog::finished, this, &View::slotSummaryTaskEditFinished); 1982 dia->open(); 1983 break; 1984 } 1985 default: 1986 break; // avoid warnings 1987 } 1988 } 1989 1990 void View::slotProjectEditFinished(int result) 1991 { 1992 MainProjectDialog *dia = qobject_cast<MainProjectDialog*>(sender()); 1993 if (dia == 0) { 1994 return; 1995 } 1996 if (result == QDialog::Accepted) { 1997 KUndo2Command * cmd = dia->buildCommand(); 1998 if (cmd) { 1999 getPart() ->addCommand(cmd); 2000 } 2001 } 2002 dia->deleteLater(); 2003 } 2004 2005 void View::slotTaskEditFinished(int result) 2006 { 2007 TaskDialog *dia = qobject_cast<TaskDialog*>(sender()); 2008 if (dia == 0) { 2009 return; 2010 } 2011 if (result == QDialog::Accepted) { 2012 KUndo2Command * cmd = dia->buildCommand(); 2013 if (cmd) { 2014 getPart() ->addCommand(cmd); 2015 } 2016 } 2017 dia->deleteLater(); 2018 } 2019 2020 void View::slotSummaryTaskEditFinished(int result) 2021 { 2022 SummaryTaskDialog *dia = qobject_cast<SummaryTaskDialog*>(sender()); 2023 if (dia == 0) { 2024 return; 2025 } 2026 if (result == QDialog::Accepted) { 2027 KUndo2Command * cmd = dia->buildCommand(); 2028 if (cmd) { 2029 getPart() ->addCommand(cmd); 2030 } 2031 } 2032 dia->deleteLater(); 2033 } 2034 2035 ScheduleManager *View::currentScheduleManager() const 2036 { 2037 return m_scheduleActions.value(m_scheduleActionGroup->checkedAction()); 2038 } 2039 2040 long View::activeScheduleId() const 2041 { 2042 ScheduleManager *s = m_scheduleActions.value(m_scheduleActionGroup->checkedAction()); 2043 return s == nullptr || s->expected() == nullptr ? -1 : s->expected()->id(); 2044 } 2045 2046 void View::setActiveSchedule(long id) 2047 { 2048 if (id != -1) { 2049 QMap<QAction*, ScheduleManager*>::const_iterator it = m_scheduleActions.constBegin(); 2050 for (; it != m_scheduleActions.constEnd(); ++it) { 2051 int mid = it.value()->expected() == nullptr ? -1 : it.value()->expected()->id(); 2052 if (mid == id) { 2053 it.key()->setChecked(true); 2054 slotViewSchedule(it.key()); // signal not emitted from group, so trigger it here 2055 break; 2056 } 2057 } 2058 } 2059 } 2060 2061 void View::slotTaskProgress() 2062 { 2063 //debugPlan; 2064 Node * node = currentNode(); 2065 if (!node) 2066 return ; 2067 2068 switch (node->type()) { 2069 case Node::Type_Project: { 2070 break; 2071 } 2072 case Node::Type_Subproject: 2073 //TODO 2074 break; 2075 case Node::Type_Task: { 2076 Task *task = dynamic_cast<Task *>(node); 2077 Q_ASSERT(task); 2078 TaskProgressDialog *dia = new TaskProgressDialog(*task, currentScheduleManager(), getProject().standardWorktime(), this); 2079 connect(dia, &QDialog::finished, this, &View::slotTaskProgressFinished); 2080 dia->open(); 2081 break; 2082 } 2083 case Node::Type_Milestone: { 2084 Task *task = dynamic_cast<Task *>(node); 2085 Q_ASSERT(task); 2086 MilestoneProgressDialog *dia = new MilestoneProgressDialog(*task, this); 2087 connect(dia, &QDialog::finished, this, &View::slotMilestoneProgressFinished); 2088 dia->open(); 2089 break; 2090 } 2091 case Node::Type_Summarytask: { 2092 // TODO 2093 break; 2094 } 2095 default: 2096 break; // avoid warnings 2097 } 2098 } 2099 2100 void View::slotTaskProgressFinished(int result) 2101 { 2102 TaskProgressDialog *dia = qobject_cast<TaskProgressDialog*>(sender()); 2103 if (dia == 0) { 2104 return; 2105 } 2106 if (result == QDialog::Accepted) { 2107 KUndo2Command * m = dia->buildCommand(); 2108 if (m) { 2109 getPart() ->addCommand(m); 2110 } 2111 } 2112 dia->deleteLater(); 2113 } 2114 2115 void View::slotMilestoneProgressFinished(int result) 2116 { 2117 MilestoneProgressDialog *dia = qobject_cast<MilestoneProgressDialog*>(sender()); 2118 if (dia == 0) { 2119 return; 2120 } 2121 if (result == QDialog::Accepted) { 2122 KUndo2Command * m = dia->buildCommand(); 2123 if (m) { 2124 getPart() ->addCommand(m); 2125 } 2126 } 2127 dia->deleteLater(); 2128 } 2129 2130 void View::slotOpenProjectDescription() 2131 { 2132 debugPlan<<koDocument()->isReadWrite(); 2133 TaskDescriptionDialog *dia = new TaskDescriptionDialog(getProject(), this, !koDocument()->isReadWrite()); 2134 connect(dia, &QDialog::finished, this, &View::slotTaskDescriptionFinished); 2135 dia->open(); 2136 } 2137 2138 void View::slotTaskDescription() 2139 { 2140 slotOpenTaskDescription(!koDocument()->isReadWrite()); 2141 } 2142 2143 void View::slotOpenTaskDescription(bool ro) 2144 { 2145 //debugPlan; 2146 Node * node = currentNode(); 2147 if (!node) 2148 return ; 2149 2150 switch (node->type()) { 2151 case Node::Type_Subproject: 2152 //TODO 2153 break; 2154 case Node::Type_Project: 2155 case Node::Type_Task: 2156 case Node::Type_Milestone: 2157 case Node::Type_Summarytask: { 2158 TaskDescriptionDialog *dia = new TaskDescriptionDialog(*node, this, ro); 2159 connect(dia, &QDialog::finished, this, &View::slotTaskDescriptionFinished); 2160 dia->open(); 2161 break; 2162 } 2163 default: 2164 break; // avoid warnings 2165 } 2166 } 2167 2168 void View::slotTaskDescriptionFinished(int result) 2169 { 2170 TaskDescriptionDialog *dia = qobject_cast<TaskDescriptionDialog*>(sender()); 2171 if (dia == 0) { 2172 return; 2173 } 2174 if (result == QDialog::Accepted) { 2175 KUndo2Command * m = dia->buildCommand(); 2176 if (m) { 2177 getPart() ->addCommand(m); 2178 } 2179 } 2180 dia->deleteLater(); 2181 } 2182 2183 void View::slotDocuments() 2184 { 2185 //debugPlan; 2186 Node * node = currentNode(); 2187 if (!node) { 2188 return ; 2189 } 2190 switch (node->type()) { 2191 case Node::Type_Subproject: 2192 //TODO 2193 break; 2194 case Node::Type_Project: 2195 case Node::Type_Summarytask: 2196 case Node::Type_Task: 2197 case Node::Type_Milestone: { 2198 DocumentsDialog *dia = new DocumentsDialog(*node, this); 2199 connect(dia, &QDialog::finished, this, &View::slotDocumentsFinished); 2200 dia->open(); 2201 break; 2202 } 2203 default: 2204 break; // avoid warnings 2205 } 2206 } 2207 2208 void View::slotDocumentsFinished(int result) 2209 { 2210 DocumentsDialog *dia = qobject_cast<DocumentsDialog*>(sender()); 2211 if (dia == 0) { 2212 return; 2213 } 2214 if (result == QDialog::Accepted) { 2215 KUndo2Command * m = dia->buildCommand(); 2216 if (m) { 2217 getPart()->addCommand(m); 2218 } 2219 } 2220 dia->deleteLater(); 2221 } 2222 2223 void View::slotDeleteTaskList(QList<Node*> lst) 2224 { 2225 //debugPlan; 2226 foreach (Node *n, lst) { 2227 if (n->isScheduled()) { 2228 KMessageBox::ButtonCode res = KMessageBox::warningContinueCancel(this, i18n("A task that has been scheduled will be deleted. This will invalidate the schedule.")); 2229 if (res == KMessageBox::Cancel) { 2230 return; 2231 } 2232 break; 2233 } 2234 } 2235 if (lst.count() == 1) { 2236 getPart()->addCommand(new NodeDeleteCmd(lst.takeFirst(), kundo2_i18n("Delete task"))); 2237 return; 2238 } 2239 int num = 0; 2240 MacroCommand *cmd = new MacroCommand(kundo2_i18np("Delete task", "Delete tasks", lst.count())); 2241 while (!lst.isEmpty()) { 2242 Node *node = lst.takeFirst(); 2243 if (node == 0 || node->parentNode() == 0) { 2244 debugPlan << (node ?"Task is main project" :"No current task"); 2245 continue; 2246 } 2247 bool del = true; 2248 foreach (Node *n, lst) { 2249 if (node->isChildOf(n)) { 2250 del = false; // node is going to be deleted when we delete n 2251 break; 2252 } 2253 } 2254 if (del) { 2255 //debugPlan<<num<<": delete:"<<node->name(); 2256 cmd->addCommand(new NodeDeleteCmd(node, kundo2_i18n("Delete task"))); 2257 num++; 2258 } 2259 } 2260 if (num > 0) { 2261 getPart()->addCommand(cmd); 2262 } else { 2263 delete cmd; 2264 } 2265 } 2266 2267 void View::slotDeleteTask(Node *node) 2268 { 2269 //debugPlan; 2270 if (node == 0 || node->parentNode() == 0) { 2271 debugPlan << (node ?"Task is main project" :"No current task"); 2272 return ; 2273 } 2274 if (node->isScheduled()) { 2275 KMessageBox::ButtonCode res = KMessageBox::warningContinueCancel(this, i18n("This task has been scheduled. This will invalidate the schedule.")); 2276 if (res == KMessageBox::Cancel) { 2277 return; 2278 } 2279 } 2280 NodeDeleteCmd *cmd = new NodeDeleteCmd(node, kundo2_i18n("Delete task")); 2281 getPart() ->addCommand(cmd); 2282 } 2283 2284 void View::slotDeleteCurrentTask() 2285 { 2286 //debugPlan; 2287 return slotDeleteTask(currentNode()); 2288 } 2289 2290 void View::slotIndentTask() 2291 { 2292 //debugPlan; 2293 Node * node = currentNode(); 2294 if (node == 0 || node->parentNode() == 0) { 2295 debugPlan << (node ?"Task is main project" :"No current task"); 2296 return ; 2297 } 2298 if (getProject().canIndentTask(node)) { 2299 NodeIndentCmd * cmd = new NodeIndentCmd(*node, kundo2_i18n("Indent task")); 2300 getPart() ->addCommand(cmd); 2301 } 2302 } 2303 2304 void View::slotUnindentTask() 2305 { 2306 //debugPlan; 2307 Node * node = currentNode(); 2308 if (node == 0 || node->parentNode() == 0) { 2309 debugPlan << (node ?"Task is main project" :"No current task"); 2310 return ; 2311 } 2312 if (getProject().canUnindentTask(node)) { 2313 NodeUnindentCmd * cmd = new NodeUnindentCmd(*node, kundo2_i18n("Unindent task")); 2314 getPart() ->addCommand(cmd); 2315 } 2316 } 2317 2318 void View::slotMoveTaskUp() 2319 { 2320 //debugPlan; 2321 2322 Node * task = currentNode(); 2323 if (0 == task) { 2324 // is always != 0. At least we would get the Project, but you never know who might change that 2325 // so better be careful 2326 errorPlan << "No current task" << endl; 2327 return ; 2328 } 2329 2330 if (Node::Type_Project == task->type()) { 2331 debugPlan <<"The root node cannot be moved up"; 2332 return ; 2333 } 2334 if (getProject().canMoveTaskUp(task)) { 2335 NodeMoveUpCmd * cmd = new NodeMoveUpCmd(*task, kundo2_i18n("Move task up")); 2336 getPart() ->addCommand(cmd); 2337 } 2338 } 2339 2340 void View::slotMoveTaskDown() 2341 { 2342 //debugPlan; 2343 2344 Node * task = currentNode(); 2345 if (0 == task) { 2346 // is always != 0. At least we would get the Project, but you never know who might change that 2347 // so better be careful 2348 return ; 2349 } 2350 2351 if (Node::Type_Project == task->type()) { 2352 debugPlan <<"The root node cannot be moved down"; 2353 return ; 2354 } 2355 if (getProject().canMoveTaskDown(task)) { 2356 NodeMoveDownCmd * cmd = new NodeMoveDownCmd(*task, kundo2_i18n("Move task down")); 2357 getPart() ->addCommand(cmd); 2358 } 2359 } 2360 2361 void View::openRelationDialog(Node *par, Node *child) 2362 { 2363 //debugPlan; 2364 Relation * rel = new Relation(par, child); 2365 AddRelationDialog *dia = new AddRelationDialog(getProject(), rel, this); 2366 connect(dia, &QDialog::finished, this, &View::slotAddRelationFinished); 2367 dia->open(); 2368 } 2369 2370 void View::slotAddRelationFinished(int result) 2371 { 2372 AddRelationDialog *dia = qobject_cast<AddRelationDialog*>(sender()); 2373 if (dia == 0) { 2374 return; 2375 } 2376 if (result == QDialog::Accepted) { 2377 KUndo2Command * m = dia->buildCommand(); 2378 if (m) { 2379 getPart() ->addCommand(m); 2380 } 2381 } 2382 dia->deleteLater(); 2383 } 2384 2385 void View::slotAddRelation(Node *par, Node *child, int linkType) 2386 { 2387 //debugPlan; 2388 if (linkType == Relation::FinishStart || 2389 linkType == Relation::StartStart || 2390 linkType == Relation::FinishFinish) { 2391 Relation * rel = new Relation(par, child, static_cast<Relation::Type>(linkType)); 2392 getPart() ->addCommand(new AddRelationCmd(getProject(), rel, kundo2_i18n("Add task dependency"))); 2393 } else { 2394 openRelationDialog(par, child); 2395 } 2396 } 2397 2398 void View::slotEditRelation(Relation *rel) 2399 { 2400 //debugPlan; 2401 ModifyRelationDialog *dia = new ModifyRelationDialog(getProject(), rel, this); 2402 connect(dia, &QDialog::finished, this, &View::slotModifyRelationFinished); 2403 dia->open(); 2404 } 2405 2406 void View::slotModifyRelationFinished(int result) 2407 { 2408 ModifyRelationDialog *dia = qobject_cast<ModifyRelationDialog*>(sender()); 2409 if (dia == 0) { 2410 return ; 2411 } 2412 if (result == QDialog::Accepted) { 2413 KUndo2Command *cmd = dia->buildCommand(); 2414 if (cmd) { 2415 getPart() ->addCommand(cmd); 2416 } 2417 } 2418 dia->deleteLater(); 2419 } 2420 2421 void View::slotModifyRelation(Relation *rel, int linkType) 2422 { 2423 //debugPlan; 2424 if (linkType == Relation::FinishStart || 2425 linkType == Relation::StartStart || 2426 linkType == Relation::FinishFinish) { 2427 getPart() ->addCommand(new ModifyRelationTypeCmd(rel, static_cast<Relation::Type>(linkType))); 2428 } else { 2429 slotEditRelation(rel); 2430 } 2431 } 2432 2433 void View::slotModifyCurrentRelation() 2434 { 2435 ViewBase *v = dynamic_cast<ViewBase*>(m_tab->currentWidget()); 2436 if (v == 0) { 2437 return; 2438 } 2439 Relation *rel = v->currentRelation(); 2440 if (rel) { 2441 slotEditRelation(rel); 2442 } 2443 } 2444 2445 void View::slotDeleteRelation() 2446 { 2447 ViewBase *v = dynamic_cast<ViewBase*>(m_tab->currentWidget()); 2448 if (v == 0) { 2449 return; 2450 } 2451 Relation *rel = v->currentRelation(); 2452 if (rel) { 2453 getPart()->addCommand(new DeleteRelationCmd(getProject(), rel, kundo2_i18n("Delete task dependency"))); 2454 } 2455 } 2456 2457 void View::slotEditCurrentResource() 2458 { 2459 //debugPlan; 2460 slotEditResource(currentResource()); 2461 } 2462 2463 void View::slotEditResource(Resource *resource) 2464 { 2465 if (resource == 0) { 2466 return ; 2467 } 2468 ResourceDialog *dia = new ResourceDialog(getProject(), resource, this); 2469 connect(dia, &QDialog::finished, this, &View::slotEditResourceFinished); 2470 dia->open(); 2471 } 2472 2473 void View::slotEditResourceFinished(int result) 2474 { 2475 //debugPlan; 2476 ResourceDialog *dia = qobject_cast<ResourceDialog*>(sender()); 2477 if (dia == 0) { 2478 return ; 2479 } 2480 if (result == QDialog::Accepted) { 2481 KUndo2Command * cmd = dia->buildCommand(); 2482 if (cmd) 2483 getPart() ->addCommand(cmd); 2484 } 2485 dia->deleteLater(); 2486 } 2487 2488 void View::slotDeleteResource(Resource *resource) 2489 { 2490 getPart()->addCommand(new RemoveResourceCmd(resource->parentGroup(), resource, kundo2_i18n("Delete resource"))); 2491 } 2492 2493 void View::slotDeleteResourceGroup(ResourceGroup *group) 2494 { 2495 getPart()->addCommand(new RemoveResourceGroupCmd(group->project(), group, kundo2_i18n("Delete resourcegroup"))); 2496 } 2497 2498 void View::slotDeleteResourceObjects(QObjectList lst) 2499 { 2500 //debugPlan; 2501 foreach (QObject *o, lst) { 2502 Resource *r = qobject_cast<Resource*>(o); 2503 if (r && r->isScheduled()) { 2504 KMessageBox::ButtonCode res = KMessageBox::warningContinueCancel(this, i18n("A resource that has been scheduled will be deleted. This will invalidate the schedule.")); 2505 if (res == KMessageBox::Cancel) { 2506 return; 2507 } 2508 break; 2509 } 2510 ResourceGroup *g = qobject_cast<ResourceGroup*>(o); 2511 if (g && g->isScheduled()) { 2512 KMessageBox::ButtonCode res = KMessageBox::warningContinueCancel(this, i18n("A resource that has been scheduled will be deleted. This will invalidate the schedule.")); 2513 if (res == KMessageBox::Cancel) { 2514 return; 2515 } 2516 break; 2517 } 2518 } 2519 if (lst.count() == 1) { 2520 Resource *r = qobject_cast<Resource*>(lst.first()); 2521 if (r) { 2522 slotDeleteResource(r); 2523 } else { 2524 ResourceGroup *g = qobject_cast<ResourceGroup*>(lst.first()); 2525 if (g) { 2526 slotDeleteResourceGroup(g); 2527 } 2528 } 2529 return; 2530 } 2531 // int num = 0; 2532 MacroCommand *cmd = 0, *rc = 0, *gc = 0; 2533 foreach (QObject *o, lst) { 2534 Resource *r = qobject_cast<Resource*>(o); 2535 if (r) { 2536 if (rc == 0) rc = new MacroCommand(KUndo2MagicString()); 2537 rc->addCommand(new RemoveResourceCmd(r->parentGroup(), r)); 2538 continue; 2539 } 2540 ResourceGroup *g = qobject_cast<ResourceGroup*>(o); 2541 if (g) { 2542 if (gc == 0) gc = new MacroCommand(KUndo2MagicString()); 2543 gc->addCommand(new RemoveResourceGroupCmd(g->project(), g)); 2544 } 2545 } 2546 if (rc || gc) { 2547 KUndo2MagicString s; 2548 if (rc && gc) { 2549 s = kundo2_i18n("Delete resourcegroups and resources"); 2550 } else if (rc) { 2551 s = kundo2_i18np("Delete resource", "Delete resources", lst.count()); 2552 } else { 2553 s = kundo2_i18np("Delete resourcegroup", "Delete resourcegroups", lst.count()); 2554 } 2555 cmd = new MacroCommand(s); 2556 } 2557 if (rc) 2558 cmd->addCommand(rc); 2559 if (gc) 2560 cmd->addCommand(gc); 2561 if (cmd) 2562 getPart()->addCommand(cmd); 2563 } 2564 2565 2566 void View::updateReadWrite(bool readwrite) 2567 { 2568 m_readWrite = readwrite; 2569 m_viewlist->setReadWrite(readwrite); 2570 } 2571 2572 MainDocument *View::getPart() const 2573 { 2574 return (MainDocument *) koDocument(); 2575 } 2576 2577 KoPart *View::getKoPart() const 2578 { 2579 return m_partpart; 2580 } 2581 2582 void View::slotConnectNode() 2583 { 2584 //debugPlan; 2585 /* NodeItem *curr = ganttview->currentItem(); 2586 if (curr) { 2587 debugPlan<<"node="<<curr->getNode().name(); 2588 }*/ 2589 } 2590 2591 QMenu * View::popupMenu(const QString& name) 2592 { 2593 //debugPlan; 2594 if (factory()) { 2595 return ((QMenu*) factory() ->container(name, this)); 2596 } 2597 debugPlan<<"No factory"; 2598 return 0L; 2599 } 2600 2601 void View::slotUpdate() 2602 { 2603 //debugPlan<<"calculate="<<calculate; 2604 2605 // m_updateResourceview = true; 2606 m_updateResourceAssignmentView = true; 2607 m_updatePertEditor = true; 2608 updateView(m_tab->currentWidget()); 2609 } 2610 2611 void View::slotGuiActivated(ViewBase *view, bool activate) 2612 { 2613 if (activate) { 2614 foreach (DockWidget *ds, view->dockers()) { 2615 m_dockers.append(ds); 2616 ds->activate(mainWindow()); 2617 } 2618 if (!m_dockers.isEmpty()) {debugPlan<<"Added dockers:"<<view<<m_dockers;} 2619 } else { 2620 if (!m_dockers.isEmpty()) {debugPlan<<"Remove dockers:"<<view<<m_dockers;} 2621 while (! m_dockers.isEmpty()) { 2622 m_dockers.takeLast()->deactivate(mainWindow()); 2623 } 2624 } 2625 } 2626 2627 void View::guiActivateEvent(bool activated) 2628 { 2629 if (activated) { 2630 // plug my own actionlists, they may be gone 2631 slotPlugScheduleActions(); 2632 } 2633 // propagate to sub-view 2634 ViewBase *v = dynamic_cast<ViewBase*>(m_tab->currentWidget()); 2635 if (v) { 2636 v->setGuiActive(activated); 2637 } 2638 } 2639 2640 void View::slotViewListItemRemoved(ViewListItem *item) 2641 { 2642 getPart()->removeViewListItem(this, item); 2643 } 2644 2645 void View::removeViewListItem(const ViewListItem *item) 2646 { 2647 if (item == 0) { 2648 return; 2649 } 2650 ViewListItem *itm = m_viewlist->findItem(item->tag()); 2651 if (itm == 0) { 2652 return; 2653 } 2654 m_viewlist->removeViewListItem(itm); 2655 return; 2656 } 2657 2658 void View::slotViewListItemInserted(ViewListItem *item, ViewListItem *parent, int index) 2659 { 2660 getPart()->insertViewListItem(this, item, parent, index); 2661 } 2662 2663 void View::addViewListItem(const ViewListItem *item, const ViewListItem *parent, int index) 2664 { 2665 if (item == 0) { 2666 return; 2667 } 2668 if (parent == 0) { 2669 if (item->type() != ViewListItem::ItemType_Category) { 2670 return; 2671 } 2672 m_viewlist->blockSignals(true); 2673 ViewListItem *cat = m_viewlist->addCategory(item->tag(), item->text(0)); 2674 cat->setToolTip(0, item->toolTip(0)); 2675 m_viewlist->blockSignals(false); 2676 return; 2677 } 2678 ViewListItem *cat = m_viewlist->findCategory(parent->tag()); 2679 if (cat == 0) { 2680 return; 2681 } 2682 m_viewlist->blockSignals(true); 2683 createView(cat, item->viewType(), item->tag(), item->text(0), item->toolTip(0), index); 2684 m_viewlist->blockSignals(false); 2685 } 2686 2687 void View::createReportView(const QDomDocument &doc) 2688 { 2689 #ifdef PLAN_USE_KREPORT 2690 QPointer<ViewListReportsDialog> vd = new ViewListReportsDialog(this, *m_viewlist, doc, this); 2691 vd->exec(); // FIXME make non-crash 2692 delete vd; 2693 #else 2694 Q_UNUSED(doc) 2695 #endif 2696 } 2697 2698 void View::slotOpenReportFile() 2699 { 2700 #ifdef PLAN_USE_KREPORT 2701 QFileDialog *dlg = new QFileDialog(this); 2702 connect(dlg, &QDialog::finished, &View::slotOpenReportFileFinished(int))); 2703 dlg->open(); 2704 #endif 2705 } 2706 2707 void View::slotOpenReportFileFinished(int result) 2708 { 2709 #ifdef PLAN_USE_KREPORT 2710 QFileDialog *fdlg = qobject_cast<QFileDialog*>(sender()); 2711 if (fdlg == 0 || result != QDialog::Accepted) { 2712 return; 2713 } 2714 QString fn = fdlg->selectedFiles().value(0); 2715 if (fn.isEmpty()) { 2716 return; 2717 } 2718 QFile file(fn); 2719 if (! file.open(QIODevice::ReadOnly | QIODevice::Text)) { 2720 KMessageBox::sorry(this, xi18nc("@info", "Cannot open file:<br/><filename>%1</filename>", fn)); 2721 return; 2722 } 2723 QDomDocument doc; 2724 doc.setContent(&file); 2725 createReportView(doc); 2726 #else 2727 Q_UNUSED(result) 2728 #endif 2729 } 2730 2731 void View::slotReportDesignFinished(int /*result */) 2732 { 2733 #ifdef PLAN_USE_KREPORT 2734 if (sender()) { 2735 sender()->deleteLater(); 2736 } 2737 #endif 2738 } 2739 2740 void View::slotCreateView() 2741 { 2742 ViewListDialog *dlg = new ViewListDialog(this, *m_viewlist, this); 2743 connect(dlg, &QDialog::finished, this, &View::slotCreateViewFinished); 2744 dlg->open(); 2745 } 2746 2747 void View::slotCreateViewFinished(int) 2748 { 2749 if (sender()) { 2750 sender()->deleteLater(); 2751 } 2752 } 2753 2754 void View::slotViewActivated(ViewListItem *item, ViewListItem *prev) 2755 { 2756 QApplication::setOverrideCursor(Qt::WaitCursor); 2757 if (prev && prev->type() == ViewListItem::ItemType_Category && m_viewlist->previousViewItem()) { 2758 // A view is shown anyway... 2759 ViewBase *v = qobject_cast<ViewBase*>(m_viewlist->previousViewItem()->view()); 2760 if (v) { 2761 factory()->removeClient(v); 2762 v->setGuiActive(false); 2763 } 2764 } else if (prev && prev->type() == ViewListItem::ItemType_SubView) { 2765 ViewBase *v = qobject_cast<ViewBase*>(prev->view()); 2766 if (v) { 2767 factory()->removeClient(v); 2768 v->setGuiActive(false); 2769 } 2770 } 2771 if (item && item->type() == ViewListItem::ItemType_SubView) { 2772 //debugPlan<<"Activate:"<<item; 2773 m_tab->setCurrentWidget(item->view()); 2774 // Add sub-view specific gui 2775 ViewBase *v = dynamic_cast<ViewBase*>(m_tab->currentWidget()); 2776 if (v) { 2777 factory()->addClient(v); 2778 v->setGuiActive(true); 2779 } 2780 } 2781 QApplication::restoreOverrideCursor(); 2782 } 2783 2784 QWidget *View::canvas() const 2785 { 2786 return m_tab->currentWidget();//KoView::canvas(); 2787 } 2788 2789 KoPageLayout View::pageLayout() const 2790 { 2791 return currentView()->pageLayout(); 2792 } 2793 2794 void View::setPageLayout(const KoPageLayout &pageLayout) 2795 { 2796 currentView()->setPageLayout(pageLayout); 2797 } 2798 2799 QPrintDialog *View::createPrintDialog(KoPrintJob *printJob, QWidget *parent) 2800 { 2801 debugPlan<<printJob; 2802 KoPrintingDialog *job = dynamic_cast<KoPrintingDialog*>(printJob); 2803 if (! job) { 2804 return 0; 2805 } 2806 QPrintDialog *dia = KoView::createPrintDialog(job, parent); 2807 2808 PrintingDialog *j = dynamic_cast<PrintingDialog*>(job); 2809 if (j) { 2810 new PrintingControlPrivate(j, dia); 2811 } 2812 return dia; 2813 } 2814 2815 void View::slotCurrentChanged(int view) 2816 { 2817 m_visitedViews << view; 2818 ViewListItem *item = m_viewlist->findItem(qobject_cast<ViewBase*>(m_tab->currentWidget())); 2819 m_viewlist->setCurrentItem(item); 2820 } 2821 2822 void View::slotSelectDefaultView() 2823 { 2824 m_tab->setCurrentIndex(qMin(m_defaultView, m_tab->count()-1)); 2825 } 2826 2827 void View::updateView(QWidget *) 2828 { 2829 QApplication::setOverrideCursor(Qt::WaitCursor); 2830 //setScheduleActionsEnabled(); 2831 2832 QWidget *widget2; 2833 2834 widget2 = m_viewlist->findView("ResourceAssignmentView"); 2835 if (widget2 && m_updateResourceAssignmentView) 2836 static_cast<ViewBase*>(widget2) ->draw(getProject()); 2837 m_updateResourceAssignmentView = false; 2838 2839 QApplication::restoreOverrideCursor(); 2840 } 2841 2842 void View::slotRenameNode(Node *node, const QString& name) 2843 { 2844 //debugPlan<<name; 2845 if (node) { 2846 KUndo2MagicString s = kundo2_i18n("Modify name"); 2847 switch(node->type()) { 2848 case Node::Type_Task: s = kundo2_i18n("Modify task name"); break; 2849 case Node::Type_Milestone: s = kundo2_i18n("Modify milestone name"); break; 2850 case Node::Type_Summarytask: s = kundo2_i18n("Modify summarytask name"); break; 2851 case Node::Type_Project: s = kundo2_i18n("Modify project name"); break; 2852 } 2853 NodeModifyNameCmd * cmd = new NodeModifyNameCmd(*node, name, s); 2854 getPart() ->addCommand(cmd); 2855 } 2856 } 2857 2858 void View::slotPopupMenuRequested(const QString& menuname, const QPoint & pos) 2859 { 2860 QMenu * menu = this->popupMenu(menuname); 2861 if (menu) { 2862 //debugPlan<<menu<<":"<<menu->actions().count(); 2863 ViewBase *v = qobject_cast<ViewBase*>(m_tab->currentWidget()); 2864 //debugPlan<<v<<menuname; 2865 QList<QAction*> lst; 2866 if (v) { 2867 lst = v->contextActionList(); 2868 debugPlan<<lst; 2869 if (! lst.isEmpty()) { 2870 menu->addSeparator(); 2871 foreach (QAction *a, lst) { 2872 menu->addAction(a); 2873 } 2874 } 2875 } 2876 menu->exec(pos); 2877 foreach (QAction *a, lst) { 2878 menu->removeAction(a); 2879 } 2880 } 2881 } 2882 2883 void View::slotPopupMenu(const QString& menuname, const QPoint &pos, ViewListItem *item) 2884 { 2885 //debugPlan<<menuname; 2886 m_viewlistItem = item; 2887 slotPopupMenuRequested(menuname, pos); 2888 } 2889 2890 bool View::loadContext() 2891 { 2892 Context *ctx = getPart()->context(); 2893 if (ctx == 0 || ! ctx->isLoaded()) { 2894 return false; 2895 } 2896 KoXmlElement n = ctx->context(); 2897 QString cv = n.attribute("current-view"); 2898 if (! cv.isEmpty()) { 2899 m_viewlist->setSelected(m_viewlist->findItem(cv)); 2900 } else debugPlan<<"No current view"; 2901 2902 long id = n.attribute("current-schedule", "-1").toLong(); 2903 if (id != -1) { 2904 setActiveSchedule(id); 2905 } else debugPlan<<"No current schedule"; 2906 2907 return true; 2908 } 2909 2910 void View::saveContext(QDomElement &me) const 2911 { 2912 //debugPlan; 2913 long id = activeScheduleId(); 2914 if (id != -1) { 2915 me.setAttribute("current-schedule", QString::number((qlonglong)id)); 2916 } 2917 ViewListItem *item = m_viewlist->findItem(qobject_cast<ViewBase*>(m_tab->currentWidget())); 2918 if (item) { 2919 me.setAttribute("current-view", item->tag()); 2920 } 2921 m_viewlist->save(me); 2922 } 2923 2924 void View::loadWorkPackage(Project *project, const QList<QUrl> &urls) 2925 { 2926 bool loaded = false; 2927 for (const QUrl &url : urls) { 2928 loaded |= getPart()->loadWorkPackage(*project, url); 2929 } 2930 if (loaded) { 2931 slotWorkPackageLoaded(); 2932 } 2933 } 2934 2935 void View::setLabel(ScheduleManager *sm) 2936 { 2937 //debugPlan; 2938 Schedule *s = sm == 0 ? 0 : sm->expected(); 2939 if (s && !s->isDeleted() && s->isScheduled()) { 2940 m_estlabel->setText(sm->name()); 2941 return; 2942 } 2943 m_estlabel->setText(xi18nc("@info:status", "Not scheduled")); 2944 } 2945 2946 void View::slotWorkPackageLoaded() 2947 { 2948 debugPlan<<getPart()->workPackages(); 2949 addStatusBarItem(m_workPackageButton, 0, true); 2950 emit workPackagesAvailable(true); 2951 } 2952 2953 void View::openWorkPackageMergeDialog() 2954 { 2955 WorkPackageMergeDialog *dlg = new WorkPackageMergeDialog(&getProject(), getPart()->workPackages(), this); 2956 connect(dlg, &QDialog::finished, this, &View::workPackageMergeDialogFinished); 2957 connect(dlg, SIGNAL(terminateWorkPackage(const KPlato::Package*)), getPart(), SLOT(terminateWorkPackage(const KPlato::Package*))); 2958 connect(dlg, &WorkPackageMergeDialog::executeCommand, koDocument(), &KoDocument::addCommand); 2959 dlg->open(); 2960 removeStatusBarItem(m_workPackageButton); 2961 emit workPackagesAvailable(false); 2962 } 2963 2964 void View::workPackageMergeDialogFinished(int result) 2965 { 2966 debugPlanWp<<"result:"<<result<<"sender:"<<sender(); 2967 WorkPackageMergeDialog *dlg = qobject_cast<WorkPackageMergeDialog*>(sender()); 2968 Q_ASSERT(dlg); 2969 if (!getPart()->workPackages().isEmpty()) { 2970 slotWorkPackageLoaded(); 2971 } 2972 if (dlg) { 2973 dlg->deleteLater(); 2974 } 2975 } 2976 2977 2978 void View::slotMailWorkpackage(Node *node, Resource *resource) 2979 { 2980 debugPlan; 2981 QTemporaryFile tmpfile(QDir::tempPath() + QLatin1String("/calligraplanwork_XXXXXX") + QLatin1String(".planwork")); 2982 tmpfile.setAutoRemove(false); 2983 if (! tmpfile.open()) { 2984 debugPlan<<"Failed to open file"; 2985 KMessageBox::error(0, i18n("Failed to open temporary file")); 2986 return; 2987 } 2988 QUrl url = QUrl::fromLocalFile(tmpfile.fileName()); 2989 if (! getPart()->saveWorkPackageUrl(url, node, activeScheduleId(), resource)) { 2990 debugPlan<<"Failed to save to file"; 2991 KMessageBox::error(0, xi18nc("@info", "Failed to save to temporary file:<br/> <filename>%1</filename>", url.url())); 2992 return; 2993 } 2994 QStringList attachURLs; 2995 attachURLs << url.url(); 2996 QString to = resource == 0 ? node->leader() : (resource->name() + " <" + resource->email() + '>'); 2997 QString cc; 2998 QString bcc; 2999 QString subject = i18n("Work Package: %1", node->name()); 3000 QString body = i18nc("1=project name, 2=task name", "%1\n%2", getProject().name(), node->name()); 3001 QString messageFile; 3002 3003 KToolInvocation::invokeMailer(to, cc, bcc, subject, body, messageFile, attachURLs); 3004 } 3005 3006 void View::slotPublishWorkpackages(const QList<Node*> &nodes, Resource *resource, bool mailTo) 3007 { 3008 debugPlanWp<<resource<<nodes; 3009 if (resource == 0) { 3010 warnPlan<<"No resource, we don't handle node->leader() yet"; 3011 return; 3012 } 3013 bool mail = mailTo; 3014 QString body; 3015 QStringList attachURLs; 3016 3017 QString path; 3018 if (getProject().workPackageInfo().publishUrl.isValid()) { 3019 path = getProject().workPackageInfo().publishUrl.path(); 3020 debugPlanWp<<"publish:"<<path; 3021 } else { 3022 path = QDir::tempPath(); 3023 mail = true; 3024 } 3025 foreach (Node *n, nodes) { 3026 QTemporaryFile tmpfile(path + QLatin1String("/calligraplanwork_XXXXXX") + QLatin1String(".planwork")); 3027 tmpfile.setAutoRemove(false); 3028 if (! tmpfile.open()) { 3029 debugPlanWp<<"Failed to open file"; 3030 KMessageBox::error(0, i18n("Failed to open work package file")); 3031 return; 3032 } 3033 QUrl url = QUrl::fromLocalFile(tmpfile.fileName()); 3034 debugPlanWp<<url; 3035 if (! getPart()->saveWorkPackageUrl(url, n, activeScheduleId(), resource)) { 3036 debugPlan<<"Failed to save to file"; 3037 KMessageBox::error(0, xi18nc("@info", "Failed to save to temporary file:<br/><filename>%1</filename>", url.url())); 3038 return; 3039 } 3040 attachURLs << url.url(); 3041 body += n->name() + '\n'; 3042 } 3043 if (mail) { 3044 debugPlanWp<<attachURLs; 3045 QString to = resource->name() + " <" + resource->email() + '>'; 3046 QString subject = i18n("Work Package for project: %1", getProject().name()); 3047 QString cc; 3048 QString bcc; 3049 QString messageFile; 3050 3051 KToolInvocation::invokeMailer(to, cc, bcc, subject, body, messageFile, attachURLs); 3052 } 3053 } 3054 3055 void View::slotCurrencyConfig() 3056 { 3057 LocaleConfigMoneyDialog *dlg = new LocaleConfigMoneyDialog(getProject().locale(), this); 3058 connect(dlg, &QDialog::finished, this, &View::slotCurrencyConfigFinished); 3059 dlg->open(); 3060 } 3061 3062 void View::slotCurrencyConfigFinished(int result) 3063 { 3064 LocaleConfigMoneyDialog *dlg = qobject_cast<LocaleConfigMoneyDialog*>(sender()); 3065 if (dlg == 0) { 3066 return; 3067 } 3068 if (result == QDialog::Accepted) { 3069 KUndo2Command *c = dlg->buildCommand(getProject()); 3070 if (c) { 3071 getPart()->addCommand(c); 3072 } 3073 } 3074 dlg->deleteLater(); 3075 } 3076 3077 void View::saveTaskModule(const QUrl &url, Project *project) 3078 { 3079 // NOTE: workaround: KoResourcePaths::saveLocation("calligraplan_taskmodules"); does not work 3080 const QString dir = KoResourcePaths::saveLocation("appdata", "taskmodules/"); 3081 debugPlan<<"dir="<<dir; 3082 if (! dir.isEmpty()) { 3083 Part *part = new Part(this); 3084 MainDocument *doc = new MainDocument(part); 3085 part->setDocument(doc); 3086 doc->disconnect(); // doc shall not handle feedback from openUrl() 3087 doc->setAutoSave(0); //disable 3088 doc->insertProject(*project, 0, 0); // FIXME: destroys project, find better way 3089 doc->getProject().setName(project->name()); 3090 doc->getProject().setLeader(project->leader()); 3091 doc->getProject().setDescription(project->description()); 3092 doc->saveNativeFormat(dir + url.fileName()); 3093 part->deleteLater(); // also deletes document 3094 debugPlan<<dir + url.fileName(); 3095 } else { 3096 debugPlan<<"Could not find a location"; 3097 } 3098 } 3099 3100 void View::removeTaskModule(const QUrl &url) 3101 { 3102 debugPlan<<url; 3103 } 3104 3105 QString View::standardTaskStatusReport() const 3106 { 3107 QString s; 3108 #ifdef PLAN_USE_KREPORT 3109 s = QString::fromLatin1( 3110 "<planreportdefinition version=\"1.0\" mime=\"application/x-vnd.kde.plan.report.definition\" editor=\"Plan\" >" 3111 "<data-source select-from=\"taskstatus\" ></data-source>" 3112 "<report:content xmlns:report=\"http://kexi-project.org/report/2.0\" xmlns:fo=\"urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0\" xmlns:svg=\"urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0\" >" 3113 "<report:title>%1</report:title>" 3114 "<report:script report:script-interpreter=\"javascript\" ></report:script>" 3115 "<report:grid report:grid-divisions=\"4\" report:grid-snap=\"1\" report:page-unit=\"cm\" report:grid-visible=\"1\" />" 3116 "<report:page-style report:print-orientation=\"portrait\" fo:margin-bottom=\"1cm\" fo:margin-top=\"1cm\" fo:margin-left=\"1cm\" fo:margin-right=\"1cm\" report:page-size=\"A4\" >predefined</report:page-style>" 3117 "<report:body>" 3118 "<report:section svg:height=\"1.75cm\" fo:background-color=\"#ffffff\" report:section-type=\"header-page-any\" >" 3119 "<report:field report:name=\"field16\" report:horizontal-align=\"left\" report:item-data-source=\"#project.manager\" svg:x=\"13cm\" svg:width=\"5.9714cm\" svg:y=\"0.4cm\" report:vertical-align=\"bottom\" svg:height=\"0.6cm\" report:z-index=\"0\" >" 3120 "<report:text-style fo:font-weight=\"bold\" fo:letter-spacing=\"0%\" style:letter-kerning=\"true\" fo:font-size=\"10\" fo:foreground-color=\"#000000\" fo:font-family=\"DejaVu Sans\" fo:background-color=\"#ffffff\" fo:background-opacity=\"100%\" />" 3121 "<report:line-style report:line-style=\"nopen\" report:line-weight=\"1\" report:line-color=\"#000000\" />" 3122 "</report:field>" 3123 "<report:label report:name=\"label16\" report:horizontal-align=\"left\" svg:x=\"13cm\" svg:width=\"5.9714cm\" svg:y=\"0cm\" report:caption=\"%2\" report:vertical-align=\"center\" svg:height=\"0.4cm\" report:z-index=\"1\" >" 3124 "<report:text-style fo:letter-spacing=\"0%\" style:letter-kerning=\"true\" fo:font-size=\"8\" fo:foreground-color=\"#000000\" fo:font-family=\"DejaVu Sans\" fo:font-style=\"italic\" fo:background-color=\"#ffffff\" fo:background-opacity=\"100%\" />" 3125 "<report:line-style report:line-style=\"nopen\" report:line-weight=\"1\" report:line-color=\"#000000\" />" 3126 "</report:label>" 3127 "<report:field report:name=\"field17\" report:horizontal-align=\"left\" report:item-data-source=\"#project.name\" svg:x=\"0cm\" svg:width=\"13cm\" svg:y=\"0.4cm\" report:vertical-align=\"bottom\" svg:height=\"0.6cm\" report:z-index=\"1\" >" 3128 "<report:text-style fo:font-weight=\"bold\" fo:letter-spacing=\"0%\" style:letter-kerning=\"true\" fo:font-size=\"10\" fo:foreground-color=\"#000000\" fo:font-family=\"DejaVu Sans\" fo:background-color=\"#ffffff\" fo:background-opacity=\"0%\" />" 3129 "<report:line-style report:line-style=\"nopen\" report:line-weight=\"1\" report:line-color=\"#000000\" />" 3130 "</report:field>" 3131 "<report:label report:name=\"label18\" report:horizontal-align=\"left\" svg:x=\"0cm\" svg:width=\"13cm\" svg:y=\"0cm\" report:caption=\"%3\" report:vertical-align=\"center\" svg:height=\"0.4cm\" report:z-index=\"0\" >" 3132 "<report:text-style fo:letter-spacing=\"0%\" style:letter-kerning=\"true\" fo:font-size=\"8\" fo:foreground-color=\"#000000\" fo:font-family=\"DejaVu Sans\" fo:font-style=\"italic\" fo:background-color=\"#ffffff\" fo:background-opacity=\"100%\" />" 3133 "<report:line-style report:line-style=\"nopen\" report:line-weight=\"1\" report:line-color=\"#000000\" />" 3134 "</report:label>" 3135 "<report:line report:name=\"line15\" svg:y1=\"1.2229cm\" svg:x1=\"0cm\" svg:y2=\"1.2229cm\" svg:x2=\"18.9715cm\" report:z-index=\"0\" >" 3136 "<report:line-style report:line-style=\"solid\" report:line-weight=\"1\" report:line-color=\"#000000\" />" 3137 "</report:line>" 3138 "</report:section>" 3139 "<report:section svg:height=\"1.50cm\" fo:background-color=\"#ffffff\" report:section-type=\"header-report\" >" 3140 "<report:label report:name=\"label17\" report:horizontal-align=\"left\" svg:x=\"0cm\" svg:width=\"18.97cm\" svg:y=\"0cm\" report:caption=\"%4\" report:vertical-align=\"center\" svg:height=\"1.25cm\" report:z-index=\"0\" >" 3141 "<report:text-style fo:letter-spacing=\"0%\" style:letter-kerning=\"true\" fo:font-size=\"10\" fo:foreground-color=\"#000000\" fo:font-family=\"DejaVu Sans\" fo:background-color=\"#ffffff\" fo:background-opacity=\"100%\" />" 3142 "<report:line-style report:line-style=\"nopen\" report:line-weight=\"1\" report:line-color=\"#000000\" />" 3143 "</report:label>" 3144 "</report:section>" 3145 "<report:section svg:height=\"2.50cm\" fo:background-color=\"#ffffff\" report:section-type=\"footer-page-any\" >" 3146 "<report:field report:name=\"field10\" report:horizontal-align=\"right\" report:item-data-source=\"=constants.PageNumber()\" svg:x=\"6.75cm\" svg:width=\"0.75cm\" svg:y=\"0.25cm\" report:vertical-align=\"center\" svg:height=\"0.75cm\" report:z-index=\"0\" >" 3147 "<report:text-style fo:letter-spacing=\"0%\" style:letter-kerning=\"true\" fo:font-size=\"8\" fo:foreground-color=\"#000000\" fo:font-family=\"DejaVu Sans\" fo:background-color=\"#ffffff\" fo:background-opacity=\"100%\" />" 3148 "<report:line-style report:line-style=\"nopen\" report:line-weight=\"1\" report:line-color=\"#000000\" />" 3149 "</report:field>" 3150 "<report:field report:name=\"field11\" report:horizontal-align=\"left\" report:item-data-source=\"=constants.PageTotal()\" svg:x=\"8.25cm\" svg:width=\"3cm\" svg:y=\"0.25cm\" report:vertical-align=\"center\" svg:height=\"0.75cm\" report:z-index=\"0\" >" 3151 "<report:text-style fo:letter-spacing=\"0%\" style:letter-kerning=\"true\" fo:font-size=\"8\" fo:foreground-color=\"#000000\" fo:font-family=\"DejaVu Sans\" fo:background-color=\"#ffffff\" fo:background-opacity=\"100%\" />" 3152 "<report:line-style report:line-style=\"nopen\" report:line-weight=\"1\" report:line-color=\"#000000\" />" 3153 "</report:field>" 3154 "<report:label report:name=\"label12\" report:horizontal-align=\"center\" svg:x=\"7.5cm\" svg:width=\"0.75cm\" svg:y=\"0.25cm\" report:caption=\"%5\" report:vertical-align=\"center\" svg:height=\"0.75cm\" report:z-index=\"0\" >" 3155 "<report:text-style fo:letter-spacing=\"0%\" style:letter-kerning=\"true\" fo:font-size=\"8\" fo:foreground-color=\"#000000\" fo:font-family=\"DejaVu Sans\" fo:font-style=\"italic\" fo:background-color=\"#ffffff\" fo:background-opacity=\"100%\" />" 3156 "<report:line-style report:line-style=\"nopen\" report:line-weight=\"1\" report:line-color=\"#000000\" />" 3157 "</report:label>" 3158 "<report:label report:name=\"label13\" report:horizontal-align=\"right\" svg:x=\"5.75cm\" svg:width=\"1cm\" svg:y=\"0.25cm\" report:caption=\"%6\" report:vertical-align=\"center\" svg:height=\"0.75cm\" report:z-index=\"0\" >" 3159 "<report:text-style fo:letter-spacing=\"0%\" style:letter-kerning=\"true\" fo:font-size=\"8\" fo:foreground-color=\"#000000\" fo:font-family=\"DejaVu Sans\" fo:font-style=\"italic\" fo:background-color=\"#ffffff\" fo:background-opacity=\"100%\" />" 3160 "<report:line-style report:line-style=\"nopen\" report:line-weight=\"1\" report:line-color=\"#000000\" />" 3161 "</report:label>" 3162 "<report:line report:name=\"line14\" svg:y1=\"0.2195cm\" svg:x1=\"0cm\" svg:y2=\"0.2195cm\" svg:x2=\"18.9715cm\" report:z-index=\"0\" >" 3163 "<report:line-style report:line-style=\"solid\" report:line-weight=\"1\" report:line-color=\"#000000\" />" 3164 "</report:line>" 3165 "</report:section>" 3166 "<report:detail>" 3167 "<report:group report:group-sort=\"ascending\" report:group-column=\"Parent\" >" 3168 "<report:section svg:height=\"2.50cm\" fo:background-color=\"#ffffff\" report:section-type=\"group-header\" >" 3169 "<report:label report:name=\"label6\" report:horizontal-align=\"left\" svg:x=\"0.5cm\" svg:width=\"3.75cm\" svg:y=\"1.75cm\" report:caption=\"%7\" report:vertical-align=\"center\" svg:height=\"0.75cm\" report:z-index=\"0\" >" 3170 "<report:text-style fo:letter-spacing=\"0%\" style:letter-kerning=\"true\" fo:font-size=\"8\" fo:foreground-color=\"#000000\" fo:font-family=\"DejaVu Sans\" fo:background-color=\"#ffffff\" fo:background-opacity=\"100%\" />" 3171 "<report:line-style report:line-style=\"nopen\" report:line-weight=\"1\" report:line-color=\"#000000\" />" 3172 "</report:label>" 3173 "<report:field report:name=\"field8\" report:horizontal-align=\"left\" report:item-data-source=\"Parent\" svg:x=\"0.5cm\" svg:width=\"8cm\" svg:y=\"1cm\" report:vertical-align=\"center\" svg:height=\"0.689cm\" report:z-index=\"0\" >" 3174 "<report:text-style fo:font-weight=\"bold\" fo:letter-spacing=\"0%\" style:letter-kerning=\"true\" fo:font-size=\"8\" fo:foreground-color=\"#000000\" fo:font-family=\"DejaVu Sans\" fo:background-color=\"#ffffff\" fo:background-opacity=\"100%\" />" 3175 "<report:line-style report:line-style=\"nopen\" report:line-weight=\"1\" report:line-color=\"#000000\" />" 3176 "</report:field>" 3177 "<report:label report:name=\"label8\" report:horizontal-align=\"center\" svg:x=\"4.25cm\" svg:width=\"4.25cm\" svg:y=\"1.75cm\" report:caption=\"%8\" report:vertical-align=\"center\" svg:height=\"0.75cm\" report:z-index=\"0\" >" 3178 "<report:text-style fo:letter-spacing=\"0%\" style:letter-kerning=\"true\" fo:font-size=\"8\" fo:foreground-color=\"#000000\" fo:font-family=\"DejaVu Sans\" fo:background-color=\"#ffffff\" fo:background-opacity=\"100%\" />" 3179 "<report:line-style report:line-style=\"nopen\" report:line-weight=\"1\" report:line-color=\"#000000\" />" 3180 "</report:label>" 3181 "</report:section>" 3182 "</report:group>" 3183 "<report:section svg:height=\"0.50cm\" fo:background-color=\"#ffffff\" report:section-type=\"detail\" >" 3184 "<report:field report:name=\"field7\" report:horizontal-align=\"left\" report:item-data-source=\"NodeName\" svg:x=\"0.5cm\" svg:width=\"3.75cm\" svg:y=\"0cm\" report:vertical-align=\"center\" svg:height=\"0.5cm\" report:z-index=\"0\" >" 3185 "<report:text-style fo:letter-spacing=\"0%\" style:letter-kerning=\"true\" fo:font-size=\"8\" fo:foreground-color=\"#000000\" fo:font-family=\"DejaVu Sans\" fo:background-color=\"#ffffff\" fo:background-opacity=\"100%\" />" 3186 "<report:line-style report:line-style=\"nopen\" report:line-weight=\"1\" report:line-color=\"#000000\" />" 3187 "</report:field>" 3188 "<report:field report:name=\"field9\" report:horizontal-align=\"center\" report:item-data-source=\"NodeCompleted\" svg:x=\"4.25cm\" svg:width=\"4.25cm\" svg:y=\"0cm\" report:vertical-align=\"center\" svg:height=\"0.5cm\" report:z-index=\"0\" >" 3189 "<report:text-style fo:letter-spacing=\"0%\" style:letter-kerning=\"true\" fo:font-size=\"8\" fo:foreground-color=\"#000000\" fo:font-family=\"DejaVu Sans\" fo:background-color=\"#ffffff\" fo:background-opacity=\"100%\" />" 3190 "<report:line-style report:line-style=\"nopen\" report:line-weight=\"1\" report:line-color=\"#000000\" />" 3191 "</report:field>" 3192 "</report:section>" 3193 "</report:detail>" 3194 "</report:body>" 3195 "</report:content>" 3196 "</planreportdefinition>") 3197 .arg( 3198 i18n("Report"), 3199 i18nc("Project manager", "Manager:"), 3200 i18n("Project:"), 3201 i18n("Task Status Report"), 3202 i18nc("As in: Page 1 of 2", "of"), 3203 i18n("Page"), 3204 i18nc("Task name", "Name"), 3205 i18nc("Task completion", "Completion (%)") 3206 ); 3207 #endif 3208 return s; 3209 }