Measure: Fix TaskMeasure

Made several fixes to TaskMeasure:
* Move to correct namespace
* Handle possible exception in update() method
* Add null pointer checks for buttonBox
* Cannot use 'Measure::MeasurePython' as template argument in addObject<>
  because the macro PROPERTY_HEADER_WITH_OVERRIDE determines the invalid
  string 'App::FeaturePythonT<FeatureT>' so that an exception is raised

Note: The changes might fix issue 20304
This commit is contained in:
wmayer
2025-03-21 15:00:12 +01:00
committed by Ladislav Michl
parent 1acafb240a
commit 8165d12607
4 changed files with 32 additions and 17 deletions

View File

@@ -3065,7 +3065,7 @@ DocumentObject* Document::addObject(const char* sType,
Base::Type::getTypeIfDerivedFrom(sType, DocumentObject::getClassTypeId(), true);
if (type.isBad()) {
std::stringstream str;
str << "'" << sType << "' is not a document object type";
str << "Document::addObject: '" << sType << "' is not a document object type";
throw Base::TypeError(str.str());
}

View File

@@ -62,7 +62,7 @@ void StdCmdMeasure::activated(int iMsg)
{
Q_UNUSED(iMsg);
Gui::TaskMeasure* task = new Gui::TaskMeasure();
MeasureGui::TaskMeasure* task = new MeasureGui::TaskMeasure();
task->setDocumentName(this->getDocument()->getName());
Gui::Control().showDialog(task);
}

View File

@@ -48,7 +48,7 @@
#include <QMenu>
#include <QToolTip>
using namespace Gui;
using namespace MeasureGui;
namespace
{
@@ -225,7 +225,9 @@ Measure::MeasureBase* TaskMeasure::createObject(const App::MeasureType* measureT
auto pyMeasureClass = measureType->pythonClass;
// Create a MeasurePython instance
// Measure::MeasurePython is an alias so we need to use the string based addObject for now.
// Note: writing addObject<Measure::MeasurePython>() is not yet supported because
// getClassName() will determine the string 'App::FeaturePythonT<FeatureT>' instead
// of 'Measure::MeasurePython'
auto featurePython = doc->addObject("Measure::MeasurePython", measureType->label.c_str());
_mMeasureObject = dynamic_cast<Measure::MeasureBase*>(featurePython);
@@ -245,8 +247,17 @@ Measure::MeasureBase* TaskMeasure::createObject(const App::MeasureType* measureT
return _mMeasureObject;
}
void TaskMeasure::update()
{
try {
tryUpdate();
}
catch (const Base::Exception& e) {
e.reportException();
}
}
void TaskMeasure::tryUpdate()
{
App::Document* doc = App::GetApplication().getActiveDocument();
@@ -274,7 +285,7 @@ void TaskMeasure::update()
std::string mode = explicitMode ? modeSwitch->currentText().toStdString() : "";
App::MeasureSelection selection;
for (auto s : Gui::Selection().getSelection(doc->getName(), ResolveMode::NoResolve)) {
for (auto s : Gui::Selection().getSelection(doc->getName(), Gui::ResolveMode::NoResolve)) {
App::SubObjectT sub(s.pObject, s.SubName);
App::MeasureSelectionItem item = {sub, Base::Vector3d(s.x, s.y, s.z)};
@@ -358,7 +369,7 @@ void TaskMeasure::initViewObject()
void TaskMeasure::close()
{
Control().closeDialog();
Gui::Control().closeDialog();
}
@@ -460,9 +471,10 @@ void TaskMeasure::clearSelection()
void TaskMeasure::onSelectionChanged(const Gui::SelectionChanges& msg)
{
// Skip non-relevant events
if (msg.Type != SelectionChanges::AddSelection && msg.Type != SelectionChanges::RmvSelection
&& msg.Type != SelectionChanges::SetSelection
&& msg.Type != SelectionChanges::ClrSelection) {
if (msg.Type != Gui::SelectionChanges::AddSelection
&& msg.Type != Gui::SelectionChanges::RmvSelection
&& msg.Type != Gui::SelectionChanges::SetSelection
&& msg.Type != Gui::SelectionChanges::ClrSelection) {
return;
}
@@ -476,9 +488,9 @@ void TaskMeasure::onSelectionChanged(const Gui::SelectionChanges& msg)
const bool shift = (modifier & Qt::ShiftModifier) > 0;
// shift inverts the current state temporarily
const auto autosave = (mAutoSave && !shift) || (!mAutoSave && shift);
if ((!ctrl && Selection().getSelectionStyle() == SelectionStyle::NormalSelection)
|| (ctrl && Selection().getSelectionStyle() == SelectionStyle::GreedySelection)) {
if (autosave && this->buttonBox->button(QDialogButtonBox::Apply)->isEnabled()) {
if ((!ctrl && Gui::Selection().getSelectionStyle() == SelectionStyle::NormalSelection)
|| (ctrl && Gui::Selection().getSelectionStyle() == SelectionStyle::GreedySelection)) {
if (autosave && buttonBox && buttonBox->button(QDialogButtonBox::Apply)->isEnabled()) {
apply(false);
}
}
@@ -506,7 +518,9 @@ bool TaskMeasure::eventFilter(QObject* obj, QEvent* event)
if (keyEvent->key() == Qt::Key_Return || keyEvent->key() == Qt::Key_Enter) {
// Save object. Indirectly dependent on whether the apply button is enabled
// enabled if valid measurement object.
this->buttonBox->button(QDialogButtonBox::Apply)->click();
if (buttonBox) {
buttonBox->button(QDialogButtonBox::Apply)->click();
}
return true;
}
}

View File

@@ -41,10 +41,10 @@
#include <Gui/TaskView/TaskView.h>
#include <Gui/Selection/Selection.h>
namespace Gui
namespace MeasureGui
{
class TaskMeasure: public TaskView::TaskDialog, public Gui::SelectionObserver
class TaskMeasure: public Gui::TaskView::TaskDialog, public Gui::SelectionObserver
{
public:
@@ -70,6 +70,7 @@ public:
bool eventFilter(QObject* obj, QEvent* event) override;
private:
void tryUpdate();
void onSelectionChanged(const Gui::SelectionChanges& msg) override;
Measure::MeasureBase* _mMeasureObject = nullptr;
@@ -103,6 +104,6 @@ private:
bool mAutoSave = false;
};
} // namespace Gui
} // namespace MeasureGui
#endif // MEASURE_TASKMEASURE_H