diff options
Diffstat (limited to 'kplato/kptpart.cc')
-rw-r--r-- | kplato/kptpart.cc | 419 |
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" |