You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
451 lines
15 KiB
451 lines
15 KiB
/***************************************************************************
|
|
projectsession.cpp - description
|
|
-------------------
|
|
begin : 30 Nov 2002
|
|
copyright : (C) 2002 by Falk Brettschneider
|
|
email : falk@tdevelop.org
|
|
***************************************************************************/
|
|
|
|
/***************************************************************************
|
|
* *
|
|
* 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 <tqdom.h>
|
|
#include <tqptrlist.h>
|
|
#include <tqfile.h>
|
|
#include <tqtimer.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 tdevelop 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();
|
|
TQDomDocument doc("KDevPrjSession");
|
|
domdoc=doc;
|
|
domdoc.appendChild( domdoc.createProcessingInstruction( "xml", "version=\"1.0\" encoding=\"UTF-8\"" ) );
|
|
// KDevPrjSession is the root element of the XML file
|
|
TQDomElement session = domdoc.documentElement();
|
|
session = domdoc.createElement("KDevPrjSession");
|
|
domdoc.appendChild( session);
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
bool ProjectSession::restoreFromFile( const TQString & sessionFileName, const TQValueList< KDevPlugin * > plugins )
|
|
{
|
|
bool bFileOpenOK = true;
|
|
|
|
TQFile 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 TDevelop project session ('KDevPrjSession').\n").arg(sessionFileName)
|
|
+ i18n("The document type seems to be: '%1'.").arg(domdoc.doctype().name()));
|
|
return false;
|
|
}
|
|
|
|
TQDomElement session = domdoc.documentElement();
|
|
|
|
// read the information about the mainframe widget
|
|
if (bFileOpenOK) {
|
|
recreateDocs(session);
|
|
}
|
|
|
|
// now also let the plugins load their session stuff
|
|
TQDomElement pluginListEl = session.namedItem("pluginList").toElement();
|
|
TQValueList<KDevPlugin*>::ConstIterator it = plugins.begin();
|
|
while( it != plugins.end() )
|
|
{
|
|
KDevPlugin* pPlugin = (*it);
|
|
TQString pluginName = pPlugin->instance()->instanceName();
|
|
TQDomElement pluginEl = pluginListEl.namedItem(pluginName).toElement();
|
|
if (!pluginEl.isNull()) {
|
|
// now plugin, load what you find!
|
|
pPlugin->restorePartialProjectSession(&pluginEl);
|
|
}
|
|
++it;
|
|
}
|
|
|
|
TQTimer::singleShot( 0, this, TQT_SLOT(loadDocument()) );
|
|
|
|
return true;
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
void ProjectSession::recreateDocs(TQDomElement& el)
|
|
{
|
|
//// TQDomElement mainframeEl = el.namedItem("Mainframe").toElement();
|
|
//// bool bMaxMode =initXMLTree() (bool) mainframeEl.attribute("MaximizeMode", "0").toInt();
|
|
//// QextMdiMainFrm* pMainWidget = (QextMdiMainFrm*) tqApp->mainWidget();
|
|
//// pMainWidget->setEnableMaximizedChildFrmMode(bMaxMode);
|
|
//// bool bTaskBarWasOn = pMainWidget->isViewTaskBarOn();
|
|
//// pMainWidget->hideViewTaskBar();
|
|
|
|
// read the information about the documents
|
|
TQDomElement docsAndViewsEl = el.namedItem("DocsAndViews").toElement();
|
|
int nNrOfDocs = docsAndViewsEl.attribute("NumberOfDocuments", "0").toInt();
|
|
// loop over all docs
|
|
int nDoc = 0;
|
|
TQDomElement docEl;
|
|
for (docEl = docsAndViewsEl.firstChild().toElement(), nDoc = 0;
|
|
nDoc < nNrOfDocs;
|
|
nDoc++, docEl = docEl.nextSibling().toElement())
|
|
{
|
|
// read the document name and type
|
|
TQString 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, TQDomElement 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 )
|
|
{
|
|
TQDomElement 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;
|
|
|
|
TQDomElement viewEl;
|
|
TQString viewType;
|
|
TQString 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);
|
|
}
|
|
TQDomElement 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 TQString & sessionFileName, const TQValueList< KDevPlugin * > plugins )
|
|
{
|
|
TQString section, keyword;
|
|
TQDomElement session = domdoc.documentElement();
|
|
|
|
int nDocs = 0;
|
|
TQString docIdStr;
|
|
|
|
//// // read the information about the mainframe widget
|
|
//// TQDomElement 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
|
|
TQDomElement 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)
|
|
TQDomNode n = docsAndViewsEl.firstChild();
|
|
while ( !n.isNull() ) {
|
|
TQDomNode toBeRemoved = n;
|
|
n = n.nextSibling();
|
|
docsAndViewsEl.removeChild(toBeRemoved);
|
|
}
|
|
}
|
|
|
|
TQPtrListIterator<KParts::Part> it( *PartController::getInstance()->parts() );
|
|
for ( ; it.current(); ++it )
|
|
{
|
|
|
|
KParts::ReadOnlyPart* pReadOnlyPart = dynamic_cast<KParts::ReadOnlyPart*>(it.current());
|
|
if (!pReadOnlyPart)
|
|
continue;
|
|
|
|
TQString url = pReadOnlyPart->url().url();
|
|
|
|
docIdStr.setNum(nDocs);
|
|
TQDomElement docEl = domdoc.createElement("Doc" + docIdStr);
|
|
docEl.setAttribute( "URL", url);
|
|
docsAndViewsEl.appendChild( docEl);
|
|
nDocs++;
|
|
docEl.setAttribute( "NumberOfViews", 1);
|
|
|
|
TQDomElement 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 ) )
|
|
{
|
|
TQString encoding = ei->encoding();
|
|
if ( !encoding.isNull() )
|
|
{
|
|
viewEl.setAttribute( "Encoding", encoding );
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
viewEl.setAttribute("Type", "Other");
|
|
}
|
|
}
|
|
|
|
/*
|
|
TQPtrListIterator<KParts::Part> it( *PartController::getInstance()->parts() );
|
|
for ( ; it.current(); ++it ) {
|
|
//// TQString partName = it.current()->name();
|
|
//// TQMessageBox::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?
|
|
TQString url = pReadOnlyPart->url().url();
|
|
|
|
docIdStr.setNum(nDocs);
|
|
TQDomElement docEl = domdoc.createElement("Doc" + docIdStr);
|
|
docEl.setAttribute( "URL", url);
|
|
docsAndViewsEl.appendChild( docEl);
|
|
nDocs++;
|
|
//// docEl.setAttribute( "Type", "???");
|
|
//// // get the view list
|
|
//// TQPtrList<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;
|
|
TQString viewIdStr;
|
|
//// for (viewList.first(), nView = 0; viewList.current() != 0; viewList.next(), nView++) {
|
|
//// pView = viewList.current();
|
|
//// if (pView != 0L) {
|
|
viewIdStr.setNum( nView);
|
|
TQDomElement viewEl = domdoc.createElement( "View"+viewIdStr);
|
|
docEl.appendChild( viewEl);
|
|
// focus?
|
|
//// viewEl.setAttribute("Focus", (((CEditWidget*)pView->parentWidget()) == m_pDocViewMan->currentEditView()));
|
|
viewEl.setAttribute("Type", "???");
|
|
|
|
TQDomElement 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
|
|
TQDomElement 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)
|
|
TQDomNode n = pluginListEl.firstChild();
|
|
while ( !n.isNull() ) {
|
|
TQDomNode toBeRemoved = n;
|
|
n = n.nextSibling();
|
|
pluginListEl.removeChild(toBeRemoved);
|
|
}
|
|
}
|
|
|
|
TQValueList<KDevPlugin*>::ConstIterator itt = plugins.begin();
|
|
while( itt != plugins.end() )
|
|
{
|
|
KDevPlugin* pPlugin = (*itt);
|
|
TQString pluginName = pPlugin->instance()->instanceName();
|
|
TQDomElement 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
|
|
TQFile f(sessionFileName);
|
|
if ( f.open(IO_WriteOnly) ) { // file opened successfully
|
|
TQTextStream 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();
|
|
//TQTimer::singleShot( 0, this, TQT_SLOT(loadDocument()) );
|
|
}
|
|
}
|
|
|