1
/***************************************************************************
2
* Copyright (c) 2004 Jļæ½rgen Riegel <juergen.riegel@web.de> *
4
* This file is part of the FreeCAD CAx development system. *
6
* This library is free software; you can redistribute it and/or *
7
* modify it under the terms of the GNU Library General Public *
8
* License as published by the Free Software Foundation; either *
9
* version 2 of the License, or (at your option) any later version. *
11
* This library is distributed in the hope that it will be useful, *
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14
* GNU Library General Public License for more details. *
16
* You should have received a copy of the GNU Library General Public *
17
* License along with this library; see the file COPYING.LIB. If not, *
18
* write to the Free Software Foundation, Inc., 59 Temple Place, *
19
* Suite 330, Boston, MA 02111-1307, USA *
21
***************************************************************************/
24
#include "PreCompiled.h"
28
# include <qfileinfo.h>
29
# include <qmessagebox.h>
30
# include <qstatusbar.h>
31
# include <boost/signals.hpp>
32
# include <boost/bind.hpp>
35
#include <Base/Console.h>
36
#include <Base/Exception.h>
37
#include <Base/Matrix.h>
38
#include <Base/Reader.h>
39
#include <Base/Writer.h>
41
#include <App/Document.h>
42
#include <App/DocumentObject.h>
44
#include "Application.h"
45
#include "MainWindow.h"
48
#include "DocumentPy.h"
50
#include "FileDialog.h"
51
#include "View3DInventor.h"
52
#include "View3DInventorViewer.h"
53
#include "BitmapFactory.h"
54
#include "ViewProviderDocumentObject.h"
55
#include "Selection.h"
56
#include "SoFCSelection.h"
57
#include "WaitCursor.h"
58
#include "Thumbnail.h"
72
ViewProvider* _pcInEdit;
73
Application* _pcAppWnd;
75
App::Document* _pcDocument;
76
/// List of all registered views
77
std::list<Gui::BaseView*> _LpcViews;
78
/// List of all registered views
79
std::list<Gui::BaseView*> _LpcPassivViews;
80
std::map<App::DocumentObject*,ViewProviderDocumentObject*> _ViewProviderMap;
81
std::map<std::string,ViewProvider*> _ViewProviderMapAnnotation;
86
/* TRANSLATOR Gui::Document */
88
int Document::_iDocCount = 0;
90
Document::Document(App::Document* pcDocument,Application * app)
95
d->_iDocId = (++_iDocCount);
96
d->_isClosing = false;
97
d->_isModified = false;
99
d->_pcDocument = pcDocument;
102
//pcDocument->m_sig.connect(boost::bind(&Gui::Document::refresh, this, _1));
103
//boost::bind(&Gui::Document::slotNewObject, this, _1)
105
//App::Document::connection_t m_connection;
106
//m_connection = pcDocument->connect(boost::bind(&Document::slotNewObject, this, _1));
107
pcDocument->signalNewObject.connect(boost::bind(&Gui::Document::slotNewObject, this, _1));
108
pcDocument->signalDeletedObject.connect(boost::bind(&Gui::Document::slotDeletedObject, this, _1));
109
pcDocument->signalChangedObject.connect(boost::bind(&Gui::Document::slotChangedObject, this, _1, _2));
110
pcDocument->signalRenamedObject.connect(boost::bind(&Gui::Document::slotRenamedObject, this, _1));
111
pcDocument->signalActivatedObject.connect(boost::bind(&Gui::Document::slotActivatedObject, this, _1));
112
//pcDocument->signalNewObject.connect(&(this->slotNewObject));
113
pcDocument->signalSaveDocument.connect(boost::bind(&Gui::Document::Save, this, _1));
114
pcDocument->signalRestoreDocument.connect(boost::bind(&Gui::Document::Restore, this, _1));
116
// pointer to the python class
117
// NOTE: As this Python object doesn't get returned to the interpreter we
118
// mustn't increment it (Werner Jan-12-2006)
119
_pcDocPy = new Gui::DocumentPy(this);
121
if (App::GetApplication().GetParameterGroupByPath
122
("User parameter:BaseApp/Preferences/Document")->GetBool("UsingUndo",false))
123
d->_pcDocument->setUndoMode(1);
126
Document::~Document()
128
// e.g. if document gets closed from within a Python command
129
d->_isClosing = true;
130
// Calls Document::detachView()
131
while (d->_LpcViews.size() > 0)
132
delete d->_LpcViews.front();
134
std::map<App::DocumentObject*,ViewProviderDocumentObject*>::iterator it;
135
for (it = d->_ViewProviderMap.begin();it != d->_ViewProviderMap.end(); ++it)
137
std::map<std::string,ViewProvider*>::iterator it2;
138
for (it2 = d->_ViewProviderMapAnnotation.begin();it2 != d->_ViewProviderMapAnnotation.end(); ++it2)
141
// remove the reference from the object
142
_pcDocPy->setInvalid();
147
//*****************************************************************************************************
148
// 3D viewer handling
149
//*****************************************************************************************************
151
bool Document::setEdit(Gui::ViewProvider* p, int ModNum)
155
View3DInventor *pcIvView = dynamic_cast<View3DInventor *>(getActiveView());
156
if (pcIvView && pcIvView->getViewer()->setEdit(p,ModNum)) {
158
if (d->_pcInEdit->isDerivedFrom(ViewProviderDocumentObject::getClassTypeId()))
159
signalInEdit(*(static_cast<ViewProviderDocumentObject*>(d->_pcInEdit)));
166
void Document::resetEdit(void)
168
std::list<Gui::BaseView*>::iterator VIt;
170
for (VIt = d->_LpcViews.begin();VIt != d->_LpcViews.end();VIt++) {
171
View3DInventor *pcIvView = dynamic_cast<View3DInventor *>(*VIt);
173
pcIvView->getViewer()->resetEdit();
176
if (d->_pcInEdit->isDerivedFrom(ViewProviderDocumentObject::getClassTypeId()))
177
signalResetEdit(*(static_cast<ViewProviderDocumentObject*>(d->_pcInEdit)));
182
ViewProvider *Document::getInEdit(void) const
187
void Document::setAnnotationViewProvider(const char* name, ViewProvider *pcProvider)
189
std::list<Gui::BaseView*>::iterator VIt;
192
std::map<std::string,ViewProvider*>::iterator it = d->_ViewProviderMapAnnotation.find(name);
193
if (it != d->_ViewProviderMapAnnotation.end())
194
removeAnnotationViewProvider(name);
197
d->_ViewProviderMapAnnotation[name] = pcProvider;
199
// cycling to all views of the document
200
for(VIt = d->_LpcViews.begin();VIt != d->_LpcViews.end();VIt++) {
201
View3DInventor *pcIvView = dynamic_cast<View3DInventor *>(*VIt);
203
pcIvView->getViewer()->addViewProvider(pcProvider);
207
ViewProvider * Document::getAnnotationViewProvider(const char* name) const
209
std::map<std::string,ViewProvider*>::const_iterator it = d->_ViewProviderMapAnnotation.find(name);
210
return ( (it != d->_ViewProviderMapAnnotation.end()) ? it->second : 0 );
213
void Document::removeAnnotationViewProvider(const char* name)
215
std::map<std::string,ViewProvider*>::iterator it = d->_ViewProviderMapAnnotation.find(name);
216
std::list<Gui::BaseView*>::iterator VIt;
218
// cycling to all views of the document
219
for (VIt = d->_LpcViews.begin();VIt != d->_LpcViews.end();VIt++) {
220
View3DInventor *pcIvView = dynamic_cast<View3DInventor *>(*VIt);
222
pcIvView->getViewer()->removeViewProvider(it->second);
226
d->_ViewProviderMapAnnotation.erase(it);
230
ViewProvider* Document::getViewProvider(App::DocumentObject* Feat) const
232
std::map<App::DocumentObject*,ViewProviderDocumentObject*>::const_iterator
233
it = d->_ViewProviderMap.find( Feat );
234
return ( (it != d->_ViewProviderMap.end()) ? it->second : 0 );
237
std::vector<ViewProvider*> Document::getViewProvidersOfType(const Base::Type& typeId) const
239
std::vector<ViewProvider*> Objects;
240
for (std::map<App::DocumentObject*,ViewProviderDocumentObject*>::const_iterator it =
241
d->_ViewProviderMap.begin(); it != d->_ViewProviderMap.end(); ++it ) {
242
if (it->second->getTypeId().isDerivedFrom(typeId))
243
Objects.push_back(it->second);
248
ViewProvider *Document::getViewProviderByName(const char* name) const
250
// first check on feature name
251
App::DocumentObject *pcFeat = getDocument()->getObject(name);
255
std::map<App::DocumentObject*,ViewProviderDocumentObject*>::const_iterator
256
it = d->_ViewProviderMap.find( pcFeat );
258
if (it != d->_ViewProviderMap.end())
261
// then try annotation name
262
std::map<std::string,ViewProvider*>::const_iterator it2 = d->_ViewProviderMapAnnotation.find( name );
264
if (it2 != d->_ViewProviderMapAnnotation.end())
271
bool Document::isShow(const char* name)
273
ViewProvider* pcProv = getViewProviderByName(name);
274
return pcProv ? pcProv->isShow() : false;
277
/// put the feature in show
278
void Document::setShow(const char* name)
280
ViewProvider* pcProv = getViewProviderByName(name);
282
if (pcProv && pcProv->getTypeId().isDerivedFrom(ViewProviderDocumentObject::getClassTypeId())) {
283
((ViewProviderDocumentObject*)pcProv)->Visibility.setValue(true);
287
/// set the feature in Noshow
288
void Document::setHide(const char* name)
290
ViewProvider* pcProv = getViewProviderByName(name);
292
if (pcProv && pcProv->getTypeId().isDerivedFrom(ViewProviderDocumentObject::getClassTypeId())) {
293
((ViewProviderDocumentObject*)pcProv)->Visibility.setValue(false);
297
/// set the feature in Noshow
298
void Document::setPos(const char* name, const Base::Matrix4D& rclMtrx)
300
ViewProvider* pcProv = getViewProviderByName(name);
302
pcProv->setTransformation(rclMtrx);
306
//*****************************************************************************************************
308
//*****************************************************************************************************
309
void Document::slotNewObject(App::DocumentObject& Obj)
311
//Base::Console().Log("Document::slotNewObject() called\n");
312
std::string cName = Obj.getViewProviderName();
314
// handle document object with no view provider specified
315
Base::Console().Log("%s has no view provider specified\n", Obj.getTypeId().getName());
320
Base::BaseClass* base = static_cast<Base::BaseClass*>(Base::Type::createInstanceByName(cName.c_str(),true));
322
// type not derived from ViewProviderDocumentObject!!!
323
assert(base->getTypeId().isDerivedFrom(Gui::ViewProviderDocumentObject::getClassTypeId()));
324
ViewProviderDocumentObject *pcProvider = static_cast<ViewProviderDocumentObject*>(base);
325
d->_ViewProviderMap[&Obj] = pcProvider;
328
// if succesfully created set the right name and calculate the view
329
pcProvider->attach(&Obj);
330
pcProvider->updateView();
331
pcProvider->setActiveMode();
333
catch(const Base::MemoryException& e){
334
Base::Console().Error("Memory exception in '%s' thrown: %s\n",Obj.getNameInDocument(),e.what());
336
catch(Base::Exception &e){
341
Base::Console().Error("App::Document::_RecomputeFeature(): Unknown exception in Feature \"%s\" thrown\n",Obj.getNameInDocument());
344
std::list<Gui::BaseView*>::iterator VIt;
345
// cycling to all views of the document
346
for (VIt = d->_LpcViews.begin();VIt != d->_LpcViews.end();VIt++) {
347
View3DInventor *pcIvView = dynamic_cast<View3DInventor *>(*VIt);
349
pcIvView->getViewer()->addViewProvider(pcProvider);
352
// adding to the tree
353
signalNewObject(*pcProvider);
356
Base::Console().Warning("Gui::Document::slotNewObject() no view provider for the object %s found\n",cName.c_str());
360
void Document::slotDeletedObject(App::DocumentObject& Obj)
362
std::list<Gui::BaseView*>::iterator VIt;
364
//Base::Console().Log("Document::slotDeleteObject() called\n");
366
// cycling to all views of the document
367
ViewProvider* viewProvider = getViewProvider(&Obj);
368
for (VIt = d->_LpcViews.begin();VIt != d->_LpcViews.end();VIt++) {
369
View3DInventor *pcIvView = dynamic_cast<View3DInventor *>(*VIt);
370
if (pcIvView && viewProvider) {
371
if (d->_pcInEdit == viewProvider)
373
pcIvView->getViewer()->removeViewProvider(viewProvider);
377
if (viewProvider && viewProvider->getTypeId().isDerivedFrom(
378
ViewProviderDocumentObject::getClassTypeId())) {
379
// removing from tree
380
signalDeletedObject(*(static_cast<ViewProviderDocumentObject*>(viewProvider)));
383
d->_ViewProviderMap.erase(&Obj);
387
void Document::slotChangedObject(App::DocumentObject& Obj, App::Property& Prop)
389
//Base::Console().Log("Document::slotChangedObject() called\n");
390
ViewProvider* viewProvider = getViewProvider(&Obj);
393
viewProvider->update(&Prop);
394
} catch(const Base::MemoryException& e) {
395
Base::Console().Error("Memory exception in '%s' thrown: %s\n",Obj.getNameInDocument(),e.what());
396
} catch(Base::Exception &e){
399
Base::Console().Error("Cannot update representation for '%s'.\n", Obj.getNameInDocument());
402
if (viewProvider->isDerivedFrom(ViewProviderDocumentObject::getClassTypeId()))
403
signalChangedObject(*(static_cast<ViewProviderDocumentObject*>(viewProvider)));
406
// a property of an object has changed
410
void Document::slotRenamedObject(App::DocumentObject& Obj)
412
ViewProvider* viewProvider = getViewProvider(&Obj);
413
if (viewProvider && viewProvider->isDerivedFrom(ViewProviderDocumentObject::getClassTypeId())) {
414
signalRenamedObject(*(static_cast<ViewProviderDocumentObject*>(viewProvider)));
418
void Document::slotActivatedObject(App::DocumentObject& Obj)
420
ViewProvider* viewProvider = getViewProvider(&Obj);
421
if (viewProvider && viewProvider->isDerivedFrom(ViewProviderDocumentObject::getClassTypeId())) {
422
signalActivatedObject(*(static_cast<ViewProviderDocumentObject*>(viewProvider)));
426
void Document::setModified(bool b)
430
std::list<MDIView*> mdis = getMDIViews();
431
for (std::list<MDIView*>::iterator it = mdis.begin(); it != mdis.end(); ++it) {
432
(*it)->setWindowModified(b);
436
bool Document::isModified() const
438
return d->_isModified;
441
App::Document* Document::getDocument(void) const
443
return d->_pcDocument;
446
/// Save the document
447
bool Document::save(void)
449
if (d->_pcDocument->isSaved()) {
451
Command::doCommand(Command::Doc,"App.getDocument(\"%s\").save()"
452
,d->_pcDocument->getName());
461
/// Save the document under a new file name
462
bool Document::saveAs(void)
464
getMainWindow()->statusBar()->showMessage(QObject::tr("Save document under new filename..."));
466
QString exe = QString::fromUtf8(App::Application::Config()["ExeName"].c_str());
467
QString fn = QFileDialog::getSaveFileName(getMainWindow(), QObject::tr("Save %1 Document").arg(exe),
468
QDir::currentPath(), QObject::tr("%1 document (*.FCStd)").arg(exe));
470
QString file = fn.toLower();
471
if (!file.endsWith(QLatin1String(".fcstd"))) {
472
fn += QLatin1String(".fcstd");
476
// if we auto-append the extension make sure that we don't override an existing file
477
int ret = QMessageBox::question(getMainWindow(), QObject::tr("Save As"),
478
QObject::tr("%1 already exists.\n"
479
"Do you want to replace it?").arg(fn),
480
QMessageBox::Yes|QMessageBox::Default,
481
QMessageBox::No|QMessageBox::Escape);
482
if (ret != QMessageBox::Yes)
491
QString bn = fi.baseName();
493
const char * DocName = App::GetApplication().getDocumentName(getDocument());
495
// save as new file name
497
Command::doCommand(Command::Doc,"App.getDocument(\"%s\").FileName = \"%s\""
498
, DocName, (const char*)fn.toUtf8());
499
Command::doCommand(Command::Doc,"App.getDocument(\"%s\").Label = \"%s\""
500
, DocName, (const char*)bn.toUtf8());
501
Command::doCommand(Command::Doc,"App.getDocument(\"%s\").save()"
505
getMainWindow()->appendRecentFile(fi.filePath());
509
getMainWindow()->statusBar()->showMessage(QObject::tr("Saving aborted"), 2000);
514
unsigned int Document::getMemSize (void) const
516
unsigned int size = 0;
518
// size of the view providers in the document
519
std::map<App::DocumentObject*,ViewProviderDocumentObject*>::const_iterator it;
520
for (it = d->_ViewProviderMap.begin(); it != d->_ViewProviderMap.end(); ++it)
521
size += it->second->getMemSize();
526
* Adds a separate XML file to the projects file that contains information about the view providers.
528
void Document::Save (Base::Writer &writer) const
530
// It's only possible to add extra information if force of XML is disabled
531
if (writer.isForceXML() == false) {
532
writer.addFile("GuiDocument.xml", this);
534
if (App::GetApplication().GetParameterGroupByPath
535
("User parameter:BaseApp/Preferences/Document")->GetBool("SaveThumbnail",false)) {
536
std::list<MDIView*> mdi = getMDIViews();
537
for (std::list<MDIView*>::iterator it = mdi.begin(); it != mdi.end(); ++it) {
538
if ((*it)->getTypeId().isDerivedFrom(View3DInventor::getClassTypeId())) {
539
View3DInventorViewer* view = static_cast<View3DInventor*>(*it)->getViewer();
540
d->thumb.setFileName(d->_pcDocument->FileName.getValue());
541
d->thumb.setSize(128);
542
d->thumb.setViewer(view);
543
d->thumb.Save(writer);
552
* Loads a separate XML file from the projects file with information about the view providers.
554
void Document::Restore(Base::XMLReader &reader)
556
reader.addFile("GuiDocument.xml",this);
560
* Restores the properties of the view providers.
562
void Document::RestoreDocFile(Base::Reader &reader)
564
// We must create an XML parser to read from the input stream
565
Base::XMLReader xmlReader("GuiDocument.xml", reader);
569
xmlReader.readElement("Document");
570
long scheme = xmlReader.getAttributeAsInteger("SchemaVersion");
572
// At this stage all the document objects and their associated view providers exist.
573
// Now we must restore the properties of the view providers only.
577
// read the viewproviders itself
578
xmlReader.readElement("ViewProviderData");
579
Cnt = xmlReader.getAttributeAsInteger("Count");
580
for (i=0 ;i<Cnt ;i++) {
581
xmlReader.readElement("ViewProvider");
582
std::string name = xmlReader.getAttribute("name");
583
ViewProvider* pObj = getViewProviderByName(name.c_str());
584
if (pObj) // check if this feature has been registered
586
pObj->Restore(xmlReader);
588
// As the view providers don't get notified when their proprties
589
// change while reading we must force this here
590
std::map<std::string,App::Property*> Map;
591
pObj->getPropertyMap(Map);
592
for (std::map<std::string,App::Property*>::iterator it = Map.begin();
593
it != Map.end(); ++it)
596
xmlReader.readEndElement("ViewProvider");
598
xmlReader.readEndElement("ViewProviderData");
600
// read camera settings
601
xmlReader.readElement("Camera");
602
const char* ppReturn = xmlReader.getAttribute("settings");
603
std::string sMsg = "SetCamera ";
605
if (strcmp(ppReturn, "") != 0) { // non-empty attribute
606
if (d->_pcAppWnd->sendHasMsgToActiveView("SetCamera"))
607
d->_pcAppWnd->sendMsgToActiveView(sMsg.c_str());
611
xmlReader.readEndElement("Document");
613
// reset modifeid flag
618
* Saves the properties of the view providers.
620
void Document::SaveDocFile (Base::Writer &writer) const
622
writer.Stream() << "<?xml version='1.0' encoding='utf-8'?>" << std::endl
623
<< "<!--" << std::endl
624
<< " FreeCAD Document, see http://free-cad.sourceforge.net for more informations..."
625
<< std::endl << "-->" << std::endl;
627
writer.Stream() << "<Document SchemaVersion=\"1\">" << std::endl;
629
std::map<App::DocumentObject*,ViewProviderDocumentObject*>::const_iterator it;
631
// writing the view provider names itself
632
writer.incInd(); // indention for 'ViewProviderData Count'
633
writer.Stream() << writer.ind() << "<ViewProviderData Count=\""
634
<< d->_ViewProviderMap.size() <<"\">" << std::endl;
636
bool xml = writer.isForceXML();
637
writer.setForceXML(true);
638
writer.incInd(); // indention for 'ViewProvider name'
639
for(it = d->_ViewProviderMap.begin(); it != d->_ViewProviderMap.end(); ++it) {
640
App::DocumentObject* doc = it->first;
641
ViewProvider* obj = it->second;
642
writer.Stream() << writer.ind() << "<ViewProvider name=\""
643
<< doc->getNameInDocument() << "\">" << std::endl;
645
writer.Stream() << writer.ind() << "</ViewProvider>" << std::endl;
647
writer.setForceXML(xml);
649
writer.decInd(); // indention for 'ViewProvider name'
650
writer.Stream() << writer.ind() << "</ViewProviderData>" << std::endl;
651
writer.decInd(); // indention for 'ViewProviderData Count'
653
// set camera settings
655
if (d->_pcAppWnd->sendHasMsgToActiveView("GetCamera")) {
656
const char* ppReturn=0;
657
d->_pcAppWnd->sendMsgToActiveView("GetCamera",&ppReturn);
659
// remove the first line because it's a comment like '#Inventor V2.1 ascii'
660
QStringList lines = QString(QString::fromAscii(ppReturn)).split(QLatin1String("\n"));
661
if (lines.size() > 1) {
663
viewPos = lines.join(QLatin1String(" "));
667
writer.incInd(); // indention for camera settings
668
writer.Stream() << writer.ind() << "<Camera settings=\""
669
<< (const char*)viewPos.toAscii() <<"\"/>" << std::endl;
670
writer.decInd(); // indention for camera settings
671
writer.Stream() << "</Document>" << std::endl;
674
void Document::createView(const char* sType)
676
QPixmap FCIcon = Gui::BitmapFactory().pixmap(App::Application::Config()["AppIcon"].c_str());
678
if (strcmp(sType,"View3DIv") == 0){
679
pcView3D = new Gui::View3DInventor(this,getMainWindow());
681
// add the selction node of the document
682
//((View3DInventor*)pcView3D)->getViewer()->addSelectionNode(pcSelection);
684
// attach the viewprovider
685
std::map<App::DocumentObject*,ViewProviderDocumentObject*>::const_iterator It1;
686
for (It1=d->_ViewProviderMap.begin();It1!=d->_ViewProviderMap.end();++It1)
687
((View3DInventor*)pcView3D)->getViewer()->addViewProvider(It1->second);
688
std::map<std::string,ViewProvider*>::const_iterator It2;
689
for (It2=d->_ViewProviderMapAnnotation.begin();It2!=d->_ViewProviderMapAnnotation.end();++It2)
690
((View3DInventor*)pcView3D)->getViewer()->addViewProvider(It2->second);
692
} else /* if(strcmp(sType,"View3DOCC") == 0){
693
pcView3D = new MDIView3D(this,_pcAppWnd,"View3DOCC");
696
Base::Console().Error("Document::createView(): Unknown view type: %s\n",sType);
700
const char* name = getDocument()->Label.getValue();
702
QString aName = QString::fromAscii("%1 : %2[*]")
703
.arg(QString::fromUtf8(name)).arg(d->_iWinCount++);
705
pcView3D->setWindowTitle(aName);
706
pcView3D->setWindowIcon(FCIcon);
707
pcView3D->resize( 400, 300 );
708
getMainWindow()->addWindow(pcView3D);
711
void Document::attachView(Gui::BaseView* pcView, bool bPassiv)
714
d->_LpcViews.push_back(pcView);
716
d->_LpcPassivViews.push_back(pcView);
719
void Document::detachView(Gui::BaseView* pcView, bool bPassiv)
722
if (find(d->_LpcPassivViews.begin(),d->_LpcPassivViews.end(),pcView)
723
!= d->_LpcPassivViews.end())
724
d->_LpcPassivViews.remove(pcView);
727
if (find(d->_LpcViews.begin(),d->_LpcViews.end(),pcView)
728
!= d->_LpcViews.end())
729
d->_LpcViews.remove(pcView);
732
if (d->_LpcViews.size() == 0) {
733
// decouple a passive view
734
std::list<Gui::BaseView*>::iterator It = d->_LpcPassivViews.begin();
735
while (It != d->_LpcPassivViews.end()) {
736
(*It)->setDocument(0);
737
It = d->_LpcPassivViews.begin();
740
// is already closing the document
741
if (d->_isClosing == false)
742
d->_pcAppWnd->onLastWindowClosed(this);
747
void Document::onUpdate(void)
749
#ifdef FC_LOGUPDATECHAIN
750
Base::Console().Log("Acti: Gui::Document::onUpdate()");
753
std::list<Gui::BaseView*>::iterator It;
755
for(It = d->_LpcViews.begin();It != d->_LpcViews.end();It++) {
759
for(It = d->_LpcPassivViews.begin();It != d->_LpcPassivViews.end();It++) {
764
void Document::onRelabel(void)
766
#ifdef FC_LOGUPDATECHAIN
767
Base::Console().Log("Acti: Gui::Document::onRelabel()");
770
std::list<Gui::BaseView*>::iterator It;
772
for (It = d->_LpcViews.begin();It != d->_LpcViews.end();It++) {
773
(*It)->onRelabel(this);
776
for (It = d->_LpcPassivViews.begin();It != d->_LpcPassivViews.end();It++) {
777
(*It)->onRelabel(this);
781
bool Document::isLastView(void)
783
if (d->_LpcViews.size() <= 1)
789
* This method checks if the document can be closed. It checks on
790
* the save state of the document and is able to abort the closing.
792
bool Document::canClose ()
794
if (!getDocument()->isClosable()) {
795
QMessageBox::warning(getActiveView(),
796
QObject::tr("Document not closable"),
797
QObject::tr("The document is not closable for the moment."));
804
switch(QMessageBox::question(getActiveView(),
805
QObject::tr("Unsaved document"),
806
QObject::tr("Save document before close?"),
807
QMessageBox::Yes | QMessageBox::Default,
809
QMessageBox::Cancel | QMessageBox::Escape))
811
case QMessageBox::Yes:
814
case QMessageBox::No:
817
case QMessageBox::Cancel:
825
std::list<MDIView*> Document::getMDIViews() const
827
std::list<MDIView*> views;
828
for (std::list<BaseView*>::const_iterator it = d->_LpcViews.begin();
829
it != d->_LpcViews.end(); ++it) {
830
MDIView* view = dynamic_cast<MDIView*>(*it);
832
views.push_back(view);
838
/// send messages to the active view
839
bool Document::sendMsgToViews(const char* pMsg)
841
std::list<Gui::BaseView*>::iterator It;
842
const char** pReturnIgnore=0;
844
for (It = d->_LpcViews.begin();It != d->_LpcViews.end();It++) {
845
if ((*It)->onMsg(pMsg,pReturnIgnore)) {
850
for (It = d->_LpcPassivViews.begin();It != d->_LpcPassivViews.end();It++) {
851
if ((*It)->onMsg(pMsg,pReturnIgnore)) {
859
/// Getter for the active view
860
MDIView* Document::getActiveView(void) const
862
// get the main window's active view
863
MDIView* active = getMainWindow()->activeWindow();
865
// get all MDI views of the document
866
std::list<MDIView*> mdis = getMDIViews();
868
// check whether the active view is part of this document
870
for (std::list<MDIView*>::const_iterator it = mdis.begin(); it != mdis.end(); ++it) {
871
if ((*it) == active) {
877
// the active view is not part of this document, just use the first view
878
if (!ok && !mdis.empty())
879
active = mdis.front();
885
//--------------------------------------------------------------------------
886
// UNDO REDO transaction handling
887
//--------------------------------------------------------------------------
888
/** Open a new Undo transaction on the active document
889
* This method opens a new UNDO transaction on the active document. This transaction
890
* will later appear in the UNDO/REDO dialog with the name of the command. If the user
891
* recall the transaction everything changed on the document between OpenCommand() and
892
* CommitCommand will be undone (or redone). You can use an alternetive name for the
893
* operation default is the command name.
894
* @see CommitCommand(),AbortCommand()
896
void Document::openCommand(const char* sName)
898
getDocument()->openTransaction(sName);
901
void Document::commitCommand(void)
903
getDocument()->commitTransaction();
906
void Document::abortCommand(void)
908
getDocument()->abortTransaction();
911
/// Get a string vector with the 'Undo' actions
912
std::vector<std::string> Document::getUndoVector(void) const
914
return getDocument()->getAvailableUndoNames();
917
/// Get a string vector with the 'Redo' actions
918
std::vector<std::string> Document::getRedoVector(void) const
920
return getDocument()->getAvailableRedoNames();
923
/// Will UNDO one or more steps
924
void Document::undo(int iSteps)
926
for (int i=0;i<iSteps;i++) {
927
getDocument()->undo();
931
/// Will REDO one or more steps
932
void Document::redo(int iSteps)
934
for (int i=0;i<iSteps;i++) {
935
getDocument()->redo();
939
PyObject* Document::getPyObject(void)