summaryrefslogtreecommitdiffstats
path: root/src/projectsession.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/projectsession.cpp')
-rw-r--r--src/projectsession.cpp450
1 files changed, 450 insertions, 0 deletions
diff --git a/src/projectsession.cpp b/src/projectsession.cpp
new file mode 100644
index 00000000..be3ec4a1
--- /dev/null
+++ b/src/projectsession.cpp
@@ -0,0 +1,450 @@
+/***************************************************************************
+ projectsession.cpp - description
+ -------------------
+ begin : 30 Nov 2002
+ copyright : (C) 2002 by Falk Brettschneider
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include <qdom.h>
+#include <qptrlist.h>
+#include <qfile.h>
+#include <qtimer.h>
+
+#include <kparts/part.h>
+#include <kurl.h>
+#include <kmessagebox.h>
+#include <klocale.h>
+#include <kinstance.h>
+#include <ktexteditor/viewcursorinterface.h>
+#include <ktexteditor/document.h>
+#include <ktexteditor/encodinginterface.h>
+
+#include "api.h"
+#include "partcontroller.h"
+#include "domutil.h"
+#include "documentationpart.h"
+#include "toplevel.h"
+#include "kdevplugin.h"
+
+#include "projectsession.h"
+#include "projectsession.moc"
+//---------------------------------------------------------------------------
+ProjectSession::ProjectSession()
+{
+ initXMLTree();
+}
+
+//---------------------------------------------------------------------------
+ProjectSession::~ProjectSession()
+{
+}
+
+//---------------------------------------------------------------------------
+void ProjectSession::initXMLTree()
+{
+ // initializes the XML tree on startup of kdevelop and when a project
+ // has been closed to ensure that the XML tree exists already including
+ // doctype when a project gets opened that doesn't have a kdevses file
+ // or a new project gets generated (which doesn't have a kdevses file
+ // either as the project has never been closed before opening it).
+ domdoc.clear();
+ QDomDocument doc("KDevPrjSession");
+ domdoc=doc;
+ domdoc.appendChild( domdoc.createProcessingInstruction( "xml", "version=\"1.0\" encoding=\"UTF-8\"" ) );
+ // KDevPrjSession is the root element of the XML file
+ QDomElement session = domdoc.documentElement();
+ session = domdoc.createElement("KDevPrjSession");
+ domdoc.appendChild( session);
+}
+
+//---------------------------------------------------------------------------
+bool ProjectSession::restoreFromFile( const QString & sessionFileName, const QValueList< KDevPlugin * > plugins )
+{
+ bool bFileOpenOK = true;
+
+ QFile f(sessionFileName);
+ if ( f.open(IO_ReadOnly) ) { // file opened successfully
+ bool ok = domdoc.setContent( &f);
+ f.close();
+ if (!ok) {
+ KMessageBox::sorry(0L,
+ i18n("The file %1 does not contain valid XML.\n"
+ "The loading of the session failed.").arg(sessionFileName));
+ initXMLTree(); // because it was now broken after failed setContent()
+ return false;
+ }
+ }
+ else {
+ bFileOpenOK = false;
+ }
+
+ // Check for proper document type.
+ if (domdoc.doctype().name() != "KDevPrjSession") {
+ KMessageBox::sorry(0L,
+ i18n("The file %1 does not contain a valid KDevelop project session ('KDevPrjSession').\n").arg(sessionFileName)
+ + i18n("The document type seems to be: '%1'.").arg(domdoc.doctype().name()));
+ return false;
+ }
+
+ QDomElement session = domdoc.documentElement();
+
+ // read the information about the mainframe widget
+ if (bFileOpenOK) {
+ recreateDocs(session);
+ }
+
+ // now also let the plugins load their session stuff
+ QDomElement pluginListEl = session.namedItem("pluginList").toElement();
+ QValueList<KDevPlugin*>::ConstIterator it = plugins.begin();
+ while( it != plugins.end() )
+ {
+ KDevPlugin* pPlugin = (*it);
+ QString pluginName = pPlugin->instance()->instanceName();
+ QDomElement pluginEl = pluginListEl.namedItem(pluginName).toElement();
+ if (!pluginEl.isNull()) {
+ // now plugin, load what you find!
+ pPlugin->restorePartialProjectSession(&pluginEl);
+ }
+ ++it;
+ }
+
+ QTimer::singleShot( 0, this, SLOT(loadDocument()) );
+
+ return true;
+}
+
+//---------------------------------------------------------------------------
+void ProjectSession::recreateDocs(QDomElement& el)
+{
+//// QDomElement mainframeEl = el.namedItem("Mainframe").toElement();
+//// bool bMaxMode =initXMLTree() (bool) mainframeEl.attribute("MaximizeMode", "0").toInt();
+//// QextMdiMainFrm* pMainWidget = (QextMdiMainFrm*) qApp->mainWidget();
+//// pMainWidget->setEnableMaximizedChildFrmMode(bMaxMode);
+//// bool bTaskBarWasOn = pMainWidget->isViewTaskBarOn();
+//// pMainWidget->hideViewTaskBar();
+
+ // read the information about the documents
+ QDomElement docsAndViewsEl = el.namedItem("DocsAndViews").toElement();
+ int nNrOfDocs = docsAndViewsEl.attribute("NumberOfDocuments", "0").toInt();
+ // loop over all docs
+ int nDoc = 0;
+ QDomElement docEl;
+ for (docEl = docsAndViewsEl.firstChild().toElement(), nDoc = 0;
+ nDoc < nNrOfDocs;
+ nDoc++, docEl = docEl.nextSibling().toElement())
+ {
+ // read the document name and type
+ QString docName = docEl.attribute( "URL", "");
+ if (!docName.isEmpty() /* && URL::exists(docName)*/) {
+ KURL url(docName);
+ // create the views of this document, the first view creation will also create the document
+ kdDebug() << k_funcinfo << "Doc to be activated? " << (nDoc == nNrOfDocs - 1) << endl;
+ recreateViews(url, docEl, (nDoc == nNrOfDocs - 1));
+ }
+ }
+
+ //FIXME: God, I hate KMDI. What the hell is this?
+/* if (nNrOfDocs > 0) {
+ API::getInstance()->mainWindow()->callCommand("qextmdi-UI: do hack on session loading finished");
+ }*/
+//// if (bTaskBarWasOn) {
+//// pMainWidget->showViewTaskBar();
+//// }
+}
+
+//---------------------------------------------------------------------------
+void ProjectSession::recreateViews(KURL& url, QDomElement docEl, bool activate)
+{
+ // read information about the views
+ int nNrOfViews = docEl.attribute( "NumberOfViews", "0").toInt();
+
+ // we should restore every view, but right now we only support a single view per document
+ // so use this simple method for now
+
+ if ( nNrOfViews > 0 )
+ {
+ QDomElement viewEl = docEl.firstChild().toElement();
+ DocumentData dd;
+ dd.type = viewEl.attribute("Type");
+ dd.line = viewEl.attribute("line", "0").toInt();
+ dd.url = url;
+ dd.activate = activate;
+ dd.encoding = viewEl.attribute( "Encoding" );
+
+ _docDataList << dd;
+ }
+
+/*
+ // loop over all views of this document
+ int nView = 0;
+
+ QDomElement viewEl;
+ QString viewType;
+ QString context;
+ if (docEl.hasAttribute("context")) {
+ context = docEl.attribute("context");
+ }
+
+ for (viewEl = docEl.firstChild().toElement(), nView = 0; nView < nNrOfViews; nView++, viewEl = viewEl.nextSibling().toElement()) {
+
+//// // is it the focused view? (XXX well, this only refers to the module instance)
+//// if (viewEl.attribute( "Focus", "0").toInt()) {
+//// // yes, memorize for later use
+//// pFocusedView = pView;
+//// }
+
+ if (context.isEmpty()) {
+ int line = 0;
+ if (viewEl.hasAttribute("line")) {
+ line = viewEl.attribute("line", "0").toInt();
+ }
+ PartController::getInstance()->editDocument(url, line);
+ }
+ else {
+ PartController::getInstance()->showDocument(url);
+ }
+ QDomElement viewPropertiesEl = viewEl.namedItem("AdditionalSettings").toElement();
+ if (!viewPropertiesEl.isNull()) {
+ emit sig_restoreAdditionalViewProperties(url.url(), &viewPropertiesEl);
+ }
+
+ }
+//// // restore focus
+//// if (pFocusedView != 0L) {
+//// if (pFocusedView->parentWidget()->inherits("QextMdiChildView")) {
+//// ((QextMdiChildView*)pFocusedView->parentWidget())->activate();
+//// }
+//// pFocusedView->setFocus();
+//// }
+*/
+}
+
+//---------------------------------------------------------------------------
+bool ProjectSession::saveToFile( const QString & sessionFileName, const QValueList< KDevPlugin * > plugins )
+{
+ QString section, keyword;
+ QDomElement session = domdoc.documentElement();
+
+ int nDocs = 0;
+ QString docIdStr;
+
+//// // read the information about the mainframe widget
+//// QDomElement mainframeEl = session.namedItem("Mainframe").toElement();
+//// if(mainframeEl.isNull()){
+//// mainframeEl=domdoc.createElement("Mainframe");
+//// session.appendChild( mainframeEl);
+//// }
+//// bool bMaxMode = ((QextMdiMainFrm*)m_pDocViewMan->parent())->isInMaximizedChildFrmMode();
+//// mainframeEl.setAttribute("MaximizeMode", bMaxMode);
+
+
+ // read the information about the documents
+ QDomElement docsAndViewsEl = session.namedItem("DocsAndViews").toElement();
+ if (docsAndViewsEl.isNull()) {
+ docsAndViewsEl = domdoc.createElement("DocsAndViews");
+ session.appendChild( docsAndViewsEl);
+ }
+ else {
+ // we need to remove the old ones before memorizing the current ones (to avoid merging)
+ QDomNode n = docsAndViewsEl.firstChild();
+ while ( !n.isNull() ) {
+ QDomNode toBeRemoved = n;
+ n = n.nextSibling();
+ docsAndViewsEl.removeChild(toBeRemoved);
+ }
+ }
+
+ QPtrListIterator<KParts::Part> it( *PartController::getInstance()->parts() );
+ for ( ; it.current(); ++it )
+ {
+
+ KParts::ReadOnlyPart* pReadOnlyPart = dynamic_cast<KParts::ReadOnlyPart*>(it.current());
+ if (!pReadOnlyPart)
+ continue;
+
+ QString url = pReadOnlyPart->url().url();
+
+ docIdStr.setNum(nDocs);
+ QDomElement docEl = domdoc.createElement("Doc" + docIdStr);
+ docEl.setAttribute( "URL", url);
+ docsAndViewsEl.appendChild( docEl);
+ nDocs++;
+ docEl.setAttribute( "NumberOfViews", 1);
+
+ QDomElement viewEl = domdoc.createElement( "View0");
+ docEl.appendChild( viewEl);
+
+ if ( dynamic_cast<HTMLDocumentationPart*>(pReadOnlyPart) )
+ {
+ viewEl.setAttribute("Type", "Documentation");
+ }
+ else if ( pReadOnlyPart->inherits("KTextEditor::Document") )
+ {
+ viewEl.setAttribute("Type", "Source");
+ KTextEditor::ViewCursorInterface *iface = dynamic_cast<KTextEditor::ViewCursorInterface*>(pReadOnlyPart->widget());
+ if (iface) {
+ unsigned int line, col;
+ iface->cursorPosition(&line, &col);
+ viewEl.setAttribute( "line", line );
+ }
+ if ( KTextEditor::EncodingInterface * ei = dynamic_cast<KTextEditor::EncodingInterface*>( pReadOnlyPart ) )
+ {
+ QString encoding = ei->encoding();
+ if ( !encoding.isNull() )
+ {
+ viewEl.setAttribute( "Encoding", encoding );
+ }
+ }
+ }
+ else
+ {
+ viewEl.setAttribute("Type", "Other");
+ }
+ }
+
+/*
+ QPtrListIterator<KParts::Part> it( *PartController::getInstance()->parts() );
+ for ( ; it.current(); ++it ) {
+//// QString partName = it.current()->name();
+//// QMessageBox::information(0L,"",partName);
+
+ KParts::ReadOnlyPart* pReadOnlyPart = dynamic_cast<KParts::ReadOnlyPart*>(it.current());
+ if (!pReadOnlyPart)
+ continue; // note: read-write parts are also a read-only part, they inherit from it
+
+ HTMLDocumentationPart* pDocuPart = dynamic_cast<HTMLDocumentationPart*>(pReadOnlyPart);
+
+ /// @todo Save relative path for project sharing?
+ QString url = pReadOnlyPart->url().url();
+
+ docIdStr.setNum(nDocs);
+ QDomElement docEl = domdoc.createElement("Doc" + docIdStr);
+ docEl.setAttribute( "URL", url);
+ docsAndViewsEl.appendChild( docEl);
+ nDocs++;
+//// docEl.setAttribute( "Type", "???");
+//// // get the view list
+//// QPtrList<KWpEditorPartriteView> viewList = pDoc->viewList();
+//// // write the number of views
+//// docEl.setAttribute( "NumberOfViews", viewList.count());
+ docEl.setAttribute( "NumberOfViews", 1);
+ // loop over all views of this document
+ int nView = 0;
+//// KWriteView* pView = 0L;
+ QString viewIdStr;
+//// for (viewList.first(), nView = 0; viewList.current() != 0; viewList.next(), nView++) {
+//// pView = viewList.current();
+//// if (pView != 0L) {
+ viewIdStr.setNum( nView);
+ QDomElement viewEl = domdoc.createElement( "View"+viewIdStr);
+ docEl.appendChild( viewEl);
+ // focus?
+//// viewEl.setAttribute("Focus", (((CEditWidget*)pView->parentWidget()) == m_pDocViewMan->currentEditView()));
+ viewEl.setAttribute("Type", "???");
+
+ QDomElement viewPropertiesEl = domdoc.createElement("AdditionalSettings");
+ viewEl.appendChild(viewPropertiesEl);
+ emit sig_saveAdditionalViewProperties(url, &viewPropertiesEl);
+
+ if (pReadOnlyPart->inherits("KTextEditor::Document")) {
+ KTextEditor::ViewCursorInterface *iface = dynamic_cast<KTextEditor::ViewCursorInterface*>(pReadOnlyPart->widget());
+ if (iface) {
+ unsigned int line, col;
+ iface->cursorPosition(&line, &col);
+ viewEl.setAttribute( "line", line );
+ }
+ }
+
+ if (pDocuPart) {
+ docEl.setAttribute( "context", pDocuPart->context() );
+ }
+ }
+*/
+ docsAndViewsEl.setAttribute("NumberOfDocuments", nDocs);
+
+
+ // now also let the project-related plugins save their session stuff
+ // read the information about the documents
+ QDomElement pluginListEl = session.namedItem("pluginList").toElement();
+ if (pluginListEl.isNull()) {
+ pluginListEl = domdoc.createElement("pluginList");
+ session.appendChild( pluginListEl);
+ }
+ else {
+ // we need to remove the old ones before memorizing the current ones (to avoid merging)
+ QDomNode n = pluginListEl.firstChild();
+ while ( !n.isNull() ) {
+ QDomNode toBeRemoved = n;
+ n = n.nextSibling();
+ pluginListEl.removeChild(toBeRemoved);
+ }
+ }
+
+ QValueList<KDevPlugin*>::ConstIterator itt = plugins.begin();
+ while( itt != plugins.end() )
+ {
+ KDevPlugin* pPlugin = (*itt);
+ QString pluginName = pPlugin->instance()->instanceName();
+ QDomElement pluginEl = domdoc.createElement(pluginName);
+
+ // now plugin, save what you have!
+ pPlugin->savePartialProjectSession(&pluginEl);
+
+ // if the plugin wrote anything, accept itt for the session, otherwise forget itt
+ if (pluginEl.hasChildNodes() || pluginEl.hasAttributes())
+ {
+ pluginListEl.appendChild(pluginEl);
+ }
+ ++itt;
+ }
+
+ // Write it out to the session file on disc
+ QFile f(sessionFileName);
+ if ( f.open(IO_WriteOnly) ) { // file opened successfully
+ QTextStream t( &f ); // use a text stream
+ t << domdoc.toCString();
+ f.close();
+ }
+ initXMLTree(); // clear and initialize the tree again
+
+ return true;
+}
+
+
+void ProjectSession::loadDocument( )
+{
+ while ( !_docDataList.isEmpty() )
+ {
+ DocumentData & dd = _docDataList.first();
+ if ( dd.type == "Source" )
+ {
+ PartController::getInstance()->setEncoding( dd.encoding );
+ PartController::getInstance()->editDocumentInternal( dd.url, dd.line, -1, dd.activate );
+ }
+ else if ( dd.type == "Documentation" )
+ {
+ // FIXME needs to be deferred if !activate ?
+ PartController::getInstance()->showDocument( dd.url, true );
+ }
+ else
+ {
+ // FIXME needs to be deferred if !activate ?
+ PartController::getInstance()->editDocument( dd.url );
+ }
+ _docDataList.pop_front();
+
+ loadDocument();
+ //QTimer::singleShot( 0, this, SLOT(loadDocument()) );
+ }
+}
+