|
|
|
/***************************************************************************
|
|
|
|
* 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 <tqfile.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 )
|
|
|
|
: TQObject( 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() )
|
|
|
|
{
|
|
|
|
TQFile file(url.path());
|
|
|
|
if ( file.open(IO_ReadOnly) == false )
|
|
|
|
{
|
|
|
|
KMessageBox::sorry( 0l, i18n("Could not open '%1'").tqarg( 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;
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString fileName = url.fileName();
|
|
|
|
TQString 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 );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TQString DocManager::untitledName( int type )
|
|
|
|
{
|
|
|
|
TQString name;
|
|
|
|
switch(type)
|
|
|
|
{
|
|
|
|
case Document::dt_circuit:
|
|
|
|
{
|
|
|
|
if ( m_countCircuit>1 )
|
|
|
|
name = i18n("Untitled (Circuit %1)").tqarg(TQString::number(m_countCircuit));
|
|
|
|
else
|
|
|
|
name = i18n("Untitled (Circuit)");
|
|
|
|
m_countCircuit++;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case Document::dt_flowcode:
|
|
|
|
{
|
|
|
|
if ( m_countFlowCode>1 )
|
|
|
|
name = i18n("Untitled (FlowCode %1)").tqarg(TQString::number(m_countFlowCode));
|
|
|
|
else
|
|
|
|
name = i18n("Untitled (FlowCode)");
|
|
|
|
m_countFlowCode++;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case Document::dt_mechanics:
|
|
|
|
{
|
|
|
|
if ( m_countMechanics>1 )
|
|
|
|
name = i18n("Untitled (Mechanics %1)").tqarg(TQString::number(m_countMechanics));
|
|
|
|
else
|
|
|
|
name = i18n("Untitled (Mechanics)");
|
|
|
|
m_countMechanics++;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
{
|
|
|
|
if ( m_countOther>1 )
|
|
|
|
name = i18n("Untitled (%1)").tqarg(TQString::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, TQT_SIGNAL(modifiedStateChanged()), p_ktechlab, TQT_SLOT(slotDocModifiedChanged()) );
|
|
|
|
connect( document, TQT_SIGNAL(fileNameChanged(const KURL&)), p_ktechlab, TQT_SLOT(slotDocModifiedChanged()) );
|
|
|
|
connect( document, TQT_SIGNAL(fileNameChanged(const KURL&)), p_ktechlab, TQT_SLOT(addRecentFile(const KURL&)) );
|
|
|
|
connect( document, TQT_SIGNAL(destroyed(TQObject* )), this, TQT_SLOT(documentDestroyed(TQObject* )) );
|
|
|
|
connect( document, TQT_SIGNAL(viewFocused(View* )), this, TQT_SLOT(slotViewFocused(View* )) );
|
|
|
|
connect( document, TQT_SIGNAL(viewUnfocused()), this, TQT_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( TQObject *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, TQT_SIGNAL(undoRedoStateChanged()), p_ktechlab, TQT_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, TQT_SIGNAL(undoRedoStateChanged()), p_ktechlab, TQT_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\"").tqarg(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\"").tqarg(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\"").tqarg(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\"").tqarg(url.prettyURL()) );
|
|
|
|
document->deleteLater();
|
|
|
|
return 0l;
|
|
|
|
}
|
|
|
|
|
|
|
|
handleNewDocument( document, viewArea );
|
|
|
|
emit fileOpened(url);
|
|
|
|
return document;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#include "docmanager.moc"
|