summaryrefslogtreecommitdiffstats
path: root/kplato/kptpart.cc
diff options
context:
space:
mode:
Diffstat (limited to 'kplato/kptpart.cc')
-rw-r--r--kplato/kptpart.cc419
1 files changed, 419 insertions, 0 deletions
diff --git a/kplato/kptpart.cc b/kplato/kptpart.cc
new file mode 100644
index 00000000..42055e88
--- /dev/null
+++ b/kplato/kptpart.cc
@@ -0,0 +1,419 @@
+/* This file is part of the KDE project
+ Copyright (C) 1998, 1999, 2000 Torben Weis <[email protected]>
+ Copyright (C) 2004, 2005 Dag Andersen <[email protected]>
+ Copyright (C) 2006 Raphael Langerhorst <[email protected]>
+ Copyright (C) 2006 Dag Andersen <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+
+#include "kptpart.h"
+#include "kptview.h"
+#include "kptfactory.h"
+#include "kptproject.h"
+#include "kptprojectdialog.h"
+#include "kptresource.h"
+#include "kptcontext.h"
+#include "kptganttview.h"
+#include "KDGanttViewTaskLink.h"
+
+#include <qpainter.h>
+#include <qfileinfo.h>
+
+#include <kdebug.h>
+#include <kconfig.h>
+#include <klocale.h>
+#include <kmessagebox.h>
+#include <kstandarddirs.h>
+#include <kcommand.h>
+#include <KoTemplateChooseDia.h>
+#include <KoCommandHistory.h>
+#include <KoGlobal.h>
+
+#define CURRENT_SYNTAX_VERSION "0.5"
+
+namespace KPlato
+{
+
+Part::Part(QWidget *parentWidget, const char *widgetName,
+ QObject *parent, const char *name, bool singleViewMode)
+ : KoDocument(parentWidget, widgetName, parent, name, singleViewMode),
+ m_project(0), m_projectDialog(0), m_parentWidget(parentWidget), m_view(0),
+ m_embeddedGanttView(new GanttView(parentWidget)),
+ m_embeddedContext(new Context()), m_embeddedContextInitialized(false),
+ m_context(0), m_xmlLoader()
+{
+ m_update = m_calculate = false;
+ m_commandHistory = new KoCommandHistory(actionCollection());
+
+ setInstance(Factory::global());
+ setTemplateType("kplato_template");
+ m_config.setReadWrite(isReadWrite()|| !isEmbedded());
+ m_config.load();
+
+ delete m_project;
+ m_project = new Project(); // after config is loaded
+
+ connect(m_commandHistory, SIGNAL(commandExecuted()), SLOT(slotCommandExecuted()));
+ connect(m_commandHistory, SIGNAL(documentRestored()), SLOT(slotDocumentRestored()));
+
+ //FIXME the following is really dirty, we should make KPlato::Context a real class
+ // with getter and setter and signals when content changes, thus we can keep track
+ QTimer* timer = new QTimer(this,"context update timer");
+ connect(timer,SIGNAL(timeout()),this,SLOT(slotCopyContextFromView()));
+ timer->start(500);
+}
+
+
+Part::~Part() {
+ m_config.save();
+ delete m_commandHistory; // before project, in case of dependencies...
+ delete m_project;
+ delete m_projectDialog;
+ if (m_embeddedGanttView)
+ delete m_embeddedGanttView;
+ if (m_embeddedContext)
+ delete m_embeddedContext;
+}
+
+
+bool Part::initDoc(InitDocFlags flags, QWidget* parentWidget) {
+ bool result = true;
+
+ if (flags==KoDocument::InitDocEmpty)
+ {
+ delete m_project;
+ m_project = new Project();
+ setAutoSave(0); // disable
+ setModified(false);
+ return true;
+ }
+
+ QString templateDoc;
+ KoTemplateChooseDia::ReturnType ret;
+ KoTemplateChooseDia::DialogType dlgtype;
+ if (flags != KoDocument::InitDocFileNew )
+ dlgtype = KoTemplateChooseDia::Everything;
+ else
+ dlgtype = KoTemplateChooseDia::OnlyTemplates;
+
+ ret = KoTemplateChooseDia::choose(Factory::global(), templateDoc,
+ dlgtype,
+ "kplato_template",
+ parentWidget);
+ if (ret == KoTemplateChooseDia::Template) {
+ resetURL();
+ result = loadNativeFormat(templateDoc);
+ if ( !result )
+ showLoadingErrorDialog();
+ } else if (ret == KoTemplateChooseDia::File) {
+ KURL url(templateDoc);
+ kdDebug() << "Part::initDoc opening URL " << url.prettyURL() <<endl;
+ result = openURL(url);
+ } else if (ret == KoTemplateChooseDia::Empty) {
+ // Make a fresh project and let the user enter some info
+ delete m_project;
+ m_project = new Project();
+ // an emty project should be empty
+ // m_projectDialog = new ProjectDialog(*m_project, m_view);
+ // m_projectDialog->exec();
+
+ result = true;
+ } else {
+ result = false;
+ }
+ setAutoSave(0); // disable
+ setModified(false);
+ return result;
+}
+
+
+KoView *Part::createViewInstance(QWidget *parent, const char *name) {
+ m_view = new View(this, parent, name);
+ connect(m_view,SIGNAL(destroyed()),this,SLOT(slotViewDestroyed()));
+
+ // If there is a project dialog this should be deleted so it will
+ // use the m_view as parent. If the dialog will be needed again,
+ // it will be made at that point
+ if (m_projectDialog != 0) {
+ kdDebug() << "Deleting m_projectDialog because of new ViewInstance\n";
+ delete m_projectDialog;
+ m_projectDialog = 0;
+ }
+ if (m_context)
+ m_view->setContext( *m_context );
+ else if (m_embeddedContext && m_embeddedContextInitialized)
+ m_view->setContext( *m_embeddedContext );
+ else {
+ // Activate menu actions. Assumes ganttview, we don't get any
+ // 'aboutToShow' signal. Need to redo action control.
+ m_view->setTaskActionsEnabled(true);
+ }
+ //m_view->setBaselineMode(getProject().isBaselined()); FIXME: Removed for this release
+ return m_view;
+}
+
+
+void Part::editProject() {
+
+ QWidget* parent = m_parentWidget;
+ if (m_view)
+ parent = m_view;
+
+ if (m_projectDialog == 0)
+ // Make the dialog
+ m_projectDialog = new ProjectDialog(*m_project, parent);
+
+ m_projectDialog->exec();
+}
+
+
+bool Part::loadXML(QIODevice *, const QDomDocument &document) {
+ QTime dt;
+ dt.start();
+ emit sigProgress( 0 );
+
+ QString value;
+ QDomElement plan = document.documentElement();
+
+ // Check if this is the right app
+ value = plan.attribute("mime", QString::null);
+ if (value.isEmpty()) {
+ kdError() << "No mime type specified!" << endl;
+ setErrorMessage(i18n("Invalid document. No mimetype specified."));
+ return false;
+ }
+ else if (value != "application/x-vnd.kde.kplato") {
+ kdError() << "Unknown mime type " << value << endl;
+ setErrorMessage(i18n("Invalid document. Expected mimetype application/x-vnd.kde.kplato, got %1").arg(value));
+ return false;
+ }
+ QString m_syntaxVersion = plan.attribute("version", CURRENT_SYNTAX_VERSION);
+ if (m_syntaxVersion > CURRENT_SYNTAX_VERSION) {
+ int ret = KMessageBox::warningContinueCancel(
+ 0, i18n("This document was created with a newer version of KPlato (syntax version: %1)\n"
+ "Opening it in this version of KPlato will lose some information.").arg(m_syntaxVersion),
+ i18n("File-Format Mismatch"), i18n("Continue") );
+ if (ret == KMessageBox::Cancel)
+ {
+ setErrorMessage("USER_CANCELED");
+ return false;
+ }
+ }
+ emit sigProgress(5);
+
+ QDomNodeList list = plan.childNodes();
+ if (list.count() > 2) {
+ // TODO: Make a proper bitching about this
+ kdDebug() << "*** Error ***\n";
+ kdDebug() << " Children count should be 1 but is " << list.count()
+ << "\n";
+ return false;
+ }
+ m_xmlLoader.startLoad();
+ for (unsigned int i = 0; i < list.count(); ++i) {
+ if (list.item(i).isElement()) {
+ QDomElement e = list.item(i).toElement();
+
+ if (e.tagName() == "context") {
+ delete m_context;
+ m_context = new Context();
+ m_context->load(e);
+ } else if (e.tagName() == "project") {
+ Project *newProject = new Project();
+ if (newProject->load(e)) {
+ // The load went fine. Throw out the old project
+ delete m_project;
+ m_project = newProject;
+ delete m_projectDialog;
+ m_projectDialog = 0;
+ }
+ else {
+ delete newProject;
+ m_xmlLoader.addMsg(XMLLoaderObject::Errors, "Loading of project failed");
+ //TODO add some ui here
+ }
+ }
+ }
+ }
+ m_xmlLoader.stopLoad();
+ emit sigProgress(100); // the rest is only processing, not loading
+
+ kdDebug() << "Loading took " << (float)(dt.elapsed()) / 1000 << " seconds" << endl;
+
+ // do some sanity checking on document.
+ emit sigProgress(-1);
+
+ m_commandHistory->clear();
+ m_commandHistory->documentSaved();
+ setModified( false );
+ if (m_view)
+ m_view->slotUpdate(false);
+ return true;
+}
+
+QDomDocument Part::saveXML() {
+ QDomDocument document("kplato");
+
+ document.appendChild(document.createProcessingInstruction(
+ "xml",
+ "version=\"1.0\" encoding=\"UTF-8\""));
+
+ QDomElement doc = document.createElement("kplato");
+ doc.setAttribute("editor", "KPlato");
+ doc.setAttribute("mime", "application/x-vnd.kde.kplato");
+ doc.setAttribute("version", CURRENT_SYNTAX_VERSION);
+ document.appendChild(doc);
+
+ delete m_context;
+ m_context = 0;
+ if (m_view) {
+ m_context = new Context();
+ m_view->getContext(*m_context);
+ }
+ if (m_context) {
+ m_context->save(doc);
+ }
+ // Save the project
+ m_project->save(doc);
+
+ m_commandHistory->documentSaved();
+ return document;
+}
+
+
+void Part::slotDocumentRestored() {
+ //kdDebug()<<k_funcinfo<<endl;
+ setModified(false);
+}
+
+
+void Part::paintContent(QPainter &painter, const QRect &rect,
+ bool /*transparent*/,
+ double zoomX, double /*zoomY*/)
+{
+ kdDebug() << "----------- KPlato: Part::paintContent ------------" << endl;
+ if (isEmbedded() && m_embeddedGanttView && m_project)
+ {
+ if (m_embeddedContext)
+ {
+ int ganttsize = m_embeddedContext->ganttview.ganttviewsize;
+ int tasksize = m_embeddedContext->ganttview.taskviewsize;
+ bool showtaskname = m_embeddedContext->ganttview.showTaskName;
+
+// m_embeddedContext->ganttview.ganttviewsize += m_embeddedContext->ganttview.taskviewsize;
+// m_embeddedContext->ganttview.taskviewsize = 0; //TODO this doesn't have any effect?! (bug?)
+ m_embeddedContext->ganttview.showTaskName = true; //since task view is not shown(?), show name in the gantt itself
+
+ m_embeddedGanttView->setContext( m_embeddedContext->ganttview, *m_project );
+
+ m_embeddedContext->ganttview.ganttviewsize = ganttsize;
+ m_embeddedContext->ganttview.taskviewsize = tasksize;
+ m_embeddedContext->ganttview.showTaskName = showtaskname;
+ }
+ else
+ {
+ kdWarning() << "Don't have any context to set!" << endl;
+ }
+ painter.setClipRect(rect, QPainter::CoordPainter);
+ // We don't support zoom yet, so use the painters scaling
+ double d_zoom = 1.0;
+ setZoomAndResolution(100, KoGlobal::dpiX(), KoGlobal::dpiY());
+ if ( m_zoomedResolutionX != zoomX ) {
+ d_zoom *= ( zoomX / m_zoomedResolutionX );
+ painter.scale(d_zoom, d_zoom);
+ }
+
+ m_embeddedGanttView->clear();
+ m_embeddedGanttView->draw(*m_project);
+ m_embeddedGanttView->drawOnPainter(&painter,rect);
+ }
+ // ####### handle transparency
+
+ // Need to draw only the document rectangle described in the parameter rect.
+// int left = rect.left() / 20;
+// int right = rect.right() / 20 + 1;
+// int top = rect.top() / 20;
+// int bottom = rect.bottom() / 20 + 1;
+
+// for( int x = left; x < right; ++x )
+// painter.drawLine( x * 40, top * 20, 40 * 20, bottom * 20 );
+// for( int y = left; y < right; ++y )
+// painter.drawLine( left * 20, y * 20, right * 20, y * 20 );
+}
+
+
+void Part::addCommand(KCommand * cmd, bool execute)
+{
+ m_commandHistory->addCommand(cmd, execute);
+}
+
+void Part::slotCommandExecuted() {
+ //kdDebug()<<k_funcinfo<<endl;
+ setModified(true);
+ kdDebug() << "------- KPlato, is embedded: " << isEmbedded() << endl;
+ if (m_view == NULL)
+ return;
+
+ if (m_calculate)
+ m_view->slotUpdate(false/*config().behavior().calculationMode == Behavior::OnChange*/);
+ else if (m_update)
+ m_view->slotUpdate(false);
+
+ if (m_baseline)
+ m_view->setBaselineMode(getProject().isBaselined());
+
+ m_update = m_calculate = m_baseline = false;
+}
+
+void Part::slotCopyContextFromView()
+{
+ if (m_view)
+ {
+// kdDebug() << "Updating embedded context from view context." << endl;
+ this->m_view->getContext( *m_embeddedContext );
+ this->m_embeddedContextInitialized = true;
+ }
+// else
+// {
+// kdDebug() << "Not updating the context." << endl;
+// if (m_context)
+// kdDebug() << "Current View: " << m_context->currentView << endl;
+// }
+}
+
+void Part::slotViewDestroyed()
+{
+ m_view = NULL;
+}
+
+void Part::setCommandType(int type) {
+ //kdDebug()<<k_funcinfo<<"type="<<type<<endl;
+ if (type == 0)
+ m_update = true;
+ else if (type == 1)
+ m_calculate = true;
+ else if (type == 2)
+ m_baseline = true;
+}
+
+void Part::generateWBS() {
+ m_project->generateWBS(1, m_wbsDefinition);
+}
+
+} //KPlato namespace
+
+#include "kptpart.moc"