Files
create/src/Gui/PropertyPage.cpp
2025-11-11 13:49:01 +01:00

314 lines
9.8 KiB
C++

// SPDX-License-Identifier: LGPL-2.1-or-later
/****************************************************************************
* Copyright (c) 2004 Werner Mayer <wmayer[at]users.sourceforge.net> *
* Copyright (c) 2023 FreeCAD Project Association *
* *
* This file is part of FreeCAD. *
* *
* FreeCAD is free software: you can redistribute it and/or modify it *
* under the terms of the GNU Lesser General Public License as *
* published by the Free Software Foundation, either version 2.1 of the *
* License, or (at your option) any later version. *
* *
* FreeCAD is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with FreeCAD. If not, see *
* <https://www.gnu.org/licenses/>. *
* *
***************************************************************************/
#include <QVBoxLayout>
#include <Base/Console.h>
#include <App/Application.h>
#include "PropertyPage.h"
#include "PrefWidgets.h"
#include "UiLoader.h"
using namespace Gui::Dialog;
/** Construction */
PropertyPage::PropertyPage(QWidget* parent)
: QWidget(parent)
, bChanged {false}
{}
/** Applies all changes. Reimplement this in your subclasses. */
void PropertyPage::apply()
{}
/** Discards all changes. Reimplement this in your subclasses. */
void PropertyPage::cancel()
{}
/** Resets to the default values. Reimplement this in your subclasses. */
void PropertyPage::reset()
{}
/** Returns whether the page was modified or not. */
bool PropertyPage::isModified() const
{
return bChanged;
}
/** Sets the page to be modified. */
void PropertyPage::setModified(bool value)
{
bChanged = value;
}
/** Applies all changes calling @ref apply() and resets the modified state. */
void PropertyPage::onApply()
{
if (isModified()) {
apply();
}
setModified(false);
}
/** Discards all changes calling @ref cancel() and resets the modified state. */
void PropertyPage::onCancel()
{
if (isModified()) {
cancel();
setModified(false);
}
}
/** Resets to the default values. */
void PropertyPage::onReset()
{
reset();
}
// ----------------------------------------------------------------
/** Construction */
PreferencePage::PreferencePage(QWidget* parent)
: QWidget(parent)
, restartRequired(false)
{}
void PreferencePage::changeEvent(QEvent* event)
{
QWidget::changeEvent(event);
}
bool PreferencePage::isRestartRequired() const
{
return restartRequired;
}
void PreferencePage::requireRestart()
{
restartRequired = true;
}
// ----------------------------------------------------------------
PreferenceUiForm::PreferenceUiForm(const QString& fn, QWidget* parent)
: PreferencePage(parent)
, _form(nullptr)
{
auto loader = UiLoader::newInstance();
loader->setWorkingDirectory(QFileInfo(fn).absolutePath());
QFile file(fn);
if (file.open(QFile::ReadOnly)) {
_form = loader->load(&file, this);
}
file.close();
if (_form) {
this->setWindowTitle(_form->windowTitle());
auto layout = new QVBoxLayout;
layout->addWidget(_form);
setLayout(layout);
}
else {
Base::Console().error("Failed to load UI file from '%s'\n", (const char*)fn.toUtf8());
}
}
PreferenceUiForm::~PreferenceUiForm() = default;
void PreferenceUiForm::changeEvent(QEvent* e)
{
QWidget::changeEvent(e);
}
template<typename PW>
void PreferenceUiForm::loadPrefWidgets()
{
QList<PW> pw = _form->findChildren<PW>();
for (typename QList<PW>::iterator it = pw.begin(); it != pw.end(); ++it) {
(*it)->onRestore();
}
}
template<typename PW>
void PreferenceUiForm::savePrefWidgets()
{
QList<PW> pw = _form->findChildren<PW>();
for (typename QList<PW>::iterator it = pw.begin(); it != pw.end(); ++it) {
(*it)->onSave();
}
}
void PreferenceUiForm::loadSettings()
{
if (!_form) {
return;
}
// search for all pref widgets to restore their settings
loadPrefWidgets<Gui::PrefSpinBox*>();
loadPrefWidgets<Gui::PrefDoubleSpinBox*>();
loadPrefWidgets<Gui::PrefLineEdit*>();
loadPrefWidgets<Gui::PrefTextEdit*>();
loadPrefWidgets<Gui::PrefFileChooser*>();
loadPrefWidgets<Gui::PrefComboBox*>();
loadPrefWidgets<Gui::PrefFontBox*>();
loadPrefWidgets<Gui::PrefCheckBox*>();
loadPrefWidgets<Gui::PrefRadioButton*>();
loadPrefWidgets<Gui::PrefSlider*>();
loadPrefWidgets<Gui::PrefColorButton*>();
loadPrefWidgets<Gui::PrefUnitSpinBox*>();
loadPrefWidgets<Gui::PrefQuantitySpinBox*>();
loadPrefWidgets<Gui::PrefCheckableGroupBox*>();
}
void PreferenceUiForm::saveSettings()
{
if (!_form) {
return;
}
// search for all pref widgets to save their settings
savePrefWidgets<Gui::PrefSpinBox*>();
savePrefWidgets<Gui::PrefDoubleSpinBox*>();
savePrefWidgets<Gui::PrefLineEdit*>();
savePrefWidgets<Gui::PrefTextEdit*>();
savePrefWidgets<Gui::PrefFileChooser*>();
savePrefWidgets<Gui::PrefComboBox*>();
savePrefWidgets<Gui::PrefFontBox*>();
savePrefWidgets<Gui::PrefCheckBox*>();
savePrefWidgets<Gui::PrefRadioButton*>();
savePrefWidgets<Gui::PrefSlider*>();
savePrefWidgets<Gui::PrefColorButton*>();
savePrefWidgets<Gui::PrefUnitSpinBox*>();
savePrefWidgets<Gui::PrefQuantitySpinBox*>();
savePrefWidgets<Gui::PrefCheckableGroupBox*>();
}
QWidget* Gui::Dialog::PreferenceUiForm::form()
{
return _form;
}
void PreferencePage::resetSettingsToDefaults()
{
auto prefs = this->findChildren<QObject*>();
for (const auto& pref : prefs) {
if (!pref->property("prefPath").isNull() && !pref->property("prefEntry").isNull()) {
std::string path = pref->property("prefPath").toString().toStdString();
std::string entry = pref->property("prefEntry").toString().toStdString();
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath(
std::string("User parameter:BaseApp/Preferences/" + path).c_str()
);
for (const auto& pn : hGrp->GetParameterNames(entry.c_str())) {
hGrp->RemoveAttribute(pn.first, pn.second.c_str());
}
}
}
}
// ----------------------------------------------------------------
/** Construction */
CustomizeActionPage::CustomizeActionPage(QWidget* parent)
: QWidget(parent)
{}
/** Destruction */
CustomizeActionPage::~CustomizeActionPage() = default;
bool CustomizeActionPage::event(QEvent* e)
{
bool ok = QWidget::event(e);
if (e->type() == QEvent::ParentChange || e->type() == QEvent::ParentAboutToChange) {
QWidget* topLevel = this->parentWidget();
while (topLevel && !topLevel->inherits("QDialog")) {
topLevel = topLevel->parentWidget();
}
if (topLevel) {
int index = topLevel->metaObject()->indexOfSignal(
QMetaObject::normalizedSignature("addMacroAction(const QByteArray&)")
);
if (index >= 0) {
if (e->type() == QEvent::ParentChange) {
connect(
topLevel,
SIGNAL(addMacroAction(const QByteArray&)),
this,
SLOT(onAddMacroAction(const QByteArray&))
);
connect(
topLevel,
SIGNAL(removeMacroAction(const QByteArray&)),
this,
SLOT(onRemoveMacroAction(const QByteArray&))
);
connect(
topLevel,
SIGNAL(modifyMacroAction(const QByteArray&)),
this,
SLOT(onModifyMacroAction(const QByteArray&))
);
}
else {
disconnect(
topLevel,
SIGNAL(addMacroAction(const QByteArray&)),
this,
SLOT(onAddMacroAction(const QByteArray&))
);
disconnect(
topLevel,
SIGNAL(removeMacroAction(const QByteArray&)),
this,
SLOT(onRemoveMacroAction(const QByteArray&))
);
disconnect(
topLevel,
SIGNAL(modifyMacroAction(const QByteArray&)),
this,
SLOT(onModifyMacroAction(const QByteArray&))
);
}
}
}
}
return ok;
}
void CustomizeActionPage::changeEvent(QEvent* e)
{
QWidget::changeEvent(e);
}
#include "moc_PropertyPage.cpp"