Merge branch 'main' into main

This commit is contained in:
HowThatWorks
2024-05-07 08:17:42 +02:00
committed by GitHub
785 changed files with 82619 additions and 64374 deletions
@@ -92,8 +92,11 @@ macro(SetupShibokenAndPyside)
if(PYSIDE_MAJOR_VERSION LESS 6)
file(WRITE ${CMAKE_BINARY_DIR}/Ext/PySide/QtSvgWidgets.py "from PySide${PYSIDE_MAJOR_VERSION}.QtSvg import QGraphicsSvgItem\n"
"from PySide${PYSIDE_MAJOR_VERSION}.QtSvg import QSvgWidget\n")
file(WRITE ${CMAKE_BINARY_DIR}/Ext/PySide/QtWebEngineWidgets.py "from PySide${PYSIDE_MAJOR_VERSION}.QtWebEngineWidgets import *\n")
else()
file(WRITE ${CMAKE_BINARY_DIR}/Ext/PySide/QtSvgWidgets.py "from PySide${PYSIDE_MAJOR_VERSION}.QtSvgWidgets import *\n")
file(WRITE ${CMAKE_BINARY_DIR}/Ext/PySide/QtWebEngineWidgets.py "from PySide${PYSIDE_MAJOR_VERSION}.QtWebEngineWidgets import *\n"
"from PySide${PYSIDE_MAJOR_VERSION}.QtWebEngineCore import QWebEnginePage\n")
endif()
endif()
+23 -15
View File
@@ -3072,7 +3072,8 @@ void PropertyMaterialList::Save(Base::Writer& writer) const
{
if (!writer.isForceXML()) {
writer.Stream() << writer.ind() << "<MaterialList file=\""
<< (getSize() ? writer.addFile(getName(), this) : "") << "\"/>"
<< (getSize() ? writer.addFile(getName(), this) : "") << "\""
<< " version=\"2\"/>"
<< std::endl;
}
}
@@ -3082,6 +3083,9 @@ void PropertyMaterialList::Restore(Base::XMLReader& reader)
reader.readElement("MaterialList");
if (reader.hasAttribute("file")) {
std::string file(reader.getAttribute("file"));
if (reader.hasAttribute("version")) {
formatVersion = static_cast<Format>(reader.getAttributeAsInteger("version"));
}
if (!file.empty()) {
// initiate a file read
@@ -3093,10 +3097,6 @@ void PropertyMaterialList::Restore(Base::XMLReader& reader)
void PropertyMaterialList::SaveDocFile(Base::Writer& writer) const
{
Base::OutputStream str(writer.Stream());
// Write the version. Versions should be negative. A non-negative value is a count
// and should be processed as a V0
int32_t version = -1;
str << version;
uint32_t uCt = (uint32_t)getSize();
str << uCt;
for (const auto& it : _lValueList) {
@@ -3113,14 +3113,22 @@ void PropertyMaterialList::SaveDocFile(Base::Writer& writer) const
void PropertyMaterialList::RestoreDocFile(Base::Reader& reader)
{
Base::InputStream str(reader);
int32_t version;
str >> version;
if (version < 0) {
RestoreDocFileV1(reader);
if (formatVersion == Version_2) {
// V2 is same as V0
uint32_t count = 0;
str >> count;
RestoreDocFileV0(count, reader);
}
else {
uint32_t uCt = static_cast<uint32_t>(version);
RestoreDocFileV0(uCt, reader);
int32_t version;
str >> version;
if (version < 0) {
RestoreDocFileV1(reader);
}
else {
uint32_t uCt = static_cast<uint32_t>(version);
RestoreDocFileV0(uCt, reader);
}
}
}
@@ -3128,8 +3136,8 @@ void PropertyMaterialList::RestoreDocFileV0(uint32_t count, Base::Reader& reader
{
Base::InputStream str(reader);
std::vector<Material> values(count);
uint32_t value; // must be 32 bit long
float valueF;
uint32_t value {}; // must be 32 bit long
float valueF {};
for (auto& it : values) {
str >> value;
it.ambientColor.setPackedValue(value);
@@ -3153,8 +3161,8 @@ void PropertyMaterialList::RestoreDocFileV1(Base::Reader& reader)
uint32_t count = 0;
str >> count;
std::vector<Material> values(count);
uint32_t value; // must be 32 bit long
float valueF;
uint32_t value {}; // must be 32 bit long
float valueF {};
for (auto& it : values) {
str >> value;
it.ambientColor.setPackedValue(value);
+9 -1
View File
@@ -1189,13 +1189,21 @@ public:
protected:
Material getPyValue(PyObject* py) const override;
private:
enum Format {
Version_0,
Version_1,
Version_2
};
void RestoreDocFileV0(uint32_t count, Base::Reader& reader);
void RestoreDocFileV1(Base::Reader& reader);
private:
void verifyIndex(int index) const;
void setSizeOne();
int resizeByOneIfNeeded(int index);
Format formatVersion {Version_0};
};
+1 -1
View File
@@ -13,7 +13,7 @@ that reference the same configurable object</source>
<context>
<name>QObject</name>
<message>
<location filename="../../Application.cpp" line="447"/>
<location filename="../../Application.cpp" line="451"/>
<source>Unnamed</source>
<translation type="unfinished"></translation>
</message>
+1 -1
View File
@@ -13,7 +13,7 @@ that reference the same configurable object</source>
<context>
<name>QObject</name>
<message>
<location filename="../../Application.cpp" line="447"/>
<location filename="../../Application.cpp" line="451"/>
<source>Unnamed</source>
<translation>Без назвы</translation>
</message>
+1 -1
View File
@@ -13,7 +13,7 @@ that reference the same configurable object</source>
<context>
<name>QObject</name>
<message>
<location filename="../../Application.cpp" line="447"/>
<location filename="../../Application.cpp" line="451"/>
<source>Unnamed</source>
<translation>Sense nom</translation>
</message>
+1 -1
View File
@@ -14,7 +14,7 @@ které odkazují na stejný konfigurovatelný objekt</translation>
<context>
<name>QObject</name>
<message>
<location filename="../../Application.cpp" line="447"/>
<location filename="../../Application.cpp" line="451"/>
<source>Unnamed</source>
<translation>Nepojmenovaný</translation>
</message>
+1 -1
View File
@@ -14,7 +14,7 @@ angewendet werden soll, die das gleiche konfigurierbare Objekt referenzieren</tr
<context>
<name>QObject</name>
<message>
<location filename="../../Application.cpp" line="447"/>
<location filename="../../Application.cpp" line="451"/>
<source>Unnamed</source>
<translation>Unbenannt</translation>
</message>
+1 -1
View File
@@ -14,7 +14,7 @@ that reference the same configurable object</source>
<context>
<name>QObject</name>
<message>
<location filename="../../Application.cpp" line="447"/>
<location filename="../../Application.cpp" line="451"/>
<source>Unnamed</source>
<translation>Ανώνυμο</translation>
</message>
+1 -1
View File
@@ -14,7 +14,7 @@ que hacen referencia al mismo objeto configurable</translation>
<context>
<name>QObject</name>
<message>
<location filename="../../Application.cpp" line="447"/>
<location filename="../../Application.cpp" line="451"/>
<source>Unnamed</source>
<translation>Sin nombre</translation>
</message>
+1 -1
View File
@@ -13,7 +13,7 @@ that reference the same configurable object</source>
<context>
<name>QObject</name>
<message>
<location filename="../../Application.cpp" line="447"/>
<location filename="../../Application.cpp" line="451"/>
<source>Unnamed</source>
<translation>Sin nombre</translation>
</message>
+1 -1
View File
@@ -13,7 +13,7 @@ that reference the same configurable object</source>
<context>
<name>QObject</name>
<message>
<location filename="../../Application.cpp" line="447"/>
<location filename="../../Application.cpp" line="451"/>
<source>Unnamed</source>
<translation>Izenik gabea</translation>
</message>
+1 -1
View File
@@ -14,7 +14,7 @@ that reference the same configurable object</translation>
<context>
<name>QObject</name>
<message>
<location filename="../../Application.cpp" line="447"/>
<location filename="../../Application.cpp" line="451"/>
<source>Unnamed</source>
<translation>Nimetön</translation>
</message>
+1 -1
View File
@@ -13,7 +13,7 @@ that reference the same configurable object</source>
<context>
<name>QObject</name>
<message>
<location filename="../../Application.cpp" line="447"/>
<location filename="../../Application.cpp" line="451"/>
<source>Unnamed</source>
<translation>Sans nom</translation>
</message>
+1 -1
View File
@@ -14,7 +14,7 @@ na sve veze koje referenciraju isti konfigurabilni objekt</translation>
<context>
<name>QObject</name>
<message>
<location filename="../../Application.cpp" line="447"/>
<location filename="../../Application.cpp" line="451"/>
<source>Unnamed</source>
<translation>Neimenovano</translation>
</message>
+1 -1
View File
@@ -14,7 +14,7 @@ amelyek ugyanarra a konfigurálható tárgyra hivatkoznak</translation>
<context>
<name>QObject</name>
<message>
<location filename="../../Application.cpp" line="447"/>
<location filename="../../Application.cpp" line="451"/>
<source>Unnamed</source>
<translation>Névtelen</translation>
</message>
+1 -1
View File
@@ -13,7 +13,7 @@ that reference the same configurable object</source>
<context>
<name>QObject</name>
<message>
<location filename="../../Application.cpp" line="447"/>
<location filename="../../Application.cpp" line="451"/>
<source>Unnamed</source>
<translation>Tanpa nama</translation>
</message>
+1 -1
View File
@@ -14,7 +14,7 @@ che fanno riferimento allo stesso oggetto configurabile</translation>
<context>
<name>QObject</name>
<message>
<location filename="../../Application.cpp" line="447"/>
<location filename="../../Application.cpp" line="451"/>
<source>Unnamed</source>
<translation>Senza nome</translation>
</message>
+1 -1
View File
@@ -13,7 +13,7 @@ that reference the same configurable object</source>
<context>
<name>QObject</name>
<message>
<location filename="../../Application.cpp" line="447"/>
<location filename="../../Application.cpp" line="451"/>
<source>Unnamed</source>
<translation></translation>
</message>
+1 -1
View File
@@ -13,7 +13,7 @@ that reference the same configurable object</source>
<context>
<name>QObject</name>
<message>
<location filename="../../Application.cpp" line="447"/>
<location filename="../../Application.cpp" line="451"/>
<source>Unnamed</source>
<translation></translation>
</message>
+1 -1
View File
@@ -14,7 +14,7 @@ that reference the same configurable object</translation>
<context>
<name>QObject</name>
<message>
<location filename="../../Application.cpp" line="447"/>
<location filename="../../Application.cpp" line="451"/>
<source>Unnamed</source>
<translation></translation>
</message>
+1 -1
View File
@@ -14,7 +14,7 @@ die verwijzen naar hetzelfde configureerbare object</translation>
<context>
<name>QObject</name>
<message>
<location filename="../../Application.cpp" line="447"/>
<location filename="../../Application.cpp" line="451"/>
<source>Unnamed</source>
<translation>Naamloos</translation>
</message>
+1 -1
View File
@@ -14,7 +14,7 @@ które odnoszą się do tego samego obiektu konfigurowalnego</translation>
<context>
<name>QObject</name>
<message>
<location filename="../../Application.cpp" line="447"/>
<location filename="../../Application.cpp" line="451"/>
<source>Unnamed</source>
<translation>Nienazwany</translation>
</message>
+1 -1
View File
@@ -14,7 +14,7 @@ que referenciam o mesmo objeto configurável</translation>
<context>
<name>QObject</name>
<message>
<location filename="../../Application.cpp" line="447"/>
<location filename="../../Application.cpp" line="451"/>
<source>Unnamed</source>
<translation>Sem nome</translation>
</message>
+1 -1
View File
@@ -14,7 +14,7 @@ that reference the same configurable object</translation>
<context>
<name>QObject</name>
<message>
<location filename="../../Application.cpp" line="447"/>
<location filename="../../Application.cpp" line="451"/>
<source>Unnamed</source>
<translation>Sem nome</translation>
</message>
+1 -1
View File
@@ -14,7 +14,7 @@ care fac referire la același obiect configurabil</translation>
<context>
<name>QObject</name>
<message>
<location filename="../../Application.cpp" line="447"/>
<location filename="../../Application.cpp" line="451"/>
<source>Unnamed</source>
<translation>Nedenumit</translation>
</message>
+1 -1
View File
@@ -13,7 +13,7 @@ that reference the same configurable object</source>
<context>
<name>QObject</name>
<message>
<location filename="../../Application.cpp" line="447"/>
<location filename="../../Application.cpp" line="451"/>
<source>Unnamed</source>
<translation>Безымянный</translation>
</message>
+1 -1
View File
@@ -14,7 +14,7 @@ za vse povezave, ki se sklicujejo na isti nastavljivi predmet</translation>
<context>
<name>QObject</name>
<message>
<location filename="../../Application.cpp" line="447"/>
<location filename="../../Application.cpp" line="451"/>
<source>Unnamed</source>
<translation>Neimenovan</translation>
</message>
+1 -1
View File
@@ -14,7 +14,7 @@ that reference the same configurable object</translation>
<context>
<name>QObject</name>
<message>
<location filename="../../Application.cpp" line="447"/>
<location filename="../../Application.cpp" line="451"/>
<source>Unnamed</source>
<translation>Bez imena</translation>
</message>
+1 -1
View File
@@ -14,7 +14,7 @@ that reference the same configurable object</translation>
<context>
<name>QObject</name>
<message>
<location filename="../../Application.cpp" line="447"/>
<location filename="../../Application.cpp" line="451"/>
<source>Unnamed</source>
<translation>Без имена</translation>
</message>
+1 -1
View File
@@ -14,7 +14,7 @@ that reference the same configurable object</translation>
<context>
<name>QObject</name>
<message>
<location filename="../../Application.cpp" line="447"/>
<location filename="../../Application.cpp" line="451"/>
<source>Unnamed</source>
<translation>Namnlös</translation>
</message>
+1 -1
View File
@@ -14,7 +14,7 @@ uygulanmayacağına ilişkin son kullanıcı seçimini saklar</translation>
<context>
<name>QObject</name>
<message>
<location filename="../../Application.cpp" line="447"/>
<location filename="../../Application.cpp" line="451"/>
<source>Unnamed</source>
<translation>İsimsiz</translation>
</message>
+1 -1
View File
@@ -13,7 +13,7 @@ that reference the same configurable object</source>
<context>
<name>QObject</name>
<message>
<location filename="../../Application.cpp" line="447"/>
<location filename="../../Application.cpp" line="451"/>
<source>Unnamed</source>
<translation>Без назви</translation>
</message>
+1 -1
View File
@@ -14,7 +14,7 @@ that reference the same configurable object</translation>
<context>
<name>QObject</name>
<message>
<location filename="../../Application.cpp" line="447"/>
<location filename="../../Application.cpp" line="451"/>
<source>Unnamed</source>
<translation>Sense nom</translation>
</message>
+1 -1
View File
@@ -14,7 +14,7 @@ that reference the same configurable object</translation>
<context>
<name>QObject</name>
<message>
<location filename="../../Application.cpp" line="447"/>
<location filename="../../Application.cpp" line="451"/>
<source>Unnamed</source>
<translation></translation>
</message>
+1 -1
View File
@@ -14,7 +14,7 @@ that reference the same configurable object</translation>
<context>
<name>QObject</name>
<message>
<location filename="../../Application.cpp" line="447"/>
<location filename="../../Application.cpp" line="451"/>
<source>Unnamed</source>
<translation></translation>
</message>
+2 -10
View File
@@ -36,7 +36,6 @@
# include <QToolBar>
# include <QToolButton>
# include <QToolTip>
# include <QMenuBar>
#endif
#include <Base/Exception.h>
@@ -55,7 +54,6 @@
#include "Macro.h"
#include "MainWindow.h"
#include "PythonEditor.h"
#include "UserSettings.h"
#include "WhatsThis.h"
#include "Widgets.h"
#include "Workbench.h"
@@ -631,7 +629,7 @@ WorkbenchGroup::WorkbenchGroup ( Command* pcCmd, QObject * parent )
void WorkbenchGroup::addTo(QWidget *widget)
{
if (widget->inherits("QToolBar") || widget->inherits("QMenuBar")) {
if (widget->inherits("QToolBar")) {
ParameterGrp::handle hGrp;
hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Workbenches");
QWidget* wbSel;
@@ -642,13 +640,7 @@ void WorkbenchGroup::addTo(QWidget *widget)
wbSel = new WorkbenchTabWidget(this, widget);
}
if (widget->inherits("QToolBar")) {
qobject_cast<QToolBar*>(widget)->addWidget(wbSel);
}
else {
bool left = WorkbenchSwitcher::isLeftCorner(WorkbenchSwitcher::getValue());
qobject_cast<QMenuBar*>(widget)->setCornerWidget(wbSel, left ? Qt::TopLeftCorner : Qt::TopRightCorner);
}
static_cast<QToolBar*>(widget)->addWidget(wbSel);
}
else if (widget->inherits("QMenu")) {
auto menu = qobject_cast<QMenu*>(widget);
+2 -7
View File
@@ -172,9 +172,7 @@ SbBool BlenderNavigationStyle::processSoEvent(const SoEvent * const ev)
case SoMouseButtonEvent::BUTTON3:
if (press) {
this->centerTime = ev->getTime();
float ratio = vp.getViewportAspectRatio();
SbViewVolume vv = viewer->getSoRenderManager()->getCamera()->getViewVolume(ratio);
this->panningplane = vv.getPlane(viewer->getSoRenderManager()->getCamera()->focalDistance.getValue());
setupPanningPlane(getCamera());
this->lockrecenter = false;
}
else {
@@ -182,10 +180,7 @@ SbBool BlenderNavigationStyle::processSoEvent(const SoEvent * const ev)
float dci = (float)QApplication::doubleClickInterval()/1000.0f;
// is it just a middle click?
if (tmp.getValue() < dci && !this->lockrecenter) {
if (!this->lookAtPoint(pos)) {
panToCenter(panningplane, posn);
this->interactiveCountDec();
}
lookAtPoint(pos);
processed = true;
}
}
+2 -7
View File
@@ -179,9 +179,7 @@ SbBool CADNavigationStyle::processSoEvent(const SoEvent * const ev)
case SoMouseButtonEvent::BUTTON3:
if (press) {
this->centerTime = ev->getTime();
float ratio = vp.getViewportAspectRatio();
SbViewVolume vv = viewer->getSoRenderManager()->getCamera()->getViewVolume(ratio);
this->panningplane = vv.getPlane(viewer->getSoRenderManager()->getCamera()->focalDistance.getValue());
setupPanningPlane(getCamera());
this->lockrecenter = false;
}
else {
@@ -189,10 +187,7 @@ SbBool CADNavigationStyle::processSoEvent(const SoEvent * const ev)
float dci = (float)QApplication::doubleClickInterval()/1000.0f;
// is it just a middle click?
if (tmp.getValue() < dci && !this->lockrecenter) {
if (!this->lookAtPoint(pos)) {
panToCenter(panningplane, posn);
this->interactiveCountDec();
}
lookAtPoint(pos);
processed = true;
}
}
-2
View File
@@ -1217,7 +1217,6 @@ SET(FreeCADGui_CPP_SRCS
ManualAlignment.cpp
StartupProcess.cpp
TransactionObject.cpp
UserSettings.cpp
)
SET(FreeCADGui_SRCS
Application.h
@@ -1255,7 +1254,6 @@ SET(FreeCADGui_SRCS
ManualAlignment.h
StartupProcess.h
TransactionObject.h
UserSettings.h
${FreeCADGui_SDK_MOC_HDRS}
)
+20 -11
View File
@@ -1419,6 +1419,7 @@ void Document::RestoreDocFile(Base::Reader &reader)
for (int i=0; i<Cnt; i++) {
localreader->readElement("ViewProvider");
std::string name = localreader->getAttribute("name");
bool expanded = false;
if (!hasExpansion && localreader->hasAttribute("expanded")) {
const char* attr = localreader->getAttribute("expanded");
@@ -1426,15 +1427,24 @@ void Document::RestoreDocFile(Base::Reader &reader)
expanded = true;
}
}
ViewProvider* pObj = getViewProviderByName(name.c_str());
int treeRank = -1;
if (localreader->hasAttribute("treeRank")) {
treeRank = int(localreader->getAttributeAsInteger("treeRank"));
}
auto pObj = dynamic_cast<ViewProviderDocumentObject*>(getViewProviderByName(name.c_str()));
// check if this feature has been registered
if (pObj){
if (pObj) {
pObj->Restore(*localreader);
}
if (pObj && treeRank >= 0) {
pObj->setTreeRank(treeRank);
}
if (pObj && expanded) {
auto vp = static_cast<Gui::ViewProviderDocumentObject*>(pObj);
this->signalExpandObject(*vp, TreeItemMode::ExpandItem,0,0);
this->signalExpandObject(*pObj, TreeItemMode::ExpandItem, 0, 0);
}
localreader->readEndElement("ViewProvider");
}
@@ -1536,8 +1546,6 @@ void Document::SaveDocFile (Base::Writer &writer) const
if(!hasExpansion)
writer.Stream() << ">" << std::endl;
std::map<const App::DocumentObject*,ViewProviderDocumentObject*>::const_iterator it;
// writing the view provider names itself
writer.Stream() << writer.ind() << "<ViewProviderData Count=\""
<< d->_ViewProviderMap.size() <<"\">" << std::endl;
@@ -1545,12 +1553,13 @@ void Document::SaveDocFile (Base::Writer &writer) const
bool xml = writer.isForceXML();
//writer.setForceXML(true);
writer.incInd(); // indentation for 'ViewProvider name'
for(it = d->_ViewProviderMap.begin(); it != d->_ViewProviderMap.end(); ++it) {
const App::DocumentObject* doc = it->first;
ViewProvider* obj = it->second;
for(const auto& it : d->_ViewProviderMap) {
const App::DocumentObject* doc = it.first;
ViewProviderDocumentObject* obj = it.second;
writer.Stream() << writer.ind() << "<ViewProvider name=\""
<< doc->getNameInDocument() << "\" "
<< "expanded=\"" << (doc->testStatus(App::Expand) ? 1:0) << "\"";
<< doc->getNameInDocument() << "\""
<< " expanded=\"" << (doc->testStatus(App::Expand) ? 1:0) << "\""
<< " treeRank=\"" << obj->getTreeRank() << "\"";
if (obj->hasExtensions())
writer.Stream() << " Extensions=\"True\"";
+10 -17
View File
@@ -297,7 +297,8 @@ public:
//MMB click
if(ev.isPress(3) && ev.mbstate() == 0x010){
ev.flags->processed = true;
ns.onSetRotationCenter(ev.inventor_event->getPosition());
ns.setupPanningPlane(ns.viewer->getCamera());
ns.lookAtPoint(ev.inventor_event->getPosition());
return transit<NS::AwaitingReleaseState>();
}
@@ -314,8 +315,10 @@ public:
bool press = (kbev->getState() == SoKeyboardEvent::DOWN);
switch (kbev->getKey()) {
case SoKeyboardEvent::H:
if (!press)
ns.onSetRotationCenter(kbev->getPosition());
if (!press) {
ns.setupPanningPlane(ns.viewer->getCamera());
ns.lookAtPoint(kbev->getPosition());
}
break;
case SoKeyboardEvent::PAGE_UP:
if(!press){
@@ -538,7 +541,7 @@ public:
if (ns.logging)
Base::Console().Log(" -> PanState\n");
this->ratio = ns.viewer->getSoRenderManager()->getViewportRegion().getViewportAspectRatio();
ns.pan(ns.viewer->getSoRenderManager()->getCamera());//set up panningplane
ns.setupPanningPlane(ns.viewer->getSoRenderManager()->getCamera());//set up panningplane
}
virtual ~PanState() = default;
@@ -585,7 +588,7 @@ public:
if (ns.logging)
Base::Console().Log(" -> StickyPanState\n");
this->ratio = ns.viewer->getSoRenderManager()->getViewportRegion().getViewportAspectRatio();
ns.pan(ns.viewer->getSoRenderManager()->getCamera());//set up panningplane
ns.setupPanningPlane(ns.viewer->getSoRenderManager()->getCamera());//set up panningplane
}
virtual ~StickyPanState(){
auto &ns = this->outermost_context().ns;
@@ -631,7 +634,7 @@ public:
this->base_pos = static_cast<const NS::Event*>(this->triggering_event())->inventor_event->getPosition();
if (ns.logging)
Base::Console().Log(" -> TiltState\n");
ns.pan(ns.viewer->getSoRenderManager()->getCamera());//set up panningplane
ns.setupPanningPlane(ns.viewer->getSoRenderManager()->getCamera());//set up panningplane
}
virtual ~TiltState() = default;
@@ -681,7 +684,7 @@ public:
this->base_pos = static_cast<const NS::Event*>(this->triggering_event())->inventor_event->getPosition();
if (ns.logging)
Base::Console().Log(" -> GestureState\n");
ns.pan(ns.viewer->getSoRenderManager()->getCamera());//set up panningplane
ns.setupPanningPlane(ns.viewer->getSoRenderManager()->getCamera());//set up panningplane
this->ratio = ns.viewer->getSoRenderManager()->getViewportRegion().getViewportAspectRatio();
enableTilt = !(App::GetApplication().GetParameterGroupByPath
("User parameter:BaseApp/Preferences/View")->GetBool("DisableTouchTilt",true));
@@ -1007,16 +1010,6 @@ void GestureNavigationStyle::onRollGesture(int direction)
}
void GestureNavigationStyle::onSetRotationCenter(SbVec2s cursor){
SbBool ret = NavigationStyle::lookAtPoint(cursor);
if(!ret){
this->interactiveCountDec(); //this was in original gesture nav. Not sure what is it needed for --DeepSOIC
Base::Console().Log(
"No object under cursor! Can't set new center of rotation.\n");
}
}
void GestureNavigationStyle::EventQueue::post(const NS::Event& ev)
{
ev.flags->processed = true;
-2
View File
@@ -107,8 +107,6 @@ public: //gesture reactions
///Roll gesture is like: press LMB, press RMB, release LMB, release RMB.
/// This function is called by state machine whenever it picks up roll gesture.
void onRollGesture(int direction);
///Called by state machine, when set-rotation-center gesture is detected (MMB click, or H key)
void onSetRotationCenter(SbVec2s cursor);
};
}
+4 -14
View File
@@ -126,9 +126,7 @@ SbBool InventorNavigationStyle::processSoEvent(const SoEvent * const ev)
if (press && ev->wasShiftDown() &&
(this->currentmode != NavigationStyle::SELECTION)) {
this->centerTime = ev->getTime();
float ratio = vp.getViewportAspectRatio();
SbViewVolume vv = viewer->getSoRenderManager()->getCamera()->getViewVolume(ratio);
this->panningplane = vv.getPlane(viewer->getSoRenderManager()->getCamera()->focalDistance.getValue());
setupPanningPlane(getCamera());
this->lockrecenter = false;
}
else if (!press && ev->wasShiftDown() &&
@@ -137,10 +135,7 @@ SbBool InventorNavigationStyle::processSoEvent(const SoEvent * const ev)
float dci = (float)QApplication::doubleClickInterval()/1000.0f;
// is it just a left click?
if (tmp.getValue() < dci && !this->lockrecenter) {
if (!this->lookAtPoint(pos)) {
panToCenter(panningplane, posn);
this->interactiveCountDec();
}
lookAtPoint(pos);
processed = true;
}
}
@@ -191,9 +186,7 @@ SbBool InventorNavigationStyle::processSoEvent(const SoEvent * const ev)
case SoMouseButtonEvent::BUTTON3:
if (press) {
this->centerTime = ev->getTime();
float ratio = vp.getViewportAspectRatio();
SbViewVolume vv = viewer->getSoRenderManager()->getCamera()->getViewVolume(ratio);
this->panningplane = vv.getPlane(viewer->getSoRenderManager()->getCamera()->focalDistance.getValue());
setupPanningPlane(getCamera());
this->lockrecenter = false;
}
else {
@@ -201,10 +194,7 @@ SbBool InventorNavigationStyle::processSoEvent(const SoEvent * const ev)
float dci = (float)QApplication::doubleClickInterval()/1000.0f;
// is it just a middle click?
if (tmp.getValue() < dci && !this->lockrecenter) {
if (!this->lookAtPoint(pos)) {
panToCenter(panningplane, posn);
this->interactiveCountDec();
}
lookAtPoint(pos);
processed = true;
}
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+60 -36
View File
@@ -37,6 +37,7 @@
# include <QLabel>
# include <QMdiSubWindow>
# include <QMenu>
# include <QMenuBar>
# include <QMessageBox>
# include <QMimeData>
# include <QPainter>
@@ -268,6 +269,7 @@ struct MainWindowP
{
DimensionWidget* sizeLabel;
QLabel* actionLabel;
QLabel* rightSideLabel;
QTimer* actionTimer;
QTimer* statusTimer;
QTimer* activityTimer;
@@ -444,6 +446,7 @@ MainWindow::MainWindow(QWidget * parent, Qt::WindowFlags f)
// labels and progressbar
d->status = new StatusBarObserver();
d->actionLabel = new QLabel(statusBar());
d->actionLabel->setTextInteractionFlags(Qt::TextSelectableByMouse);
// d->actionLabel->setMinimumWidth(120);
d->sizeLabel = new DimensionWidget(statusBar());
@@ -453,6 +456,10 @@ MainWindow::MainWindow(QWidget * parent, Qt::WindowFlags f)
statusBar()->addPermanentWidget(progressBar, 0);
statusBar()->addPermanentWidget(d->sizeLabel, 0);
d->rightSideLabel = new QLabel(statusBar());
d->rightSideLabel->setTextInteractionFlags(Qt::TextSelectableByMouse);
statusBar()->addPermanentWidget(d->rightSideLabel);
auto hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/NotificationArea");
auto notificationAreaEnabled = hGrp->GetBool("NotificationAreaEnabled", true);
@@ -463,6 +470,7 @@ MainWindow::MainWindow(QWidget * parent, Qt::WindowFlags f)
notificationArea->setStyleSheet(QStringLiteral("text-align:left;"));
statusBar()->addPermanentWidget(notificationArea);
}
// clears the action label
d->actionTimer = new QTimer( this );
d->actionTimer->setObjectName(QString::fromLatin1("actionTimer"));
@@ -789,7 +797,19 @@ bool MainWindow::updateDAGView(bool show)
QMenu* MainWindow::createPopupMenu ()
{
QMenu* menu = QMainWindow::createPopupMenu();
QMenu *menu = new QMenu(this);
populateDockWindowMenu(menu);
menu->addSeparator();
populateToolBarMenu(menu);
QMenu *undockMenu = new QMenu(menu);
ToolBarManager::getInstance()->populateUndockMenu(undockMenu);
if (undockMenu->actions().isEmpty()) {
delete undockMenu;
}
else {
menu->addMenu(undockMenu);
}
menu->addSeparator();
Workbench* wb = WorkbenchManager::instance()->active();
if (wb) {
MenuItem item;
@@ -989,32 +1009,16 @@ void MainWindow::whatsThis()
void MainWindow::showDocumentation(const QString& help)
{
Base::PyGILStateLocker lock;
PyObject* module = PyImport_ImportModule("Help");
if (module) {
Py_DECREF(module);
Gui::Command::addModule(Gui::Command::Gui,"Help");
Gui::Command::doCommand(Gui::Command::Gui,"Help.show(\"%s\")", help.toStdString().c_str());
try {
PyObject* module = PyImport_ImportModule("Help");
if (module) {
Py_DECREF(module);
Gui::Command::addModule(Gui::Command::Gui,"Help");
Gui::Command::doCommand(Gui::Command::Gui,"Help.show(\"%s\")", help.toStdString().c_str());
}
}
else {
PyErr_Clear();
QUrl url(help);
if (url.scheme().isEmpty()) {
QMessageBox msgBox(getMainWindow());
msgBox.setWindowTitle(tr("Help addon needed!"));
msgBox.setText(tr("The Help system of %1 is now handled by the \"Help\" addon. "
"It can easily be installed via the Addons Manager").arg(QString(qApp->applicationName())));
QAbstractButton* pButtonAddonMgr = msgBox.addButton(tr("Open Addon Manager"), QMessageBox::YesRole);
msgBox.addButton(QMessageBox::Ok);
msgBox.exec();
if (msgBox.clickedButton() == pButtonAddonMgr) {
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Addons");
hGrp->SetASCII("SelectedAddon", "Help");
Gui::Command::doCommand(Gui::Command::Gui,"Gui.runCommand('Std_AddonMgr',0)");
}
}
else {
QDesktopServices::openUrl(url);
}
catch (const Base::Exception& e) {
e.ReportException();
}
}
@@ -1406,26 +1410,41 @@ void MainWindow::onToolBarMenuAboutToShow()
{
auto menu = static_cast<QMenu*>(sender());
menu->clear();
QList<QToolBar*> dock = this->findChildren<QToolBar*>();
for (const auto & it : dock) {
if (it->parentWidget() == this) {
QAction* action = it->toggleViewAction();
action->setToolTip(tr("Toggles this toolbar"));
action->setStatusTip(tr("Toggles this toolbar"));
action->setWhatsThis(tr("Toggles this toolbar"));
menu->addAction(action);
}
}
populateToolBarMenu(menu);
menu->addSeparator();
Application::Instance->commandManager().getCommandByName("Std_ToggleToolBarLock")->addTo(menu);
}
void MainWindow::populateToolBarMenu(QMenu *menu)
{
QList<QToolBar*> toolbars = this->findChildren<QToolBar*>();
for (const auto & toolbar : toolbars) {
if (auto parent = toolbar->parentWidget()) {
if (parent == this
|| parent == statusBar()
|| parent->parentWidget() == statusBar()
|| parent->parentWidget() == menuBar()) {
QAction* action = toolbar->toggleViewAction();
action->setToolTip(tr("Toggles this toolbar"));
action->setStatusTip(tr("Toggles this toolbar"));
action->setWhatsThis(tr("Toggles this toolbar"));
menu->addAction(action);
}
}
}
}
void MainWindow::onDockWindowMenuAboutToShow()
{
auto menu = static_cast<QMenu*>(sender());
menu->clear();
populateDockWindowMenu(menu);
}
void MainWindow::populateDockWindowMenu(QMenu *menu)
{
QList<QDockWidget*> dock = this->findChildren<QDockWidget*>();
for (auto & it : dock) {
QAction* action = it->toggleViewAction();
@@ -2419,6 +2438,11 @@ void MainWindow::showMessage(const QString& message, int timeout) {
d->actionTimer->stop();
}
void MainWindow::setRightSideMessage(const QString& message)
{
d->rightSideLabel->setText(message.simplified());
}
void MainWindow::showStatus(int type, const QString& message)
{
if(QApplication::instance()->thread() != QThread::currentThread()) {
+4
View File
@@ -265,6 +265,7 @@ public Q_SLOTS:
void statusMessageChanged();
void showMessage (const QString & message, int timeout = 0);
void setRightSideMessage(const QString & message);
// Set main window title
void setWindowTitle(const QString& string);
@@ -308,6 +309,9 @@ private:
bool updateComboView(bool show);
bool updateDAGView(bool show);
void populateToolBarMenu(QMenu *);
void populateDockWindowMenu(QMenu *);
static void renderDevBuildWarning(QPainter &painter, const QPoint startPosition, const QSize maxSize);
private Q_SLOTS:
+8 -16
View File
@@ -280,13 +280,9 @@ SbBool MayaGestureNavigationStyle::processSoEvent(const SoEvent * const ev)
switch (event->getKey()) {
case SoKeyboardEvent::H:
processed = true;
if(!press){
SbBool ret = NavigationStyle::lookAtPoint(event->getPosition());
if(!ret){
this->interactiveCountDec();
Base::Console().Log(
"No object under cursor! Can't set new center of rotation.\n");
}
if (!press) {
setupPanningPlane(viewer->getCamera());
lookAtPoint(event->getPosition());
}
break;
default:
@@ -397,7 +393,7 @@ SbBool MayaGestureNavigationStyle::processSoEvent(const SoEvent * const ev)
//reset/start move detection machine
this->mousedownPos = pos;
this->mouseMoveThresholdBroken = false;
pan(viewer->getSoRenderManager()->getCamera());//set up panningplane
setupPanningPlane(viewer->getSoRenderManager()->getCamera());//set up panningplane
int &cnt = this->mousedownConsumedCount;
this->mousedownConsumedEvents[cnt] = *event;//hopefully, a shallow copy is enough. There are no pointers stored in events, apparently. Will lose a subclass, though.
cnt++;
@@ -431,12 +427,8 @@ SbBool MayaGestureNavigationStyle::processSoEvent(const SoEvent * const ev)
setViewingMode(NavigationStyle::PANNING);
} else if(press){
// if not PANNING then look at point
SbBool ret = NavigationStyle::lookAtPoint(event->getPosition());
if(!ret){
this->interactiveCountDec();
Base::Console().Log(
"No object under cursor! Can't set new center of rotation.\n");
}
setupPanningPlane(viewer->getCamera());
lookAtPoint(event->getPosition());
}
processed = true;
break;
@@ -480,11 +472,11 @@ SbBool MayaGestureNavigationStyle::processSoEvent(const SoEvent * const ev)
if (gesture->state == SoGestureEvent::SbGSStart
|| gesture->state == SoGestureEvent::SbGSUpdate) {//even if we didn't get a start, assume the first update is a start (sort-of fail-safe).
if (type.isDerivedFrom(SoGesturePanEvent::getClassTypeId())) {
pan(viewer->getSoRenderManager()->getCamera());//set up panning plane
setupPanningPlane(viewer->getSoRenderManager()->getCamera());//set up panning plane
setViewingMode(NavigationStyle::PANNING);
processed = true;
} else if (type.isDerivedFrom(SoGesturePinchEvent::getClassTypeId())) {
pan(viewer->getSoRenderManager()->getCamera());//set up panning plane
setupPanningPlane(viewer->getSoRenderManager()->getCamera());//set up panning plane
setRotationCenter(getFocalPoint());
setViewingMode(NavigationStyle::DRAGGING);
processed = true;
-38
View File
@@ -31,7 +31,6 @@
#include "Application.h"
#include "Command.h"
#include "MainWindow.h"
#include "UserSettings.h"
using namespace Gui;
@@ -288,8 +287,6 @@ void MenuManager::setup(MenuItem* menuItems) const
}
}
setupMenuBarCornerWidgets();
// hide all menus which we don't need for the moment
for (QList<QAction*>::Iterator it = actions.begin(); it != actions.end(); ++it) {
(*it)->setVisible(false);
@@ -366,41 +363,6 @@ void MenuManager::setup(MenuItem* item, QMenu* menu) const
}
}
void MenuManager::setupMenuBarCornerWidgets() const
{
/*Note: currently only workbench selector uses corner widget.*/
QMenuBar* menuBar = getMainWindow()->menuBar();
std::string pos = WorkbenchSwitcher::getValue();
bool showLeftWidget = false;
bool showRightWidget = false;
//Right corner widget
if (WorkbenchSwitcher::isRightCorner(pos)) {
//add workbench selector to menubar right corner widget.
if (!menuBar->cornerWidget(Qt::TopRightCorner)) {
Application::Instance->commandManager().addTo("Std_Workbench", menuBar);
}
showRightWidget = true;
}
//Left corner widget
else if (WorkbenchSwitcher::isLeftCorner(pos)) {
//add workbench selector to menubar left corner widget.
if (!menuBar->cornerWidget(Qt::TopLeftCorner)) {
Application::Instance->commandManager().addTo("Std_Workbench", menuBar);
}
showLeftWidget = true;
}
// Set visibility of corner widget
if (QWidget* right = menuBar->cornerWidget(Qt::TopRightCorner)) {
right->setVisible(showRightWidget);
}
if (QWidget* left = menuBar->cornerWidget(Qt::TopLeftCorner)) {
left->setVisible(showLeftWidget);
}
}
void MenuManager::retranslate() const
{
QMenuBar* menuBar = getMainWindow()->menuBar();
-1
View File
@@ -79,7 +79,6 @@ class GuiExport MenuManager
public:
/** Sets up the menus of a given workbench. */
void setup(MenuItem*) const;
void setupMenuBarCornerWidgets() const;
/// sets up a context menu out of item
void setupContextMenu(MenuItem* item, QMenu &menu) const;
void retranslate() const;
+34 -27
View File
@@ -327,27 +327,41 @@ void NavigationStyle::seekToPoint(const SbVec3f& scenepos)
viewer->seekToPoint(scenepos);
}
SbBool NavigationStyle::lookAtPoint(const SbVec2s screenpos)
void NavigationStyle::lookAtPoint(const SbVec2s screenpos)
{
SoCamera* cam = viewer->getSoRenderManager()->getCamera();
if (!cam)
return false;
const SoCamera* camera = viewer->getCamera();
if (!camera) {
return;
}
SoRayPickAction rpaction(viewer->getSoRenderManager()->getViewportRegion());
SoRayPickAction rpaction(viewer->getViewportRegion());
rpaction.setPoint(screenpos);
rpaction.setRadius(viewer->getPickRadius());
rpaction.apply(viewer->getSoRenderManager()->getSceneGraph());
SoPickedPoint * picked = rpaction.getPickedPoint();
if (!picked) {
this->interactiveCountInc();
return false;
const SoPickedPoint* picked = rpaction.getPickedPoint();
// Point is either the hitpoint or the projected point on the panning plane
SbVec3f point;
if (picked) {
point = picked->getPoint();
}
else {
const SbViewportRegion& vp = viewer->getViewportRegion();
const float aspectratio = vp.getViewportAspectRatio();
SbViewVolume vv = camera->getViewVolume(aspectratio);
// See note in Coin docs for SoCamera::getViewVolume re:viewport mapping
if (aspectratio < 1.0) {
vv.scale(1.0 / aspectratio);
}
SbLine line;
vv.projectPointToLine(normalizePixelPos(screenpos), line);
panningplane.intersect(line, point);
}
SbVec3f hitpoint;
hitpoint = picked->getPoint();
lookAtPoint(hitpoint);
return true;
lookAtPoint(point);
}
void NavigationStyle::lookAtPoint(const SbVec3f& position)
@@ -593,35 +607,28 @@ void NavigationStyle::panCamera(SoCamera * cam, float aspectratio, const SbPlane
}
}
void NavigationStyle::pan(SoCamera* camera)
void NavigationStyle::setupPanningPlane(const SoCamera* camera)
{
// The plane we're projecting the mouse coordinates to get 3D
// coordinates should stay the same during the whole pan
// operation, so we should calculate this value here.
if (!camera) { // can happen for empty scenegraph
if (!camera) { // can happen for empty scenegraph
this->panningplane = SbPlane(SbVec3f(0, 0, 1), 0);
}
else {
const SbViewportRegion & vp = viewer->getSoRenderManager()->getViewportRegion();
float aspectratio = vp.getViewportAspectRatio();
const SbViewportRegion& vp = viewer->getViewportRegion();
const float aspectratio = vp.getViewportAspectRatio();
SbViewVolume vv = camera->getViewVolume(aspectratio);
// See note in Coin docs for SoCamera::getViewVolume re:viewport mapping
if(aspectratio < 1.0)
if (aspectratio < 1.0) {
vv.scale(1.0 / aspectratio);
}
this->panningplane = vv.getPlane(camera->focalDistance.getValue());
}
}
void NavigationStyle::panToCenter(const SbPlane & pplane, const SbVec2f & currpos)
{
const SbViewportRegion & vp = viewer->getSoRenderManager()->getViewportRegion();
float ratio = vp.getViewportAspectRatio();
panCamera(viewer->getSoRenderManager()->getCamera(), ratio, pplane, SbVec2f(0.5,0.5), currpos);
this->rotationCenterFound = false;
}
/** Dependent on the camera type this will either shrink or expand the
* height of the viewport (orthogonal camera) or move the camera
* closer or further away from the focal point in the scene.
@@ -1382,7 +1389,7 @@ void NavigationStyle::setViewingMode(const ViewerMode newmode)
case PANNING:
animator->stop();
pan(viewer->getSoRenderManager()->getCamera());
setupPanningPlane(viewer->getSoRenderManager()->getCamera());
this->interactiveCountInc();
break;
+2 -3
View File
@@ -197,7 +197,7 @@ protected:
void setSeekMode(SbBool enable);
SbBool seekToPoint(const SbVec2s screenpos);
void seekToPoint(const SbVec3f& scenepos);
SbBool lookAtPoint(const SbVec2s screenpos);
void lookAtPoint(const SbVec2s screenpos);
void lookAtPoint(const SbVec3f& position);
void panCamera(SoCamera * camera,
@@ -205,8 +205,7 @@ protected:
const SbPlane & panplane,
const SbVec2f & previous,
const SbVec2f & current);
void pan(SoCamera* camera);
void panToCenter(const SbPlane & pplane, const SbVec2f & currpos);
void setupPanningPlane(const SoCamera* camera);
int getDelta() const;
void zoom(SoCamera * camera, float diffvalue);
void zoomByCursor(const SbVec2f & thispos, const SbVec2f & prevpos);
+1 -3
View File
@@ -170,9 +170,7 @@ SbBool OpenCascadeNavigationStyle::processSoEvent(const SoEvent * const ev)
case SoMouseButtonEvent::BUTTON3:
if (press) {
this->centerTime = ev->getTime();
float ratio = vp.getViewportAspectRatio();
SbViewVolume vv = viewer->getSoRenderManager()->getCamera()->getViewVolume(ratio);
this->panningplane = vv.getPlane(viewer->getSoRenderManager()->getCamera()->focalDistance.getValue());
setupPanningPlane(getCamera());
this->lockrecenter = false;
}
else if (this->currentmode == NavigationStyle::PANNING) {
+1 -3
View File
@@ -170,9 +170,7 @@ SbBool OpenSCADNavigationStyle::processSoEvent(const SoEvent * const ev)
this->button3down = press;
if (press) {
this->centerTime = ev->getTime();
float ratio = vp.getViewportAspectRatio();
SbViewVolume vv = viewer->getSoRenderManager()->getCamera()->getViewVolume(ratio);
this->panningplane = vv.getPlane(viewer->getSoRenderManager()->getCamera()->focalDistance.getValue());
setupPanningPlane(getCamera());
this->lockrecenter = false;
}
else if (curmode == NavigationStyle::PANNING) {
+6 -2
View File
@@ -1594,15 +1594,19 @@ void OverlayManager::onDockVisibleChange(bool visible)
void OverlayManager::onDockFeaturesChange(QDockWidget::DockWidgetFeatures features)
{
Q_UNUSED(features);
auto dw = qobject_cast<QDockWidget*>(sender());
if (!dw)
if (!dw) {
return;
}
// Rebuild the title widget as it may have a different set of buttons shown.
if (QWidget *titleBarWidget = dw->titleBarWidget()) {
if (auto *titleBarWidget = qobject_cast<OverlayTitleBar*>(dw->titleBarWidget())) {
dw->setTitleBarWidget(nullptr);
delete titleBarWidget;
}
setupTitleBar(dw);
}
+92 -129
View File
@@ -14,6 +14,75 @@
<string>Available Workbenches</string>
</property>
<layout class="QGridLayout" name="gridLayout_3">
<item row="4" column="0">
<layout class="QHBoxLayout">
<property name="spacing">
<number>6</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="WorkbenchSelectorItemLabel">
<property name="text">
<string>Workbench selector items style:</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="WorkbenchSelectorItem">
<property name="toolTip">
<string>Customize how the items are displayed.</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="0">
<widget class="ListWidgetDragBugFix" name="wbList"/>
</item>
<item row="3" column="0">
<layout class="QHBoxLayout">
<property name="spacing">
<number>6</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="WorkbenchSelectorTypeLabel">
<property name="text">
<string>Workbench selector type:</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="WorkbenchSelectorType">
<property name="toolTip">
<string>Choose the workbench selector widget type (restart required).</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="0" column="0">
<widget class="QLabel" name="noteLabel">
<property name="sizePolicy">
@@ -37,8 +106,24 @@ Currently, your system has the following workbenches:&lt;/p&gt;&lt;/body&gt;&lt;
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="ListWidgetDragBugFix" name="wbList"/>
<item row="5" column="0">
<widget class="Gui::PrefCheckBox" name="CheckBox_WbByTab">
<property name="toolTip">
<string>If checked, application will remember which workbench is active for each tab of the viewport</string>
</property>
<property name="text">
<string>Remember active workbench by tab</string>
</property>
<property name="checked">
<bool>false</bool>
</property>
<property name="prefEntry" stdset="0">
<cstring>SaveWBbyTab</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>View</cstring>
</property>
</widget>
</item>
<item row="2" column="0">
<layout class="QHBoxLayout">
@@ -74,142 +159,20 @@ after FreeCAD launches</string>
</item>
</layout>
</item>
<item row="3" column="0">
<layout class="QHBoxLayout">
<property name="spacing">
<number>6</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="WorkbenchSelectorTypeLabel">
<property name="text">
<string>Workbench selector type:</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="WorkbenchSelectorType">
<property name="toolTip">
<string>Choose the workbench selector widget type (restart required).</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="4" column="0">
<layout class="QHBoxLayout">
<property name="spacing">
<number>6</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="WorkbenchSelectorPositionLabel">
<property name="text">
<string>Workbench selector position:</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="WorkbenchSelectorPosition">
<property name="toolTip">
<string>Customize where the workbench selector appears (restart required).
'Toolbar': In the toolbars, as a movable toolbar.
'Left Corner': In the menu bar, on the left corner.
'Right Corner': In the menu bar, on the right corner.</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="5" column="0">
<layout class="QHBoxLayout">
<property name="spacing">
<number>6</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="WorkbenchSelectorItemLabel">
<property name="text">
<string>Workbench selector items style:</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="WorkbenchSelectorItem">
<property name="toolTip">
<string>Customize how the items are displayed.</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="6" column="0">
<widget class="Gui::PrefCheckBox" name="CheckBox_WbByTab">
<property name="toolTip">
<string>If checked, application will remember which workbench is active for each tab of the viewport</string>
</property>
<property name="text">
<string>Remember active workbench by tab</string>
</property>
<property name="checked">
<bool>false</bool>
</property>
<property name="prefEntry" stdset="0">
<cstring>SaveWBbyTab</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>View</cstring>
</property>
</widget>
</item>
</layout>
</widget>
<layoutdefault spacing="6" margin="11"/>
<customwidgets>
<customwidget>
<class>ListWidgetDragBugFix</class>
<extends>QListWidget</extends>
<header>ListWidgetDragBugFix.h</header>
</customwidget>
<customwidget>
<class>Gui::PrefCheckBox</class>
<extends>QCheckBox</extends>
<header>Gui/PrefWidgets.h</header>
</customwidget>
<customwidget>
<class>ListWidgetDragBugFix</class>
<extends>QListWidget</extends>
<header>ListWidgetDragBugFix.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>
@@ -33,7 +33,6 @@
#endif
#include <Gui/Application.h>
#include <Gui/UserSettings.h>
#include <Gui/Workbench.h>
#include <Gui/WorkbenchManager.h>
@@ -365,9 +364,6 @@ void DlgSettingsWorkbenchesImp::resetSettingsToDefaults()
hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/MainWindow");
hGrp->RemoveASCII("WSPosition");
if (ui->WorkbenchSelectorPosition->currentIndex() != WorkbenchSwitcher::getIndex()) {
requireRestart();
}
//finally reset all the parameters associated to Gui::Pref* widgets
PreferencePage::resetSettingsToDefaults();
@@ -499,19 +495,11 @@ void DlgSettingsWorkbenchesImp::changeEvent(QEvent *e)
void DlgSettingsWorkbenchesImp::saveWorkbenchSelector()
{
//save workbench selector position
int prevIndex = WorkbenchSwitcher::getIndex();
auto index = ui->WorkbenchSelectorPosition->currentIndex();
if (prevIndex != index) {
WorkbenchSwitcher::setIndex(index);
requireRestart();
}
//save workbench selector type
ParameterGrp::handle hGrp;
hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Workbenches");
prevIndex = hGrp->GetInt("WorkbenchSelectorType", 0);
index = ui->WorkbenchSelectorType->currentIndex();
int prevIndex = hGrp->GetInt("WorkbenchSelectorType", 0);
int index = ui->WorkbenchSelectorType->currentIndex();
if (prevIndex != index) {
hGrp->SetInt("WorkbenchSelectorType", index);
requireRestart();
@@ -528,13 +516,6 @@ void DlgSettingsWorkbenchesImp::saveWorkbenchSelector()
void DlgSettingsWorkbenchesImp::loadWorkbenchSelector()
{
//workbench selector position combobox setup
ui->WorkbenchSelectorPosition->clear();
ui->WorkbenchSelectorPosition->addItem(tr("Toolbar"));
ui->WorkbenchSelectorPosition->addItem(tr("Left corner"));
ui->WorkbenchSelectorPosition->addItem(tr("Right corner"));
ui->WorkbenchSelectorPosition->setCurrentIndex(WorkbenchSwitcher::getIndex());
//workbench selector type setup
ParameterGrp::handle hGrp;
hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Workbenches");
+30
View File
@@ -583,6 +583,36 @@ QObject* PythonWrapper::toQObject(const Py::Object& pyobject)
return qt_getCppType<QObject>(pyobject.ptr());
}
qsizetype PythonWrapper::toEnum(PyObject* pyPtr)
{
#if defined (HAVE_SHIBOKEN) && defined(HAVE_PYSIDE)
return Shiboken::Enum::getValue(pyPtr);
#else
return toEnum(Py::Object(pyPtr);
#endif
}
qsizetype PythonWrapper::toEnum(const Py::Object& pyobject)
{
#if defined (HAVE_SHIBOKEN) && defined(HAVE_PYSIDE)
return toEnum(pyobject.ptr());
#else
try {
Py::Int ret;
if (pyobject.hasAttr(std::string("value"))) {
ret = Py::Int(pyobject.getAttr(std::string("value")));
} else {
ret = Py::Int(pyobject);
}
return (qsizetype)ret;
}
catch (Py::Exception&) {
Base::PyException e; // extract the Python error text
e.ReportException();
}
#endif
}
QGraphicsItem* PythonWrapper::toQGraphicsItem(PyObject* pyPtr)
{
return qt_getCppType<QGraphicsItem>(pyPtr);
+2
View File
@@ -54,6 +54,8 @@ public:
bool toCString(const Py::Object&, std::string&);
QObject* toQObject(const Py::Object&);
qsizetype toEnum(PyObject* pyPtr);
qsizetype toEnum(const Py::Object& pyobject);
QGraphicsItem* toQGraphicsItem(PyObject* ptr);
QGraphicsItem* toQGraphicsItem(const Py::Object& pyObject);
QGraphicsObject* toQGraphicsObject(PyObject* pyPtr);
+2 -7
View File
@@ -171,9 +171,7 @@ SbBool RevitNavigationStyle::processSoEvent(const SoEvent * const ev)
case SoMouseButtonEvent::BUTTON3:
if (press) {
this->centerTime = ev->getTime();
float ratio = vp.getViewportAspectRatio();
SbViewVolume vv = viewer->getSoRenderManager()->getCamera()->getViewVolume(ratio);
this->panningplane = vv.getPlane(viewer->getSoRenderManager()->getCamera()->focalDistance.getValue());
setupPanningPlane(getCamera());
this->lockrecenter = false;
}
else {
@@ -181,10 +179,7 @@ SbBool RevitNavigationStyle::processSoEvent(const SoEvent * const ev)
float dci = (float)QApplication::doubleClickInterval()/1000.0f;
// is it just a middle click?
if (tmp.getValue() < dci && !this->lockrecenter) {
if (!this->lookAtPoint(pos)) {
panToCenter(panningplane, posn);
this->interactiveCountDec();
}
lookAtPoint(pos);
processed = true;
}
}
+3 -3
View File
@@ -201,7 +201,7 @@ SoGroup* TDragger::buildGeometry()
coneSeparator->addChild(coneLightModel);
auto pickStyle = new SoPickStyle();
pickStyle->style.setValue(SoPickStyle::SHAPE);
pickStyle->style.setValue(SoPickStyle::SHAPE_ON_TOP);
pickStyle->setOverride(TRUE);
coneSeparator->addChild(pickStyle);
@@ -487,7 +487,7 @@ SoGroup* TPlanarDragger::buildGeometry()
root->addChild(translation);
auto pickStyle = new SoPickStyle();
pickStyle->style.setValue(SoPickStyle::SHAPE);
pickStyle->style.setValue(SoPickStyle::SHAPE_ON_TOP);
pickStyle->setOverride(TRUE);
root->addChild(pickStyle);
@@ -798,7 +798,7 @@ SoGroup* RDragger::buildGeometry()
root->addChild(lineSet);
auto pickStyle = new SoPickStyle();
pickStyle->style.setValue(SoPickStyle::SHAPE);
pickStyle->style.setValue(SoPickStyle::SHAPE_ON_TOP);
pickStyle->setOverride(TRUE);
root->addChild(pickStyle);
+2 -1
View File
@@ -742,7 +742,8 @@ SoFCUnifiedSelection::handleEvent(SoHandleEventAction * action)
// check to see if the mouse is over a geometry...
auto infos = this->getPickedList(action,!Selection().needPickedList());
bool greedySel = Gui::Selection().getSelectionStyle() == Gui::SelectionSingleton::SelectionStyle::GreedySelection;
if(setSelection(infos, event->wasCtrlDown() || greedySel))
greedySel = greedySel || event->wasCtrlDown();
if(setSelection(infos, greedySel) || greedySel)
action->setHandled();
} // mouse release
}
+3 -2
View File
@@ -734,8 +734,9 @@ QDialogButtonBox::StandardButtons TaskDialogPython::getStandardButtons() const
if (dlg.hasAttr(std::string("getStandardButtons"))) {
Py::Callable method(dlg.getAttr(std::string("getStandardButtons")));
Py::Tuple args;
Py::Int ret(method.apply(args));
int value = (int)ret;
Gui::PythonWrapper wrap;
wrap.loadWidgetsModule();
int value = wrap.toEnum(method.apply(args));
return {value};
}
}
+1 -3
View File
@@ -163,9 +163,7 @@ SbBool TinkerCADNavigationStyle::processSoEvent(const SoEvent * const ev)
this->button3down = press;
if (press) {
this->centerTime = ev->getTime();
float ratio = vp.getViewportAspectRatio();
SbViewVolume vv = viewer->getSoRenderManager()->getCamera()->getViewVolume(ratio);
this->panningplane = vv.getPlane(viewer->getSoRenderManager()->getCamera()->focalDistance.getValue());
setupPanningPlane(getCamera());
}
else if (curmode == NavigationStyle::PANNING) {
newmode = NavigationStyle::IDLE;
+611 -36
View File
@@ -21,18 +21,29 @@
***************************************************************************/
#include "PreCompiled.h"
#include "Selection.h"
#include <boost/signals2/connection.hpp>
#ifndef _PreComp_
# include <QAction>
# include <QApplication>
# include <QHBoxLayout>
# include <QMenuBar>
# include <QMouseEvent>
# include <QPointer>
# include <QStatusBar>
# include <QToolBar>
# include <QToolButton>
# include <QPointer>
#endif
#include <boost/algorithm/string/predicate.hpp>
#include <Base/Tools.h>
#include "ToolBarManager.h"
#include "Application.h"
#include "Command.h"
#include "MainWindow.h"
#include "OverlayWidgets.h"
using namespace Gui;
@@ -154,6 +165,135 @@ QList<ToolBarItem*> ToolBarItem::getItems() const
// -----------------------------------------------------------
namespace Gui {
class ToolBarArea : public QWidget
{
using inherited = QWidget;
public:
ToolBarArea(QWidget *parent,
ParameterGrp::handle hParam,
boost::signals2::scoped_connection &conn,
QTimer *timer = nullptr)
: QWidget(parent)
, _sizingTimer(timer)
, _hParam(hParam)
, _conn(conn)
{
_layout = new QHBoxLayout(this);
_layout->setMargin(0);
}
void addWidget(QWidget *w)
{
if (_layout->indexOf(w) < 0) {
_layout->addWidget(w);
adjustParent();
QString name = w->objectName();
if (!name.isEmpty()) {
Base::ConnectionBlocker block(_conn);
_hParam->SetInt(w->objectName().toUtf8().constData(), _layout->count()-1);
}
}
}
void insertWidget(int idx, QWidget *w)
{
int index = _layout->indexOf(w);
if (index == idx)
return;
if (index > 0)
_layout->removeWidget(w);
_layout->insertWidget(idx, w);
adjustParent();
saveState();
}
void adjustParent()
{
if (_sizingTimer) {
_sizingTimer->start(10);
}
}
void removeWidget(QWidget *w)
{
_layout->removeWidget(w);
QString name = w->objectName();
if (!name.isEmpty()) {
Base::ConnectionBlocker block(_conn);
_hParam->RemoveInt(name.toUtf8().constData());
}
adjustParent();
}
QWidget *widgetAt(int index) const
{
auto item = _layout->itemAt(index);
return item ? item->widget() : nullptr;
}
int count() const
{
return _layout->count();
}
int indexOf(QWidget *w) const
{
return _layout->indexOf(w);
}
template<class FuncT>
void foreachToolBar(FuncT &&func)
{
for (int i = 0, c = _layout->count(); i < c; ++i) {
auto toolbar = qobject_cast<QToolBar*>(widgetAt(i));
if (!toolbar || toolbar->objectName().isEmpty()
|| toolbar->objectName().startsWith(QStringLiteral("*")))
continue;
func(toolbar, i, this);
}
}
void saveState()
{
Base::ConnectionBlocker block(_conn);
for (auto &v : _hParam->GetIntMap()) {
_hParam->RemoveInt(v.first.c_str());
}
foreachToolBar([this](QToolBar *toolbar, int idx, ToolBarArea*) {
_hParam->SetInt(toolbar->objectName().toUtf8().constData(), idx);
});
};
void restoreState(const std::map<int, QToolBar*> &toolbars)
{
for (const auto &[index, toolbar] : toolbars) {
bool visible = toolbar->isVisible();
getMainWindow()->removeToolBar(toolbar);
toolbar->setOrientation(Qt::Horizontal);
insertWidget(index, toolbar);
toolbar->setVisible(visible);
}
for (const auto &[name, visible] : _hParam->GetBoolMap()) {
auto widget = findChild<QWidget*>(QString::fromUtf8(name.c_str()));
if (widget)
widget->setVisible(visible);
}
};
private:
QHBoxLayout *_layout;
QPointer<QTimer> _sizingTimer;
ParameterGrp::handle _hParam;
boost::signals2::scoped_connection &_conn;
};
} // namespace Gui
// -----------------------------------------------------------
ToolBarManager* ToolBarManager::_instance=nullptr;
ToolBarManager* ToolBarManager::getInstance()
@@ -169,7 +309,100 @@ void ToolBarManager::destruct()
_instance = nullptr;
}
ToolBarManager::ToolBarManager() = default;
ToolBarManager::ToolBarManager()
{
hGeneral = App::GetApplication().GetUserParameter().GetGroup(
"BaseApp/Preferences/General");
hStatusBar = App::GetApplication().GetUserParameter().GetGroup(
"BaseApp/MainWindow/StatusBar");
hMenuBarRight = App::GetApplication().GetUserParameter().GetGroup(
"BaseApp/MainWindow/MenuBarRight");
hMenuBarLeft = App::GetApplication().GetUserParameter().GetGroup(
"BaseApp/MainWindow/MenuBarLeft");
hPref = App::GetApplication().GetUserParameter().GetGroup(
"BaseApp/MainWindow/Toolbars");
if (auto sb = getMainWindow()->statusBar()) {
sb->installEventFilter(this);
statusBarArea = new ToolBarArea(sb, hStatusBar, connParam);
statusBarArea->setObjectName(QStringLiteral("StatusBarArea"));
sb->insertPermanentWidget(2, statusBarArea);
statusBarArea->show();
}
if (auto mb = getMainWindow()->menuBar()) {
mb->installEventFilter(this);
menuBarLeftArea = new ToolBarArea(mb, hMenuBarLeft, connParam, &menuBarTimer);
menuBarLeftArea->setObjectName(QStringLiteral("MenuBarLeftArea"));
mb->setCornerWidget(menuBarLeftArea, Qt::TopLeftCorner);
menuBarLeftArea->show();
menuBarRightArea = new ToolBarArea(mb, hMenuBarRight, connParam, &menuBarTimer);
menuBarRightArea->setObjectName(QStringLiteral("MenuBarRightArea"));
mb->setCornerWidget(menuBarRightArea, Qt::TopRightCorner);
menuBarRightArea->show();
}
sizeTimer.setSingleShot(true);
connect(&sizeTimer, &QTimer::timeout, [this]{
setupToolBarIconSize();
});
resizeTimer.setSingleShot(true);
connect(&resizeTimer, &QTimer::timeout, [this]{
for (const auto &[toolbar, guard] : resizingToolbars) {
if (guard) {
setToolBarIconSize(toolbar);
}
}
resizingToolbars.clear();
});
auto refreshParams = [this](const char *name) {
bool sizeChanged = false;
if (!name || boost::equals(name, "ToolbarIconSize")) {
_toolBarIconSize = hGeneral->GetInt("ToolbarIconSize", 24);
sizeChanged = true;
}
if (!name || boost::equals(name, "StatusBarIconSize")) {
_statusBarIconSize = hGeneral->GetInt("StatusBarIconSize", 0);
sizeChanged = true;
}
if (!name || boost::equals(name, "MenuBarIconSize")) {
_menuBarIconSize = hGeneral->GetInt("MenuBarIconSize", 0);
sizeChanged = true;
}
if (sizeChanged) {
sizeTimer.start(100);
}
};
refreshParams(nullptr);
connParam = App::GetApplication().GetUserParameter().signalParamChanged.connect(
[this, refreshParams](ParameterGrp *hParam, ParameterGrp::ParamType, const char *name, const char *) {
if (hParam == hGeneral && name) {
refreshParams(name);
}
if (hParam == hPref
|| hParam == hStatusBar
|| hParam == hMenuBarRight
|| hParam == hMenuBarLeft)
timer.start(100);
});
timer.setSingleShot(true);
connect(&timer, &QTimer::timeout, [this]{
onTimer();
});
menuBarTimer.setSingleShot(true);
QObject::connect(&menuBarTimer, &QTimer::timeout, [] {
if (auto menuBar = getMainWindow()->menuBar()) {
menuBar->adjustSize();
}
});
}
ToolBarManager::~ToolBarManager() = default;
@@ -199,6 +432,49 @@ QPointer<QWidget> createActionWidget()
}
}
int ToolBarManager::toolBarIconSize(QWidget *widget) const
{
int s = _toolBarIconSize;
if (widget) {
if (widget->parentWidget() == statusBarArea) {
if (_statusBarIconSize > 0)
s = _statusBarIconSize;
else
s *= 0.6;
}
else if (widget->parentWidget() == menuBarLeftArea
|| widget->parentWidget() == menuBarRightArea) {
if (_menuBarIconSize > 0)
s = _menuBarIconSize;
else
s *= 0.6;
}
}
return std::max(s, 5);
}
void ToolBarManager::setupToolBarIconSize()
{
int s = toolBarIconSize();
getMainWindow()->setIconSize(QSize(s, s));
// Most of the the toolbar will have explicit icon size, so the above call
// to QMainWindow::setIconSize() will have no effect. We need to explicitly
// change the icon size.
for (auto toolbar : getMainWindow()->findChildren<QToolBar*>()) {
setToolBarIconSize(toolbar);
}
}
void ToolBarManager::setToolBarIconSize(QToolBar *toolbar)
{
int s = toolBarIconSize(toolbar);
toolbar->setIconSize(QSize(s, s));
if (toolbar->parentWidget() == menuBarLeftArea)
menuBarLeftArea->adjustParent();
else if (toolbar->parentWidget() == menuBarRightArea)
menuBarRightArea->adjustParent();
}
void ToolBarManager::setup(ToolBarItem* toolBarItems)
{
if (!toolBarItems)
@@ -212,8 +488,6 @@ void ToolBarManager::setup(ToolBarItem* toolBarItems)
int max_width = getMainWindow()->width();
int top_width = 0;
ParameterGrp::handle hPref = App::GetApplication().GetUserParameter().GetGroup("BaseApp")
->GetGroup("MainWindow")->GetGroup("Toolbars");
bool nameAsToolTip = App::GetApplication().GetUserParameter().GetGroup("BaseApp")
->GetGroup("Preferences")->GetGroup("MainWindow")->GetBool("ToolBarNameAsToolTip",true);
QList<ToolBarItem*> items = toolBarItems->getItems();
@@ -291,7 +565,6 @@ void ToolBarManager::setup(ToolBarItem* toolBarItems)
}
}
}
// hide all unneeded toolbars
for (QList<QToolBar*>::Iterator it = toolbars.begin(); it != toolbars.end(); ++it) {
// make sure that the main window has the focus when hiding the toolbar with
@@ -313,10 +586,8 @@ void ToolBarManager::setup(ToolBarItem* toolBarItems)
(*it)->toggleViewAction()->setVisible(false);
}
hPref = App::GetApplication().GetUserParameter().GetGroup("BaseApp")
->GetGroup("Preferences")->GetGroup("General");
bool lockToolBars = hPref->GetBool("LockToolBars", false);
setMovable(!lockToolBars);
setMovable(!areToolBarsLocked());
restoreState();
}
void ToolBarManager::setup(ToolBarItem* item, QToolBar* toolbar) const
@@ -357,6 +628,11 @@ void ToolBarManager::setup(ToolBarItem* item, QToolBar* toolbar) const
}
}
void ToolBarManager::onTimer()
{
restoreState();
}
void ToolBarManager::saveState() const
{
auto ignoreSave = [](QAction* action) {
@@ -377,9 +653,6 @@ void ToolBarManager::saveState() const
return value == ToolBarItem::DefaultVisibility::Unavailable;
};
ParameterGrp::handle hPref = App::GetApplication().GetUserParameter().GetGroup("BaseApp")
->GetGroup("MainWindow")->GetGroup("Toolbars");
QList<QToolBar*> toolbars = toolBars();
for (QStringList::ConstIterator it = this->toolbarNames.begin(); it != this->toolbarNames.end(); ++it) {
QToolBar* toolbar = findToolBar(toolbars, *it);
@@ -396,19 +669,326 @@ void ToolBarManager::saveState() const
void ToolBarManager::restoreState() const
{
ParameterGrp::handle hPref = App::GetApplication().GetUserParameter().GetGroup("BaseApp")
->GetGroup("MainWindow")->GetGroup("Toolbars");
std::map<int, QToolBar*> sbToolBars;
std::map<int, QToolBar*> mbRightToolBars;
std::map<int, QToolBar*> mbLeftToolBars;
QList<QToolBar*> toolbars = toolBars();
for (QStringList::ConstIterator it = this->toolbarNames.begin(); it != this->toolbarNames.end(); ++it) {
QToolBar* toolbar = findToolBar(toolbars, *it);
if (toolbar) {
QByteArray toolbarName = toolbar->objectName().toUtf8();
toolbar->setVisible(hPref->GetBool(toolbarName.constData(), toolbar->isVisible()));
if (getToolbarPolicy(toolbar) != ToolBarItem::DefaultVisibility::Unavailable) {
toolbar->setVisible(hPref->GetBool(toolbarName.constData(), toolbar->isVisible()));
}
int idx = hStatusBar->GetInt(toolbarName, -1);
if (idx >= 0) {
sbToolBars[idx] = toolbar;
continue;
}
idx = hMenuBarLeft->GetInt(toolbarName, -1);
if (idx >= 0) {
mbLeftToolBars[idx] = toolbar;
continue;
}
idx = hMenuBarRight->GetInt(toolbarName, -1);
if (idx >= 0) {
mbRightToolBars[idx] = toolbar;
continue;
}
if (toolbar->parentWidget() != getMainWindow()) {
getMainWindow()->addToolBar(toolbar);
}
}
}
setMovable(!areToolBarsLocked());
statusBarArea->restoreState(sbToolBars);
menuBarRightArea->restoreState(mbRightToolBars);
menuBarLeftArea->restoreState(mbLeftToolBars);
}
bool ToolBarManager::addToolBarToArea(QObject *source, QMouseEvent *ev)
{
auto statusBar = getMainWindow()->statusBar();
if (!statusBar || !statusBar->isVisible())
statusBar = nullptr;
auto menuBar = getMainWindow()->menuBar();
if (!menuBar || !menuBar->isVisible()) {
if (!statusBar)
return false;
menuBar = nullptr;
}
auto tb = qobject_cast<QToolBar*>(source);
if (!tb || !tb->isFloating())
return false;
static QPointer<OverlayDragFrame> tbPlaceholder;
static QPointer<ToolBarArea> lastArea;
static int tbIndex = -1;
if (ev->type() == QEvent::MouseMove) {
if (tb->orientation() != Qt::Horizontal
|| ev->buttons() != Qt::LeftButton) {
if (tbIndex >= 0) {
if (lastArea) {
lastArea->removeWidget(tbPlaceholder);
lastArea = nullptr;
}
tbPlaceholder->hide();
tbIndex = -1;
}
return false;
}
}
if (ev->type() == QEvent::MouseButtonRelease && ev->button() != Qt::LeftButton)
return false;
QPoint pos = QCursor::pos();
ToolBarArea *area = nullptr;
if (statusBar) {
QRect rect(statusBar->mapToGlobal(QPoint(0,0)), statusBar->size());
if (rect.contains(pos))
area = statusBarArea;
}
if (!area) {
if (!menuBar) {
return false;
}
QRect rect(menuBar->mapToGlobal(QPoint(0,0)), menuBar->size());
if (rect.contains(pos)) {
if (pos.x() - rect.left() < menuBar->width()/2) {
area = menuBarLeftArea;
}
else {
area = menuBarRightArea;
}
}
else {
if (tbPlaceholder) {
if (lastArea) {
lastArea->removeWidget(tbPlaceholder);
lastArea = nullptr;
}
tbPlaceholder->hide();
tbIndex = -1;
}
return false;
}
}
int idx = 0;
for (int c = area->count(); idx < c ;++idx) {
auto w = area->widgetAt(idx);
if (!w || w->isHidden())
continue;
int p = w->mapToGlobal(w->rect().center()).x();
if (pos.x() < p)
break;
}
if (tbIndex >= 0 && tbIndex == idx-1)
idx = tbIndex;
if (ev->type() == QEvent::MouseMove) {
if (!tbPlaceholder) {
tbPlaceholder = new OverlayDragFrame(getMainWindow());
tbPlaceholder->hide();
tbIndex = -1;
}
if (tbIndex != idx) {
tbIndex = idx;
tbPlaceholder->setSizePolicy(tb->sizePolicy());
tbPlaceholder->setMinimumWidth(tb->minimumWidth());
tbPlaceholder->resize(tb->size());
area->insertWidget(idx, tbPlaceholder);
lastArea = area;
tbPlaceholder->adjustSize();
tbPlaceholder->show();
}
} else {
tbIndex = idx;
QTimer::singleShot(10, tb, [tb,this]() {
if (!lastArea)
return;
else {
tbPlaceholder->hide();
QSignalBlocker block(tb);
lastArea->removeWidget(tbPlaceholder);
getMainWindow()->removeToolBar(tb);
tb->setOrientation(Qt::Horizontal);
lastArea->insertWidget(tbIndex, tb);
tb->setVisible(true);
lastArea = nullptr;
}
tb->topLevelChanged(false);
tbIndex = -1;
});
}
return false;
}
void ToolBarManager::populateUndockMenu(QMenu *menu, ToolBarArea *area)
{
menu->setTitle(tr("Undock toolbars"));
auto tooltip = QObject::tr("Undock from status bar");
auto addMenuUndockItem = [&](QToolBar *toolbar, int, ToolBarArea *area) {
auto *action = toolbar->toggleViewAction();
auto undockAction = new QAction(menu);
undockAction->setText(action->text());
undockAction->setToolTip(tooltip);
menu->addAction(undockAction);
QObject::connect(undockAction, &QAction::triggered, [area, toolbar, this]() {
if (toolbar->parentWidget() == getMainWindow()) {
return;
}
auto pos = toolbar->mapToGlobal(QPoint(0, 0));
QSignalBlocker blocker(toolbar);
area->removeWidget(toolbar);
getMainWindow()->addToolBar(toolbar);
toolbar->setWindowFlags(Qt::Tool
| Qt::FramelessWindowHint
| Qt::X11BypassWindowManagerHint);
toolbar->move(pos.x(), pos.y()-toolbar->height()-10);
toolbar->adjustSize();
toolbar->setVisible(true);
toolbar->topLevelChanged(true);
});
};
if (area)
area->foreachToolBar(addMenuUndockItem);
else {
statusBarArea->foreachToolBar(addMenuUndockItem);
menuBarLeftArea->foreachToolBar(addMenuUndockItem);
menuBarRightArea->foreachToolBar(addMenuUndockItem);
}
}
bool ToolBarManager::showContextMenu(QObject *source)
{
QMenu menu;
QMenu menuUndock;
QHBoxLayout *layout = nullptr;
ToolBarArea *area;
if (getMainWindow()->statusBar() == source) {
area = statusBarArea;
for (auto l : source->findChildren<QHBoxLayout*>()) {
if(l->indexOf(area) >= 0) {
layout = l;
break;
}
}
}
else if (getMainWindow()->menuBar() == source) {
QPoint pos = QCursor::pos();
QRect rect(menuBarLeftArea->mapToGlobal(QPoint(0,0)), menuBarLeftArea->size());
if (rect.contains(pos)) {
area = menuBarLeftArea;
}
else {
rect = QRect(menuBarRightArea->mapToGlobal(QPoint(0,0)), menuBarRightArea->size());
if (rect.contains(pos)) {
area = menuBarRightArea;
}
else {
return false;
}
}
}
else {
return false;
}
auto addMenuVisibleItem = [&](QToolBar *toolbar, int, ToolBarArea *) {
auto action = toolbar->toggleViewAction();
if ((action->isVisible() || toolbar->isVisible()) && action->text().size()) {
action->setVisible(true);
menu.addAction(action);
}
};
if (layout) {
for (int i = 0, c = layout->count(); i < c; ++i) {
auto widget = layout->itemAt(i)->widget();
if (!widget || widget == area
|| widget->objectName().isEmpty()
|| widget->objectName().startsWith(QStringLiteral("*")))
{
continue;
}
QString name = widget->windowTitle();
if (name.isEmpty()) {
name = widget->objectName();
name.replace(QLatin1Char('_'), QLatin1Char(' '));
name = name.simplified();
}
QAction *action = new QAction(&menu);
action->setText(name);
action->setCheckable(true);
action->setChecked(widget->isVisible());
menu.addAction(action);
auto onToggle = [widget, this](bool visible) {
onToggleStatusBarWidget(widget, visible);
};
QObject::connect(action, &QAction::triggered, onToggle);
}
}
area->foreachToolBar(addMenuVisibleItem);
populateUndockMenu(&menuUndock, area);
if (menuUndock.actions().size()) {
menu.addSeparator();
menu.addMenu(&menuUndock);
}
menu.exec(QCursor::pos());
return true;
}
void ToolBarManager::onToggleStatusBarWidget(QWidget *widget, bool visible)
{
Base::ConnectionBlocker block(connParam);
widget->setVisible(visible);
hStatusBar->SetBool(widget->objectName().toUtf8().constData(), widget->isVisible());
}
bool ToolBarManager::eventFilter(QObject *source, QEvent *ev)
{
bool res = false;
switch(ev->type()) {
case QEvent::Show:
case QEvent::Hide:
if (auto toolbar = qobject_cast<QToolBar*>(source)) {
auto parent = toolbar->parentWidget();
if (parent == menuBarLeftArea || parent == menuBarRightArea) {
menuBarTimer.start(10);
}
}
break;
case QEvent::MouseButtonRelease: {
auto mev = static_cast<QMouseEvent*>(ev);
if (mev->button() == Qt::RightButton) {
if (showContextMenu(source)) {
return true;
}
}
}
// fall through
case QEvent::MouseMove:
res = addToolBarToArea(source, static_cast<QMouseEvent*>(ev));
break;
case QEvent::ParentChange:
if (auto toolbar = qobject_cast<QToolBar*>(source)) {
resizingToolbars[toolbar] = toolbar;
resizeTimer.start(100);
}
break;
default:
break;
}
return res;
}
void ToolBarManager::retranslate() const
@@ -424,24 +1004,12 @@ void ToolBarManager::retranslate() const
bool Gui::ToolBarManager::areToolBarsLocked() const
{
auto hPref = App::GetApplication()
.GetUserParameter()
.GetGroup("BaseApp")
->GetGroup("Preferences")
->GetGroup("General");
return hPref->GetBool("LockToolBars", false);
return hGeneral->GetBool("LockToolBars", false);
}
void Gui::ToolBarManager::setToolBarsLocked(bool locked) const
{
auto hPref = App::GetApplication()
.GetUserParameter()
.GetGroup("BaseApp")
->GetGroup("Preferences")
->GetGroup("General");
hPref->SetBool("LockToolBars", locked);
hGeneral->SetBool("LockToolBars", locked);
setMovable(!locked);
}
@@ -475,12 +1043,19 @@ QAction* ToolBarManager::findAction(const QList<QAction*>& acts, const QString&
QList<QToolBar*> ToolBarManager::toolBars() const
{
QWidget* mw = getMainWindow();
auto mw = getMainWindow();
QList<QToolBar*> tb;
QList<QToolBar*> bars = getMainWindow()->findChildren<QToolBar*>();
for (QList<QToolBar*>::Iterator it = bars.begin(); it != bars.end(); ++it) {
if ((*it)->parentWidget() == mw)
auto parent = (*it)->parentWidget();
if (parent == mw
|| parent == mw->statusBar()
|| parent == statusBarArea
|| parent == menuBarLeftArea
|| parent == menuBarRightArea) {
tb.push_back(*it);
(*it)->installEventFilter(const_cast<ToolBarManager*>(this));
}
}
return tb;
@@ -507,13 +1082,11 @@ void ToolBarManager::setState(const QList<QString>& names, State state)
void ToolBarManager::setState(const QString& name, State state)
{
ParameterGrp::handle hPref = App::GetApplication().GetUserParameter().GetGroup("BaseApp")->GetGroup("MainWindow")->GetGroup("Toolbars");
auto visibility = [hPref, name](bool defaultvalue) {
auto visibility = [this, name](bool defaultvalue) {
return hPref->GetBool(name.toStdString().c_str(), defaultvalue);
};
auto saveVisibility = [hPref, name](bool value) {
auto saveVisibility = [this, name](bool value) {
hPref->SetBool(name.toStdString().c_str(), value);
};
@@ -574,3 +1147,5 @@ void ToolBarManager::setState(const QString& name, State state)
}
}
}
#include "moc_ToolBarManager.cpp"
+43 -1
View File
@@ -25,14 +25,23 @@
#define GUI_TOOLBARMANAGER_H
#include <string>
#include <boost_signals2.hpp>
#include <QStringList>
#include <QTimer>
#include <FCGlobal.h>
#include <Base/Parameter.h>
class QAction;
class QMenu;
class QMouseEvent;
class QToolBar;
namespace Gui {
class ToolBarArea;
class GuiExport ToolBarItem
{
public:
@@ -83,8 +92,9 @@ private:
* @see MenuManager
* @author Werner Mayer
*/
class GuiExport ToolBarManager
class GuiExport ToolBarManager : public QObject
{
Q_OBJECT
public:
enum class State {
@@ -109,6 +119,11 @@ public:
void setState(const QList<QString>& names, State state);
void setState(const QString& name, State state);
int toolBarIconSize(QWidget *widget=nullptr) const;
void setupToolBarIconSize();
void populateUndockMenu(QMenu *menu, ToolBarArea *area = nullptr);
protected:
void setup(ToolBarItem*, QToolBar*) const;
@@ -116,6 +131,14 @@ protected:
ToolBarItem::DefaultVisibility getToolbarPolicy(const QToolBar *) const;
bool addToolBarToArea(QObject *source, QMouseEvent *ev);
bool showContextMenu(QObject *source);
void onToggleStatusBarWidget(QWidget *widget, bool visible);
void setToolBarIconSize(QToolBar *toolbar);
void onTimer();
bool eventFilter(QObject *source, QEvent *ev) override;
/** Returns a list of all currently existing toolbars. */
QList<QToolBar*> toolBars() const;
QToolBar* findToolBar(const QList<QToolBar*>&, const QString&) const;
@@ -126,6 +149,25 @@ protected:
private:
QStringList toolbarNames;
static ToolBarManager* _instance;
QTimer timer;
QTimer menuBarTimer;
QTimer sizeTimer;
QTimer resizeTimer;
boost::signals2::scoped_connection connParam;
ToolBarArea *statusBarArea = nullptr;
ToolBarArea *menuBarLeftArea = nullptr;
ToolBarArea *menuBarRightArea = nullptr;
ParameterGrp::handle hGeneral;
ParameterGrp::handle hPref;
ParameterGrp::handle hStatusBar;
ParameterGrp::handle hMenuBarLeft;
ParameterGrp::handle hMenuBarRight;
std::map<QToolBar*, QPointer<QToolBar>> resizingToolbars;
int _toolBarIconSize = 0;
int _statusBarIconSize = 0;
int _menuBarIconSize = 0;
mutable bool restored = false;
};
} // namespace Gui
+102 -26
View File
@@ -206,6 +206,7 @@ using DocumentObjectItems = std::set<DocumentObjectItem*>;
class Gui::DocumentObjectData {
public:
bool dirtyFlag {};
DocumentItem* docItem;
DocumentObjectItems items;
ViewProviderDocumentObject* viewObject;
@@ -243,6 +244,24 @@ public:
label2 = viewObject->getObject()->Label2.getValue();
}
void insertItem(DocumentObjectItem* item)
{
items.insert(item);
dirtyFlag = true;
}
void removeItem(DocumentObjectItem* item)
{
auto it = items.find(item);
if (it == items.end()) {
assert(0);
}
else {
items.erase(it);
dirtyFlag = true;
}
}
const char* getTreeName() const {
return docItem->getTreeName();
}
@@ -907,7 +926,11 @@ void TreeWidget::contextMenuEvent(QContextMenuEvent* e)
if (this->contextItem && this->contextItem->type() == DocumentType) {
auto docitem = static_cast<DocumentItem*>(this->contextItem);
App::Document* doc = docitem->document()->getDocument();
App::GetApplication().setActiveDocument(doc);
// It's better to let user decide whether and how to activate
// the current document, such as by double-clicking.
// App::GetApplication().setActiveDocument(doc);
showHiddenAction->setChecked(docitem->showHidden());
contextMenu.addAction(this->showHiddenAction);
contextMenu.addAction(this->searchObjectsAction);
@@ -1983,7 +2006,8 @@ TreeWidget::TargetItemInfo TreeWidget::getTargetInfo(QEvent* ev)
return targetInfo;
}
bool TreeWidget::dropInDocument(QDropEvent* event, TargetItemInfo& targetInfo, std::vector<std::pair<DocumentObjectItem*, std::vector<std::string> > > items)
bool TreeWidget::dropInDocument(QDropEvent* event, TargetItemInfo& targetInfo,
std::vector<TreeWidget::ObjectItemSubname> items)
{
std::string errMsg;
auto da = event->dropAction();
@@ -2142,7 +2166,8 @@ bool TreeWidget::dropInDocument(QDropEvent* event, TargetItemInfo& targetInfo, s
}
else if (da == Qt::MoveAction && obj->getDocument() == targetInfo.targetDoc) {
// Moving a object within the document root.
res = obj;
// Do not set 'res' as changing the placement is not desired: #13690
droppedObjs.push_back(obj);
}
else {
// Moving a object from another document.
@@ -2187,7 +2212,8 @@ bool TreeWidget::dropInDocument(QDropEvent* event, TargetItemInfo& targetInfo, s
return touched;
}
bool TreeWidget::dropInObject(QDropEvent* event, TargetItemInfo& targetInfo, std::vector<std::pair<DocumentObjectItem*, std::vector<std::string> > > items)
bool TreeWidget::dropInObject(QDropEvent* event, TargetItemInfo& targetInfo,
std::vector<TreeWidget::ObjectItemSubname> items)
{
std::string errMsg;
auto da = event->dropAction();
@@ -2554,7 +2580,7 @@ void TreeWidget::dropEvent(QDropEvent* event)
}
// filter out the selected items we cannot handle
std::vector<std::pair<DocumentObjectItem*, std::vector<std::string> > > items;
std::vector<ObjectItemSubname> items;
items = DropHandler::filterItems(selectedItems(), targetInfo.targetItem);
if (items.empty()) {
return; // nothing needs to be done
@@ -2635,7 +2661,7 @@ void TreeWidget::sortDroppedObjects(TargetItemInfo& targetInfo, std::vector<App:
auto vpA = dynamic_cast<Gui::ViewProviderDocumentObject*>(Gui::Application::Instance->getViewProvider(a));
auto vpB = dynamic_cast<Gui::ViewProviderDocumentObject*>(Gui::Application::Instance->getViewProvider(b));
if (vpA && vpB) {
return vpA->TreeRank.getValue() < vpB->TreeRank.getValue();
return vpA->getTreeRank() < vpB->getTreeRank();
}
return false; // Keep the original order if either vpA or vpB is nullptr
});
@@ -2643,10 +2669,10 @@ void TreeWidget::sortDroppedObjects(TargetItemInfo& targetInfo, std::vector<App:
// Then we move dropped objects to their correct position
sortIntoList(objList);
// Then we update the TreeRank properties
// Then we set the tree rank
for (size_t i = 0; i < sortedObjList.size(); ++i) {
auto vp = dynamic_cast<ViewProviderDocumentObject*>(Application::Instance->getViewProvider(sortedObjList[i]));
vp->TreeRank.setValue(i);
vp->setTreeRank(i);
}
// Lastly we refresh the tree
@@ -3035,7 +3061,9 @@ void TreeWidget::onItemEntered(QTreeWidgetItem* item)
Selection().rmvPreselect();
}
void TreeWidget::leaveEvent(QEvent*) {
void TreeWidget::leaveEvent(QEvent* event)
{
Q_UNUSED(event)
if (!updateBlocked && TreeParams::getPreSelection()) {
preselectTimer->stop();
Selection().rmvPreselect();
@@ -4053,10 +4081,10 @@ int DocumentItem::findRootIndex(App::DocumentObject* childObj) {
int first, last;
auto getTreeRank = [](Gui::ViewProviderDocumentObject* vp) -> int {
if (vp->TreeRank.getValue() == -1) {
vp->TreeRank.setValue(vp->getObject()->getID());
if (vp->getTreeRank() == -1) {
vp->setTreeRank(vp->getObject()->getID());
}
return vp->TreeRank.getValue();
return vp->getTreeRank();
};
auto vpc = dynamic_cast<ViewProviderDocumentObject*>(Application::Instance->getViewProvider(childObj));
@@ -4098,7 +4126,7 @@ int DocumentItem::findRootIndex(App::DocumentObject* childObj) {
if (citem->type() != TreeWidget::ObjectType)
continue;
auto vp = static_cast<DocumentObjectItem*>(citem)->object();
if (vp->TreeRank.getValue() < childTreeRank) {
if (vp->getTreeRank() < childTreeRank) {
first = ++pos;
count -= step + 1;
}
@@ -4130,7 +4158,7 @@ void DocumentItem::sortObjectItems()
std::stable_sort(sortedItems.begin(), sortedItems.end(),
[](DocumentObjectItem* a, DocumentObjectItem* b) {
return a->object()->TreeRank.getValue() < b->object()->TreeRank.getValue();
return a->object()->getTreeRank() < b->object()->getTreeRank();
});
int sortedIndex = 0;
@@ -4544,12 +4572,18 @@ void DocumentItem::clearSelection(DocumentObjectItem* exclude)
// Block signals here otherwise we get a recursion and quadratic runtime
bool ok = treeWidget()->blockSignals(true);
FOREACH_ITEM_ALL(item);
_v.second->dirtyFlag = false;
if (item == exclude) {
if (item->selected > 0)
item->selected = -1;
else
item->selected = 0;
updateItemSelection(item);
// The set has been changed while calling updateItemSelection
// so that the iterator has become invalid -> Abort
if (_v.second->dirtyFlag) {
break;
}
}
else {
item->selected = 0;
@@ -4586,7 +4620,13 @@ void DocumentItem::updateSelection(QTreeWidgetItem* ti, bool unselect) {
updateSelection(ti->child(i));
}
void DocumentItem::updateItemSelection(DocumentObjectItem* item) {
void DocumentItem::updateItemSelection(DocumentObjectItem* item)
{
// Note: In several places of this function the selection is altered and the notification of
// the selection observers can trigger a recreation of all DocumentObjectItem so that the
// passed 'item' can become a dangling pointer.
// Thus,'item' mustn't be accessed any more after altering the selection.
// For further details see the bug analsysis of #13107
bool selected = item->isSelected();
bool checked = item->checkState(0) == Qt::Checked;
@@ -4654,23 +4694,30 @@ void DocumentItem::updateItemSelection(DocumentObjectItem* item) {
Gui::Selection().rmvSelection(docname, objname, subname.c_str());
return;
}
auto vobj = item->object();
selected = false;
if (!item->mySubs.empty()) {
for (auto& sub : item->mySubs) {
if (Gui::Selection().addSelection(docname, objname, (subname + sub).c_str()))
if (Gui::Selection().addSelection(docname, objname, (subname + sub).c_str())) {
selected = true;
}
}
}
if (!selected) {
item->mySubs.clear();
if (!Gui::Selection().addSelection(docname, objname, subname.c_str())) {
item->selected = 0;
item->setSelected(false);
item->setCheckState(false);
// Safely re-access the item
DocumentObjectItem* item2 = findItem(vobj->getObject(), subname);
if (item2) {
item2->selected = 0;
item2->setSelected(false);
item2->setCheckState(false);
}
return;
}
}
getTree()->syncView(item->object());
getTree()->syncView(vobj);
}
App::DocumentObject* DocumentItem::getTopParent(App::DocumentObject* obj, std::string& subname) {
@@ -4717,6 +4764,39 @@ App::DocumentObject* DocumentItem::getTopParent(App::DocumentObject* obj, std::s
return topParent;
}
DocumentObjectItem *DocumentItem::findItem(App::DocumentObject* obj, const std::string& subname) const
{
auto it = ObjectMap.find(obj);
if (it == ObjectMap.end()) {
return nullptr;
}
// There is only one instance in the tree view
if (it->second->items.size() == 1) {
return *(it->second->items.begin());
}
// If there are multiple instances use the one with the same subname
DocumentObjectItem* item {};
for (auto jt : it->second->items) {
std::ostringstream str;
App::DocumentObject* topParent = nullptr;
jt->getSubName(str, topParent);
if (topParent) {
if (!obj->redirectSubName(str, topParent, nullptr)) {
str << obj->getNameInDocument() << '.';
}
}
if (subname == str.str()) {
item = jt;
break;
}
}
return item;
}
DocumentObjectItem* DocumentItem::findItemByObject(
bool sync, App::DocumentObject* obj, const char* subname, bool select)
{
@@ -5017,7 +5097,7 @@ DocumentObjectItem::DocumentObjectItem(DocumentItem* ownerDocItem, DocumentObjec
setFlags(flags() | Qt::ItemIsEditable | Qt::ItemIsUserCheckable);
setCheckState(false);
myData->items.insert(this);
myData->insertItem(this);
++countItems;
TREE_LOG("Create item: " << countItems << ", " << object()->getObject()->getFullName());
}
@@ -5026,11 +5106,7 @@ DocumentObjectItem::~DocumentObjectItem()
{
--countItems;
TREE_LOG("Delete item: " << countItems << ", " << object()->getObject()->getFullName());
auto it = myData->items.find(this);
if (it == myData->items.end())
assert(0);
else
myData->items.erase(it);
myData->removeItem(this);
if (myData->rootItem == this)
myData->rootItem = nullptr;

Some files were not shown because too many files have changed in this diff Show More