KDevelop API Documentation

projectsession.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002                           projectsession.cpp  -  description
00003                              -------------------
00004     begin                : 30 Nov 2002
00005     copyright            : (C) 2002 by Falk Brettschneider
00006     email                : falk@kdevelop.org
00007  ***************************************************************************/
00008 
00009 /***************************************************************************
00010  *                                                                         *
00011  *   This program is free software; you can redistribute it and/or modify  *
00012  *   it under the terms of the GNU General Public License as published by  *
00013  *   the Free Software Foundation; either version 2 of the License, or     *
00014  *   (at your option) any later version.                                   *
00015  *                                                                         *
00016  ***************************************************************************/
00017 
00018 #include <qdom.h>
00019 #include <qptrlist.h>
00020 #include <qfile.h>
00021 #include <qtimer.h>
00022 
00023 #include <kparts/part.h>
00024 #include <kurl.h>
00025 #include <kmessagebox.h>
00026 #include <klocale.h>
00027 #include <kinstance.h>
00028 #include "ktexteditor/viewcursorinterface.h"
00029 #include "ktexteditor/document.h"
00030 
00031 #include "api.h"
00032 #include "partcontroller.h"
00033 #include "domutil.h"
00034 #include "documentationpart.h"
00035 #include "toplevel.h"
00036 #include "kdevplugin.h"
00037 
00038 #include "projectsession.h"
00039 #include "projectsession.moc"
00040 //---------------------------------------------------------------------------
00041 ProjectSession::ProjectSession()
00042 {
00043   initXMLTree();
00044 }
00045 
00046 //---------------------------------------------------------------------------
00047 ProjectSession::~ProjectSession()
00048 {
00049 }
00050 
00051 //---------------------------------------------------------------------------
00052 void ProjectSession::initXMLTree()
00053 {
00054   // initializes the XML tree on startup of kdevelop and when a project
00055   // has been closed to ensure that the XML tree exists already including
00056   // doctype when a project gets opened that doesn't have a kdevses file
00057   // or a new project gets generated (which doesn't have a kdevses file
00058   // either as the project has never been closed before opening it).
00059   domdoc.clear();
00060   QDomDocument doc("KDevPrjSession");
00061   domdoc=doc;
00062   domdoc.appendChild( domdoc.createProcessingInstruction( "xml", "version=\"1.0\" encoding=\"UTF-8\"" ) );
00063   // KDevPrjSession is the root element of the XML file
00064   QDomElement session = domdoc.documentElement();
00065   session = domdoc.createElement("KDevPrjSession");
00066   domdoc.appendChild( session);
00067 }
00068 
00069 //---------------------------------------------------------------------------
00070 bool ProjectSession::restoreFromFile( const QString & sessionFileName, const QValueList< KDevPlugin * > plugins )
00071 {
00072   bool bFileOpenOK = true;
00073 
00074   QFile f(sessionFileName);
00075   if ( f.open(IO_ReadOnly) ) {  // file opened successfully
00076     bool ok = domdoc.setContent( &f);
00077     f.close();
00078     if (!ok) {
00079       KMessageBox::sorry(0L,
00080                          i18n("The file %1 does not contain valid XML.\n"
00081                          "The loading of the session failed.").arg(sessionFileName));
00082       initXMLTree(); // because it was now broken after failed setContent()
00083       return false;
00084     }
00085   }
00086   else {
00087     bFileOpenOK = false;
00088   }
00089 
00090   // Check for proper document type.
00091   if (domdoc.doctype().name() != "KDevPrjSession") {
00092     KMessageBox::sorry(0L,
00093     i18n("The file %1 does not contain a valid KDevelop project session ('KDevPrjSession').\n").arg(sessionFileName)
00094     + i18n("The document type seems to be: '%1'.").arg(domdoc.doctype().name()));
00095     return false;
00096   }
00097 
00098   QDomElement session = domdoc.documentElement();
00099 
00100   // read the information about the mainframe widget
00101   if (bFileOpenOK) {
00102     recreateDocs(session);
00103   }
00104 
00105     // now also let the plugins load their session stuff
00106     QDomElement pluginListEl = session.namedItem("pluginList").toElement();
00107     QValueList<KDevPlugin*>::ConstIterator it = plugins.begin();
00108     while( it != plugins.end() )
00109     {
00110         KDevPlugin* pPlugin = (*it);
00111         QString pluginName = pPlugin->instance()->instanceName();
00112         QDomElement pluginEl = pluginListEl.namedItem(pluginName).toElement();
00113         if (!pluginEl.isNull()) {
00114             // now plugin, load what you find!
00115             pPlugin->restorePartialProjectSession(&pluginEl);
00116         }
00117         ++it;
00118     }
00119   
00120     QTimer::singleShot( 0, this, SLOT(loadDocument()) );
00121 
00122   return true;
00123 }
00124 
00125 //---------------------------------------------------------------------------
00126 void ProjectSession::recreateDocs(QDomElement& el)
00127 {
00134 
00135   // read the information about the documents
00136   QDomElement docsAndViewsEl = el.namedItem("DocsAndViews").toElement();
00137   int nNrOfDocs = docsAndViewsEl.attribute("NumberOfDocuments", "0").toInt();
00138   // loop over all docs
00139   int nDoc = 0;
00140   QDomElement docEl;
00141   for (docEl = docsAndViewsEl.firstChild().toElement(), nDoc = 0;
00142        nDoc < nNrOfDocs;
00143        nDoc++, docEl = docEl.nextSibling().toElement())
00144   {
00145     // read the document name and type
00146     QString docName = docEl.attribute( "URL", "");
00147     if (!docName.isEmpty() /* && URL::exists(docName)*/) {
00148       KURL url(docName);
00149       // create the views of this document, the first view creation will also create the document
00150       kdDebug() << k_funcinfo << "Doc to be activated? " << (nDoc == nNrOfDocs - 1) << endl;
00151       recreateViews(url, docEl, (nDoc == nNrOfDocs - 1));
00152     }
00153   }
00154 
00155   if (nNrOfDocs > 0) {
00156       API::getInstance()->mainWindow()->callCommand("qextmdi-UI: do hack on session loading finished");
00157   }
00161 }
00162 
00163 //---------------------------------------------------------------------------
00164 void ProjectSession::recreateViews(KURL& url, QDomElement docEl, bool activate)
00165 {
00166   // read information about the views
00167   int nNrOfViews = docEl.attribute( "NumberOfViews", "0").toInt();
00168   
00169   // we should restore every view, but right now we only support a single view per document
00170   // so use this simple method for now
00171 
00172     if ( nNrOfViews > 0 )
00173     {
00174         QDomElement viewEl = docEl.firstChild().toElement();
00175         DocumentData dd;
00176         dd.type = viewEl.attribute("Type");
00177         dd.line = viewEl.attribute("line", "0").toInt();
00178         dd.url = url;
00179         dd.activate = activate;
00180         
00181         _docDataList << dd;
00182     }  
00183   
00184 /*  
00185   // loop over all views of this document
00186   int nView = 0;
00187 
00188   QDomElement viewEl;
00189   QString viewType;
00190   QString context;
00191   if (docEl.hasAttribute("context")) {
00192     context = docEl.attribute("context");
00193   }
00194 
00195   for (viewEl = docEl.firstChild().toElement(), nView = 0; nView < nNrOfViews; nView++, viewEl = viewEl.nextSibling().toElement()) {
00196 
00202 
00203     if (context.isEmpty()) {
00204       int line = 0;
00205       if (viewEl.hasAttribute("line")) {
00206         line = viewEl.attribute("line", "0").toInt();
00207       }
00208       PartController::getInstance()->editDocument(url, line);
00209     }
00210     else {
00211       PartController::getInstance()->showDocument(url);
00212     }
00213     QDomElement viewPropertiesEl = viewEl.namedItem("AdditionalSettings").toElement();
00214     if (!viewPropertiesEl.isNull()) {
00215       emit sig_restoreAdditionalViewProperties(url.url(), &viewPropertiesEl);
00216     }
00217 
00218   }
00226 */
00227 }
00228 
00229 //---------------------------------------------------------------------------
00230 bool ProjectSession::saveToFile( const QString & sessionFileName, const QValueList< KDevPlugin * > plugins )
00231 {
00232 
00233   QString section, keyword;
00234   QDomElement session = domdoc.documentElement();
00235 
00236 
00237   int nDocs = 0;
00238   QString docIdStr;
00239 
00248 
00249 
00250   // read the information about the documents
00251   QDomElement docsAndViewsEl = session.namedItem("DocsAndViews").toElement();
00252   if (docsAndViewsEl.isNull()) {
00253     docsAndViewsEl = domdoc.createElement("DocsAndViews");
00254     session.appendChild( docsAndViewsEl);
00255   }
00256   else {
00257     // we need to remove the old ones before memorizing the current ones (to avoid merging)
00258     QDomNode n = docsAndViewsEl.firstChild();
00259     while ( !n.isNull() ) {
00260       QDomNode toBeRemoved = n;
00261       n = n.nextSibling();
00262       docsAndViewsEl.removeChild(toBeRemoved);
00263     }
00264   }
00265 
00266     QPtrListIterator<KParts::Part> it( *PartController::getInstance()->parts() );
00267     for ( ; it.current(); ++it ) 
00268     {
00269     
00270         KParts::ReadOnlyPart* pReadOnlyPart = dynamic_cast<KParts::ReadOnlyPart*>(it.current());
00271         if (!pReadOnlyPart)
00272             continue; 
00273     
00274         QString url = pReadOnlyPart->url().url();
00275     
00276         docIdStr.setNum(nDocs);
00277         QDomElement docEl = domdoc.createElement("Doc" + docIdStr);
00278         docEl.setAttribute( "URL", url);
00279         docsAndViewsEl.appendChild( docEl);
00280         nDocs++;
00281         docEl.setAttribute( "NumberOfViews", 1);
00282         
00283         QDomElement viewEl = domdoc.createElement( "View0");
00284         docEl.appendChild( viewEl);
00285         
00286         if ( dynamic_cast<DocumentationPart*>(pReadOnlyPart) )
00287         {
00288             viewEl.setAttribute("Type", "Documentation");
00289         }
00290         else if ( pReadOnlyPart->inherits("KTextEditor::Document") )
00291         {
00292             viewEl.setAttribute("Type", "Source");
00293             KTextEditor::ViewCursorInterface *iface = dynamic_cast<KTextEditor::ViewCursorInterface*>(pReadOnlyPart->widget());
00294             if (iface) {
00295                 unsigned int line, col;
00296                 iface->cursorPosition(&line, &col);
00297                 viewEl.setAttribute( "line", line );
00298             }
00299         }
00300         else
00301         {
00302             viewEl.setAttribute("Type", "Other");
00303         }
00304     }
00305   
00306 /*
00307   QPtrListIterator<KParts::Part> it( *PartController::getInstance()->parts() );
00308   for ( ; it.current(); ++it ) {
00311 
00312     KParts::ReadOnlyPart* pReadOnlyPart = dynamic_cast<KParts::ReadOnlyPart*>(it.current());
00313     if (!pReadOnlyPart)
00314       continue; // note: read-write parts are also a read-only part, they inherit from it
00315 
00316     DocumentationPart* pDocuPart = dynamic_cast<DocumentationPart*>(pReadOnlyPart);
00317 
00319     QString url = pReadOnlyPart->url().url();
00320 
00321     docIdStr.setNum(nDocs);
00322     QDomElement docEl = domdoc.createElement("Doc" + docIdStr);
00323     docEl.setAttribute( "URL", url);
00324     docsAndViewsEl.appendChild( docEl);
00325     nDocs++;
00331     docEl.setAttribute( "NumberOfViews", 1);
00332     // loop over all views of this document
00333     int nView = 0;
00335     QString viewIdStr;
00339         viewIdStr.setNum( nView);
00340         QDomElement viewEl = domdoc.createElement( "View"+viewIdStr);
00341         docEl.appendChild( viewEl);
00342         // focus?
00344         viewEl.setAttribute("Type", "???");
00345 
00346     QDomElement viewPropertiesEl = domdoc.createElement("AdditionalSettings");
00347     viewEl.appendChild(viewPropertiesEl);
00348     emit sig_saveAdditionalViewProperties(url, &viewPropertiesEl);
00349 
00350     if (pReadOnlyPart->inherits("KTextEditor::Document")) {
00351       KTextEditor::ViewCursorInterface *iface = dynamic_cast<KTextEditor::ViewCursorInterface*>(pReadOnlyPart->widget());
00352       if (iface) {
00353         unsigned int line, col;
00354         iface->cursorPosition(&line, &col);
00355         viewEl.setAttribute( "line", line );
00356       }
00357     }
00358 
00359     if (pDocuPart) {
00360       docEl.setAttribute( "context", pDocuPart->context() );
00361     }
00362   }
00363 */
00364   docsAndViewsEl.setAttribute("NumberOfDocuments", nDocs);
00365 
00366 
00367   // now also let the project-related plugins save their session stuff
00368   // read the information about the documents
00369   QDomElement pluginListEl = session.namedItem("pluginList").toElement();
00370   if (pluginListEl.isNull()) {
00371     pluginListEl = domdoc.createElement("pluginList");
00372     session.appendChild( pluginListEl);
00373   }
00374   else {
00375     // we need to remove the old ones before memorizing the current ones (to avoid merging)
00376     QDomNode n = pluginListEl.firstChild();
00377     while ( !n.isNull() ) {
00378       QDomNode toBeRemoved = n;
00379       n = n.nextSibling();
00380       pluginListEl.removeChild(toBeRemoved);
00381     }
00382   }
00383 
00384     QValueList<KDevPlugin*>::ConstIterator itt = plugins.begin();
00385     while( itt != plugins.end() )
00386     {
00387         KDevPlugin* pPlugin = (*itt);
00388         QString pluginName = pPlugin->instance()->instanceName();
00389         QDomElement pluginEl = domdoc.createElement(pluginName);
00390         
00391         // now plugin, save what you have!
00392         pPlugin->savePartialProjectSession(&pluginEl);
00393         
00394         // if the plugin wrote anything, accept itt for the session, otherwise forget itt
00395         if (pluginEl.hasChildNodes() || pluginEl.hasAttributes()) 
00396         {
00397             pluginListEl.appendChild(pluginEl);
00398         }
00399         ++itt;
00400     }
00401 
00402   // Write it out to the session file on disc
00403   QFile f(sessionFileName);
00404   if ( f.open(IO_WriteOnly) ) {    // file opened successfully
00405     QTextStream t( &f );        // use a text stream
00406     t << domdoc.toCString();
00407     f.close();
00408   }
00409   initXMLTree();  // clear and initialize the tree again
00410 
00411   return true;
00412 }
00413 
00414 
00415 void ProjectSession::loadDocument( )
00416 {
00417     if ( !_docDataList.isEmpty() )
00418     {
00419         DocumentData & dd = _docDataList.first();
00420         if ( dd.type == "Source" )
00421         {
00422             PartController::getInstance()->editDocumentInternal( dd.url, dd.line, -1, dd.activate );
00423         }
00424         else if ( dd.type == "Documentation" )
00425         {
00426             // FIXME needs to be deferred if !activate ?
00427             PartController::getInstance()->showDocument( dd.url, true );
00428         }
00429         else
00430         {
00431             // FIXME needs to be deferred if !activate ?
00432             PartController::getInstance()->editDocument( dd.url );
00433         }       
00434         _docDataList.pop_front();
00435         
00436         loadDocument();
00437         //QTimer::singleShot( 0, this, SLOT(loadDocument()) );
00438     }
00439 }
00440 
KDE Logo
This file is part of the documentation for KDevelop Version 3.1.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Tue Feb 22 09:22:43 2005 by doxygen 1.3.9.1 written by Dimitri van Heesch, © 1997-2003