00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "circuitdocument.h"
00012 #include "docmanager.h"
00013 #include "docmanageriface.h"
00014 #include "flowcodedocument.h"
00015 #include "iteminterface.h"
00016 #include "itemselector.h"
00017 #include "ktechlab.h"
00018 #include "core/ktlconfig.h"
00019 #include "mechanicsdocument.h"
00020 #include "textdocument.h"
00021 #include "textview.h"
00022 #include "viewcontainer.h"
00023
00024 #include <klocale.h>
00025 #include <kmessagebox.h>
00026 #include <ktabwidget.h>
00027 #include <qfile.h>
00028
00029 #include <cassert>
00030
00031 DocManager * DocManager::m_pSelf = 0;
00032
00033 DocManager * DocManager::self( KTechlab * ktechlab )
00034 {
00035 if ( !m_pSelf )
00036 {
00037 assert(ktechlab);
00038 m_pSelf = new DocManager(ktechlab);
00039 }
00040 return m_pSelf;
00041 }
00042
00043
00044 DocManager::DocManager( KTechlab * ktechlab )
00045 : QObject( ktechlab ),
00046 p_ktechlab(ktechlab)
00047 {
00048 p_focusedView = 0;
00049 m_countCircuit = 0;
00050 m_countFlowCode = 0;
00051 m_countMechanics = 0;
00052 m_countOther = 0;
00053 p_connectedDocument = 0;
00054 m_nextDocumentID = 1;
00055 m_pIface = new DocManagerIface(this);
00056 }
00057
00058
00059 DocManager::~DocManager()
00060 {
00061 }
00062
00063
00064 bool DocManager::closeAll()
00065 {
00066 const DocumentList::iterator end = m_documentList.end();
00067 while ( !m_documentList.isEmpty() )
00068 {
00069 Document *document = m_documentList.first();
00070 if ( document->fileClose() )
00071 {
00072 m_documentList.remove(document);
00073 removeDocumentAssociations(document);
00074 }
00075 else
00076 return false;
00077 }
00078 return true;
00079 }
00080
00081
00082 void DocManager::gotoTextLine( const KURL &url, int line )
00083 {
00084 TextDocument * doc = dynamic_cast<TextDocument*>( openURL(url) );
00085 if (!doc)
00086 return;
00087
00088 doc->textView()->gotoLine(line);
00089 }
00090
00091
00092 Document* DocManager::openURL( const KURL &url, ViewArea *viewArea )
00093 {
00094 if ( url.isEmpty() )
00095 return 0;
00096
00097 if ( url.isLocalFile() )
00098 {
00099 QFile file(url.path());
00100 if ( file.open(IO_ReadOnly) == false )
00101 {
00102 KMessageBox::sorry( 0, i18n("Could not open '%1'").arg( url.prettyURL() ) );
00103 return 0;
00104 }
00105 file.close();
00106 }
00107
00108
00109
00110
00111 Document *document = findDocument(url);
00112 if ( document )
00113 {
00114 if ( viewArea )
00115 createNewView( document, viewArea );
00116 else
00117 giveDocumentFocus( document, viewArea );
00118 return document;
00119 }
00120
00121 QString fileName = url.fileName();
00122 QString extension = fileName.right( fileName.length() - fileName.findRev('.') );
00123
00124 if ( extension == ".circuit" )
00125 return openCircuitFile( url, viewArea );
00126
00127 else if ( extension == ".flowcode" )
00128 return openFlowCodeFile( url, viewArea );
00129
00130 else if ( extension == ".mechanics" )
00131 return openMechanicsFile( url, viewArea );
00132
00133 else
00134 return openTextFile( url, viewArea );
00135 }
00136
00137
00138 Document *DocManager::getFocusedDocument() const
00139 {
00140 Document * doc = p_focusedView ? p_focusedView->document() : 0;
00141 return (doc && !doc->isDeleted()) ? doc : 0;
00142 }
00143
00144
00145 void DocManager::giveDocumentFocus( Document * toFocus, ViewArea * viewAreaForNew )
00146 {
00147 if ( !toFocus )
00148 return;
00149
00150 if ( View * activeView = toFocus->activeView() )
00151 {
00152 p_ktechlab->tabWidget()->showPage( activeView->viewContainer() );
00153 activeView->setFocused();
00154 activeView->viewContainer()->setFocused();
00155 }
00156 else if ( viewAreaForNew )
00157 createNewView( toFocus, viewAreaForNew );
00158 }
00159
00160
00161 QString DocManager::untitledName( int type )
00162 {
00163 QString name;
00164 switch(type)
00165 {
00166 case Document::dt_circuit:
00167 {
00168 if ( m_countCircuit>1 )
00169 name = i18n("Untitled (Circuit %1)").arg(QString::number(m_countCircuit));
00170 else
00171 name = i18n("Untitled (Circuit)");
00172 m_countCircuit++;
00173 break;
00174 }
00175 case Document::dt_flowcode:
00176 {
00177 if ( m_countFlowCode>1 )
00178 name = i18n("Untitled (FlowCode %1)").arg(QString::number(m_countFlowCode));
00179 else
00180 name = i18n("Untitled (FlowCode)");
00181 m_countFlowCode++;
00182 break;
00183 }
00184 case Document::dt_mechanics:
00185 {
00186 if ( m_countMechanics>1 )
00187 name = i18n("Untitled (Mechanics %1)").arg(QString::number(m_countMechanics));
00188 else
00189 name = i18n("Untitled (Mechanics)");
00190 m_countMechanics++;
00191 break;
00192 }
00193 default:
00194 {
00195 if ( m_countOther>1 )
00196 name = i18n("Untitled (%1)").arg(QString::number(m_countOther));
00197 else
00198 name = i18n("Untitled");
00199 m_countOther++;
00200 break;
00201 }
00202 }
00203 return name;
00204 }
00205
00206
00207 Document *DocManager::findDocument( const KURL &url ) const
00208 {
00209
00210 if ( m_associatedDocuments.contains(url) )
00211 return m_associatedDocuments[url];
00212
00213
00214 const DocumentList::const_iterator end = m_documentList.end();
00215 for ( DocumentList::const_iterator it = m_documentList.begin(); it != end; ++it )
00216 {
00217 if ( (*it)->url() == url )
00218 return *it;
00219 }
00220
00221 return 0;
00222 }
00223
00224
00225 void DocManager::associateDocument( const KURL &url, Document *document )
00226 {
00227 if (!document)
00228 return;
00229
00230 m_associatedDocuments[url] = document;
00231 }
00232
00233
00234 void DocManager::removeDocumentAssociations( Document *document )
00235 {
00236 bool doneErase;
00237 do
00238 {
00239 doneErase = false;
00240 const URLDocumentMap::iterator end = m_associatedDocuments.end();
00241 for ( URLDocumentMap::iterator it = m_associatedDocuments.begin(); it != end; ++it )
00242 {
00243 if ( it.data() == document )
00244 {
00245 doneErase = true;
00246 m_associatedDocuments.erase(it);
00247 break;
00248 }
00249 }
00250 }
00251 while (doneErase);
00252 }
00253
00254
00255 void DocManager::handleNewDocument( Document *document, ViewArea *viewArea )
00256 {
00257 if ( !document || m_documentList.contains(document) )
00258 return;
00259
00260 m_documentList.append(document);
00261 document->setDCOPID(m_nextDocumentID++);
00262
00263 connect( document, SIGNAL(modifiedStateChanged()), p_ktechlab, SLOT(slotDocModifiedChanged()) );
00264 connect( document, SIGNAL(fileNameChanged(const KURL&)), p_ktechlab, SLOT(slotDocModifiedChanged()) );
00265 connect( document, SIGNAL(fileNameChanged(const KURL&)), p_ktechlab, SLOT(addRecentFile(const KURL&)) );
00266 connect( document, SIGNAL(destroyed(QObject* )), this, SLOT(documentDestroyed(QObject* )) );
00267 connect( document, SIGNAL(viewFocused(View* )), this, SLOT(slotViewFocused(View* )) );
00268 connect( document, SIGNAL(viewUnfocused()), this, SLOT(slotViewUnfocused()) );
00269
00270 createNewView( document, viewArea );
00271 }
00272
00273
00274 View *DocManager::createNewView( Document *document, ViewArea *viewArea )
00275 {
00276 if (!document)
00277 return 0;
00278
00279 View *view = 0;
00280
00281 if (viewArea)
00282 view = document->createView( viewArea->viewContainer(), viewArea->id() );
00283
00284 else
00285 {
00286 ViewContainer *viewContainer = new ViewContainer( document->caption(), p_ktechlab );
00287 view = document->createView( viewContainer, 0 );
00288 p_ktechlab->addWindow(viewContainer);
00289 }
00290
00291 view->setFocused();
00292 return view;
00293 }
00294
00295
00296 void DocManager::documentDestroyed( QObject *obj )
00297 {
00298 Document *doc = static_cast<Document*>(obj);
00299 m_documentList.remove(doc);
00300 removeDocumentAssociations(doc);
00301 disableContextActions();
00302 }
00303
00304
00305 void DocManager::slotViewFocused( View *view )
00306 {
00307 ViewContainer * vc = static_cast<ViewContainer*>(p_ktechlab->tabWidget()->currentPage());
00308 if (!vc)
00309 view = 0;
00310
00311 if (!view)
00312 return;
00313
00314
00315
00316
00317 if ( view->viewContainer() != vc )
00318 view = vc->activeView();
00319
00320 if ( !view || (View*)p_focusedView == view )
00321 return;
00322
00323 if (p_focusedView)
00324 slotViewUnfocused();
00325
00326 p_focusedView = view;
00327
00328 if ( TextView * textView = dynamic_cast<TextView*>((View*)p_focusedView) )
00329 p_ktechlab->factory()->addClient( textView->kateView() );
00330 else
00331 p_ktechlab->factory()->addClient( p_focusedView );
00332
00333 Document *document = view->document();
00334
00335 connect( document, SIGNAL(undoRedoStateChanged()), p_ktechlab, SLOT(slotDocUndoRedoChanged()) );
00336 p_connectedDocument = document;
00337
00338 if ( document->type() == Document::dt_circuit ||
00339 document->type() == Document::dt_flowcode ||
00340 document->type() == Document::dt_mechanics )
00341 {
00342 ItemDocument *cvb = static_cast<ItemDocument*>(view->document());
00343 ItemInterface::self()->slotItemDocumentChanged(cvb);
00344 }
00345
00346 p_ktechlab->slotDocUndoRedoChanged();
00347 p_ktechlab->slotDocModifiedChanged();
00348 p_ktechlab->requestUpdateCaptions();
00349 }
00350
00351
00352 void DocManager::slotViewUnfocused()
00353 {
00354 p_ktechlab->removeGUIClients();
00355 disableContextActions();
00356
00357 if (!p_focusedView)
00358 return;
00359
00360 if (p_connectedDocument)
00361 {
00362 disconnect( p_connectedDocument, SIGNAL(undoRedoStateChanged()), p_ktechlab, SLOT(slotDocUndoRedoChanged()) );
00363 p_connectedDocument = 0;
00364 }
00365
00366 ItemInterface::self()->slotItemDocumentChanged(0);
00367 p_focusedView = 0;
00368
00369
00370 p_ktechlab->requestUpdateCaptions();
00371 }
00372
00373
00374 void DocManager::disableContextActions()
00375 {
00376 p_ktechlab->action("file_save")->setEnabled(false);
00377 p_ktechlab->action("file_save_as")->setEnabled(false);
00378 p_ktechlab->action("file_close")->setEnabled(false);
00379 p_ktechlab->action("file_print")->setEnabled(false);
00380 p_ktechlab->action("edit_undo")->setEnabled(false);
00381 p_ktechlab->action("edit_redo")->setEnabled(false);
00382 p_ktechlab->action("edit_cut")->setEnabled(false);
00383 p_ktechlab->action("edit_copy")->setEnabled(false);
00384 p_ktechlab->action("edit_paste")->setEnabled(false);
00385 p_ktechlab->action("view_split_leftright")->setEnabled(false);
00386 p_ktechlab->action("view_split_topbottom")->setEnabled(false);
00387 }
00388
00389
00390 TextDocument *DocManager::createTextDocument()
00391 {
00392 TextDocument *document = TextDocument::constructTextDocument( untitledName(Document::dt_text), p_ktechlab );
00393 handleNewDocument(document);
00394 return document;
00395 }
00396
00397
00398 CircuitDocument *DocManager::createCircuitDocument()
00399 {
00400 CircuitDocument *document = new CircuitDocument( untitledName(Document::dt_circuit), p_ktechlab );
00401 handleNewDocument(document);
00402 if ( KTLConfig::raiseItemSelectors() )
00403 p_ktechlab->showToolView( p_ktechlab->toolView( ComponentSelector::toolViewIdentifier() ) );
00404 return document;
00405 }
00406
00407
00408 FlowCodeDocument *DocManager::createFlowCodeDocument()
00409 {
00410 FlowCodeDocument *document = new FlowCodeDocument( untitledName(Document::dt_flowcode), p_ktechlab );
00411 handleNewDocument(document);
00412 if ( KTLConfig::raiseItemSelectors() )
00413 p_ktechlab->showToolView( p_ktechlab->toolView( FlowPartSelector::toolViewIdentifier() ) );
00414 return document;
00415 }
00416
00417
00418 MechanicsDocument *DocManager::createMechanicsDocument()
00419 {
00420 MechanicsDocument *document = new MechanicsDocument( untitledName(Document::dt_mechanics), p_ktechlab );
00421 handleNewDocument(document);
00422 if ( KTLConfig::raiseItemSelectors() )
00423 p_ktechlab->showToolView( p_ktechlab->toolView( MechanicsSelector::toolViewIdentifier() ) );
00424 return document;
00425 }
00426
00427
00428 CircuitDocument *DocManager::openCircuitFile( const KURL &url, ViewArea *viewArea )
00429 {
00430 CircuitDocument *document = new CircuitDocument( url.fileName().remove(url.directory()), p_ktechlab );
00431
00432 if ( !document->openURL(url) )
00433 {
00434 KMessageBox::sorry( 0, i18n("Could not open Circuit file \"%1\"").arg(url.prettyURL()) );
00435 document->deleteLater();
00436 return 0;
00437 }
00438
00439 handleNewDocument( document, viewArea );
00440 emit fileOpened(url);
00441 return document;
00442 }
00443
00444
00445 FlowCodeDocument *DocManager::openFlowCodeFile( const KURL &url, ViewArea *viewArea )
00446 {
00447 FlowCodeDocument *document = new FlowCodeDocument( url.fileName().remove(url.directory()), p_ktechlab );
00448
00449 if ( !document->openURL(url) )
00450 {
00451 KMessageBox::sorry( 0, i18n("Could not open FlowCode file \"%1\"").arg(url.prettyURL()) );
00452 document->deleteLater();
00453 return 0;
00454 }
00455
00456 handleNewDocument( document, viewArea );
00457 emit fileOpened(url);
00458 return document;
00459 }
00460
00461
00462 MechanicsDocument *DocManager::openMechanicsFile( const KURL &url, ViewArea *viewArea )
00463 {
00464 MechanicsDocument *document = new MechanicsDocument( url.fileName().remove(url.directory()), p_ktechlab );
00465
00466 if ( !document->openURL(url) )
00467 {
00468 KMessageBox::sorry( 0, i18n("Could not open Mechanics file \"%1\"").arg(url.prettyURL()) );
00469 document->deleteLater();
00470 return 0;
00471 }
00472
00473 handleNewDocument( document, viewArea );
00474 emit fileOpened(url);
00475 return document;
00476
00477 }
00478
00479
00480 TextDocument *DocManager::openTextFile( const KURL &url, ViewArea *viewArea )
00481 {
00482 TextDocument *document = TextDocument::constructTextDocument( url.fileName().remove(url.directory()), p_ktechlab );
00483
00484 if (!document)
00485 return 0;
00486
00487 if ( !document->openURL(url) )
00488 {
00489 KMessageBox::sorry( 0, i18n("Could not open text file \"%1\"").arg(url.prettyURL()) );
00490 document->deleteLater();
00491 return 0;
00492 }
00493
00494 handleNewDocument( document, viewArea );
00495 emit fileOpened(url);
00496 return document;
00497 }
00498
00499
00500 #include "docmanager.moc"