00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "kptpart.h"
00023 #include "kptview.h"
00024 #include "kptfactory.h"
00025 #include "kptproject.h"
00026 #include "kptprojectdialog.h"
00027 #include "kptresource.h"
00028 #include "kptcontext.h"
00029 #include "kptganttview.h"
00030 #include "KDGanttViewTaskLink.h"
00031
00032 #include <qpainter.h>
00033 #include <qfileinfo.h>
00034
00035 #include <kdebug.h>
00036 #include <kconfig.h>
00037 #include <klocale.h>
00038 #include <kmessagebox.h>
00039 #include <kstandarddirs.h>
00040 #include <kcommand.h>
00041 #include <KoTemplateChooseDia.h>
00042 #include <KoCommandHistory.h>
00043 #include <KoGlobal.h>
00044
00045 #define CURRENT_SYNTAX_VERSION "0.3"
00046
00047 namespace KPlato
00048 {
00049
00050 Part::Part(QWidget *parentWidget, const char *widgetName,
00051 QObject *parent, const char *name, bool singleViewMode)
00052 : KoDocument(parentWidget, widgetName, parent, name, singleViewMode),
00053 m_project(0), m_projectDialog(0), m_parentWidget(parentWidget), m_view(0),
00054 m_embeddedGanttView(new GanttView(parentWidget)),
00055 m_embeddedContext(new Context()), m_embeddedContextInitialized(false),
00056 m_context(0), m_xmlLoader()
00057 {
00058 m_update = m_calculate = false;
00059 m_commandHistory = new KoCommandHistory(actionCollection());
00060
00061 setInstance(Factory::global());
00062 setTemplateType("kplato_template");
00063 m_config.setReadWrite(isReadWrite()|| !isEmbedded());
00064 m_config.load();
00065
00066 delete m_project;
00067 m_project = new Project();
00068
00069 connect(m_commandHistory, SIGNAL(commandExecuted()), SLOT(slotCommandExecuted()));
00070 connect(m_commandHistory, SIGNAL(documentRestored()), SLOT(slotDocumentRestored()));
00071
00072
00073
00074 QTimer* timer = new QTimer(this,"context update timer");
00075 connect(timer,SIGNAL(timeout()),this,SLOT(slotCopyContextFromView()));
00076 timer->start(500);
00077 }
00078
00079
00080 Part::~Part() {
00081 m_config.save();
00082 delete m_project;
00083 delete m_projectDialog;
00084 delete m_commandHistory;
00085 if (m_embeddedGanttView)
00086 delete m_embeddedGanttView;
00087 if (m_embeddedContext)
00088 delete m_embeddedContext;
00089 }
00090
00091
00092 bool Part::initDoc(InitDocFlags flags, QWidget* parentWidget) {
00093 bool result = true;
00094
00095 if (flags==KoDocument::InitDocEmpty)
00096 {
00097 delete m_project;
00098 m_project = new Project();
00099 setAutoSave(0);
00100 setModified(false);
00101 return true;
00102 }
00103
00104 QString templateDoc;
00105 KoTemplateChooseDia::ReturnType ret;
00106 KoTemplateChooseDia::DialogType dlgtype;
00107 if (flags != KoDocument::InitDocFileNew )
00108 dlgtype = KoTemplateChooseDia::Everything;
00109 else
00110 dlgtype = KoTemplateChooseDia::OnlyTemplates;
00111
00112 ret = KoTemplateChooseDia::choose(Factory::global(), templateDoc,
00113 dlgtype,
00114 "kplato_template",
00115 parentWidget);
00116 if (ret == KoTemplateChooseDia::Template) {
00117 resetURL();
00118 result = loadNativeFormat(templateDoc);
00119 if ( !result )
00120 showLoadingErrorDialog();
00121 } else if (ret == KoTemplateChooseDia::File) {
00122 KURL url(templateDoc);
00123 kdDebug() << "Part::initDoc opening URL " << url.prettyURL() <<endl;
00124 result = openURL(url);
00125 } else if (ret == KoTemplateChooseDia::Empty) {
00126
00127 delete m_project;
00128 m_project = new Project();
00129
00130
00131
00132
00133 result = true;
00134 } else {
00135 result = false;
00136 }
00137 setAutoSave(0);
00138 setModified(false);
00139 return result;
00140 }
00141
00142
00143 KoView *Part::createViewInstance(QWidget *parent, const char *name) {
00144 m_view = new View(this, parent, name);
00145 connect(m_view,SIGNAL(destroyed()),this,SLOT(slotViewDestroyed()));
00146
00147
00148
00149
00150 if (m_projectDialog != 0) {
00151 kdDebug() << "Deleting m_projectDialog because of new ViewInstance\n";
00152 delete m_projectDialog;
00153 m_projectDialog = 0;
00154 }
00155 if (m_context)
00156 m_view->setContext( *m_context );
00157 else if (m_embeddedContext && m_embeddedContextInitialized)
00158 m_view->setContext( *m_embeddedContext );
00159 else {
00160
00161
00162 m_view->setTaskActionsEnabled(true);
00163 }
00164
00165 return m_view;
00166 }
00167
00168
00169 void Part::editProject() {
00170
00171 QWidget* parent = m_parentWidget;
00172 if (m_view)
00173 parent = m_view;
00174
00175 if (m_projectDialog == 0)
00176
00177 m_projectDialog = new ProjectDialog(*m_project, parent);
00178
00179 m_projectDialog->exec();
00180 }
00181
00182
00183 bool Part::loadXML(QIODevice *, const QDomDocument &document) {
00184 QTime dt;
00185 dt.start();
00186 emit sigProgress( 0 );
00187
00188 QString value;
00189 QDomElement plan = document.documentElement();
00190
00191
00192 value = plan.attribute("mime", QString::null);
00193 if (value.isEmpty()) {
00194 kdError() << "No mime type specified!" << endl;
00195 setErrorMessage(i18n("Invalid document. No mimetype specified."));
00196 return false;
00197 }
00198 else if (value != "application/x-vnd.kde.kplato") {
00199 kdError() << "Unknown mime type " << value << endl;
00200 setErrorMessage(i18n("Invalid document. Expected mimetype application/x-vnd.kde.kplato, got %1").arg(value));
00201 return false;
00202 }
00203 QString m_syntaxVersion = plan.attribute("version", CURRENT_SYNTAX_VERSION);
00204 if (m_syntaxVersion > CURRENT_SYNTAX_VERSION) {
00205 int ret = KMessageBox::warningContinueCancel(
00206 0, i18n("This document was created with a newer version of KPlato (syntax version: %1)\n"
00207 "Opening it in this version of KPlato will lose some information.").arg(m_syntaxVersion),
00208 i18n("File-Format Mismatch"), i18n("Continue") );
00209 if (ret == KMessageBox::Cancel)
00210 {
00211 setErrorMessage("USER_CANCELED");
00212 return false;
00213 }
00214 }
00215 emit sigProgress(5);
00216
00217 QDomNodeList list = plan.childNodes();
00218 if (list.count() > 2) {
00219
00220 kdDebug() << "*** Error ***\n";
00221 kdDebug() << " Children count should be 1 but is " << list.count()
00222 << "\n";
00223 return false;
00224 }
00225 m_xmlLoader.startLoad();
00226 for (unsigned int i = 0; i < list.count(); ++i) {
00227 if (list.item(i).isElement()) {
00228 QDomElement e = list.item(i).toElement();
00229
00230 if (e.tagName() == "context") {
00231 delete m_context;
00232 m_context = new Context();
00233 m_context->load(e);
00234 } else if (e.tagName() == "project") {
00235 Project *newProject = new Project();
00236 if (newProject->load(e)) {
00237
00238 delete m_project;
00239 m_project = newProject;
00240 delete m_projectDialog;
00241 m_projectDialog = 0;
00242 }
00243 else {
00244 delete newProject;
00245 m_xmlLoader.addMsg(XMLLoaderObject::Errors, "Loading of project failed");
00246
00247 }
00248 }
00249 }
00250 }
00251 m_xmlLoader.stopLoad();
00252 emit sigProgress(100);
00253
00254 kdDebug() << "Loading took " << (float)(dt.elapsed()) / 1000 << " seconds" << endl;
00255
00256
00257 emit sigProgress(-1);
00258
00259 m_commandHistory->clear();
00260 m_commandHistory->documentSaved();
00261 setModified( false );
00262 if (m_view)
00263 m_view->slotUpdate(false);
00264 return true;
00265 }
00266
00267 QDomDocument Part::saveXML() {
00268 QDomDocument document("kplato");
00269
00270 document.appendChild(document.createProcessingInstruction(
00271 "xml",
00272 "version=\"1.0\" encoding=\"UTF-8\""));
00273
00274 QDomElement doc = document.createElement("kplato");
00275 doc.setAttribute("editor", "KPlato");
00276 doc.setAttribute("mime", "application/x-vnd.kde.kplato");
00277 doc.setAttribute("version", CURRENT_SYNTAX_VERSION);
00278 document.appendChild(doc);
00279
00280 delete m_context;
00281 m_context = 0;
00282 if (m_view) {
00283 m_context = new Context();
00284 m_view->getContext(*m_context);
00285 }
00286 if (m_context) {
00287 m_context->save(doc);
00288 }
00289
00290 m_project->save(doc);
00291
00292 m_commandHistory->documentSaved();
00293 return document;
00294 }
00295
00296
00297 void Part::slotDocumentRestored() {
00298
00299 setModified(false);
00300 }
00301
00302
00303 void Part::paintContent(QPainter &painter, const QRect &rect,
00304 bool ,
00305 double zoomX, double )
00306 {
00307 kdDebug() << "----------- KPlato: Part::paintContent ------------" << endl;
00308 if (isEmbedded() && m_embeddedGanttView && m_project)
00309 {
00310 if (m_embeddedContext)
00311 {
00312 int ganttsize = m_embeddedContext->ganttview.ganttviewsize;
00313 int tasksize = m_embeddedContext->ganttview.taskviewsize;
00314 bool showtaskname = m_embeddedContext->ganttview.showTaskName;
00315
00316
00317
00318 m_embeddedContext->ganttview.showTaskName = true;
00319
00320 m_embeddedGanttView->setContext( m_embeddedContext->ganttview, *m_project );
00321
00322 m_embeddedContext->ganttview.ganttviewsize = ganttsize;
00323 m_embeddedContext->ganttview.taskviewsize = tasksize;
00324 m_embeddedContext->ganttview.showTaskName = showtaskname;
00325 }
00326 else
00327 {
00328 kdWarning() << "Don't have any context to set!" << endl;
00329 }
00330 painter.setClipRect(rect, QPainter::CoordPainter);
00331
00332 double d_zoom = 1.0;
00333 setZoomAndResolution(100, KoGlobal::dpiX(), KoGlobal::dpiY());
00334 if ( m_zoomedResolutionX != zoomX ) {
00335 d_zoom *= ( zoomX / m_zoomedResolutionX );
00336 painter.scale(d_zoom, d_zoom);
00337 }
00338
00339 m_embeddedGanttView->clear();
00340 m_embeddedGanttView->draw(*m_project);
00341 m_embeddedGanttView->drawOnPainter(&painter,rect);
00342 }
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355 }
00356
00357
00358 void Part::addCommand(KCommand * cmd, bool execute)
00359 {
00360 m_commandHistory->addCommand(cmd, execute);
00361 }
00362
00363 void Part::slotCommandExecuted() {
00364
00365 setModified(true);
00366 kdDebug() << "------- KPlato, is embedded: " << isEmbedded() << endl;
00367 if (m_view == NULL)
00368 return;
00369
00370 if (m_calculate)
00371 m_view->slotUpdate(false);
00372 else if (m_update)
00373 m_view->slotUpdate(false);
00374
00375 if (m_baseline)
00376 m_view->setBaselineMode(getProject().isBaselined());
00377
00378 m_update = m_calculate = m_baseline = false;
00379 }
00380
00381 void Part::slotCopyContextFromView()
00382 {
00383 if (m_view)
00384 {
00385
00386 this->m_view->getContext( *m_embeddedContext );
00387 this->m_embeddedContextInitialized = true;
00388 }
00389
00390
00391
00392
00393
00394
00395 }
00396
00397 void Part::slotViewDestroyed()
00398 {
00399 m_view = NULL;
00400 }
00401
00402 void Part::setCommandType(int type) {
00403
00404 if (type == 0)
00405 m_update = true;
00406 else if (type == 1)
00407 m_calculate = true;
00408 else if (type == 2)
00409 m_baseline = true;
00410 }
00411
00412 void Part::generateWBS() {
00413 m_project->generateWBS(1, m_wbsDefinition);
00414 }
00415
00416 }
00417
00418 #include "kptpart.moc"