summaryrefslogtreecommitdiffstats
path: root/src/docmanager.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/docmanager.cpp')
-rw-r--r--src/docmanager.cpp500
1 files changed, 500 insertions, 0 deletions
diff --git a/src/docmanager.cpp b/src/docmanager.cpp
new file mode 100644
index 0000000..bf49985
--- /dev/null
+++ b/src/docmanager.cpp
@@ -0,0 +1,500 @@
+/***************************************************************************
+ * Copyright (C) 2005 by David Saxton *
+ * david@bluehaze.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 "circuitdocument.h"
+#include "docmanager.h"
+#include "docmanageriface.h"
+#include "flowcodedocument.h"
+#include "iteminterface.h"
+#include "itemselector.h"
+#include "ktechlab.h"
+#include "core/ktlconfig.h"
+#include "mechanicsdocument.h"
+#include "textdocument.h"
+#include "textview.h"
+#include "viewcontainer.h"
+
+#include <klocale.h>
+#include <kmessagebox.h>
+#include <ktabwidget.h>
+#include <qfile.h>
+
+#include <assert.h>
+
+DocManager * DocManager::m_pSelf = 0l;
+
+DocManager * DocManager::self( KTechlab * ktechlab )
+{
+ if ( !m_pSelf )
+ {
+ assert(ktechlab);
+ m_pSelf = new DocManager(ktechlab);
+ }
+ return m_pSelf;
+}
+
+
+DocManager::DocManager( KTechlab * ktechlab )
+ : QObject( ktechlab ),
+ p_ktechlab(ktechlab)
+{
+ p_focusedView = 0l;
+ m_countCircuit = 0;
+ m_countFlowCode = 0;
+ m_countMechanics = 0;
+ m_countOther = 0;
+ p_connectedDocument = 0l;
+ m_nextDocumentID = 1;
+ m_pIface = new DocManagerIface(this);
+}
+
+
+DocManager::~DocManager()
+{
+}
+
+
+bool DocManager::closeAll()
+{
+ const DocumentList::iterator end = m_documentList.end();
+ while ( !m_documentList.isEmpty() )
+ {
+ Document *document = m_documentList.first();
+ if ( document->fileClose() )
+ {
+ m_documentList.remove(document);
+ removeDocumentAssociations(document);
+ }
+ else
+ return false;
+ }
+ return true;
+}
+
+
+void DocManager::gotoTextLine( const KURL &url, int line )
+{
+ TextDocument * doc = dynamic_cast<TextDocument*>( openURL(url) );
+ if (!doc)
+ return;
+
+ doc->textView()->gotoLine(line);
+}
+
+
+Document* DocManager::openURL( const KURL &url, ViewArea *viewArea )
+{
+ if ( url.isEmpty() )
+ return 0l;
+
+ if ( url.isLocalFile() )
+ {
+ QFile file(url.path());
+ if ( file.open(IO_ReadOnly) == false )
+ {
+ KMessageBox::sorry( 0l, i18n("Could not open '%1'").arg( url.prettyURL() ) );
+ return 0l;
+ }
+ file.close();
+ }
+
+ // If the document is already open, and a specific view area hasn't been
+ // specified, then just return that document - otherwise, create a new
+ // view in the viewarea
+ Document *document = findDocument(url);
+ if ( document )
+ {
+ if ( viewArea )
+ createNewView( document, viewArea );
+ else
+ giveDocumentFocus( document, viewArea );
+ return document;
+ }
+
+ QString fileName = url.fileName();
+ QString extension = fileName.right( fileName.length() - fileName.findRev('.') );
+
+ if ( extension == ".circuit" )
+ return openCircuitFile( url, viewArea );
+
+ else if ( extension == ".flowcode" )
+ return openFlowCodeFile( url, viewArea );
+
+ else if ( extension == ".mechanics" )
+ return openMechanicsFile( url, viewArea );
+
+ else
+ return openTextFile( url, viewArea );
+}
+
+
+Document *DocManager::getFocusedDocument() const
+{
+ Document * doc = p_focusedView ? p_focusedView->document() : 0l;
+ return (doc && !doc->isDeleted()) ? doc : 0l;
+}
+
+
+void DocManager::giveDocumentFocus( Document * toFocus, ViewArea * viewAreaForNew )
+{
+ if ( !toFocus )
+ return;
+
+ if ( View * activeView = toFocus->activeView() )
+ {
+ p_ktechlab->tabWidget()->showPage( activeView->viewContainer() );
+ activeView->setFocused();
+ activeView->viewContainer()->setFocused();
+ }
+ else if ( viewAreaForNew )
+ createNewView( toFocus, viewAreaForNew );
+}
+
+
+QString DocManager::untitledName( int type )
+{
+ QString name;
+ switch(type)
+ {
+ case Document::dt_circuit:
+ {
+ if ( m_countCircuit>1 )
+ name = i18n("Untitled (Circuit %1)").arg(QString::number(m_countCircuit));
+ else
+ name = i18n("Untitled (Circuit)");
+ m_countCircuit++;
+ break;
+ }
+ case Document::dt_flowcode:
+ {
+ if ( m_countFlowCode>1 )
+ name = i18n("Untitled (FlowCode %1)").arg(QString::number(m_countFlowCode));
+ else
+ name = i18n("Untitled (FlowCode)");
+ m_countFlowCode++;
+ break;
+ }
+ case Document::dt_mechanics:
+ {
+ if ( m_countMechanics>1 )
+ name = i18n("Untitled (Mechanics %1)").arg(QString::number(m_countMechanics));
+ else
+ name = i18n("Untitled (Mechanics)");
+ m_countMechanics++;
+ break;
+ }
+ default:
+ {
+ if ( m_countOther>1 )
+ name = i18n("Untitled (%1)").arg(QString::number(m_countOther));
+ else
+ name = i18n("Untitled");
+ m_countOther++;
+ break;
+ }
+ }
+ return name;
+}
+
+
+Document *DocManager::findDocument( const KURL &url ) const
+{
+ // First, look in the associated documents
+ if ( m_associatedDocuments.contains(url) )
+ return m_associatedDocuments[url];
+
+ // Not found, so look in the known documents
+ const DocumentList::const_iterator end = m_documentList.end();
+ for ( DocumentList::const_iterator it = m_documentList.begin(); it != end; ++it )
+ {
+ if ( (*it)->url() == url )
+ return *it;
+ }
+
+ return 0l;
+}
+
+
+void DocManager::associateDocument( const KURL &url, Document *document )
+{
+ if (!document)
+ return;
+
+ m_associatedDocuments[url] = document;
+}
+
+
+void DocManager::removeDocumentAssociations( Document *document )
+{
+ bool doneErase;
+ do
+ {
+ doneErase = false;
+ const URLDocumentMap::iterator end = m_associatedDocuments.end();
+ for ( URLDocumentMap::iterator it = m_associatedDocuments.begin(); it != end; ++it )
+ {
+ if ( it.data() == document )
+ {
+ doneErase = true;
+ m_associatedDocuments.erase(it);
+ break;
+ }
+ }
+ }
+ while (doneErase);
+}
+
+
+void DocManager::handleNewDocument( Document *document, ViewArea *viewArea )
+{
+ if ( !document || m_documentList.contains(document) )
+ return;
+
+ m_documentList.append(document);
+ document->setDCOPID(m_nextDocumentID++);
+
+ connect( document, SIGNAL(modifiedStateChanged()), p_ktechlab, SLOT(slotDocModifiedChanged()) );
+ connect( document, SIGNAL(fileNameChanged(const KURL&)), p_ktechlab, SLOT(slotDocModifiedChanged()) );
+ connect( document, SIGNAL(fileNameChanged(const KURL&)), p_ktechlab, SLOT(addRecentFile(const KURL&)) );
+ connect( document, SIGNAL(destroyed(QObject* )), this, SLOT(documentDestroyed(QObject* )) );
+ connect( document, SIGNAL(viewFocused(View* )), this, SLOT(slotViewFocused(View* )) );
+ connect( document, SIGNAL(viewUnfocused()), this, SLOT(slotViewUnfocused()) );
+
+ createNewView( document, viewArea );
+}
+
+
+View *DocManager::createNewView( Document *document, ViewArea *viewArea )
+{
+ if (!document)
+ return 0l;
+
+ View *view = 0l;
+
+ if (viewArea)
+ view = document->createView( viewArea->viewContainer(), viewArea->id() );
+
+ else
+ {
+ ViewContainer *viewContainer = new ViewContainer( document->caption(), p_ktechlab );
+ view = document->createView( viewContainer, 0 );
+ p_ktechlab->addWindow(viewContainer);
+ }
+
+ view->setFocused();
+ return view;
+}
+
+
+void DocManager::documentDestroyed( QObject *obj )
+{
+ Document *doc = static_cast<Document*>(obj);
+ m_documentList.remove(doc);
+ removeDocumentAssociations(doc);
+ disableContextActions();
+}
+
+
+void DocManager::slotViewFocused( View *view )
+{
+ ViewContainer * vc = static_cast<ViewContainer*>(p_ktechlab->tabWidget()->currentPage());
+ if (!vc)
+ view = 0l;
+
+ if (!view)
+ return;
+
+ // This function can get called with a view that is not in the current view
+ // container (such as when the user right clicks and then the popup is
+ // destroyed - not too sure why, but this is the easiest way to fix it).
+ if ( view->viewContainer() != vc )
+ view = vc->activeView();
+
+ if ( !view || (View*)p_focusedView == view )
+ return;
+
+ if (p_focusedView)
+ slotViewUnfocused();
+
+ p_focusedView = view;
+
+ if ( TextView * textView = dynamic_cast<TextView*>((View*)p_focusedView) )
+ p_ktechlab->factory()->addClient( textView->kateView() );
+ else
+ p_ktechlab->factory()->addClient( p_focusedView );
+
+ Document *document = view->document();
+
+ connect( document, SIGNAL(undoRedoStateChanged()), p_ktechlab, SLOT(slotDocUndoRedoChanged()) );
+ p_connectedDocument = document;
+
+ if ( document->type() == Document::dt_circuit ||
+ document->type() == Document::dt_flowcode ||
+ document->type() == Document::dt_mechanics )
+ {
+ ItemDocument *cvb = static_cast<ItemDocument*>(view->document());
+ ItemInterface::self()->slotItemDocumentChanged(cvb);
+ }
+
+ p_ktechlab->slotDocUndoRedoChanged();
+ p_ktechlab->slotDocModifiedChanged();
+ p_ktechlab->requestUpdateCaptions();
+}
+
+
+void DocManager::slotViewUnfocused()
+{
+ p_ktechlab->removeGUIClients();
+ disableContextActions();
+
+ if (!p_focusedView)
+ return;
+
+ if (p_connectedDocument)
+ {
+ disconnect( p_connectedDocument, SIGNAL(undoRedoStateChanged()), p_ktechlab, SLOT(slotDocUndoRedoChanged()) );
+ p_connectedDocument = 0l;
+ }
+
+ ItemInterface::self()->slotItemDocumentChanged(0l);
+ p_focusedView = 0l;
+
+// p_ktechlab->setCaption( 0 );
+ p_ktechlab->requestUpdateCaptions();
+}
+
+
+void DocManager::disableContextActions()
+{
+ p_ktechlab->action("file_save")->setEnabled(false);
+ p_ktechlab->action("file_save_as")->setEnabled(false);
+ p_ktechlab->action("file_close")->setEnabled(false);
+ p_ktechlab->action("file_print")->setEnabled(false);
+ p_ktechlab->action("edit_undo")->setEnabled(false);
+ p_ktechlab->action("edit_redo")->setEnabled(false);
+ p_ktechlab->action("edit_cut")->setEnabled(false);
+ p_ktechlab->action("edit_copy")->setEnabled(false);
+ p_ktechlab->action("edit_paste")->setEnabled(false);
+ p_ktechlab->action("view_split_leftright")->setEnabled(false);
+ p_ktechlab->action("view_split_topbottom")->setEnabled(false);
+}
+
+
+TextDocument *DocManager::createTextDocument()
+{
+ TextDocument *document = TextDocument::constructTextDocument( untitledName(Document::dt_text), p_ktechlab );
+ handleNewDocument(document);
+ return document;
+}
+
+
+CircuitDocument *DocManager::createCircuitDocument()
+{
+ CircuitDocument *document = new CircuitDocument( untitledName(Document::dt_circuit), p_ktechlab );
+ handleNewDocument(document);
+ if ( KTLConfig::raiseItemSelectors() )
+ p_ktechlab->showToolView( p_ktechlab->toolView( ComponentSelector::toolViewIdentifier() ) );
+ return document;
+}
+
+
+FlowCodeDocument *DocManager::createFlowCodeDocument()
+{
+ FlowCodeDocument *document = new FlowCodeDocument( untitledName(Document::dt_flowcode), p_ktechlab );
+ handleNewDocument(document);
+ if ( KTLConfig::raiseItemSelectors() )
+ p_ktechlab->showToolView( p_ktechlab->toolView( FlowPartSelector::toolViewIdentifier() ) );
+ return document;
+}
+
+
+MechanicsDocument *DocManager::createMechanicsDocument()
+{
+ MechanicsDocument *document = new MechanicsDocument( untitledName(Document::dt_mechanics), p_ktechlab );
+ handleNewDocument(document);
+ if ( KTLConfig::raiseItemSelectors() )
+ p_ktechlab->showToolView( p_ktechlab->toolView( MechanicsSelector::toolViewIdentifier() ) );
+ return document;
+}
+
+
+CircuitDocument *DocManager::openCircuitFile( const KURL &url, ViewArea *viewArea )
+{
+ CircuitDocument *document = new CircuitDocument( url.fileName().remove(url.directory()), p_ktechlab );
+
+ if ( !document->openURL(url) )
+ {
+ KMessageBox::sorry( 0l, i18n("Could not open Circuit file \"%1\"").arg(url.prettyURL()) );
+ document->deleteLater();
+ return 0l;
+ }
+
+ handleNewDocument( document, viewArea );
+ emit fileOpened(url);
+ return document;
+}
+
+
+FlowCodeDocument *DocManager::openFlowCodeFile( const KURL &url, ViewArea *viewArea )
+{
+ FlowCodeDocument *document = new FlowCodeDocument( url.fileName().remove(url.directory()), p_ktechlab );
+
+ if ( !document->openURL(url) )
+ {
+ KMessageBox::sorry( 0l, i18n("Could not open FlowCode file \"%1\"").arg(url.prettyURL()) );
+ document->deleteLater();
+ return 0l;
+ }
+
+ handleNewDocument( document, viewArea );
+ emit fileOpened(url);
+ return document;
+}
+
+
+MechanicsDocument *DocManager::openMechanicsFile( const KURL &url, ViewArea *viewArea )
+{
+ MechanicsDocument *document = new MechanicsDocument( url.fileName().remove(url.directory()), p_ktechlab );
+
+ if ( !document->openURL(url) )
+ {
+ KMessageBox::sorry( 0l, i18n("Could not open Mechanics file \"%1\"").arg(url.prettyURL()) );
+ document->deleteLater();
+ return 0l;
+ }
+
+ handleNewDocument( document, viewArea );
+ emit fileOpened(url);
+ return document;
+
+}
+
+
+TextDocument *DocManager::openTextFile( const KURL &url, ViewArea *viewArea )
+{
+ TextDocument *document = TextDocument::constructTextDocument( url.fileName().remove(url.directory()), p_ktechlab );
+
+ if (!document)
+ return 0l;
+
+ if ( !document->openURL(url) )
+ {
+ KMessageBox::sorry( 0l, i18n("Could not open text file \"%1\"").arg(url.prettyURL()) );
+ document->deleteLater();
+ return 0l;
+ }
+
+ handleNewDocument( document, viewArea );
+ emit fileOpened(url);
+ return document;
+}
+
+
+#include "docmanager.moc"