1/* This file is part of the KDE project
2 Copyright (C) 1998, 1999, 2000 Torben Weis <weis@kde.org>
3 Copyright (C) 2002 - 2011 Dag Andersen <danders@get2net.dk>
4 Copyright (C) 2012 Dag Andersen <danders@get2net.dk>
5
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Library General Public
8 License as published by the Free Software Foundation; either
9 version 2 of the License, or (at your option) any later version.
10
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Library General Public License for more details.
15
16 You should have received a copy of the GNU Library General Public License
17 along with this library; see the file COPYING.LIB. If not, write to
18 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19* Boston, MA 02110-1301, USA.
20*/
21
22#include "kptview.h"
23
24#include <kmessagebox.h>
25
26#include "KoDocumentInfo.h"
27#include "KoMainWindow.h"
28#include <KoIcon.h>
29
30#include <QApplication>
31#include <QLabel>
32#include <QString>
33#include <QStringList>
34#include <QSize>
35#include <QStackedWidget>
36#include <QVBoxLayout>
37#include <QTreeWidget>
38#include <QTreeWidgetItem>
39#include <QPrinter>
40#include <QPrintDialog>
41#include <QProgressBar>
42#include <QSortFilterProxyModel>
43#include <QDomDocument>
44#include <QDomElement>
45#include <kundo2command.h>
46#include <QTimer>
47#include <QDockWidget>
48
49#include <kaction.h>
50#include <kactioncollection.h>
51#include <kactionmenu.h>
52#include <kmenu.h>
53#include <kstandardaction.h>
54#include <klocale.h>
55#include <kdebug.h>
56#include <ktoolbar.h>
57#include <kstandardshortcut.h>
58#include <kaccelgen.h>
59#include <kconfigdialogmanager.h>
60#include <kstatusbar.h>
61#include <kxmlguifactory.h>
62#include <kdesktopfile.h>
63#include <ktoggleaction.h>
64#include <ktemporaryfile.h>
65#include <kfiledialog.h>
66#include <kparts/event.h>
67#include <kparts/partmanager.h>
68#include <kconfigdialog.h>
69#include <ktoolinvocation.h>
70#include <krun.h>
71#include <kstandarddirs.h>
72#include <kservicetypetrader.h>
73
74#include <KoDocumentEntry.h>
75#include <KoTemplateCreateDia.h>
76#include <KoProgressUpdater.h>
77#include <KoPart.h>
78
79#include "kptviewbase.h"
80#include "kptaccountsview.h"
81#include "kptaccountseditor.h"
82#include "kptcalendareditor.h"
83#include "kptfactory.h"
84#include "kptmilestoneprogressdialog.h"
85#include "kpttaskdescriptiondialog.h"
86#include "kptnode.h"
87#include "kptmaindocument.h"
88#include "kptproject.h"
89#include "kptmainprojectdialog.h"
90#include "kpttask.h"
91#include "kptsummarytaskdialog.h"
92#include "kpttaskdialog.h"
93#include "kpttaskprogressdialog.h"
94#include "kptganttview.h"
95#include "kpttaskeditor.h"
96#include "kptdependencyeditor.h"
97#include "kptperteditor.h"
98#include "kptdatetime.h"
99#include "kptcommand.h"
100#include "kptrelation.h"
101#include "kptrelationdialog.h"
102#include "kptresourceappointmentsview.h"
103#include "kptresourceeditor.h"
104#include "kptscheduleeditor.h"
105#include "kptresourcedialog.h"
106#include "kptresource.h"
107#include "kptstandardworktimedialog.h"
108#include "kptwbsdefinitiondialog.h"
109#include "kptresourceassignmentview.h"
110#include "kpttaskstatusview.h"
111#include "kptsplitterview.h"
112#include "kptpertresult.h"
113#include "kpttaskdefaultpanel.h"
114#include "kptworkpackageconfigpanel.h"
115#include "kptcolorsconfigpanel.h"
116#include "kptinsertfiledlg.h"
117#include "kpthtmlview.h"
118#include "reports/reportview.h"
119#include "reports/reportdata.h"
120#include "about/aboutpage.h"
121#include "kptlocaleconfigmoneydialog.h"
122#include "kptflatproxymodel.h"
123#include "kpttaskstatusmodel.h"
124
125#include "kptviewlistdialog.h"
126#include "kptviewlistdocker.h"
127#include "kptviewlist.h"
128#include "kptschedulesdocker.h"
129#include "kptdebug.h"
130
131#include "plansettings.h"
132#include "kptprintingcontrolprivate.h"
133
134// #include "KPtViewAdaptor.h"
135
136#include <assert.h>
137
138namespace KPlato
139{
140
141//-------------------------------
142ConfigDialog::ConfigDialog(QWidget *parent, const QString& name, KConfigSkeleton *config )
143 : KConfigDialog( parent, name, config ),
144 m_config( config )
145{
146 KConfigDialogManager::changedMap()->insert("KRichTextWidget", SIGNAL(textChanged()) );
147}
148
149bool ConfigDialog::hasChanged()
150{
151 QRegExp kcfg( "kcfg_*" );
152 foreach ( KRichTextWidget *w, findChildren<KRichTextWidget*>( kcfg ) ) {
153 KConfigSkeletonItem *item = m_config->findItem( w->objectName().mid(5) );
154 if ( ! item->isEqual( w->toHtml() ) ) {
155 return true;
156 }
157 }
158 return false;
159}
160
161void ConfigDialog::updateSettings()
162{
163 bool changed = false;
164 QRegExp kcfg( "kcfg_*" );
165 foreach ( KRichTextWidget *w, findChildren<KRichTextWidget*>( kcfg ) ) {
166 KConfigSkeletonItem *item = m_config->findItem( w->objectName().mid(5) );
167 if ( ! item ) {
168 kWarning() << "The setting '" << w->objectName().mid(5) << "' has disappeared!";
169 continue;
170 }
171 if ( ! item->isEqual( QVariant( w->toHtml() ) ) ) {
172 item->setProperty( QVariant( w->toHtml() ) );
173 changed = true;
174 }
175 }
176 if ( changed ) {
177 m_config->writeConfig();
178 }
179}
180
181void ConfigDialog::updateWidgets()
182{
183 QRegExp kcfg( "kcfg_*" );
184 foreach ( KRichTextWidget *w, findChildren<KRichTextWidget*>( kcfg ) ) {
185 KConfigSkeletonItem *item = m_config->findItem( w->objectName().mid(5) );
186 if ( ! item ) {
187 kWarning() << "The setting '" << w->objectName().mid(5) << "' has disappeared!";
188 continue;
189 }
190 if ( ! item->isEqual( QVariant( w->toHtml() ) ) ) {
191 w->setHtml( item->property().toString() );
192 }
193 }
194}
195
196void ConfigDialog::updateWidgetsDefault()
197{
198 bool usedefault = m_config->useDefaults( true );
199 updateWidgets();
200 m_config->useDefaults( usedefault );
201}
202
203bool ConfigDialog::isDefault()
204{
205 bool bUseDefaults = m_config->useDefaults(true);
206 bool result = !hasChanged();
207 m_config->useDefaults(bUseDefaults);
208 return result;
209}
210
211//------------------------------------
212View::View(KoPart *part, MainDocument *doc, QWidget *parent)
213 : KoView(part, doc, parent),
214 m_currentEstimateType( Estimate::Use_Expected ),
215 m_scheduleActionGroup( new QActionGroup( this ) ),
216 m_trigged( false ),
217 m_nextScheduleManager( 0 ),
218 m_readWrite( false ),
219 m_partpart (part)
220{
221 //kDebug(planDbg());
222
223 doc->registerView( this );
224
225 setComponentData( Factory::global() );
226 if ( !doc->isReadWrite() )
227 setXMLFile( "plan_readonly.rc" );
228 else
229 setXMLFile( "plan.rc" );
230
231// new ViewAdaptor( this );
232
233 m_sp = new QSplitter( this );
234 QVBoxLayout *layout = new QVBoxLayout( this );
235 layout->setMargin(0);
236 layout->addWidget( m_sp );
237
238 ViewListDocker *docker = 0;
239 if ( mainWindow() == 0 ) {
240 // Don't use docker if embedded
241 m_viewlist = new ViewListWidget(doc, m_sp);
242 m_viewlist->setProject( &( getProject() ) );
243 connect( m_viewlist, SIGNAL(selectionChanged(ScheduleManager*)), SLOT(slotSelectionChanged(ScheduleManager*)) );
244 connect( this, SIGNAL(currentScheduleManagerChanged(ScheduleManager*)), m_viewlist, SLOT(setSelectedSchedule(ScheduleManager*)) );
245 connect( m_viewlist, SIGNAL(updateViewInfo(ViewListItem*)), SLOT(slotUpdateViewInfo(ViewListItem*)) );
246 } else {
247 ViewListDockerFactory vl(this);
248 docker = dynamic_cast<ViewListDocker *>(mainWindow()->createDockWidget(&vl));
249 if (docker->view() != this) {
250 docker->setView(this);
251 }
252 m_viewlist = docker->viewList();
253#if 0 //SchedulesDocker
254 SchedulesDockerFactory sdf;
255 SchedulesDocker *sd = dynamic_cast<SchedulesDocker*>( createDockWidget( &sdf ) );
256 Q_ASSERT( sd );
257
258 sd->setProject( &getProject() );
259 connect( sd, SIGNAL(selectionChanged(ScheduleManager*)), SLOT(slotSelectionChanged(ScheduleManager*)) );
260 connect( this, SIGNAL(currentScheduleManagerChanged(ScheduleManager*)), sd, SLOT(setSelectedSchedule(ScheduleManager*)) );
261#endif
262 }
263
264 m_tab = new QStackedWidget( m_sp );
265
266////////////////////////////////////////////////////////////////////////////////////////////////////
267
268 // Add sub views
269 createWelcomeView();
270
271 // The menu items
272 // ------ File
273 actionCreateTemplate = new KAction( i18n( "&Create Template From Document..." ), this );
274 actionCollection()->addAction("file_createtemplate", actionCreateTemplate );
275 connect( actionCreateTemplate, SIGNAL(triggered(bool)), SLOT(slotCreateTemplate()) );
276
277 actionCreateNewProject = new KAction( i18n( "&Create New Project..." ), this );
278 actionCollection()->addAction("file_createnewproject", actionCreateNewProject );
279 connect( actionCreateNewProject, SIGNAL(triggered(bool)), SLOT(slotCreateNewProject()) );
280
281 // ------ Edit
282 actionCut = actionCollection()->addAction(KStandardAction::Cut, "edit_cut", this, SLOT(slotEditCut()));
283 actionCopy = actionCollection()->addAction(KStandardAction::Copy, "edit_copy", this, SLOT(slotEditCopy()));
284 actionPaste = actionCollection()->addAction(KStandardAction::Paste, "edit_paste", this, SLOT(slotEditPaste()));
285
286 // ------ View
287 actionCollection()->addAction( KStandardAction::Redisplay, "view_refresh" , this, SLOT(slotRefreshView()) );
288
289 actionViewSelector = new KToggleAction(i18n("Show Selector"), this);
290 actionCollection()->addAction("view_show_selector", actionViewSelector );
291 connect( actionViewSelector, SIGNAL(triggered(bool)), SLOT(slotViewSelector(bool)) );
292
293 // ------ Insert
294
295 // ------ Project
296 actionEditMainProject = new KAction(koIcon("view-time-schedule-edit"), i18n("Edit Main Project..."), this);
297 actionCollection()->addAction("project_edit", actionEditMainProject );
298 connect( actionEditMainProject, SIGNAL(triggered(bool)), SLOT(slotProjectEdit()) );
299
300 actionEditStandardWorktime = new KAction(koIcon("configure"), i18n("Define Estimate Conversions..."), this);
301 actionCollection()->addAction("project_worktime", actionEditStandardWorktime );
302 connect( actionEditStandardWorktime, SIGNAL(triggered(bool)), SLOT(slotProjectWorktime()) );
303
304
305 // ------ Tools
306 actionDefineWBS = new KAction(koIcon("configure"), i18n("Define WBS Pattern..."), this);
307 actionCollection()->addAction("tools_define_wbs", actionDefineWBS );
308 connect( actionDefineWBS, SIGNAL(triggered(bool)), SLOT(slotDefineWBS()) );
309
310 actionInsertFile = new KAction(koIcon("document-import"), i18n("Insert Project File..."), this);
311 actionCollection()->addAction("insert_file", actionInsertFile );
312 connect( actionInsertFile, SIGNAL(triggered(bool)), SLOT(slotInsertFile()) );
313
314 // ------ Settings
315 actionConfigure = new KAction(koIcon("configure"), i18n("Configure Plan..."), this);
316 actionCollection()->addAction("configure", actionConfigure );
317 connect( actionConfigure, SIGNAL(triggered(bool)), SLOT(slotConfigure()) );
318
319 actionCurrencyConfig = new KAction(koIcon("configure"), i18n("Define Currency..."), this);
320 actionCollection()->addAction( "config_currency", actionCurrencyConfig );
321 connect( actionCurrencyConfig, SIGNAL(triggered(bool)), SLOT(slotCurrencyConfig()) );
322
323 actionOpenReportFile = new KAction(koIcon("document-open"), i18n("Open Report Definition File..."), this);
324 actionCollection()->addAction( "reportdesigner_open_file", actionOpenReportFile );
325 connect( actionOpenReportFile, SIGNAL(triggered(bool)), SLOT(slotOpenReportFile()) );
326
327 // ------ Help
328 actionIntroduction = new KAction(koIcon("dialog-information"), i18n("Introduction to Plan"), this);
329 actionCollection()->addAction("plan_introduction", actionIntroduction );
330 connect( actionIntroduction, SIGNAL(triggered(bool)), SLOT(slotIntroduction()) );
331
332 // ------ Popup
333 actionOpenNode = new KAction(koIcon("document-edit"), i18n("Edit..."), this);
334 actionCollection()->addAction("node_properties", actionOpenNode );
335 connect( actionOpenNode, SIGNAL(triggered(bool)), SLOT(slotOpenNode()) );
336 actionTaskProgress = new KAction(koIcon("document-edit"), i18n("Progress..."), this);
337 actionCollection()->addAction("task_progress", actionTaskProgress );
338 connect( actionTaskProgress, SIGNAL(triggered(bool)), SLOT(slotTaskProgress()) );
339 actionDeleteTask = new KAction(koIcon("edit-delete"), i18n("Delete Task"), this);
340 actionCollection()->addAction("delete_task", actionDeleteTask );
341 connect( actionDeleteTask, SIGNAL(triggered(bool)), SLOT(slotDeleteTask()) );
342 actionTaskDescription = new KAction(koIcon("document-edit"), i18n("Description..."), this);
343 actionCollection()->addAction("task_description", actionTaskDescription );
344 connect( actionTaskDescription, SIGNAL(triggered(bool)), SLOT(slotTaskDescription()) );
345 actionIndentTask = new KAction(koIcon("format-indent-more"), i18n("Indent Task"), this);
346 actionCollection()->addAction("indent_task", actionIndentTask );
347 connect( actionIndentTask, SIGNAL(triggered(bool)), SLOT(slotIndentTask()) );
348 actionUnindentTask= new KAction(koIcon("format-indent-less"), i18n("Unindent Task"), this);
349 actionCollection()->addAction("unindent_task", actionUnindentTask );
350 connect( actionUnindentTask, SIGNAL(triggered(bool)), SLOT(slotUnindentTask()) );
351 actionMoveTaskUp = new KAction(koIcon("arrow-up"), i18n("Move Task Up"), this);
352 actionCollection()->addAction("move_task_up", actionMoveTaskUp );
353 connect( actionMoveTaskUp, SIGNAL(triggered(bool)), SLOT(slotMoveTaskUp()) );
354 actionMoveTaskDown = new KAction(koIcon("arrow-down"), i18n("Move Task Down"), this);
355 actionCollection()->addAction("move_task_down", actionMoveTaskDown );
356 connect( actionMoveTaskDown, SIGNAL(triggered(bool)), SLOT(slotMoveTaskDown()) );
357
358 actionEditResource = new KAction(koIcon("document-edit"), i18n("Edit Resource..."), this);
359 actionCollection()->addAction("edit_resource", actionEditResource );
360 connect( actionEditResource, SIGNAL(triggered(bool)), SLOT(slotEditResource()) );
361
362 actionEditRelation = new KAction(koIcon("document-edit"), i18n("Edit Dependency..."), this);
363 actionCollection()->addAction("edit_dependency", actionEditRelation );
364 connect( actionEditRelation, SIGNAL(triggered(bool)), SLOT(slotModifyRelation()) );
365 actionDeleteRelation = new KAction(koIcon("edit-delete"), i18n("Delete Dependency"), this);
366 actionCollection()->addAction("delete_dependency", actionDeleteRelation );
367 connect( actionDeleteRelation, SIGNAL(triggered(bool)), SLOT(slotDeleteRelation()) );
368
369 // Viewlist popup
370 connect( m_viewlist, SIGNAL(createView()), SLOT(slotCreateView()) );
371
372 m_estlabel = new QLabel( "", 0 );
373 if ( statusBar() ) {
374 addStatusBarItem( m_estlabel, 0, true );
375 }
376
377 connect( &getProject(), SIGNAL(scheduleChanged(MainSchedule*)), SLOT(slotScheduleChanged(MainSchedule*)) );
378
379 connect( &getProject(), SIGNAL(scheduleAdded(const MainSchedule*)), SLOT(slotScheduleAdded(const MainSchedule*)) );
380 connect( &getProject(), SIGNAL(scheduleRemoved(const MainSchedule*)), SLOT(slotScheduleRemoved(const MainSchedule*)) );
381 slotPlugScheduleActions();
382
383 connect( doc, SIGNAL(changed()), SLOT(slotUpdate()) );
384
385 connect( m_scheduleActionGroup, SIGNAL(triggered(QAction*)), SLOT(slotViewSchedule(QAction*)) );
386
387
388 connect( getPart(), SIGNAL(workPackageLoaded()), SLOT(slotWorkPackageLoaded()) );
389
390 // hide unused dockers
391 QTimer::singleShot( 0, this, SLOT(hideToolDocker()) );
392 // create views after dockers hidden, views take time for large projects
393 QTimer::singleShot( 100, this, SLOT(initiateViews()) );
394
395 KService::List offers = KServiceTypeTrader::self()->query(QString::fromLatin1("Plan/ViewPlugin"),
396 QString::fromLatin1("(Type == 'Service') and "
397 "([X-Plan-Version] == 28)"));
398
399 KService::List::ConstIterator iter;
400 for(iter = offers.constBegin(); iter != offers.constEnd(); ++iter) {
401
402 KService::Ptr service = *iter;
403 QString error;
404 KXMLGUIClient* plugin =
405 dynamic_cast<KXMLGUIClient*>(service->createInstance<QObject>(this, QVariantList(), &error));
406 if(plugin) {
407 insertChildClient(plugin);
408 } else {
409 if(!error.isEmpty()) {
410 kWarning() << " Error loading plugin was : ErrNoLibrary" << error;
411 }
412 }
413 }
414
415 //kDebug(planDbg())<<" end";
416}
417
418View::~View()
419{
420/* removeStatusBarItem( m_estlabel );
421 delete m_estlabel;*/
422}
423
424// hackish way to get rid of unused dockers, but as long as no official way exists...
425void View::hideToolDocker()
426{
427 if ( mainWindow() ) {
428 QStringList lst; lst << "KPlatoViewList" << "Scripting";
429 QStringList names;
430 foreach ( QDockWidget *w, mainWindow()->dockWidgets() ) {
431 if ( ! lst.contains( w->objectName() ) ) {
432 names << w->windowTitle();
433 w->setFeatures( QDockWidget::DockWidgetClosable );
434 w->hide();
435 }
436 }
437 foreach(const KActionCollection *c, KActionCollection::allCollections()) {
438 KActionMenu *a = qobject_cast<KActionMenu*>(c->action("settings_dockers_menu"));
439 if ( a ) {
440 QList<QAction*> actions = a->menu()->actions();
441 foreach ( QAction *act, actions ) {
442 if ( names.contains( act->text() ) ) {
443 a->removeAction( act );
444 }
445 }
446 a->addSeparator();
447 break;
448 }
449 }
450 }
451}
452
453void View::initiateViews()
454{
455 QApplication::setOverrideCursor( Qt::WaitCursor );
456 createViews();
457
458 connect( m_viewlist, SIGNAL(activated(ViewListItem*,ViewListItem*)), SLOT(slotViewActivated(ViewListItem*,ViewListItem*)) );
459 // after createViews() !!
460 connect( m_viewlist, SIGNAL(viewListItemRemoved(ViewListItem*)), SLOT(slotViewListItemRemoved(ViewListItem*)) );
461 // after createViews() !!
462 connect( m_viewlist, SIGNAL(viewListItemInserted(ViewListItem*,ViewListItem*,int)), SLOT(slotViewListItemInserted(ViewListItem*,ViewListItem*,int)) );
463
464 QDockWidget *docker = qobject_cast<QDockWidget*>( m_viewlist->parent() );
465 if ( docker ) {
466 // after createViews() !!
467 connect( m_viewlist, SIGNAL(modified()), docker, SLOT(slotModified()));
468 connect( m_viewlist, SIGNAL(modified()), getPart(), SLOT(viewlistModified()));
469 connect(getPart(), SIGNAL(viewlistModified(bool)), docker, SLOT(updateWindowTitle(bool)));
470 }
471 connect( m_tab, SIGNAL(currentChanged(int)), this, SLOT(slotCurrentChanged(int)) );
472
473 loadContext();
474
475 QApplication::restoreOverrideCursor();
476}
477
478void View::slotCreateTemplate()
479{
480 KoTemplateCreateDia::createTemplate("plan_template", ".plant",
481 Factory::global(), getPart(), this);
482}
483
484void View::slotCreateNewProject()
485{
486 kDebug(planDbg());
487 if ( KMessageBox::Continue == KMessageBox::warningContinueCancel( this,
488 i18nc( "@info",
489 "<note>This action cannot be undone.</note><nl/><nl/>"
490 "Create a new Project from the current project "
491 "with new project- and task identities.<nl/>"
492 "Resource- and calendar identities are not changed.<nl/>"
493 "All scheduling information is removed.<nl/>"
494 "<nl/>Do you want to continue?" ) ) )
495 {
496 getPart()->createNewProject();
497 slotOpenNode( &getProject() );
498 }
499}
500
501void View::createViews()
502{
503 Context *ctx = getPart()->context();
504 if ( ctx && ctx->isLoaded() ) {
505 kDebug(planDbg())<<"isLoaded";
506 KoXmlNode n = ctx->context().namedItem( "categories" );
507 if ( n.isNull() ) {
508 kWarning()<<"No categories";
509 } else {
510 n = n.firstChild();
511 for ( ; ! n.isNull(); n = n.nextSibling() ) {
512 if ( ! n.isElement() ) {
513 continue;
514 }
515 KoXmlElement e = n.toElement();
516 if (e.tagName() != "category") {
517 continue;
518 }
519 kDebug(planDbg())<<"category: "<<e.attribute( "tag" );
520 ViewListItem *cat;
521 QString cn = e.attribute( "name" );
522 QString ct = e.attribute( "tag" );
523 if ( cn.isEmpty() ) {
524 cn = defaultCategoryInfo( ct ).name;
525 }
526 cat = m_viewlist->addCategory( ct, cn );
527 KoXmlNode n1 = e.firstChild();
528 for ( ; ! n1.isNull(); n1 = n1.nextSibling() ) {
529 if ( ! n1.isElement() ) {
530 continue;
531 }
532 KoXmlElement e1 = n1.toElement();
533 if (e1.tagName() != "view") {
534 continue;
535 }
536 ViewBase *v = 0;
537 QString type = e1.attribute( "viewtype" );
538 QString tag = e1.attribute( "tag" );
539 QString name = e1.attribute( "name" );
540 QString tip = e1.attribute( "tooltip" );
541 v = createView( cat, type, tag, name, tip );
542 //KoXmlNode settings = e1.namedItem( "settings " ); ????
543 KoXmlNode settings = e1.firstChild();
544 for ( ; ! settings.isNull(); settings = settings.nextSibling() ) {
545 if ( settings.nodeName() == "settings" ) {
546 break;
547 }
548 }
549 if ( v && settings.isElement() ) {
550 kDebug(planDbg())<<" settings";
551 v->loadContext( settings.toElement() );
552 }
553 }
554 }
555 }
556 } else {
557 kDebug(planDbg())<<"Default";
558 ViewListItem *cat;
559 QString ct = "Editors";
560 cat = m_viewlist->addCategory( ct, defaultCategoryInfo( ct ).name );
561
562 createCalendarEditor( cat, "CalendarEditor", QString(), TIP_USE_DEFAULT_TEXT );
563
564 createAccountsEditor( cat, "AccountsEditor", QString(), TIP_USE_DEFAULT_TEXT );
565
566 createResourceEditor( cat, "ResourceEditor", QString(), TIP_USE_DEFAULT_TEXT );
567
568 createTaskEditor( cat, "TaskEditor", QString(), TIP_USE_DEFAULT_TEXT );
569
570 createDependencyEditor( cat, "DependencyEditor", QString(), TIP_USE_DEFAULT_TEXT );
571
572 createPertEditor( cat, "PertEditor", QString(), TIP_USE_DEFAULT_TEXT );
573
574 createScheduleHandler( cat, "ScheduleHandlerView", QString(), TIP_USE_DEFAULT_TEXT );
575
576 ct = "Views";
577 cat = m_viewlist->addCategory( ct, defaultCategoryInfo( ct ).name );
578
579 createGanttView( cat, "GanttView", QString(), TIP_USE_DEFAULT_TEXT );
580
581 createMilestoneGanttView( cat, "MilestoneGanttView", QString(), TIP_USE_DEFAULT_TEXT );
582
583 createResourceAppointmentsView( cat, "ResourceAppointmentsView", QString(), TIP_USE_DEFAULT_TEXT );
584
585 createResourceAppointmentsGanttView( cat, "ResourceAppointmentsGanttView", QString(), TIP_USE_DEFAULT_TEXT );
586
587 createAccountsView( cat, "AccountsView", QString(), TIP_USE_DEFAULT_TEXT );
588
589 ct = "Execution";
590 cat = m_viewlist->addCategory( ct, defaultCategoryInfo( ct ).name );
591
592 createProjectStatusView( cat, "ProjectStatusView", QString(), TIP_USE_DEFAULT_TEXT );
593
594 createPerformanceStatusView( cat, "PerformanceStatusView", QString(), TIP_USE_DEFAULT_TEXT );
595
596 createTaskStatusView( cat, "TaskStatusView", QString(), TIP_USE_DEFAULT_TEXT );
597
598 createTaskView( cat, "TaskView", QString(), TIP_USE_DEFAULT_TEXT );
599
600 createTaskWorkPackageView( cat, "TaskWorkPackageView", QString(), TIP_USE_DEFAULT_TEXT );
601
602 ct = "Reports";
603 cat = m_viewlist->addCategory( ct, defaultCategoryInfo( ct ).name );
604 // A little hack to get the user started...
605 ReportView *rv = qobject_cast<ReportView*>( createReportView( cat, "ReportView", i18n( "Task Status Report" ), TIP_USE_DEFAULT_TEXT ) );
606 if ( rv ) {
607 QDomDocument doc;
608 doc.setContent( standardTaskStatusReport() );
609 rv->loadXML( doc );
610 }
611 }
612}
613
614ViewBase *View::createView( ViewListItem *cat, const QString &type, const QString &tag, const QString &name, const QString &tip, int index )
615{
616 ViewBase *v = 0;
617 //NOTE: type is the same as classname (so if it is changed...)
618 if ( type == "CalendarEditor" ) {
619 v = createCalendarEditor( cat, tag, name, tip, index );
620 } else if ( type == "AccountsEditor" ) {
621 v = createAccountsEditor( cat, tag, name, tip, index );
622 } else if ( type == "ResourceEditor" ) {
623 v = createResourceEditor( cat, tag, name, tip, index );
624 } else if ( type == "TaskEditor" ) {
625 v = createTaskEditor( cat, tag, name, tip, index );
626 } else if ( type == "DependencyEditor" ) {
627 v = createDependencyEditor( cat, tag, name, tip, index );
628 } else if ( type == "PertEditor" ) {
629 v = createPertEditor( cat, tag, name, tip, index );
630 } else if ( type == "ScheduleEditor" ) {
631 v = createScheduleEditor( cat, tag, name, tip, index );
632 } else if ( type == "ScheduleHandlerView" ) {
633 v = createScheduleHandler( cat, tag, name, tip, index );
634 } else if ( type == "ProjectStatusView" ) {
635 v = createProjectStatusView( cat, tag, name, tip, index );
636 } else if ( type == "TaskStatusView" ) {
637 v = createTaskStatusView( cat, tag, name, tip, index );
638 } else if ( type == "TaskView" ) {
639 v = createTaskView( cat, tag, name, tip, index );
640 } else if ( type == "TaskWorkPackageView" ) {
641 v = createTaskWorkPackageView( cat, tag, name, tip, index );
642 } else if ( type == "GanttView" ) {
643 v = createGanttView( cat, tag, name, tip, index );
644 } else if ( type == "MilestoneGanttView" ) {
645 v = createMilestoneGanttView( cat, tag, name, tip, index );
646 } else if ( type == "ResourceAppointmentsView" ) {
647 v = createResourceAppointmentsView( cat, tag, name, tip, index );
648 } else if ( type == "ResourceAppointmentsGanttView" ) {
649 v = createResourceAppointmentsGanttView( cat, tag, name, tip, index );
650 } else if ( type == "AccountsView" ) {
651 v = createAccountsView( cat, tag, name, tip, index );
652 } else if ( type == "PerformanceStatusView" ) {
653 v = createPerformanceStatusView( cat, tag, name, tip, index );
654 } else if ( type == "ReportView" ) {
655 v = createReportView( cat, tag, name, tip, index );
656 } else {
657 kWarning()<<"Unknown viewtype: "<<type;
658 }
659 return v;
660}
661
662void View::slotUpdateViewInfo( ViewListItem *itm )
663{
664 if ( itm->type() == ViewListItem::ItemType_SubView ) {
665 itm->setViewInfo( defaultViewInfo( itm->viewType() ) );
666 } else if ( itm->type() == ViewListItem::ItemType_Category ) {
667 ViewInfo vi = defaultCategoryInfo( itm->tag() );
668 itm->setViewInfo( vi );
669 }
670}
671
672ViewInfo View::defaultViewInfo( const QString &type ) const
673{
674 ViewInfo vi;
675 if ( type == "CalendarEditor" ) {
676 vi.name = i18n( "Work & Vacation" );
677 vi.tip = i18nc( "@info:tooltip", "Edit working- and vacation days for resources" );
678 } else if ( type == "AccountsEditor" ) {
679 vi.name = i18n( "Cost Breakdown Structure" );
680 vi.tip = i18nc( "@info:tooltip", "Edit cost breakdown structure." );
681 } else if ( type == "ResourceEditor" ) {
682 vi.name = i18n( "Resources" );
683 vi.tip = i18nc( "@info:tooltip", "Edit resource breakdown structure" );
684 } else if ( type == "TaskEditor" ) {
685 vi.name = i18n( "Tasks" );
686 vi.tip = i18nc( "@info:tooltip", "Edit work breakdown structure" );
687 } else if ( type == "DependencyEditor" ) {
688 vi.name = i18n( "Dependencies (Graphic)" );
689 vi.tip = i18nc( "@info:tooltip", "Edit task dependencies" );
690 } else if ( type == "PertEditor" ) {
691 vi.name = i18n( "Dependencies (List)" );
692 vi.tip = i18nc( "@info:tooltip", "Edit task dependencies" );
693 } else if ( type == "ScheduleEditor" ) {
694 // This view is not used stand-alone atm
695 vi.name = i18n( "Schedules" );
696 } else if ( type == "ScheduleHandlerView" ) {
697 vi.name = i18n( "Schedules" );
698 vi.tip = i18nc( "@info:tooltip", "Calculate and analyze project schedules" );
699 } else if ( type == "ProjectStatusView" ) {
700 vi.name = i18n( "Project Performance Chart" );
701 vi.tip = i18nc( "@info:tooltip", "View project status information" );
702 } else if ( type == "TaskStatusView" ) {
703 vi.name = i18n( "Task Status" );
704 vi.tip = i18nc( "@info:tooltip", "View task progress information" );
705 } else if ( type == "TaskView" ) {
706 vi.name = i18n( "Task Execution" );
707 vi.tip = i18nc( "@info:tooltip", "View task execution information" );
708 } else if ( type == "TaskWorkPackageView" ) {
709 vi.name = i18n( "Work Package View" );
710 vi.tip = i18nc( "@info:tooltip", "View task work package information" );
711 } else if ( type == "GanttView" ) {
712 vi.name = i18n( "Gantt" );
713 vi.tip = i18nc( "@info:tooltip", "View Gantt chart" );
714 } else if ( type == "MilestoneGanttView" ) {
715 vi.name = i18n( "Milestone Gantt" );
716 vi.tip = i18nc( "@info:tooltip", "View milestone Gantt chart" );
717 } else if ( type == "ResourceAppointmentsView" ) {
718 vi.name = i18n( "Resource Assignments" );
719 vi.tip = i18nc( "@info:tooltip", "View resource assignments in a table" );
720 } else if ( type == "ResourceAppointmentsGanttView" ) {
721 vi.name = i18n( "Resource Assignments (Gantt)" );
722 vi.tip = i18nc( "@info:tooltip", "View resource assignments in Gantt chart" );
723 } else if ( type == "AccountsView" ) {
724 vi.name = i18n( "Cost Breakdown" );
725 vi.tip = i18nc( "@info:tooltip", "View planned and actual cost" );
726 } else if ( type == "PerformanceStatusView" ) {
727 vi.name = i18n( "Tasks Performance Chart" );
728 vi.tip = i18nc( "@info:tooltip", "View tasks performance status information" );
729 } else if ( type == "ReportView" ) {
730 vi.name = i18n( "Report" );
731 vi.tip = i18nc( "@info:tooltip", "View report" );
732 } else {
733 kWarning()<<"Unknown viewtype: "<<type;
734 }
735 return vi;
736}
737
738ViewInfo View::defaultCategoryInfo( const QString &type ) const
739{
740 ViewInfo vi;
741 if ( type == "Editors" ) {
742 vi.name = i18n( "Editors" );
743 } else if ( type == "Views" ) {
744 vi.name = i18n( "Views" );
745 } else if ( type == "Execution" ) {
746 vi.name = i18nc( "Project execution views", "Execution" );
747 } else if ( type == "Reports" ) {
748 vi.name = i18n( "Reports" );
749 }
750 return vi;
751}
752
753void View::slotOpenUrlRequest( HtmlView *v, const KUrl &url )
754{
755 if ( url.url().startsWith( QLatin1String( "about:plan" ) ) ) {
756 getPart()->aboutPage().generatePage( v->htmlPart(), url );
757 return;
758 }
759 if ( url.protocol() == "help" ) {
760 KToolInvocation::invokeHelp( "", url.fileName() );
761 return;
762 }
763 // try to open the url
764 new KRun( url, mainWindow() );
765}
766
767ViewBase *View::createWelcomeView()
768{
769 HtmlView *v = new HtmlView(getKoPart(), getPart(), m_tab );
770 v->htmlPart().setJScriptEnabled(false);
771 v->htmlPart().setJavaEnabled(false);
772 v->htmlPart().setMetaRefreshEnabled(false);
773 v->htmlPart().setPluginsEnabled(false);
774
775 slotOpenUrlRequest( v, KUrl( "about:plan/main" ) );
776
777 connect( v, SIGNAL(openUrlRequest(HtmlView*,KUrl)), SLOT(slotOpenUrlRequest(HtmlView*,KUrl)) );
778
779 m_tab->addWidget( v );
780 return v;
781}
782
783ViewBase *View::createResourceAppointmentsGanttView( ViewListItem *cat, const QString &tag, const QString &name, const QString &tip, int index )
784{
785 ResourceAppointmentsGanttView *v = new ResourceAppointmentsGanttView(getKoPart(), getPart(), m_tab );
786 m_tab->addWidget( v );
787
788 ViewListItem *i = m_viewlist->addView( cat, tag, name, v, getPart(), "", index );
789 ViewInfo vi = defaultViewInfo( "ResourceAppointmentsGanttView" );
790 if ( name.isEmpty() ) {
791 i->setText( 0, vi.name );
792 }
793 if ( tip == TIP_USE_DEFAULT_TEXT ) {
794 i->setToolTip( 0, vi.tip );
795 } else {
796 i->setToolTip( 0, tip );
797 }
798
799
800 connect( v, SIGNAL(guiActivated(ViewBase*,bool)), SLOT(slotGuiActivated(ViewBase*,bool)) );
801
802 connect( this, SIGNAL(currentScheduleManagerChanged(ScheduleManager*)), v, SLOT(setScheduleManager(ScheduleManager*)) );
803
804 connect( v, SIGNAL(requestPopupMenu(QString,QPoint)), this, SLOT(slotPopupMenu(QString,QPoint)) );
805
806 v->setProject( &( getProject() ) );
807 v->setScheduleManager( currentScheduleManager() );
808 v->updateReadWrite( m_readWrite );
809 return v;
810}
811
812
813ViewBase *View::createResourceAppointmentsView( ViewListItem *cat, const QString &tag, const QString &name, const QString &tip, int index )
814{
815 ResourceAppointmentsView *v = new ResourceAppointmentsView(getKoPart(), getPart(), m_tab );
816 m_tab->addWidget( v );
817
818 ViewListItem *i = m_viewlist->addView( cat, tag, name, v, getPart(), "", index );
819 ViewInfo vi = defaultViewInfo( "ResourceAppointmentsView" );
820 if ( name.isEmpty() ) {
821 i->setText( 0, vi.name );
822 }
823 if ( tip == TIP_USE_DEFAULT_TEXT ) {
824 i->setToolTip( 0, vi.tip );
825 } else {
826 i->setToolTip( 0, tip );
827 }
828
829 connect( v, SIGNAL(guiActivated(ViewBase*,bool)), SLOT(slotGuiActivated(ViewBase*,bool)) );
830
831 connect( this, SIGNAL(currentScheduleManagerChanged(ScheduleManager*)), v, SLOT(setScheduleManager(ScheduleManager*)) );
832
833 connect( v, SIGNAL(requestPopupMenu(QString,QPoint)), this, SLOT(slotPopupMenu(QString,QPoint)) );
834
835 v->setProject( &( getProject() ) );
836 v->setScheduleManager( currentScheduleManager() );
837 v->updateReadWrite( m_readWrite );
838 return v;
839}
840
841ViewBase *View::createResourceEditor( ViewListItem *cat, const QString &tag, const QString &name, const QString &tip, int index )
842{
843 ResourceEditor *resourceeditor = new ResourceEditor(getKoPart(), getPart(), m_tab );
844 m_tab->addWidget( resourceeditor );
845 resourceeditor->setProject( &(getProject()) );
846
847 ViewListItem *i = m_viewlist->addView( cat, tag, name, resourceeditor, getPart(), "", index );
848 ViewInfo vi = defaultViewInfo( "ResourceEditor" );
849 if ( name.isEmpty() ) {
850 i->setText( 0, vi.name );
851 }
852 if ( tip == TIP_USE_DEFAULT_TEXT ) {
853 i->setToolTip( 0, vi.tip );
854 } else {
855 i->setToolTip( 0, tip );
856 }
857
858 connect( resourceeditor, SIGNAL(guiActivated(ViewBase*,bool)), SLOT(slotGuiActivated(ViewBase*,bool)) );
859
860 connect( resourceeditor, SIGNAL(deleteObjectList(QObjectList)), SLOT(slotDeleteResourceObjects(QObjectList)) );
861
862 connect( resourceeditor, SIGNAL(requestPopupMenu(QString,QPoint)), this, SLOT(slotPopupMenu(QString,QPoint)) );
863 resourceeditor->updateReadWrite( m_readWrite );
864 return resourceeditor;
865}
866
867ViewBase *View::createTaskEditor( ViewListItem *cat, const QString &tag, const QString &name, const QString &tip, int index )
868{
869 TaskEditor *taskeditor = new TaskEditor(getKoPart(), getPart(), m_tab );
870 m_tab->addWidget( taskeditor );
871
872 ViewListItem *i = m_viewlist->addView( cat, tag, name, taskeditor, getPart(), "", index );
873 ViewInfo vi = defaultViewInfo( "TaskEditor" );
874 if ( name.isEmpty() ) {
875 i->setText( 0, vi.name );
876 }
877 if ( tip == TIP_USE_DEFAULT_TEXT ) {
878 i->setToolTip( 0, vi.tip );
879 } else {
880 i->setToolTip( 0, tip );
881 }
882
883 taskeditor->setProject( &(getProject()) );
884 taskeditor->setScheduleManager( currentScheduleManager() );
885
886 connect( this, SIGNAL(currentScheduleManagerChanged(ScheduleManager*)), taskeditor, SLOT(setScheduleManager(ScheduleManager*)) );
887
888 connect( taskeditor, SIGNAL(guiActivated(ViewBase*,bool)), SLOT(slotGuiActivated(ViewBase*,bool)) );
889
890 connect( taskeditor, SIGNAL(addTask()), SLOT(slotAddTask()) );
891 connect( taskeditor, SIGNAL(addMilestone()), SLOT(slotAddMilestone()) );
892 connect( taskeditor, SIGNAL(addSubtask()), SLOT(slotAddSubTask()) );
893 connect( taskeditor, SIGNAL(addSubMilestone()), SLOT(slotAddSubMilestone()) );
894 connect( taskeditor, SIGNAL(deleteTaskList(QList<Node*>)), SLOT(slotDeleteTask(QList<Node*>)) );
895 connect( taskeditor, SIGNAL(moveTaskUp()), SLOT(slotMoveTaskUp()) );
896 connect( taskeditor, SIGNAL(moveTaskDown()), SLOT(slotMoveTaskDown()) );
897 connect( taskeditor, SIGNAL(indentTask()), SLOT(slotIndentTask()) );
898 connect( taskeditor, SIGNAL(unindentTask()), SLOT(slotUnindentTask()) );
899
900 connect(taskeditor, SIGNAL(saveTaskModule(KUrl,Project*)), SLOT(saveTaskModule(KUrl,Project*)));
901 connect(taskeditor, SIGNAL(removeTaskModule(KUrl)), SLOT(removeTaskModule(KUrl)));
902
903 connect( taskeditor, SIGNAL(requestPopupMenu(QString,QPoint)), this, SLOT(slotPopupMenu(QString,QPoint)) );
904 taskeditor->updateReadWrite( m_readWrite );
905
906 // last:
907 taskeditor->setTaskModules( Factory::global().dirs()->findAllResources( "plan_taskmodules", QString(), KStandardDirs::NoDuplicates ) );
908 return taskeditor;
909}
910
911ViewBase *View::createAccountsEditor( ViewListItem *cat, const QString &tag, const QString &name, const QString &tip, int index )
912{
913 AccountsEditor *ae = new AccountsEditor(getKoPart(), getPart(), m_tab );
914 m_tab->addWidget( ae );
915
916 ViewListItem *i = m_viewlist->addView( cat, tag, name, ae, getPart(), "", index );
917 ViewInfo vi = defaultViewInfo( "AccountsEditor" );
918 if ( name.isEmpty() ) {
919 i->setText( 0, vi.name );
920 }
921 if ( tip == TIP_USE_DEFAULT_TEXT ) {
922 i->setToolTip( 0, vi.tip );
923 } else {
924 i->setToolTip( 0, tip );
925 }
926
927 ae->draw( getProject() );
928
929 connect( ae, SIGNAL(guiActivated(ViewBase*,bool)), SLOT(slotGuiActivated(ViewBase*,bool)) );
930 ae->updateReadWrite( m_readWrite );
931 return ae;
932}
933
934ViewBase *View::createCalendarEditor( ViewListItem *cat, const QString &tag, const QString &name, const QString &tip, int index )
935{
936 CalendarEditor *calendareditor = new CalendarEditor(getKoPart(), getPart(), m_tab );
937 m_tab->addWidget( calendareditor );
938
939 ViewListItem *i = m_viewlist->addView( cat, tag, name, calendareditor, getPart(), "", index );
940 ViewInfo vi = defaultViewInfo( "CalendarEditor" );
941 if ( name.isEmpty() ) {
942 i->setText( 0, vi.name );
943 }
944 if ( tip == TIP_USE_DEFAULT_TEXT ) {
945 i->setToolTip( 0, vi.tip );
946 } else {
947 i->setToolTip( 0, tip );
948 }
949
950 calendareditor->draw( getProject() );
951
952 connect( calendareditor, SIGNAL(guiActivated(ViewBase*,bool)), SLOT(slotGuiActivated(ViewBase*,bool)) );
953
954 connect( calendareditor, SIGNAL(requestPopupMenu(QString,QPoint)), this, SLOT(slotPopupMenu(QString,QPoint)) );
955 calendareditor->updateReadWrite( m_readWrite );
956 return calendareditor;
957}
958
959ViewBase *View::createScheduleHandler( ViewListItem *cat, const QString &tag, const QString &name, const QString &tip, int index )
960{
961 ScheduleHandlerView *handler = new ScheduleHandlerView(getKoPart(), getPart(), m_tab );
962 m_tab->addWidget( handler );
963
964 ViewListItem *i = m_viewlist->addView( cat, tag, name, handler, getPart(), "", index );
965 ViewInfo vi = defaultViewInfo( "ScheduleHandlerView" );
966 if ( name.isEmpty() ) {
967 i->setText( 0, vi.name );
968 }
969 if ( tip == TIP_USE_DEFAULT_TEXT ) {
970 i->setToolTip( 0, vi.tip );
971 } else {
972 i->setToolTip( 0, tip );
973 }
974
975 connect( handler->scheduleEditor(), SIGNAL(addScheduleManager(Project*)), SLOT(slotAddScheduleManager(Project*)) );
976 connect( handler->scheduleEditor(), SIGNAL(deleteScheduleManager(Project*,ScheduleManager*)), SLOT(slotDeleteScheduleManager(Project*,ScheduleManager*)) );
977 connect( handler->scheduleEditor(), SIGNAL(moveScheduleManager(ScheduleManager*,ScheduleManager*,int)), SLOT(slotMoveScheduleManager(ScheduleManager*,ScheduleManager*,int)));
978
979 connect( handler->scheduleEditor(), SIGNAL(calculateSchedule(Project*,ScheduleManager*)), SLOT(slotCalculateSchedule(Project*,ScheduleManager*)) );
980
981 connect( handler->scheduleEditor(), SIGNAL(baselineSchedule(Project*,ScheduleManager*)), SLOT(slotBaselineSchedule(Project*,ScheduleManager*)) );
982
983
984 connect( handler, SIGNAL(guiActivated(ViewBase*,bool)), SLOT(slotGuiActivated(ViewBase*,bool)) );
985
986 connect( this, SIGNAL(currentScheduleManagerChanged(ScheduleManager*)), handler, SIGNAL(currentScheduleManagerChanged(ScheduleManager*)) );
987
988 connect( handler, SIGNAL(requestPopupMenu(QString,QPoint)), this, SLOT(slotPopupMenu(QString,QPoint)) );
989
990 connect(handler, SIGNAL(editNode(Node*)), this, SLOT(slotOpenNode(Node*)));
991 connect(handler, SIGNAL(editResource(Resource*)), this, SLOT(slotEditResource(Resource*)));
992
993 handler->draw( getProject() );
994 handler->updateReadWrite( m_readWrite );
995 return handler;
996}
997
998ScheduleEditor *View::createScheduleEditor( QWidget *parent )
999{
1000 ScheduleEditor *scheduleeditor = new ScheduleEditor(getKoPart(), getPart(), parent );
1001
1002 connect( scheduleeditor, SIGNAL(addScheduleManager(Project*)), SLOT(slotAddScheduleManager(Project*)) );
1003 connect( scheduleeditor, SIGNAL(deleteScheduleManager(Project*,ScheduleManager*)), SLOT(slotDeleteScheduleManager(Project*,ScheduleManager*)) );
1004
1005 connect( scheduleeditor, SIGNAL(calculateSchedule(Project*,ScheduleManager*)), SLOT(slotCalculateSchedule(Project*,ScheduleManager*)) );
1006
1007 connect( scheduleeditor, SIGNAL(baselineSchedule(Project*,ScheduleManager*)), SLOT(slotBaselineSchedule(Project*,ScheduleManager*)) );
1008
1009 scheduleeditor->updateReadWrite( m_readWrite );
1010 return scheduleeditor;
1011}
1012
1013ViewBase *View::createScheduleEditor( ViewListItem *cat, const QString &tag, const QString &name, const QString &tip, int index )
1014{
1015 ScheduleEditor *scheduleeditor = new ScheduleEditor(getKoPart(), getPart(), m_tab );
1016 m_tab->addWidget( scheduleeditor );
1017
1018 ViewListItem *i = m_viewlist->addView( cat, tag, name, scheduleeditor, getPart(), "", index );
1019 ViewInfo vi = defaultViewInfo( "ScheduleEditor" );
1020 if ( name.isEmpty() ) {
1021 i->setText( 0, vi.name );
1022 }
1023 if ( tip == TIP_USE_DEFAULT_TEXT ) {
1024 i->setToolTip( 0, vi.tip );
1025 } else {
1026 i->setToolTip( 0, tip );
1027 }
1028
1029 scheduleeditor->setProject( &( getProject() ) );
1030
1031 connect( scheduleeditor, SIGNAL(guiActivated(ViewBase*,bool)), SLOT(slotGuiActivated(ViewBase*,bool)) );
1032
1033 connect( scheduleeditor, SIGNAL(addScheduleManager(Project*)), SLOT(slotAddScheduleManager(Project*)) );
1034
1035 connect( scheduleeditor, SIGNAL(deleteScheduleManager(Project*,ScheduleManager*)), SLOT(slotDeleteScheduleManager(Project*,ScheduleManager*)) );
1036
1037 connect( scheduleeditor, SIGNAL(calculateSchedule(Project*,ScheduleManager*)), SLOT(slotCalculateSchedule(Project*,ScheduleManager*)) );
1038
1039 connect( scheduleeditor, SIGNAL(baselineSchedule(Project*,ScheduleManager*)), SLOT(slotBaselineSchedule(Project*,ScheduleManager*)) );
1040
1041 scheduleeditor->updateReadWrite( m_readWrite );
1042 return scheduleeditor;
1043}
1044
1045
1046ViewBase *View::createDependencyEditor( ViewListItem *cat, const QString &tag, const QString &name, const QString &tip, int index )
1047{
1048 DependencyEditor *editor = new DependencyEditor(getKoPart(), getPart(), m_tab );
1049 m_tab->addWidget( editor );
1050
1051 ViewListItem *i = m_viewlist->addView( cat, tag, name, editor, getPart(), "", index );
1052 ViewInfo vi = defaultViewInfo( "DependencyEditor" );
1053 if ( name.isEmpty() ) {
1054 i->setText( 0, vi.name );
1055 }
1056 if ( tip == TIP_USE_DEFAULT_TEXT ) {
1057 i->setToolTip( 0, vi.tip );
1058 } else {
1059 i->setToolTip( 0, tip );
1060 }
1061
1062 editor->draw( getProject() );
1063
1064 connect( editor, SIGNAL(guiActivated(ViewBase*,bool)), SLOT(slotGuiActivated(ViewBase*,bool)) );
1065
1066 connect( editor, SIGNAL(addRelation(Node*,Node*,int)), SLOT(slotAddRelation(Node*,Node*,int)) );
1067 connect( editor, SIGNAL(modifyRelation(Relation*,int)), SLOT(slotModifyRelation(Relation*,int)) );
1068 connect( editor, SIGNAL(modifyRelation(Relation*)), SLOT(slotModifyRelation(Relation*)) );
1069
1070 connect( editor, SIGNAL(editNode(Node*)), SLOT(slotOpenNode(Node*)) );
1071 connect( editor, SIGNAL(addTask()), SLOT(slotAddTask()) );
1072 connect( editor, SIGNAL(addMilestone()), SLOT(slotAddMilestone()) );
1073 connect( editor, SIGNAL(addSubMilestone()), SLOT(slotAddSubMilestone()) );
1074 connect( editor, SIGNAL(addSubtask()), SLOT(slotAddSubTask()) );
1075 connect( editor, SIGNAL(deleteTaskList(QList<Node*>)), SLOT(slotDeleteTask(QList<Node*>)) );
1076
1077 connect( this, SIGNAL(currentScheduleManagerChanged(ScheduleManager*)), editor, SLOT(setScheduleManager(ScheduleManager*)) );
1078
1079 connect( editor, SIGNAL(requestPopupMenu(QString,QPoint)), this, SLOT(slotPopupMenu(QString,QPoint)) );
1080 editor->updateReadWrite( m_readWrite );
1081 editor->setScheduleManager( currentScheduleManager() );
1082 return editor;
1083}
1084
1085ViewBase *View::createPertEditor( ViewListItem *cat, const QString &tag, const QString &name, const QString &tip, int index )
1086{
1087 PertEditor *perteditor = new PertEditor(getKoPart(), getPart(), m_tab );
1088 m_tab->addWidget( perteditor );
1089
1090 ViewListItem *i = m_viewlist->addView( cat, tag, name, perteditor, getPart(), "", index );
1091 ViewInfo vi = defaultViewInfo( "PertEditor" );
1092 if ( name.isEmpty() ) {
1093 i->setText( 0, vi.name );
1094 }
1095 if ( tip == TIP_USE_DEFAULT_TEXT ) {
1096 i->setToolTip( 0, vi.tip );
1097 } else {
1098 i->setToolTip( 0, tip );
1099 }
1100
1101 perteditor->draw( getProject() );
1102
1103 connect( perteditor, SIGNAL(guiActivated(ViewBase*,bool)), SLOT(slotGuiActivated(ViewBase*,bool)) );
1104 m_updatePertEditor = true;
1105 perteditor->updateReadWrite( m_readWrite );
1106 return perteditor;
1107}
1108
1109ViewBase *View::createProjectStatusView( ViewListItem *cat, const QString &tag, const QString &name, const QString &tip, int index )
1110{
1111 ProjectStatusView *v = new ProjectStatusView(getKoPart(), getPart(), m_tab );
1112 m_tab->addWidget( v );
1113
1114 ViewListItem *i = m_viewlist->addView( cat, tag, name, v, getPart(), "", index );
1115 ViewInfo vi = defaultViewInfo( "ProjectStatusView" );
1116 if ( name.isEmpty() ) {
1117 i->setText( 0, vi.name );
1118 }
1119 if ( tip == TIP_USE_DEFAULT_TEXT ) {
1120 i->setToolTip( 0, vi.tip );
1121 } else {
1122 i->setToolTip( 0, tip );
1123 }
1124
1125 connect( v, SIGNAL(guiActivated(ViewBase*,bool)), SLOT(slotGuiActivated(ViewBase*,bool)) );
1126
1127 connect( this, SIGNAL(currentScheduleManagerChanged(ScheduleManager*)), v, SLOT(setScheduleManager(ScheduleManager*)) );
1128
1129 v->updateReadWrite( m_readWrite );
1130 v->setProject( &getProject() );
1131 v->setScheduleManager( currentScheduleManager() );
1132 return v;
1133}
1134
1135ViewBase *View::createPerformanceStatusView( ViewListItem *cat, const QString &tag, const QString &name, const QString &tip, int index )
1136{
1137 PerformanceStatusView *v = new PerformanceStatusView(getKoPart(), getPart(), m_tab );
1138 m_tab->addWidget( v );
1139
1140 ViewListItem *i = m_viewlist->addView( cat, tag, name, v, getPart(), "", index );
1141 ViewInfo vi = defaultViewInfo( "PerformanceStatusView" );
1142 if ( name.isEmpty() ) {
1143 i->setText( 0, vi.name );
1144 }
1145 if ( tip == TIP_USE_DEFAULT_TEXT ) {
1146 i->setToolTip( 0, vi.tip );
1147 } else {
1148 i->setToolTip( 0, tip );
1149 }
1150
1151 connect( v, SIGNAL(guiActivated(ViewBase*,bool)), SLOT(slotGuiActivated(ViewBase*,bool)) );
1152
1153 connect( this, SIGNAL(currentScheduleManagerChanged(ScheduleManager*)), v, SLOT(setScheduleManager(ScheduleManager*)) );
1154
1155 connect( v, SIGNAL(requestPopupMenu(QString,QPoint)), this, SLOT(slotPopupMenu(QString,QPoint)) );
1156
1157 v->updateReadWrite( m_readWrite );
1158 v->setProject( &getProject() );
1159 v->setScheduleManager( currentScheduleManager() );
1160 return v;
1161}
1162
1163
1164ViewBase *View::createTaskStatusView( ViewListItem *cat, const QString &tag, const QString &name, const QString &tip, int index )
1165{
1166 TaskStatusView *taskstatusview = new TaskStatusView(getKoPart(), getPart(), m_tab );
1167 m_tab->addWidget( taskstatusview );
1168
1169 ViewListItem *i = m_viewlist->addView( cat, tag, name, taskstatusview, getPart(), "", index );
1170 ViewInfo vi = defaultViewInfo( "TaskStatusView" );
1171 if ( name.isEmpty() ) {
1172 i->setText( 0, vi.name );
1173 }
1174 if ( tip == TIP_USE_DEFAULT_TEXT ) {
1175 i->setToolTip( 0, vi.tip );
1176 } else {
1177 i->setToolTip( 0, tip );
1178 }
1179
1180 connect( taskstatusview, SIGNAL(guiActivated(ViewBase*,bool)), SLOT(slotGuiActivated(ViewBase*,bool)) );
1181
1182 connect( this, SIGNAL(currentScheduleManagerChanged(ScheduleManager*)), taskstatusview, SLOT(setScheduleManager(ScheduleManager*)) );
1183
1184 connect( taskstatusview, SIGNAL(requestPopupMenu(QString,QPoint)), this, SLOT(slotPopupMenu(QString,QPoint)) );
1185
1186 taskstatusview->updateReadWrite( m_readWrite );
1187 taskstatusview->draw( getProject() );
1188 taskstatusview->setScheduleManager( currentScheduleManager() );
1189 return taskstatusview;
1190}
1191
1192ViewBase *View::createTaskView( ViewListItem *cat, const QString &tag, const QString &name, const QString &tip, int index )
1193{
1194 TaskView *v = new TaskView(getKoPart(), getPart(), m_tab );
1195 m_tab->addWidget( v );
1196
1197 ViewListItem *i = m_viewlist->addView( cat, tag, name, v, getPart(), "", index );
1198 ViewInfo vi = defaultViewInfo( "TaskView" );
1199 if ( name.isEmpty() ) {
1200 i->setText( 0, vi.name );
1201 }
1202 if ( tip == TIP_USE_DEFAULT_TEXT ) {
1203 i->setToolTip( 0, vi.tip );
1204 } else {
1205 i->setToolTip( 0, tip );
1206 }
1207
1208 v->draw( getProject() );
1209 v->setScheduleManager( currentScheduleManager() );
1210
1211 connect( this, SIGNAL(currentScheduleManagerChanged(ScheduleManager*)), v, SLOT(setScheduleManager(ScheduleManager*)) );
1212
1213 connect( v, SIGNAL(guiActivated(ViewBase*,bool)), SLOT(slotGuiActivated(ViewBase*,bool)) );
1214
1215 connect( v, SIGNAL(requestPopupMenu(QString,QPoint)), this, SLOT(slotPopupMenu(QString,QPoint)) );
1216 v->updateReadWrite( m_readWrite );
1217 return v;
1218}
1219
1220ViewBase *View::createTaskWorkPackageView( ViewListItem *cat, const QString &tag, const QString &name, const QString &tip, int index )
1221{
1222 TaskWorkPackageView *v = new TaskWorkPackageView(getKoPart(), getPart(), m_tab );
1223 m_tab->addWidget( v );
1224
1225 ViewListItem *i = m_viewlist->addView( cat, tag, name, v, getPart(), "", index );
1226 ViewInfo vi = defaultViewInfo( "TaskWorkPackageView" );
1227 if ( name.isEmpty() ) {
1228 i->setText( 0, vi.name );
1229 }
1230 if ( tip == TIP_USE_DEFAULT_TEXT ) {
1231 i->setToolTip( 0, vi.tip );
1232 } else {
1233 i->setToolTip( 0, tip );
1234 }
1235
1236 v->setProject( &getProject() );
1237 v->setScheduleManager( currentScheduleManager() );
1238
1239 connect( this, SIGNAL(currentScheduleManagerChanged(ScheduleManager*)), v, SLOT(setScheduleManager(ScheduleManager*)) );
1240
1241 connect( v, SIGNAL(guiActivated(ViewBase*,bool)), SLOT(slotGuiActivated(ViewBase*,bool)) );
1242
1243 connect( v, SIGNAL(requestPopupMenu(QString,QPoint)), this, SLOT(slotPopupMenu(QString,QPoint)) );
1244
1245 connect( v, SIGNAL(mailWorkpackage(Node*,Resource*)), SLOT(slotMailWorkpackage(Node*,Resource*)) );
1246 connect( v, SIGNAL(mailWorkpackages(QList<Node*>,Resource*)), SLOT(slotMailWorkpackages(QList<Node*>,Resource*)) );
1247
1248 connect(v, SIGNAL(checkForWorkPackages()), getPart(), SLOT(checkForWorkPackages()));
1249 v->updateReadWrite( m_readWrite );
1250 return v;
1251}
1252
1253ViewBase *View::createGanttView( ViewListItem *cat, const QString &tag, const QString &name, const QString &tip, int index )
1254{
1255 GanttView *ganttview = new GanttView(getKoPart(), getPart(), m_tab, koDocument()->isReadWrite() );
1256 m_tab->addWidget( ganttview );
1257
1258 ViewListItem *i = m_viewlist->addView( cat, tag, name, ganttview, getPart(), "", index );
1259 ViewInfo vi = defaultViewInfo( "GanttView" );
1260 if ( name.isEmpty() ) {
1261 i->setText( 0, vi.name );
1262 }
1263 if ( tip == TIP_USE_DEFAULT_TEXT ) {
1264 i->setToolTip( 0, vi.tip );
1265 } else {
1266 i->setToolTip( 0, tip );
1267 }
1268
1269 ganttview->setProject( &( getProject() ) );
1270 ganttview->setScheduleManager( currentScheduleManager() );
1271
1272 connect( ganttview, SIGNAL(guiActivated(ViewBase*,bool)), SLOT(slotGuiActivated(ViewBase*,bool)) );
1273/* TODO: Review these
1274 connect( ganttview, SIGNAL(addRelation(Node*,Node*,int)), SLOT(slotAddRelation(Node*,Node*,int)) );
1275 connect( ganttview, SIGNAL(modifyRelation(Relation*,int)), SLOT(slotModifyRelation(Relation*,int)) );
1276 connect( ganttview, SIGNAL(modifyRelation(Relation*)), SLOT(slotModifyRelation(Relation*)) );
1277 connect( ganttview, SIGNAL(itemDoubleClicked()), SLOT(slotOpenNode()) );
1278 connect( ganttview, SIGNAL(itemRenamed(Node*,QString)), this, SLOT(slotRenameNode(Node*,QString)) );*/
1279
1280 connect( this, SIGNAL(currentScheduleManagerChanged(ScheduleManager*)), ganttview, SLOT(setScheduleManager(ScheduleManager*)) );
1281
1282 connect( ganttview, SIGNAL(requestPopupMenu(QString,QPoint)), this, SLOT(slotPopupMenu(QString,QPoint)) );
1283 ganttview->updateReadWrite( m_readWrite );
1284 return ganttview;
1285}
1286
1287ViewBase *View::createMilestoneGanttView( ViewListItem *cat, const QString &tag, const QString &name, const QString &tip, int index )
1288{
1289 MilestoneGanttView *ganttview = new MilestoneGanttView(getKoPart(), getPart(), m_tab, koDocument()->isReadWrite() );
1290 m_tab->addWidget( ganttview );
1291
1292 ViewListItem *i = m_viewlist->addView( cat, tag, name, ganttview, getPart(), "", index );
1293 ViewInfo vi = defaultViewInfo( "MilestoneGanttView" );
1294 if ( name.isEmpty() ) {
1295 i->setText( 0, vi.name );
1296 }
1297 if ( tip == TIP_USE_DEFAULT_TEXT ) {
1298 i->setToolTip( 0, vi.tip );
1299 } else {
1300 i->setToolTip( 0, tip );
1301 }
1302
1303 ganttview->setProject( &( getProject() ) );
1304 ganttview->setScheduleManager( currentScheduleManager() );
1305
1306 connect( ganttview, SIGNAL(guiActivated(ViewBase*,bool)), SLOT(slotGuiActivated(ViewBase*,bool)) );
1307
1308 connect( this, SIGNAL(currentScheduleManagerChanged(ScheduleManager*)), ganttview, SLOT(setScheduleManager(ScheduleManager*)) );
1309
1310 connect( ganttview, SIGNAL(requestPopupMenu(QString,QPoint)), this, SLOT(slotPopupMenu(QString,QPoint)) );
1311 ganttview->updateReadWrite( m_readWrite );
1312 return ganttview;
1313}
1314
1315
1316ViewBase *View::createAccountsView( ViewListItem *cat, const QString &tag, const QString &name, const QString &tip, int index )
1317{
1318 AccountsView *accountsview = new AccountsView(getKoPart(), &getProject(), getPart(), m_tab );
1319 m_tab->addWidget( accountsview );
1320
1321 ViewListItem *i = m_viewlist->addView( cat, tag, name, accountsview, getPart(), "", index );
1322 ViewInfo vi = defaultViewInfo( "AccountsView" );
1323 if ( name.isEmpty() ) {
1324 i->setText( 0, vi.name );
1325 }
1326 if ( tip == TIP_USE_DEFAULT_TEXT ) {
1327 i->setToolTip( 0, vi.tip );
1328 } else {
1329 i->setToolTip( 0, tip );
1330 }
1331
1332 accountsview->setScheduleManager( currentScheduleManager() );
1333
1334 connect( this, SIGNAL(currentScheduleManagerChanged(ScheduleManager*)), accountsview, SLOT(setScheduleManager(ScheduleManager*)) );
1335
1336 connect( accountsview, SIGNAL(guiActivated(ViewBase*,bool)), SLOT(slotGuiActivated(ViewBase*,bool)) );
1337 accountsview->updateReadWrite( m_readWrite );
1338 return accountsview;
1339}
1340
1341ViewBase *View::createResourceAssignmentView( ViewListItem *cat, const QString &tag, const QString &name, const QString &tip, int index )
1342{
1343 ResourceAssignmentView *resourceAssignmentView = new ResourceAssignmentView(getKoPart(), getPart(), m_tab );
1344 m_tab->addWidget( resourceAssignmentView );
1345 m_updateResourceAssignmentView = true;
1346
1347 ViewListItem *i = m_viewlist->addView( cat, tag, name, resourceAssignmentView, getPart(), "", index );
1348 ViewInfo vi = defaultViewInfo( "ResourceAssignmentView" );
1349 if ( name.isEmpty() ) {
1350 i->setText( 0, vi.name );
1351 }
1352 if ( tip == TIP_USE_DEFAULT_TEXT ) {
1353 i->setToolTip( 0, vi.tip );
1354 } else {
1355 i->setToolTip( 0, tip );
1356 }
1357
1358 resourceAssignmentView->draw( getProject() );
1359
1360 connect( resourceAssignmentView, SIGNAL(guiActivated(ViewBase*,bool)), SLOT(slotGuiActivated(ViewBase*,bool)) );
1361
1362 connect( resourceAssignmentView, SIGNAL(requestPopupMenu(QString,QPoint)), this, SLOT(slotPopupMenu(QString,QPoint)) );
1363 resourceAssignmentView->updateReadWrite( m_readWrite );
1364 return resourceAssignmentView;
1365}
1366
1367ViewBase *View::createReportView( ViewListItem *cat, const QString &tag, const QString &name, const QString &tip, int index )
1368{
1369 ReportView *v = new ReportView(getKoPart(), getPart(), m_tab );
1370 m_tab->addWidget( v );
1371
1372 ViewListItem *i = m_viewlist->addView( cat, tag, name, v, getPart(), "", index );
1373 ViewInfo vi = defaultViewInfo( "ReportView" );
1374 if ( name.isEmpty() ) {
1375 i->setText( 0, vi.name );
1376 }
1377 if ( tip == TIP_USE_DEFAULT_TEXT ) {
1378 i->setToolTip( 0, vi.tip );
1379 } else {
1380 i->setToolTip( 0, tip );
1381 }
1382
1383 v->setProject( &getProject() );
1384
1385 connect( this, SIGNAL(currentScheduleManagerChanged(ScheduleManager*)), v, SLOT(setScheduleManager(ScheduleManager*)) );
1386 connect( this, SIGNAL(currentScheduleManagerChanged(ScheduleManager*)), v, SLOT(slotRefreshView()));
1387 v->setScheduleManager( currentScheduleManager() );
1388
1389 connect( v, SIGNAL(guiActivated(ViewBase*,bool)), SLOT(slotGuiActivated(ViewBase*,bool)) );
1390 v->updateReadWrite( m_readWrite );
1391 return v;
1392}
1393
1394Project& View::getProject() const
1395{
1396 return getPart() ->getProject();
1397}
1398
1399KoPrintJob * View::createPrintJob()
1400{
1401 KoView *v = qobject_cast<KoView*>( canvas() );
1402 if ( v == 0 ) {
1403 return 0;
1404 }
1405 return v->createPrintJob();
1406}
1407
1408ViewBase *View::currentView() const
1409{
1410 return qobject_cast<ViewBase*>( m_tab->currentWidget() );
1411}
1412
1413void View::slotEditCut()
1414{
1415 ViewBase *v = currentView();
1416 if ( v ) {
1417 v->slotEditCut();
1418 }
1419}
1420
1421void View::slotEditCopy()
1422{
1423 ViewBase *v = currentView();
1424 if ( v ) {
1425 v->slotEditCopy();
1426 }
1427}
1428
1429void View::slotEditPaste()
1430{
1431 ViewBase *v = currentView();
1432 if ( v ) {
1433 v->slotEditPaste();
1434 }
1435}
1436
1437void View::slotRefreshView()
1438{
1439 ViewBase *v = currentView();
1440 if ( v ) {
1441 v->slotRefreshView();
1442 }
1443}
1444
1445void View::slotViewSelector( bool show )
1446{
1447 //kDebug(planDbg());
1448 m_viewlist->setVisible( show );
1449}
1450
1451void View::slotInsertFile()
1452{
1453 InsertFileDialog *dlg = new InsertFileDialog( getProject(), currentTask(), this );
1454 connect(dlg, SIGNAL(finished(int)), SLOT(slotInsertFileFinished(int)));
1455 dlg->show();
1456 dlg->raise();
1457 dlg->activateWindow();
1458}
1459
1460void View::slotInsertFileFinished( int result )
1461{
1462 InsertFileDialog *dlg = qobject_cast<InsertFileDialog*>( sender() );
1463 if ( dlg == 0 ) {
1464 return;
1465 }
1466 if ( result == QDialog::Accepted ) {
1467 getPart()->insertFile( dlg->url().url(), dlg->parentNode(), dlg->afterNode() );
1468 }
1469 dlg->deleteLater();
1470}
1471
1472void View::slotProjectEdit()
1473{
1474 slotOpenNode( &getProject() );
1475}
1476
1477void View::slotProjectWorktime()
1478{
1479 StandardWorktimeDialog *dia = new StandardWorktimeDialog( getProject(), this );
1480 connect(dia, SIGNAL(finished(int)), this, SLOT(slotProjectWorktimeFinished(int)));
1481 dia->show();
1482 dia->raise();
1483 dia->activateWindow();
1484}
1485
1486void View::slotProjectWorktimeFinished( int result )
1487{
1488 StandardWorktimeDialog *dia = qobject_cast<StandardWorktimeDialog*>( sender() );
1489 if ( dia == 0 ) {
1490 return;
1491 }
1492 if ( result == QDialog::Accepted) {
1493 KUndo2Command * cmd = dia->buildCommand();
1494 if ( cmd ) {
1495 //kDebug(planDbg())<<"Modifying calendar(s)";
1496 getPart() ->addCommand( cmd ); //also executes
1497 }
1498 }
1499 dia->deleteLater();
1500}
1501
1502void View::slotSelectionChanged( ScheduleManager *sm ) {
1503 kDebug(planDbg())<<sm;
1504 if ( sm == 0 ) {
1505 return;
1506 }
1507 int idx = m_scheduleActions.values().indexOf( sm->expected() );
1508 if ( idx < 0 ) {
1509 kDebug(planDbg())<<sm<<"could not find schedule"<<sm->expected();
1510 return;
1511 }
1512 QAction *a = m_scheduleActions.keys().at( idx );
1513 Q_ASSERT( a );
1514 a->setChecked( true ); // this doesn't trigger QActionGroup
1515 slotViewSchedule( a );
1516}
1517
1518QList<QAction*> View::sortedActionList()
1519{
1520 QMap<QString, QAction*> lst;
1521 foreach ( QAction *a, m_scheduleActions.keys() ) {
1522 lst.insert( a->objectName(), a );
1523 }
1524 return lst.values();
1525}
1526
1527void View::slotScheduleRemoved( const MainSchedule *sch )
1528{
1529 kDebug(planDbg())<<sch<<sch->name();
1530 QAction *a = 0;
1531 QAction *checked = m_scheduleActionGroup->checkedAction();
1532 QMapIterator<QAction*, Schedule*> i( m_scheduleActions );
1533 while (i.hasNext()) {
1534 i.next();
1535 if ( i.value() == sch ) {
1536 a = i.key();
1537 break;
1538 }
1539 }
1540 if ( a ) {
1541 unplugActionList( "view_schedule_list" );
1542 delete a;
1543 plugActionList( "view_schedule_list", sortedActionList() );
1544 if ( checked && checked != a ) {
1545 checked->setChecked( true );
1546 } else if ( ! m_scheduleActions.isEmpty() ) {
1547 m_scheduleActions.keys().first()->setChecked( true );
1548 }
1549 }
1550 slotViewSchedule( m_scheduleActionGroup->checkedAction() );
1551}
1552
1553void View::slotScheduleAdded( const MainSchedule *sch )
1554{
1555 if ( sch->type() != Schedule::Expected ) {
1556 return; // Only view expected
1557 }
1558 MainSchedule *s = const_cast<MainSchedule*>( sch );
1559// kDebug(planDbg())<<sch->name()<<" deleted="<<sch->isDeleted()<<"scheduled="<<sch->isScheduled();
1560 QAction *checked = m_scheduleActionGroup->checkedAction();
1561 if ( ! sch->isDeleted() && sch->isScheduled() ) {
1562 unplugActionList( "view_schedule_list" );
1563 QAction *act = addScheduleAction( s );
1564 plugActionList( "view_schedule_list", sortedActionList() );
1565 if ( checked ) {
1566 checked->setChecked( true );
1567 } else if ( act ) {
1568 act->setChecked( true );
1569 } else if ( ! m_scheduleActions.isEmpty() ) {
1570 m_scheduleActions.keys().first()->setChecked( true );
1571 }
1572 }
1573 slotViewSchedule( m_scheduleActionGroup->checkedAction() );
1574}
1575
1576void View::slotScheduleChanged( MainSchedule *sch )
1577{
1578// kDebug(planDbg())<<sch->name()<<" deleted="<<sch->isDeleted()<<"scheduled="<<sch->isScheduled();
1579 if ( sch->isDeleted() || ! sch->isScheduled() ) {
1580 slotScheduleRemoved( sch );
1581 return;
1582 }
1583 if ( m_scheduleActions.values().contains( sch ) ) {
1584 slotScheduleRemoved( sch ); // hmmm, how to avoid this?
1585 }
1586 slotScheduleAdded( sch );
1587}
1588
1589QAction *View::addScheduleAction( Schedule *sch )
1590{
1591 QAction *act = 0;
1592 if ( ! sch->isDeleted() && sch->isScheduled() ) {
1593 QString n = sch->name();
1594 act = new KToggleAction( n, this);
1595 actionCollection()->addAction(n, act );
1596 m_scheduleActions.insert( act, sch );
1597 m_scheduleActionGroup->addAction( act );
1598 //kDebug(planDbg())<<"Add:"<<n;
1599 connect( act, SIGNAL(destroyed(QObject*)), SLOT(slotActionDestroyed(QObject*)) );
1600 }
1601 return act;
1602}
1603
1604void View::slotViewScheduleManager()
1605{
1606 QApplication::setOverrideCursor( Qt::WaitCursor );
1607 setLabel( m_nextScheduleManager );
1608 emit currentScheduleManagerChanged( m_nextScheduleManager );
1609 m_nextScheduleManager = 0;
1610 m_trigged = false;
1611 QApplication::restoreOverrideCursor();
1612}
1613
1614void View::slotViewSchedule( QAction *act )
1615{
1616 //kDebug(planDbg())<<act;
1617 ScheduleManager *sm = 0;
1618 if ( act != 0 ) {
1619 Schedule *sch = m_scheduleActions.value( act, 0 );
1620 sm = sch->manager();
1621 }
1622 emit currentScheduleManagerChanged( 0 );
1623 setLabel( 0 );
1624 m_nextScheduleManager = sm;
1625 // Performance is very dependent on schedule manager change since a lot is recalculated
1626 // In case of multiple changes, only issue the last change
1627 if ( ! m_trigged ) {
1628 m_trigged = true;
1629 emit currentScheduleManagerChanged( 0 );
1630 QTimer::singleShot( 0, this, SLOT(slotViewScheduleManager()) );
1631 }
1632}
1633
1634void View::slotActionDestroyed( QObject *o )
1635{
1636 //kDebug(planDbg())<<o->name();
1637 m_scheduleActions.remove( static_cast<QAction*>( o ) );
1638// slotViewSchedule( m_scheduleActionGroup->checkedAction() );
1639}
1640
1641void View::slotPlugScheduleActions()
1642{
1643 //kDebug(planDbg())<<activeScheduleId();
1644 long id = activeScheduleId();
1645 unplugActionList( "view_schedule_list" );
1646 foreach( QAction *act, m_scheduleActions.keys() ) {
1647 m_scheduleActionGroup->removeAction( act );
1648 delete act;
1649 }
1650 m_scheduleActions.clear();
1651 QAction *ca = 0;
1652 foreach( ScheduleManager *sm, getProject().allScheduleManagers() ) {
1653 Schedule *sch = sm->expected();
1654 if ( sch == 0 ) {
1655 continue;
1656 }
1657 QAction *act = addScheduleAction( sch );
1658 if ( act && id == sch->id() ) {
1659 ca = act;
1660 }
1661 }
1662 plugActionList( "view_schedule_list", sortedActionList() );
1663 if ( ca == 0 && m_scheduleActionGroup->actions().count() > 0 ) {
1664 ca = m_scheduleActionGroup->actions().first();
1665 }
1666 if ( ca ) {
1667 ca->setChecked( true );
1668 }
1669 slotViewSchedule( ca );
1670}
1671
1672void View::slotProjectCalculated( ScheduleManager *sm )
1673{
1674 // we only get here if current schedule was calculated
1675 if ( sm->isScheduled() ) {
1676 slotSelectionChanged( sm );
1677 }
1678}
1679
1680void View::slotCalculateSchedule( Project *project, ScheduleManager *sm )
1681{
1682 if ( project == 0 || sm == 0 ) {
1683 return;
1684 }
1685 if ( sm->parentManager() && ! sm->parentManager()->isScheduled() ) {
1686 // the parent must be scheduled
1687 return;
1688 }
1689 if ( sm == currentScheduleManager() ) {
1690 connect( project, SIGNAL(projectCalculated(ScheduleManager*)), this, SLOT(slotProjectCalculated(ScheduleManager*)) );
1691 }
1692 CalculateScheduleCmd *cmd = new CalculateScheduleCmd( *project, sm, kundo2_i18nc("@info:status 1=schedule name", "Calculate %1", sm->name() ) );
1693 getPart() ->addCommand( cmd );
1694 slotUpdate();
1695}
1696
1697void View::slotRemoveCommands()
1698{
1699 while ( ! m_undocommands.isEmpty() ) {
1700 m_undocommands.last()->undo();
1701 delete m_undocommands.takeLast();
1702 }
1703}
1704
1705void View::slotBaselineSchedule( Project *project, ScheduleManager *sm )
1706{
1707 if ( project == 0 || sm == 0 ) {
1708 return;
1709 }
1710 if ( ! sm->isBaselined() && project->isBaselined() ) {
1711 KMessageBox::sorry( this, i18n( "Cannot baseline. The project is already baselined." ) );
1712 return;
1713 }
1714 KUndo2Command *cmd;
1715 if ( sm->isBaselined() ) {
1716 int res = KMessageBox::warningContinueCancel( this, i18n( "This schedule is baselined. Do you want to remove the baseline?" ) );
1717 if ( res == KMessageBox::Cancel ) {
1718 return;
1719 }
1720 cmd = new ResetBaselineScheduleCmd( *sm, kundo2_i18n( "Reset baseline %1", sm->name() ) );
1721 } else {
1722 cmd = new BaselineScheduleCmd( *sm, kundo2_i18n( "Baseline %1", sm->name() ) );
1723 }
1724 getPart() ->addCommand( cmd );
1725}
1726
1727void View::slotAddScheduleManager( Project *project )
1728{
1729 if ( project == 0 ) {
1730 return;
1731 }
1732 ScheduleManager *sm = project->createScheduleManager();
1733 AddScheduleManagerCmd *cmd = new AddScheduleManagerCmd( *project, sm, -1, kundo2_i18n( "Add schedule %1", sm->name() ) );
1734 getPart() ->addCommand( cmd );
1735}
1736
1737void View::slotDeleteScheduleManager( Project *project, ScheduleManager *sm )
1738{
1739 if ( project == 0 || sm == 0) {
1740 return;
1741 }
1742 DeleteScheduleManagerCmd *cmd = new DeleteScheduleManagerCmd( *project, sm, kundo2_i18n( "Delete schedule %1", sm->name() ) );
1743 getPart() ->addCommand( cmd );
1744}
1745
1746void View::slotMoveScheduleManager( ScheduleManager *sm, ScheduleManager *parent, int index )
1747{
1748 if ( sm == 0 ) {
1749 return;
1750 }
1751 MoveScheduleManagerCmd *cmd = new MoveScheduleManagerCmd( sm, parent, index, kundo2_i18n( "Move schedule %1", sm->name() ) );
1752 getPart() ->addCommand( cmd );
1753}
1754
1755void View::slotAddSubTask()
1756{
1757 Task * node = getProject().createTask( getPart() ->config().taskDefaults() );
1758 SubTaskAddDialog *dia = new SubTaskAddDialog( getProject(), *node, currentNode(), getProject().accounts(), this );
1759 connect(dia, SIGNAL(finished(int)), SLOT(slotAddSubTaskFinished(int)));
1760 dia->show();
1761 dia->raise();
1762 dia->activateWindow();
1763}
1764
1765void View::slotAddSubTaskFinished( int result )
1766{
1767 SubTaskAddDialog *dia = qobject_cast<SubTaskAddDialog*>( sender() );
1768 if ( dia == 0 ) {
1769 return;
1770 }
1771 if ( result == QDialog::Accepted) {
1772 KUndo2Command *m = dia->buildCommand();
1773 getPart() ->addCommand( m ); // add task to project
1774 }
1775 dia->deleteLater();
1776}
1777
1778void View::slotAddTask()
1779{
1780 Task * node = getProject().createTask( getPart() ->config().taskDefaults() );
1781 TaskAddDialog *dia = new TaskAddDialog( getProject(), *node, currentNode(), getProject().accounts(), this );
1782 connect(dia, SIGNAL(finished(int)), SLOT(slotAddTaskFinished(int)));
1783 dia->show();
1784 dia->raise();
1785 dia->activateWindow();
1786}
1787
1788void View::slotAddTaskFinished( int result )
1789{
1790 TaskAddDialog *dia = qobject_cast<TaskAddDialog*>( sender() );
1791 if ( dia == 0 ) {
1792 return;
1793 }
1794 if ( result == QDialog::Accepted) {
1795 KUndo2Command *m = dia->buildCommand();
1796 getPart() ->addCommand( m ); // add task to project
1797 }
1798 dia->deleteLater();
1799}
1800
1801void View::slotAddMilestone()
1802{
1803 Task * node = getProject().createTask();
1804 node->estimate() ->clear();
1805
1806 TaskAddDialog *dia = new TaskAddDialog( getProject(), *node, currentNode(), getProject().accounts(), this );
1807 connect(dia, SIGNAL(finished(int)), SLOT(slotAddMilestoneFinished(int)));
1808 dia->show();
1809 dia->raise();
1810 dia->activateWindow();
1811}
1812
1813void View::slotAddMilestoneFinished( int result )
1814{
1815 TaskAddDialog *dia = qobject_cast<TaskAddDialog*>( sender() );
1816 if ( dia == 0 ) {
1817 return;
1818 }
1819 if ( result == QDialog::Accepted) {
1820 MacroCommand *c = new MacroCommand( kundo2_i18n( "Add milestone" ) );
1821 c->addCommand( dia->buildCommand() );
1822 getPart() ->addCommand( c ); // add task to project
1823 }
1824 dia->deleteLater();
1825}
1826
1827void View::slotAddSubMilestone()
1828{
1829 Task * node = getProject().createTask();
1830 node->estimate() ->clear();
1831
1832 SubTaskAddDialog *dia = new SubTaskAddDialog( getProject(), *node, currentNode(), getProject().accounts(), this );
1833 connect(dia, SIGNAL(finished(int)), SLOT(slotAddSubMilestoneFinished(int)));
1834 dia->show();
1835 dia->raise();
1836 dia->activateWindow();
1837}
1838
1839void 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
1853void View::slotDefineWBS()
1854{
1855 //kDebug(planDbg());
1856 Project &p = getProject();
1857 WBSDefinitionDialog *dia = new WBSDefinitionDialog( p, p.wbsDefinition(), this );
1858 connect(dia, SIGNAL(finished(int)), SLOT(slotDefineWBSFinished(int)));
1859 dia->show();
1860 dia->raise();
1861 dia->activateWindow();
1862}
1863
1864void View::slotDefineWBSFinished( int result )
1865{
1866 //kDebug(planDbg());
1867 WBSDefinitionDialog *dia = qobject_cast<WBSDefinitionDialog*>( sender() );
1868 if ( dia == 0 ) {
1869 return;
1870 }
1871 if ( result == QDialog::Accepted ) {
1872 KUndo2Command *cmd = dia->buildCommand();
1873 if ( cmd ) {
1874 getPart()->addCommand( cmd );
1875 }
1876 }
1877 dia->deleteLater();
1878}
1879
1880void View::slotConfigure()
1881{
1882 //kDebug(planDbg());
1883 if( KConfigDialog::showDialog("Plan Settings") ) {
1884 return;
1885 }
1886 ConfigDialog *dialog = new ConfigDialog( this, "Plan Settings", KPlatoSettings::self() );
1887 dialog->addPage(new TaskDefaultPanel(), i18n("Task Defaults"), koIconName("view-task") );
1888 dialog->addPage(new ColorsConfigPanel(), i18n("Task Colors"), koIconName("fill-color") );
1889 dialog->addPage(new WorkPackageConfigPanel(), i18n("Work Package"), koIconName("calligraplanwork") );
1890 dialog->show();
1891
1892}
1893
1894void View::slotIntroduction()
1895{
1896 m_tab->setCurrentIndex( 0 );
1897}
1898
1899
1900Calendar *View::currentCalendar()
1901{
1902 ViewBase *v = dynamic_cast<ViewBase*>( m_tab->currentWidget() );
1903 if ( v == 0 ) {
1904 return 0;
1905 }
1906 return v->currentCalendar();
1907}
1908
1909Node *View::currentNode() const
1910{
1911 ViewBase *v = dynamic_cast<ViewBase*>( m_tab->currentWidget() );
1912 if ( v == 0 ) {
1913 return 0;
1914 }
1915 Node * task = v->currentNode();
1916 if ( 0 != task ) {
1917 return task;
1918 }
1919 return &( getProject() );
1920}
1921
1922Task *View::currentTask() const
1923{
1924 ViewBase *v = dynamic_cast<ViewBase*>( m_tab->currentWidget() );
1925 if ( v == 0 ) {
1926 return 0;
1927 }
1928 Node * task = v->currentNode();
1929 if ( task ) {
1930 return dynamic_cast<Task*>( task );
1931 }
1932 return 0;
1933}
1934
1935Resource *View::currentResource()
1936{
1937 ViewBase *v = dynamic_cast<ViewBase*>( m_tab->currentWidget() );
1938 if ( v == 0 ) {
1939 return 0;
1940 }
1941 return v->currentResource();
1942}
1943
1944ResourceGroup *View::currentResourceGroup()
1945{
1946 ViewBase *v = dynamic_cast<ViewBase*>( m_tab->currentWidget() );
1947 if ( v == 0 ) {
1948 return 0;
1949 }
1950 return v->currentResourceGroup();
1951}
1952
1953
1954void View::slotOpenNode()
1955{
1956 //kDebug(planDbg());
1957 Node * node = currentNode();
1958 slotOpenNode( node );
1959}
1960
1961void View::slotOpenNode( Node *node )
1962{
1963 //kDebug(planDbg());
1964 if ( !node )
1965 return ;
1966
1967 switch ( node->type() ) {
1968 case Node::Type_Project: {
1969 Project * project = static_cast<Project *>( node );
1970 MainProjectDialog *dia = new MainProjectDialog( *project, this );
1971 connect(dia, SIGNAL(finished(int)), SLOT(slotProjectEditFinished(int)));
1972 dia->show();
1973 dia->raise();
1974 dia->activateWindow();
1975 break;
1976 }
1977 case Node::Type_Subproject:
1978 //TODO
1979 break;
1980 case Node::Type_Task: {
1981 Task *task = static_cast<Task *>( node );
1982 TaskDialog *dia = new TaskDialog( getProject(), *task, getProject().accounts(), this );
1983 connect(dia, SIGNAL(finished(int)), SLOT(slotTaskEditFinished(int)));
1984 dia->show();
1985 dia->raise();
1986 dia->activateWindow();
1987 break;
1988 }
1989 case Node::Type_Milestone: {
1990 // Use the normal task dialog for now.
1991 // Maybe milestone should have it's own dialog, but we need to be able to
1992 // enter a duration in case we accidentally set a tasks duration to zero
1993 // and hence, create a milestone
1994 Task *task = static_cast<Task *>( node );
1995 TaskDialog *dia = new TaskDialog( getProject(), *task, getProject().accounts(), this );
1996 connect(dia, SIGNAL(finished(int)), SLOT(slotTaskEditFinished(int)));
1997 dia->show();
1998 dia->raise();
1999 dia->activateWindow();
2000 break;
2001 }
2002 case Node::Type_Summarytask: {
2003 Task *task = dynamic_cast<Task *>( node );
2004 Q_ASSERT( task );
2005 SummaryTaskDialog *dia = new SummaryTaskDialog( *task, this );
2006 connect(dia, SIGNAL(finished(int)), SLOT(slotSummaryTaskEditFinished(int)));
2007 dia->show();
2008 dia->raise();
2009 dia->activateWindow();
2010 break;
2011 }
2012 default:
2013 break; // avoid warnings
2014 }
2015}
2016
2017void View::slotProjectEditFinished( int result )
2018{
2019 MainProjectDialog *dia = qobject_cast<MainProjectDialog*>( sender() );
2020 if ( dia == 0 ) {
2021 return;
2022 }
2023 if ( result == QDialog::Accepted) {
2024 KUndo2Command * cmd = dia->buildCommand();
2025 if ( cmd ) {
2026 getPart() ->addCommand( cmd );
2027 }
2028 }
2029 dia->deleteLater();
2030}
2031
2032void View::slotTaskEditFinished( int result )
2033{
2034 TaskDialog *dia = qobject_cast<TaskDialog*>( sender() );
2035 if ( dia == 0 ) {
2036 return;
2037 }
2038 if ( result == QDialog::Accepted) {
2039 KUndo2Command * cmd = dia->buildCommand();
2040 if ( cmd ) {
2041 getPart() ->addCommand( cmd );
2042 }
2043 }
2044 dia->deleteLater();
2045}
2046
2047void View::slotSummaryTaskEditFinished( int result )
2048{
2049 SummaryTaskDialog *dia = qobject_cast<SummaryTaskDialog*>( sender() );
2050 if ( dia == 0 ) {
2051 return;
2052 }
2053 if ( result == QDialog::Accepted) {
2054 KUndo2Command * cmd = dia->buildCommand();
2055 if ( cmd ) {
2056 getPart() ->addCommand( cmd );
2057 }
2058 }
2059 dia->deleteLater();
2060}
2061
2062ScheduleManager *View::currentScheduleManager() const
2063{
2064 Schedule *s = m_scheduleActions.value( m_scheduleActionGroup->checkedAction() );
2065 return s == 0 ? 0 : s->manager();
2066}
2067
2068long View::activeScheduleId() const
2069{
2070 Schedule *s = m_scheduleActions.value( m_scheduleActionGroup->checkedAction() );
2071 return s == 0 ? -1 : s->id();
2072}
2073
2074void View::setActiveSchedule( long id )
2075{
2076 if ( id != -1 ) {
2077 QMap<QAction*, Schedule*>::const_iterator it = m_scheduleActions.constBegin();
2078 for (; it != m_scheduleActions.constEnd(); ++it ) {
2079 if ( it.value()->id() == id ) {
2080 it.key()->setChecked( true );
2081 slotViewSchedule( it.key() ); // signal not emitted from group, so trigger it here
2082 break;
2083 }
2084 }
2085 }
2086}
2087
2088void View::slotTaskProgress()
2089{
2090 //kDebug(planDbg());
2091 Node * node = currentNode();
2092 if ( !node )
2093 return ;
2094
2095 switch ( node->type() ) {
2096 case Node::Type_Project: {
2097 break;
2098 }
2099 case Node::Type_Subproject:
2100 //TODO
2101 break;
2102 case Node::Type_Task: {
2103 Task *task = dynamic_cast<Task *>( node );
2104 Q_ASSERT( task );
2105 TaskProgressDialog *dia = new TaskProgressDialog( *task, currentScheduleManager(), getProject().standardWorktime(), this );
2106 connect(dia, SIGNAL(finished(int)), SLOT(slotTaskProgressFinished(int)));
2107 dia->show();
2108 dia->raise();
2109 dia->activateWindow();
2110 break;
2111 }
2112 case Node::Type_Milestone: {
2113 Task *task = dynamic_cast<Task *>( node );
2114 MilestoneProgressDialog *dia = new MilestoneProgressDialog( *task, this );
2115 connect(dia, SIGNAL(finished(int)), SLOT(slotMilestoneProgressFinished(int)));
2116 dia->show();
2117 dia->raise();
2118 dia->activateWindow();
2119 break;
2120 }
2121 case Node::Type_Summarytask: {
2122 // TODO
2123 break;
2124 }
2125 default:
2126 break; // avoid warnings
2127 }
2128}
2129
2130void View::slotTaskProgressFinished( int result )
2131{
2132 TaskProgressDialog *dia = qobject_cast<TaskProgressDialog*>(sender() );
2133 if ( dia == 0 ) {
2134 return;
2135 }
2136 if ( result == QDialog::Accepted) {
2137 KUndo2Command * m = dia->buildCommand();
2138 if ( m ) {
2139 getPart() ->addCommand( m );
2140 }
2141 }
2142 dia->deleteLater();
2143}
2144
2145void View::slotMilestoneProgressFinished( int result )
2146{
2147 MilestoneProgressDialog *dia = qobject_cast<MilestoneProgressDialog*>(sender() );
2148 if ( dia == 0 ) {
2149 return;
2150 }
2151 if ( result == QDialog::Accepted) {
2152 KUndo2Command * m = dia->buildCommand();
2153 if ( m ) {
2154 getPart() ->addCommand( m );
2155 }
2156 }
2157 dia->deleteLater();
2158}
2159
2160void View::slotTaskDescription()
2161{
2162 //kDebug(planDbg());
2163 Node * node = currentNode();
2164 if ( !node )
2165 return ;
2166
2167 switch ( node->type() ) {
2168 case Node::Type_Project: {
2169 break;
2170 }
2171 case Node::Type_Subproject:
2172 //TODO
2173 break;
2174 case Node::Type_Task:
2175 case Node::Type_Milestone:
2176 case Node::Type_Summarytask: {
2177 Task *task = dynamic_cast<Task *>( node );
2178 Q_ASSERT( task );
2179 TaskDescriptionDialog *dia = new TaskDescriptionDialog( *task, this );
2180 connect(dia, SIGNAL(finished(int)), SLOT(slotTaskDescriptionFinished(int)));
2181 dia->show();
2182 dia->raise();
2183 dia->activateWindow();
2184 break;
2185 }
2186 default:
2187 break; // avoid warnings
2188 }
2189}
2190
2191void View::slotTaskDescriptionFinished( int result )
2192{
2193 TaskDescriptionDialog *dia = qobject_cast<TaskDescriptionDialog*>(sender() );
2194 if ( dia == 0 ) {
2195 return;
2196 }
2197 if ( result == QDialog::Accepted) {
2198 KUndo2Command * m = dia->buildCommand();
2199 if ( m ) {
2200 getPart() ->addCommand( m );
2201 }
2202 }
2203 dia->deleteLater();
2204}
2205
2206void View::slotDeleteTask( QList<Node*> lst )
2207{
2208 //kDebug(planDbg());
2209 foreach ( Node *n, lst ) {
2210 if ( n->isScheduled() ) {
2211 int res = KMessageBox::warningContinueCancel( this, i18n( "A task that has been scheduled will be deleted. This will invalidate the schedule." ) );
2212 if ( res == KMessageBox::Cancel ) {
2213 return;
2214 }
2215 break;
2216 }
2217 }
2218 if ( lst.count() == 1 ) {
2219 getPart()->addCommand( new NodeDeleteCmd( lst.takeFirst(), kundo2_i18n( "Delete task" ) ) );
2220 return;
2221 }
2222 int num = 0;
2223 MacroCommand *cmd = new MacroCommand( kundo2_i18np( "Delete task", "Delete tasks", lst.count() ) );
2224 while ( !lst.isEmpty() ) {
2225 Node *node = lst.takeFirst();
2226 if ( node == 0 || node->parentNode() == 0 ) {
2227 kDebug(planDbg()) << ( node ?"Task is main project" :"No current task" );
2228 continue;
2229 }
2230 bool del = true;
2231 foreach ( Node *n, lst ) {
2232 if ( node->isChildOf( n ) ) {
2233 del = false; // node is going to be deleted when we delete n
2234 break;
2235 }
2236 }
2237 if ( del ) {
2238 //kDebug(planDbg())<<num<<": delete:"<<node->name();
2239 cmd->addCommand( new NodeDeleteCmd( node, kundo2_i18n( "Delete task" ) ) );
2240 num++;
2241 }
2242 }
2243 if ( num > 0 ) {
2244 getPart()->addCommand( cmd );
2245 } else {
2246 delete cmd;
2247 }
2248}
2249
2250void View::slotDeleteTask( Node *node )
2251{
2252 //kDebug(planDbg());
2253 if ( node == 0 || node->parentNode() == 0 ) {
2254 kDebug(planDbg()) << ( node ?"Task is main project" :"No current task" );
2255 return ;
2256 }
2257 if ( node->isScheduled() ) {
2258 int res = KMessageBox::warningContinueCancel( this, i18n( "This task has been scheduled. This will invalidate the schedule." ) );
2259 if ( res == KMessageBox::Cancel ) {
2260 return;
2261 }
2262 }
2263 NodeDeleteCmd *cmd = new NodeDeleteCmd( node, kundo2_i18n( "Delete task" ) );
2264 getPart() ->addCommand( cmd );
2265}
2266
2267void View::slotDeleteTask()
2268{
2269 //kDebug(planDbg());
2270 return slotDeleteTask( currentNode() );
2271}
2272
2273void View::slotIndentTask()
2274{
2275 //kDebug(planDbg());
2276 Node * node = currentNode();
2277 if ( node == 0 || node->parentNode() == 0 ) {
2278 kDebug(planDbg()) << ( node ?"Task is main project" :"No current task" );
2279 return ;
2280 }
2281 if ( getProject().canIndentTask( node ) ) {
2282 NodeIndentCmd * cmd = new NodeIndentCmd( *node, kundo2_i18n( "Indent task" ) );
2283 getPart() ->addCommand( cmd );
2284 }
2285}
2286
2287void View::slotUnindentTask()
2288{
2289 //kDebug(planDbg());
2290 Node * node = currentNode();
2291 if ( node == 0 || node->parentNode() == 0 ) {
2292 kDebug(planDbg()) << ( node ?"Task is main project" :"No current task" );
2293 return ;
2294 }
2295 if ( getProject().canUnindentTask( node ) ) {
2296 NodeUnindentCmd * cmd = new NodeUnindentCmd( *node, kundo2_i18n( "Unindent task" ) );
2297 getPart() ->addCommand( cmd );
2298 }
2299}
2300
2301void View::slotMoveTaskUp()
2302{
2303 //kDebug(planDbg());
2304
2305 Node * task = currentNode();
2306 if ( 0 == task ) {
2307 // is always != 0. At least we would get the Project, but you never know who might change that
2308 // so better be careful
2309 kError() << "No current task" << endl;
2310 return ;
2311 }
2312
2313 if ( Node::Type_Project == task->type() ) {
2314 kDebug(planDbg()) <<"The root node cannot be moved up";
2315 return ;
2316 }
2317 if ( getProject().canMoveTaskUp( task ) ) {
2318 NodeMoveUpCmd * cmd = new NodeMoveUpCmd( *task, kundo2_i18n( "Move task up" ) );
2319 getPart() ->addCommand( cmd );
2320 }
2321}
2322
2323void View::slotMoveTaskDown()
2324{
2325 //kDebug(planDbg());
2326
2327 Node * task = currentNode();
2328 if ( 0 == task ) {
2329 // is always != 0. At least we would get the Project, but you never know who might change that
2330 // so better be careful
2331 return ;
2332 }
2333
2334 if ( Node::Type_Project == task->type() ) {
2335 kDebug(planDbg()) <<"The root node cannot be moved down";
2336 return ;
2337 }
2338 if ( getProject().canMoveTaskDown( task ) ) {
2339 NodeMoveDownCmd * cmd = new NodeMoveDownCmd( *task, kundo2_i18n( "Move task down" ) );
2340 getPart() ->addCommand( cmd );
2341 }
2342}
2343
2344void View::slotAddRelation( Node *par, Node *child )
2345{
2346 //kDebug(planDbg());
2347 Relation * rel = new Relation( par, child );
2348 AddRelationDialog *dia = new AddRelationDialog( getProject(), rel, this );
2349 connect(dia, SIGNAL(finished(int)), SLOT(slotAddRelationFinished(int)));
2350 dia->show();
2351 dia->raise();
2352 dia->activateWindow();
2353}
2354
2355void View::slotAddRelationFinished( int result )
2356{
2357 AddRelationDialog *dia = qobject_cast<AddRelationDialog*>(sender() );
2358 if ( dia == 0 ) {
2359 return;
2360 }
2361 if ( result == QDialog::Accepted) {
2362 KUndo2Command * m = dia->buildCommand();
2363 if ( m ) {
2364 getPart() ->addCommand( m );
2365 }
2366 }
2367 dia->deleteLater();
2368}
2369
2370void View::slotAddRelation( Node *par, Node *child, int linkType )
2371{
2372 //kDebug(planDbg());
2373 if ( linkType == Relation::FinishStart ||
2374 linkType == Relation::StartStart ||
2375 linkType == Relation::FinishFinish ) {
2376 Relation * rel = new Relation( par, child, static_cast<Relation::Type>( linkType ) );
2377 getPart() ->addCommand( new AddRelationCmd( getProject(), rel, kundo2_i18n( "Add task dependency" ) ) );
2378 } else {
2379 slotAddRelation( par, child );
2380 }
2381}
2382
2383void View::slotModifyRelation( Relation *rel )
2384{
2385 //kDebug(planDbg());
2386 ModifyRelationDialog *dia = new ModifyRelationDialog( getProject(), rel, this );
2387 connect(dia, SIGNAL(finished(int)), SLOT(slotModifyRelationFinished(int)));
2388 dia->show();
2389 dia->raise();
2390 dia->activateWindow();
2391}
2392
2393void View::slotModifyRelationFinished( int result )
2394{
2395 ModifyRelationDialog *dia = qobject_cast<ModifyRelationDialog*>( sender() );
2396 if ( dia == 0 ) {
2397 return ;
2398 }
2399 if ( result == QDialog::Accepted) {
2400 KUndo2Command *cmd = dia->buildCommand();
2401 if ( cmd ) {
2402 getPart() ->addCommand( cmd );
2403 }
2404 }
2405 dia->deleteLater();
2406}
2407
2408void View::slotModifyRelation( Relation *rel, int linkType )
2409{
2410 //kDebug(planDbg());
2411 if ( linkType == Relation::FinishStart ||
2412 linkType == Relation::StartStart ||
2413 linkType == Relation::FinishFinish ) {
2414 getPart() ->addCommand( new ModifyRelationTypeCmd( rel, static_cast<Relation::Type>( linkType ) ) );
2415 } else {
2416 slotModifyRelation( rel );
2417 }
2418}
2419
2420void View::slotModifyRelation()
2421{
2422 ViewBase *v = dynamic_cast<ViewBase*>( m_tab->currentWidget() );
2423 if ( v == 0 ) {
2424 return;
2425 }
2426 Relation *rel = v->currentRelation();
2427 if ( rel ) {
2428 slotModifyRelation( rel );
2429 }
2430}
2431
2432void View::slotDeleteRelation()
2433{
2434 ViewBase *v = dynamic_cast<ViewBase*>( m_tab->currentWidget() );
2435 if ( v == 0 ) {
2436 return;
2437 }
2438 Relation *rel = v->currentRelation();
2439 if ( rel ) {
2440 getPart()->addCommand( new DeleteRelationCmd( getProject(), rel, kundo2_i18n( "Delete task dependency" ) ) );
2441 }
2442}
2443
2444void View::slotEditResource()
2445{
2446 //kDebug(planDbg());
2447 slotEditResource( currentResource() );
2448}
2449
2450void View::slotEditResource( Resource *resource )
2451{
2452 if ( resource == 0 ) {
2453 return ;
2454 }
2455 ResourceDialog *dia = new ResourceDialog( getProject(), resource, this );
2456 connect(dia, SIGNAL(finished(int)), SLOT(slotEditResourceFinished(int)));
2457 dia->show();
2458 dia->raise();
2459 dia->activateWindow();
2460}
2461
2462void View::slotEditResourceFinished( int result )
2463{
2464 //kDebug(planDbg());
2465 ResourceDialog *dia = qobject_cast<ResourceDialog*>( sender() );
2466 if ( dia == 0 ) {
2467 return ;
2468 }
2469 if ( result == QDialog::Accepted) {
2470 KUndo2Command * cmd = dia->buildCommand();
2471 if ( cmd )
2472 getPart() ->addCommand( cmd );
2473 }
2474 dia->deleteLater();
2475}
2476
2477void View::slotDeleteResource( Resource *resource )
2478{
2479 getPart()->addCommand( new RemoveResourceCmd( resource->parentGroup(), resource, kundo2_i18n( "Delete resource" ) ) );
2480}
2481
2482void View::slotDeleteResourceGroup( ResourceGroup *group )
2483{
2484 getPart()->addCommand( new RemoveResourceGroupCmd( group->project(), group, kundo2_i18n( "Delete resourcegroup" ) ) );
2485}
2486
2487void View::slotDeleteResourceObjects( QObjectList lst )
2488{
2489 //kDebug(planDbg());
2490 foreach ( QObject *o, lst ) {
2491 Resource *r = qobject_cast<Resource*>( o );
2492 if ( r && r->isScheduled() ) {
2493 int res = KMessageBox::warningContinueCancel( this, i18n( "A resource that has been scheduled will be deleted. This will invalidate the schedule." ) );
2494 if ( res == KMessageBox::Cancel ) {
2495 return;
2496 }
2497 break;
2498 }
2499 ResourceGroup *g = qobject_cast<ResourceGroup*>( o );
2500 if ( g && g->isScheduled() ) {
2501 int res = KMessageBox::warningContinueCancel( this, i18n( "A resource that has been scheduled will be deleted. This will invalidate the schedule." ) );
2502 if ( res == KMessageBox::Cancel ) {
2503 return;
2504 }
2505 break;
2506 }
2507 }
2508 if ( lst.count() == 1 ) {
2509 Resource *r = qobject_cast<Resource*>( lst.first() );
2510 if ( r ) {
2511 slotDeleteResource( r );
2512 } else {
2513 ResourceGroup *g = qobject_cast<ResourceGroup*>( lst.first() );
2514 if ( g ) {
2515 slotDeleteResourceGroup( g );
2516 }
2517 }
2518 return;
2519 }
2520// int num = 0;
2521 MacroCommand *cmd = 0, *rc = 0, *gc = 0;
2522 foreach ( QObject *o, lst ) {
2523 Resource *r = qobject_cast<Resource*>( o );
2524 if ( r ) {
2525 if ( rc == 0 ) rc = new MacroCommand( KUndo2MagicString() );
2526 rc->addCommand( new RemoveResourceCmd( r->parentGroup(), r ) );
2527 continue;
2528 }
2529 ResourceGroup *g = qobject_cast<ResourceGroup*>( o );
2530 if ( g ) {
2531 if ( gc == 0 ) gc = new MacroCommand( KUndo2MagicString() );
2532 gc->addCommand( new RemoveResourceGroupCmd( g->project(), g ) );
2533 }
2534 }
2535 if ( rc || gc ) {
2536 KUndo2MagicString s;
2537 if ( rc && gc ) {
2538 s = kundo2_i18n( "Delete resourcegroups and resources" );
2539 } else if ( rc ) {
2540 s = kundo2_i18np( "Delete resource", "Delete resources", lst.count() );
2541 } else {
2542 s = kundo2_i18np( "Delete resourcegroup", "Delete resourcegroups", lst.count() );
2543 }
2544 cmd = new MacroCommand( s );
2545 }
2546 if ( rc )
2547 cmd->addCommand( rc );
2548 if ( gc )
2549 cmd->addCommand( gc );
2550 if ( cmd )
2551 getPart()->addCommand( cmd );
2552}
2553
2554
2555void View::updateReadWrite( bool readwrite )
2556{
2557 m_readWrite = readwrite;
2558 m_viewlist->setReadWrite( readwrite );
2559}
2560
2561MainDocument *View::getPart() const
2562{
2563 return ( MainDocument * ) koDocument();
2564}
2565
2566KoPart *View::getKoPart() const
2567{
2568 return m_partpart;
2569}
2570
2571void View::slotConnectNode()
2572{
2573 //kDebug(planDbg());
2574 /* NodeItem *curr = ganttview->currentItem();
2575 if (curr) {
2576 kDebug(planDbg())<<"node="<<curr->getNode().name();
2577 }*/
2578}
2579
2580QMenu * View::popupMenu( const QString& name )
2581{
2582 //kDebug(planDbg());
2583 if ( factory() )
2584 return ( ( QMenu* ) factory() ->container( name, this ) );
2585 return 0L;
2586}
2587
2588void View::slotUpdate()
2589{
2590 //kDebug(planDbg())<<"calculate="<<calculate;
2591
2592// m_updateResourceview = true;
2593 m_updateResourceAssignmentView = true;
2594 m_updatePertEditor = true;
2595 updateView( m_tab->currentWidget() );
2596}
2597
2598void View::slotGuiActivated( ViewBase *view, bool activate )
2599{
2600 //FIXME: Avoid unplug if possible, it flashes the gui
2601 // always unplug, in case they already are plugged
2602 foreach( const QString &name, view->actionListNames() ) {
2603 unplugActionList( name );
2604 }
2605 if ( activate ) {
2606 foreach( const QString &name, view->actionListNames() ) {
2607 plugActionList( name, view->actionList( name ) );
2608 }
2609 foreach ( DockWidget *ds, view->dockers() ) {
2610 m_dockers.append( ds );
2611 ds->activate( mainWindow() );
2612 }
2613 kDebug(planDbg())<<"Added dockers:"<<view<<m_dockers;
2614 } else {
2615 kDebug(planDbg())<<"Remove dockers:"<<view<<m_dockers;
2616 while ( ! m_dockers.isEmpty() ) {
2617 m_dockers.takeLast()->deactivate( mainWindow() );
2618 }
2619 }
2620}
2621
2622void View::guiActivateEvent( bool activated )
2623{
2624 if ( activated ) {
2625 // plug my own actionlists, they may be gone
2626 slotPlugScheduleActions();
2627 }
2628 // propagate to sub-view
2629 ViewBase *v = dynamic_cast<ViewBase*>( m_tab->currentWidget() );
2630 if ( v ) {
2631 v->setGuiActive( activated );
2632 }
2633}
2634
2635void View::slotViewListItemRemoved( ViewListItem *item )
2636{
2637 getPart()->removeViewListItem( this, item );
2638}
2639
2640void View::removeViewListItem( const ViewListItem *item )
2641{
2642 if ( item == 0 ) {
2643 return;
2644 }
2645 ViewListItem *itm = m_viewlist->findItem( item->tag() );
2646 if ( itm == 0 ) {
2647 return;
2648 }
2649 m_viewlist->removeViewListItem( itm );
2650 return;
2651}
2652
2653void View::slotViewListItemInserted( ViewListItem *item, ViewListItem *parent, int index )
2654{
2655 getPart()->insertViewListItem( this, item, parent, index );
2656}
2657
2658void View::addViewListItem( const ViewListItem *item, const ViewListItem *parent, int index )
2659{
2660 if ( item == 0 ) {
2661 return;
2662 }
2663 if ( parent == 0 ) {
2664 if ( item->type() != ViewListItem::ItemType_Category ) {
2665 return;
2666 }
2667 m_viewlist->blockSignals( true );
2668 ViewListItem *cat = m_viewlist->addCategory( item->tag(), item->text( 0 ) );
2669 cat->setToolTip( 0, item->toolTip( 0 ) );
2670 m_viewlist->blockSignals( false );
2671 return;
2672 }
2673 ViewListItem *cat = m_viewlist->findCategory( parent->tag() );
2674 if ( cat == 0 ) {
2675 return;
2676 }
2677 m_viewlist->blockSignals( true );
2678 createView( cat, item->viewType(), item->tag(), item->text( 0 ), item->toolTip( 0 ), index );
2679 m_viewlist->blockSignals( false );
2680}
2681/*
2682void View::slotCreateReport()
2683{
2684 ReportView v(getKoPart(), getPart(), 0 );
2685 ReportDesignDialog *dlg = new ReportDesignDialog( &(getProject()), currentScheduleManager(), QDomElement(), v.createReportModels( &getProject(), currentScheduleManager() ), this );
2686 // The ReportDesignDialog can not know how to create and insert views,
2687 // so faciclitate this in the slotCreateReportView() slot.
2688 connect( dlg, SIGNAL(createReportView(ReportDesignDialog*)), SLOT(slotCreateReportView(ReportDesignDialog*)));
2689 connect(dlg, SIGNAL(finished(int)), SLOT(slotReportDesignFinished(int)));
2690 connect(dlg, SIGNAL(modifyReportDefinition(KUndo2Command*)), SLOT(slotModifyReportDefinition(KUndo2Command*)));
2691 dlg->show();
2692 dlg->raise();
2693 dlg->activateWindow();
2694}
2695*/
2696void View::slotCreateReportView( ReportDesignDialog *dlg )
2697{
2698 QPointer<ViewListReportsDialog> vd = new ViewListReportsDialog( this, *m_viewlist, dlg );
2699 connect( vd, SIGNAL(viewCreated(ViewBase*)), dlg, SLOT(slotViewCreated(ViewBase*)) );
2700 vd->exec();
2701 delete vd;
2702}
2703
2704void View::slotOpenReportFile()
2705{
2706 KFileDialog *dlg = new KFileDialog( KUrl(), QString(), this );
2707 connect(dlg, SIGNAL(finished(int)), SLOT(slotOpenReportFileFinished(int)));
2708 dlg->show();
2709 dlg->raise();
2710 dlg->activateWindow();
2711}
2712
2713void View::slotOpenReportFileFinished( int result )
2714{
2715 KFileDialog *fdlg = qobject_cast<KFileDialog*>( sender() );
2716 if ( fdlg == 0 || result != QDialog::Accepted ) {
2717 return;
2718 }
2719 QString fn = fdlg->selectedFile();
2720 if ( fn.isEmpty() ) {
2721 return;
2722 }
2723 QFile file( fn );
2724 if ( ! file.open( QIODevice::ReadOnly | QIODevice::Text ) ) {
2725 KMessageBox::sorry( this, i18nc( "@info", "Cannot open file:<br/><filename>%1</filename>", fn ) );
2726 return;
2727 }
2728 QDomDocument doc;
2729 doc.setContent( &file );
2730 QDomElement e = doc.documentElement();
2731 ReportDesignDialog *dlg = new ReportDesignDialog( e, Report::createBaseReportDataModels( this ), this );
2732 // The ReportDesignDialog can not know how to create and insert views,
2733 // so faciclitate this in the slotCreateReportView() slot.
2734 connect( dlg, SIGNAL(createReportView(ReportDesignDialog*)), SLOT(slotCreateReportView(ReportDesignDialog*)));
2735 connect(dlg, SIGNAL(modifyReportDefinition(KUndo2Command*)), SLOT(slotModifyReportDefinition(KUndo2Command*)));
2736 connect(dlg, SIGNAL(finished(int)), SLOT(slotReportDesignFinished(int)));
2737 dlg->show();
2738 dlg->raise();
2739 dlg->activateWindow();
2740}
2741
2742void View::slotReportDesignFinished( int /*result */)
2743{
2744 if ( sender() ) {
2745 sender()->deleteLater();
2746 }
2747}
2748
2749void View::slotModifyReportDefinition( KUndo2Command *cmd )
2750{
2751 cmd->redo();
2752 delete cmd; // TODO Maybe add command history to views and/or view selector?
2753 m_viewlist->setModified();
2754}
2755
2756void View::slotCreateView()
2757{
2758 ViewListDialog *dlg = new ViewListDialog( this, *m_viewlist, this );
2759 connect(dlg, SIGNAL(finished(int)), SLOT(slotCreateViewFinished(int)));
2760 dlg->show();
2761 dlg->raise();
2762 dlg->activateWindow();
2763}
2764
2765void View::slotCreateViewFinished( int )
2766{
2767 if ( sender() ) {
2768 sender()->deleteLater();
2769 }
2770}
2771
2772void View::slotViewActivated( ViewListItem *item, ViewListItem *prev )
2773{
2774 QApplication::setOverrideCursor( Qt::WaitCursor );
2775 if ( prev && prev->type() == ViewListItem::ItemType_Category && m_viewlist->previousViewItem() ) {
2776 // A view is shown anyway...
2777 ViewBase *v = qobject_cast<ViewBase*>( m_viewlist->previousViewItem()->view() );
2778 if ( v ) {
2779 v->setGuiActive( false );
2780 }
2781 } else if ( prev && prev->type() == ViewListItem::ItemType_SubView ) {
2782 ViewBase *v = qobject_cast<ViewBase*>( prev->view() );
2783 if ( v ) {
2784 v->setGuiActive( false );
2785 }
2786 }
2787 if ( item && item->type() == ViewListItem::ItemType_SubView ) {
2788 //kDebug(planDbg())<<"Activate:"<<item;
2789 m_tab->setCurrentWidget( item->view() );
2790 // Add sub-view specific gui
2791 ViewBase *v = dynamic_cast<ViewBase*>( m_tab->currentWidget() );
2792 if ( v ) {
2793 v->setGuiActive( true );
2794 }
2795 }
2796 QApplication::restoreOverrideCursor();
2797}
2798
2799QWidget *View::canvas() const
2800{
2801 return m_tab->currentWidget();//KoView::canvas();
2802}
2803
2804KoPageLayout View::pageLayout() const
2805{
2806 return currentView()->pageLayout();
2807}
2808
2809QPrintDialog *View::createPrintDialog( KoPrintJob *printJob, QWidget *parent )
2810{
2811 kDebug(planDbg())<<printJob;
2812 KoPrintingDialog *job = dynamic_cast<KoPrintingDialog*>( printJob );
2813 if ( ! job ) {
2814 return 0;
2815 }
2816 QPrintDialog *dia = KoView::createPrintDialog( job, parent );
2817
2818 PrintingDialog *j = dynamic_cast<PrintingDialog*>( job );
2819 if ( j ) {
2820 new PrintingControlPrivate( j, dia );
2821 }
2822 return dia;
2823}
2824
2825void View::slotCurrentChanged( int )
2826{
2827 ViewListItem *item = m_viewlist->findItem( qobject_cast<ViewBase*>( m_tab->currentWidget() ) );
2828 m_viewlist->setCurrentItem( item );
2829}
2830
2831void View::updateView( QWidget * )
2832{
2833 QApplication::setOverrideCursor( Qt::WaitCursor );
2834 //setScheduleActionsEnabled();
2835
2836 QWidget *widget2;
2837
2838 widget2 = m_viewlist->findView( "ResourceAssignmentView" );
2839 if ( widget2 && m_updateResourceAssignmentView )
2840 static_cast<ViewBase*>( widget2 ) ->draw( getProject() );
2841 m_updateResourceAssignmentView = false;
2842
2843 QApplication::restoreOverrideCursor();
2844}
2845
2846void View::slotRenameNode( Node *node, const QString& name )
2847{
2848 //kDebug(planDbg())<<name;
2849 if ( node ) {
2850 KUndo2MagicString s = kundo2_i18n( "Modify name" );
2851 switch( node->type() ) {
2852 case Node::Type_Task: s = kundo2_i18n( "Modify task name" ); break;
2853 case Node::Type_Milestone: s = kundo2_i18n( "Modify milestone name" ); break;
2854 case Node::Type_Summarytask: s = kundo2_i18n( "Modify summarytask name" ); break;
2855 case Node::Type_Project: s = kundo2_i18n( "Modify project name" ); break;
2856 }
2857 NodeModifyNameCmd * cmd = new NodeModifyNameCmd( *node, name, s );
2858 getPart() ->addCommand( cmd );
2859 }
2860}
2861
2862void View::slotPopupMenu( const QString& menuname, const QPoint & pos )
2863{
2864 QMenu * menu = this->popupMenu( menuname );
2865 if ( menu ) {
2866 //kDebug(planDbg())<<menu<<":"<<menu->actions().count();
2867 ViewBase *v = qobject_cast<ViewBase*>( m_tab->currentWidget() );
2868 kDebug(planDbg())<<v<<menuname;
2869 QList<QAction*> lst;
2870 if ( v ) {
2871 lst = v->contextActionList();
2872 kDebug(planDbg())<<lst;
2873 if ( ! lst.isEmpty() ) {
2874 menu->addSeparator();
2875 foreach ( QAction *a, lst ) {
2876 menu->addAction( a );
2877 }
2878 }
2879 }
2880 menu->exec( pos );
2881 foreach ( QAction *a, lst ) {
2882 menu->removeAction( a );
2883 }
2884 }
2885}
2886
2887void View::slotPopupMenu( const QString& menuname, const QPoint &pos, ViewListItem *item )
2888{
2889 //kDebug(planDbg())<<menuname;
2890 m_viewlistItem = item;
2891 slotPopupMenu( menuname, pos );
2892}
2893
2894bool View::loadContext()
2895{
2896 Context *ctx = getPart()->context();
2897 if ( ctx == 0 || ! ctx->isLoaded() ) {
2898 return false;
2899 }
2900 KoXmlElement n = ctx->context();
2901 QString cv = n.attribute( "current-view" );
2902 if ( ! cv.isEmpty() ) {
2903 m_viewlist->setSelected( m_viewlist->findItem( cv ) );
2904 } else kDebug(planDbg())<<"No current view";
2905
2906 long id = n.attribute( "current-schedule", "-1" ).toLong();
2907 if ( id != -1 ) {
2908 setActiveSchedule( id );
2909 } else kDebug(planDbg())<<"No current schedule";
2910
2911 return true;
2912}
2913
2914void View::saveContext( QDomElement &me ) const
2915{
2916 //kDebug(planDbg());
2917 long id = activeScheduleId();
2918 if ( id != -1 ) {
2919 me.setAttribute( "current-schedule", (qlonglong)id );
2920 }
2921 ViewListItem *item = m_viewlist->findItem( qobject_cast<ViewBase*>( m_tab->currentWidget() ) );
2922 if ( item ) {
2923 me.setAttribute("current-view", item->tag() );
2924 }
2925 m_viewlist->save( me );
2926}
2927
2928bool View::loadWorkPackage( Project &project, const KUrl &url )
2929{
2930 return getPart()->loadWorkPackage( project, url );
2931}
2932
2933void View::setLabel( ScheduleManager *sm )
2934{
2935 //kDebug(planDbg());
2936 Schedule *s = sm == 0 ? 0 : sm->expected();
2937 if ( s && !s->isDeleted() && s->isScheduled() ) {
2938 m_estlabel->setText( sm->name() );
2939 return;
2940 }
2941 m_estlabel->setText( i18nc( "@info:status", "Not scheduled" ) );
2942}
2943
2944void View::slotWorkPackageLoaded()
2945{
2946 kDebug(planDbg())<<getPart()->workPackages();
2947}
2948
2949void View::slotMailWorkpackage( Node *node, Resource *resource )
2950{
2951 kDebug(planDbg());
2952 KTemporaryFile tmpfile;
2953 tmpfile.setAutoRemove( false );
2954 tmpfile.setSuffix( ".planwork" );
2955 if ( ! tmpfile.open() ) {
2956 kDebug(planDbg())<<"Failed to open file";
2957 KMessageBox::error(0, i18n("Failed to open temporary file" ) );
2958 return;
2959 }
2960 KUrl url;
2961 url.setPath( tmpfile.fileName() );
2962 if ( ! getPart()->saveWorkPackageUrl( url, node, activeScheduleId(), resource ) ) {
2963 kDebug(planDbg())<<"Failed to save to file";
2964 KMessageBox::error(0, i18nc( "@info", "Failed to save to temporary file:<br/> <filename>%1</filename>", url.url() ) );
2965 return;
2966 }
2967 QStringList attachURLs;
2968 attachURLs << url.url();
2969 QString to = resource == 0 ? node->leader() : ( resource->name() + " <" + resource->email() + '>' );
2970 QString cc;
2971 QString bcc;
2972 QString subject = i18n( "Work Package: %1", node->name() );
2973 QString body = i18nc( "1=project name, 2=task name", "%1\n%2", getProject().name(), node->name() );
2974 QString messageFile;
2975
2976 KToolInvocation::invokeMailer( to, cc, bcc, subject, body, messageFile, attachURLs );
2977}
2978
2979void View::slotMailWorkpackages( const QList<Node*> &nodes, Resource *resource )
2980{
2981 kDebug(planDbg());
2982 if ( resource == 0 ) {
2983 kWarning()<<"No resource, we don't handle node->leader() yet";
2984 return;
2985 }
2986 QString to = resource->name() + " <" + resource->email() + '>';
2987 QString subject = i18n( "Work Package for project: %1", getProject().name() );
2988 QString body;
2989 QStringList attachURLs;
2990
2991 foreach ( Node *n, nodes ) {
2992 KTemporaryFile tmpfile;
2993 tmpfile.setAutoRemove( false );
2994 tmpfile.setSuffix( ".planwork" );
2995 if ( ! tmpfile.open() ) {
2996 kDebug(planDbg())<<"Failed to open file";
2997 KMessageBox::error(0, i18n("Failed to open temporary file" ) );
2998 return;
2999 }
3000 KUrl url;
3001 url.setPath( tmpfile.fileName() );
3002 if ( ! getPart()->saveWorkPackageUrl( url, n, activeScheduleId(), resource ) ) {
3003 kDebug(planDbg())<<"Failed to save to file";
3004 KMessageBox::error(0, i18nc( "@info", "Failed to save to temporary file:<br><filename>%1</filename>", url.url() ) );
3005 return;
3006 }
3007 attachURLs << url.url();
3008 body += n->name() + '\n';
3009 }
3010
3011 QString cc;
3012 QString bcc;
3013 QString messageFile;
3014
3015 KToolInvocation::invokeMailer( to, cc, bcc, subject, body, messageFile, attachURLs );
3016}
3017
3018void View::slotCurrencyConfig()
3019{
3020 LocaleConfigMoneyDialog *dlg = new LocaleConfigMoneyDialog( getProject().locale(), this );
3021 connect(dlg, SIGNAL(finished(int)), SLOT(slotCurrencyConfigFinished(int)));
3022 dlg->show();
3023 dlg->raise();
3024 dlg->activateWindow();
3025}
3026
3027void View::slotCurrencyConfigFinished( int result )
3028{
3029 LocaleConfigMoneyDialog *dlg = qobject_cast<LocaleConfigMoneyDialog*>( sender() );
3030 if ( dlg == 0 ) {
3031 return;
3032 }
3033 if ( result == QDialog::Accepted ) {
3034 KUndo2Command *c = dlg->buildCommand( getProject() );
3035 if ( c ) {
3036 getPart()->addCommand( c );
3037 }
3038 }
3039 dlg->deleteLater();
3040}
3041
3042void View::saveTaskModule( const KUrl &url, Project *project )
3043{
3044 kDebug(planDbg())<<url<<project;
3045 QString dir = Factory::global().dirs()->saveLocation( "plan_taskmodules" );
3046 kDebug(planDbg())<<"dir="<<dir;
3047 if ( ! dir.isEmpty() ) {
3048 MainDocument part(getKoPart());
3049 part.insertProject( *project, 0, 0 );
3050 part.getProject().setName( project->name() );
3051 part.getProject().setLeader( project->leader() );
3052 part.getProject().setDescription( project->description() );
3053 part.saveNativeFormat( dir + url.fileName() );
3054 kDebug(planDbg())<<dir + url.fileName();
3055 } else {
3056 kDebug(planDbg())<<"Could not find a location";
3057 }
3058}
3059
3060void View::removeTaskModule( const KUrl &url )
3061{
3062 kDebug(planDbg())<<url;
3063}
3064
3065QString View::standardTaskStatusReport() const
3066{
3067 QString s = QString::fromLatin1(
3068 "<planreportdefinition version=\"1.0\" mime=\"application/x-vnd.kde.plan.report.definition\" editor=\"Plan\" >"
3069 "<data-source select-from=\"taskstatus\" ></data-source>"
3070 "<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\" >"
3071 "<report:title>%1</report:title>"
3072 "<report:script report:script-interpreter=\"javascript\" ></report:script>"
3073 "<report:grid report:grid-divisions=\"4\" report:grid-snap=\"1\" report:page-unit=\"cm\" report:grid-visible=\"1\" />"
3074 "<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>"
3075 "<report:body>"
3076 "<report:section svg:height=\"1.75cm\" fo:background-color=\"#ffffff\" report:section-type=\"header-page-any\" >"
3077 "<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\" >"
3078 "<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%\" />"
3079 "<report:line-style report:line-style=\"nopen\" report:line-weight=\"1\" report:line-color=\"#000000\" />"
3080 "</report:field>"
3081 "<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\" >"
3082 "<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%\" />"
3083 "<report:line-style report:line-style=\"nopen\" report:line-weight=\"1\" report:line-color=\"#000000\" />"
3084 "</report:label>"
3085 "<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\" >"
3086 "<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%\" />"
3087 "<report:line-style report:line-style=\"nopen\" report:line-weight=\"1\" report:line-color=\"#000000\" />"
3088 "</report:field>"
3089 "<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\" >"
3090 "<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%\" />"
3091 "<report:line-style report:line-style=\"nopen\" report:line-weight=\"1\" report:line-color=\"#000000\" />"
3092 "</report:label>"
3093 "<report:line report:name=\"line15\" svg:y1=\"1.2229cm\" svg:x1=\"0cm\" svg:y2=\"1.2229cm\" svg:x2=\"18.9715cm\" report:z-index=\"0\" >"
3094 "<report:line-style report:line-style=\"solid\" report:line-weight=\"1\" report:line-color=\"#000000\" />"
3095 "</report:line>"
3096 "</report:section>"
3097 "<report:section svg:height=\"1.50cm\" fo:background-color=\"#ffffff\" report:section-type=\"header-report\" >"
3098 "<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\" >"
3099 "<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%\" />"
3100 "<report:line-style report:line-style=\"nopen\" report:line-weight=\"1\" report:line-color=\"#000000\" />"
3101 "</report:label>"
3102 "</report:section>"
3103 "<report:section svg:height=\"2.50cm\" fo:background-color=\"#ffffff\" report:section-type=\"footer-page-any\" >"
3104 "<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\" >"
3105 "<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%\" />"
3106 "<report:line-style report:line-style=\"nopen\" report:line-weight=\"1\" report:line-color=\"#000000\" />"
3107 "</report:field>"
3108 "<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\" >"
3109 "<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%\" />"
3110 "<report:line-style report:line-style=\"nopen\" report:line-weight=\"1\" report:line-color=\"#000000\" />"
3111 "</report:field>"
3112 "<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\" >"
3113 "<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%\" />"
3114 "<report:line-style report:line-style=\"nopen\" report:line-weight=\"1\" report:line-color=\"#000000\" />"
3115 "</report:label>"
3116 "<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\" >"
3117 "<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%\" />"
3118 "<report:line-style report:line-style=\"nopen\" report:line-weight=\"1\" report:line-color=\"#000000\" />"
3119 "</report:label>"
3120 "<report:line report:name=\"line14\" svg:y1=\"0.2195cm\" svg:x1=\"0cm\" svg:y2=\"0.2195cm\" svg:x2=\"18.9715cm\" report:z-index=\"0\" >"
3121 "<report:line-style report:line-style=\"solid\" report:line-weight=\"1\" report:line-color=\"#000000\" />"
3122 "</report:line>"
3123 "</report:section>"
3124 "<report:detail>"
3125 "<report:group report:group-sort=\"ascending\" report:group-column=\"Parent\" >"
3126 "<report:section svg:height=\"2.50cm\" fo:background-color=\"#ffffff\" report:section-type=\"group-header\" >"
3127 "<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\" >"
3128 "<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%\" />"
3129 "<report:line-style report:line-style=\"nopen\" report:line-weight=\"1\" report:line-color=\"#000000\" />"
3130 "</report:label>"
3131 "<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\" >"
3132 "<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%\" />"
3133 "<report:line-style report:line-style=\"nopen\" report:line-weight=\"1\" report:line-color=\"#000000\" />"
3134 "</report:field>"
3135 "<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\" >"
3136 "<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%\" />"
3137 "<report:line-style report:line-style=\"nopen\" report:line-weight=\"1\" report:line-color=\"#000000\" />"
3138 "</report:label>"
3139 "</report:section>"
3140 "</report:group>"
3141 "<report:section svg:height=\"0.50cm\" fo:background-color=\"#ffffff\" report:section-type=\"detail\" >"
3142 "<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\" >"
3143 "<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%\" />"
3144 "<report:line-style report:line-style=\"nopen\" report:line-weight=\"1\" report:line-color=\"#000000\" />"
3145 "</report:field>"
3146 "<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\" >"
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:section>"
3151 "</report:detail>"
3152 "</report:body>"
3153 "</report:content>"
3154 "</planreportdefinition>")
3155 .arg(
3156 i18n( "Report" ),
3157 i18nc( "Project manager", "Manager:" ),
3158 i18n( "Project:" ),
3159 i18n( "Task Status Report" ),
3160 i18nc( "As in: Page 1 of 2", "of" ),
3161 i18n( "Page" ),
3162 i18nc( "Task name", "Name" ),
3163 i18nc( "Task completion", "Completion (%)" )
3164 );
3165 return s;
3166}
3167
3168//---------------------------------
3169PrintingControlPrivate::PrintingControlPrivate( PrintingDialog *job, QPrintDialog *dia )
3170 : QObject( dia ),
3171 m_job( job ),
3172 m_dia( dia )
3173{
3174 connect(job, SIGNAL(changed()), SLOT(slotChanged()));
3175}
3176
3177void PrintingControlPrivate::slotChanged()
3178{
3179 if ( ! m_job || ! m_dia ) {
3180 return;
3181 }
3182 QSpinBox *to = m_dia->findChild<QSpinBox*>("to");
3183 QSpinBox *from = m_dia->findChild<QSpinBox*>("from");
3184 if ( to && from ) {
3185 from->setMinimum( m_job->documentFirstPage() );
3186 from->setMaximum( m_job->documentLastPage() );
3187 from->setValue( from->minimum() );
3188 to->setMinimum( from->minimum() );
3189 to->setMaximum( from->maximum() );
3190 to->setValue( to->maximum() );
3191 }
3192}
3193
3194
3195} //KPlato namespace
3196
3197#include "kptprintingcontrolprivate.moc"
3198#include "kptview.moc"
3199