Merge branch 'main' into main
This commit is contained in:
@@ -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()
|
||||
|
||||
|
||||
Vendored
+1
-1
Submodule src/3rdParty/OndselSolver updated: fe99ad2593...2d71435110
@@ -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);
|
||||
|
||||
@@ -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};
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
@@ -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\"";
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
+414
-383
File diff suppressed because it is too large
Load Diff
+424
-392
File diff suppressed because it is too large
Load Diff
+416
-385
File diff suppressed because it is too large
Load Diff
+421
-390
File diff suppressed because it is too large
Load Diff
+431
-400
File diff suppressed because it is too large
Load Diff
+416
-385
File diff suppressed because it is too large
Load Diff
+416
-385
File diff suppressed because it is too large
Load Diff
+416
-385
File diff suppressed because it is too large
Load Diff
+416
-385
File diff suppressed because it is too large
Load Diff
+416
-385
File diff suppressed because it is too large
Load Diff
+439
-408
File diff suppressed because it is too large
Load Diff
+416
-385
File diff suppressed because it is too large
Load Diff
+420
-389
File diff suppressed because it is too large
Load Diff
+417
-386
File diff suppressed because it is too large
Load Diff
+479
-449
File diff suppressed because it is too large
Load Diff
+417
-386
File diff suppressed because it is too large
Load Diff
+445
-414
File diff suppressed because it is too large
Load Diff
+416
-385
File diff suppressed because it is too large
Load Diff
+435
-404
File diff suppressed because it is too large
Load Diff
+444
-411
File diff suppressed because it is too large
Load Diff
+416
-385
File diff suppressed because it is too large
Load Diff
+416
-385
File diff suppressed because it is too large
Load Diff
+500
-457
File diff suppressed because it is too large
Load Diff
+440
-409
File diff suppressed because it is too large
Load Diff
+442
-411
File diff suppressed because it is too large
Load Diff
+445
-414
File diff suppressed because it is too large
Load Diff
+445
-414
File diff suppressed because it is too large
Load Diff
+416
-385
File diff suppressed because it is too large
Load Diff
+418
-387
File diff suppressed because it is too large
Load Diff
+419
-388
File diff suppressed because it is too large
Load Diff
+416
-385
File diff suppressed because it is too large
Load Diff
+416
-385
File diff suppressed because it is too large
Load Diff
+419
-388
File diff suppressed because it is too large
Load Diff
+60
-36
@@ -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()) {
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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:</p></body><
|
||||
</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");
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
@@ -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"
|
||||
|
||||
@@ -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
@@ -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
Reference in New Issue
Block a user