[GUI] Add PreferencePack support
Preference Packs are collections of preferences that can be applied en mass to the user's current setup. Any preference that can be stored in user.cfg can be stored in a preference pack, and they are designed to be easy to distribute. Support is also added for saving a subset of current preferences into a new preference pack in order to facilitate easy creation of new "themes", etc.
This commit is contained in:
@@ -44,6 +44,7 @@
|
||||
#endif
|
||||
|
||||
#include <boost/interprocess/sync/file_lock.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <QtOpenGL.h>
|
||||
#if defined(HAVE_QT5_OPENGL)
|
||||
#include <QWindow>
|
||||
@@ -72,6 +73,7 @@
|
||||
#include "WidgetFactory.h"
|
||||
#include "Command.h"
|
||||
#include "Macro.h"
|
||||
#include "PreferencePackManager.h"
|
||||
#include "ProgressBar.h"
|
||||
#include "Workbench.h"
|
||||
#include "WorkbenchManager.h"
|
||||
@@ -159,6 +161,9 @@ struct ApplicationP
|
||||
macroMngr = new MacroManager();
|
||||
else
|
||||
macroMngr = nullptr;
|
||||
|
||||
// Create the Theme Manager
|
||||
prefPackManager = new PreferencePackManager();
|
||||
}
|
||||
|
||||
~ApplicationP()
|
||||
@@ -172,6 +177,7 @@ struct ApplicationP
|
||||
Gui::Document* activeDocument;
|
||||
Gui::Document* editDocument;
|
||||
MacroManager* macroMngr;
|
||||
PreferencePackManager* prefPackManager;
|
||||
/// List of all registered views
|
||||
std::list<Gui::BaseView*> passive;
|
||||
bool isClosing;
|
||||
@@ -1616,6 +1622,12 @@ CommandManager &Application::commandManager(void)
|
||||
return d->commandManager;
|
||||
}
|
||||
|
||||
Gui::PreferencePackManager* Application::prefPackManager(void)
|
||||
{
|
||||
return d->prefPackManager;
|
||||
}
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// Init, Destruct and singleton
|
||||
|
||||
|
||||
@@ -43,6 +43,7 @@ class MacroManager;
|
||||
class MDIView;
|
||||
class MainWindow;
|
||||
class MenuItem;
|
||||
class PreferencePackManager;
|
||||
class ViewProvider;
|
||||
class ViewProviderDocumentObject;
|
||||
|
||||
@@ -216,6 +217,8 @@ public:
|
||||
void createStandardOperations();
|
||||
//@}
|
||||
|
||||
Gui::PreferencePackManager* prefPackManager(void);
|
||||
|
||||
/** @name Init, Destruct an Access methods */
|
||||
//@{
|
||||
/// some kind of singelton
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#add_subdirectory(Icons)
|
||||
add_subdirectory(Stylesheets)
|
||||
add_subdirectory(PreferencePacks)
|
||||
add_subdirectory(PreferencePackTemplates)
|
||||
|
||||
if(WIN32)
|
||||
add_definitions(-DFCGui -DQIIS_MAKEDLL -DQSINT_MAKEDLL -DOVR_OS_WIN32 -DQUARTER_INTERNAL -DQUARTER_MAKE_DLL -DCOIN_DLL)
|
||||
@@ -306,6 +308,7 @@ SET(Gui_UIC_SRCS
|
||||
DlgAuthorization.ui
|
||||
DlgChooseIcon.ui
|
||||
DlgCommands.ui
|
||||
DlgCreateNewPreferencePack.ui
|
||||
DlgCustomizeSpNavSettings.ui
|
||||
DlgDisplayProperties.ui
|
||||
DlgEditor.ui
|
||||
@@ -403,6 +406,7 @@ SET(Dialog_CPP_SRCS
|
||||
Clipping.cpp
|
||||
DemoMode.cpp
|
||||
DlgActivateWindowImp.cpp
|
||||
DlgCreateNewPreferencePackImp.cpp
|
||||
DlgUnitsCalculatorImp.cpp
|
||||
DlgDisplayPropertiesImp.cpp
|
||||
DlgInputDialogImp.cpp
|
||||
@@ -440,6 +444,7 @@ SET(Dialog_HPP_SRCS
|
||||
Clipping.h
|
||||
DemoMode.h
|
||||
DlgActivateWindowImp.h
|
||||
DlgCreateNewPreferencePackImp.h
|
||||
DlgUnitsCalculatorImp.h
|
||||
DlgDisplayPropertiesImp.h
|
||||
DlgInputDialogImp.h
|
||||
@@ -499,6 +504,7 @@ SET(Dialog_SRCS
|
||||
DlgCheckableMessageBox.ui
|
||||
DlgTreeWidget.ui
|
||||
DlgExpressionInput.ui
|
||||
DlgCreateNewPreferencePack.ui
|
||||
DownloadManager.ui
|
||||
DownloadItem.ui
|
||||
DocumentRecovery.ui
|
||||
@@ -1139,6 +1145,7 @@ SET(FreeCADGui_CPP_SRCS
|
||||
resource.cpp
|
||||
Control.cpp
|
||||
SpaceballEvent.cpp
|
||||
PreferencePackManager.cpp
|
||||
Thumbnail.cpp
|
||||
Utilities.cpp
|
||||
WaitCursor.cpp
|
||||
@@ -1171,6 +1178,7 @@ SET(FreeCADGui_SRCS
|
||||
Qt4All.h
|
||||
Control.h
|
||||
SpaceballEvent.h
|
||||
PreferencePackManager.h
|
||||
Thumbnail.h
|
||||
Utilities.h
|
||||
WaitCursor.h
|
||||
|
||||
107
src/Gui/DlgCreateNewPreferencePack.ui
Normal file
107
src/Gui/DlgCreateNewPreferencePack.ui
Normal file
@@ -0,0 +1,107 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>Gui::Dialog::DlgCreateNewPreferencePack</class>
|
||||
<widget class="QDialog" name="Gui::Dialog::DlgCreateNewPreferencePack">
|
||||
<property name="windowModality">
|
||||
<enum>Qt::ApplicationModal</enum>
|
||||
</property>
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>580</width>
|
||||
<height>520</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Create New Preference Pack</string>
|
||||
</property>
|
||||
<property name="modal">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Name</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="lineEdit"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTreeWidget" name="treeWidget">
|
||||
<attribute name="headerMinimumSectionSize">
|
||||
<number>50</number>
|
||||
</attribute>
|
||||
<attribute name="headerDefaultSectionSize">
|
||||
<number>250</number>
|
||||
</attribute>
|
||||
<attribute name="headerShowSortIndicator" stdset="0">
|
||||
<bool>true</bool>
|
||||
</attribute>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Property group templates</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Template Type</string>
|
||||
</property>
|
||||
</column>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>Gui::Dialog::DlgCreateNewPreferencePack</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>248</x>
|
||||
<y>254</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>157</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>Gui::Dialog::DlgCreateNewPreferencePack</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>316</x>
|
||||
<y>260</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>286</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
||||
153
src/Gui/DlgCreateNewPreferencePackImp.cpp
Normal file
153
src/Gui/DlgCreateNewPreferencePackImp.cpp
Normal file
@@ -0,0 +1,153 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2021 Chris Hennes <chennes@pioneerlibrarysystem.org> *
|
||||
* *
|
||||
* This file is part of the FreeCAD CAx development system. *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU Library General Public *
|
||||
* License as published by the Free Software Foundation; either *
|
||||
* version 2 of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This library 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 Library General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Library General Public *
|
||||
* License along with this library; see the file COPYING.LIB. If not, *
|
||||
* write to the Free Software Foundation, Inc., 59 Temple Place, *
|
||||
* Suite 330, Boston, MA 02111-1307, USA *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#include "PreCompiled.h"
|
||||
#ifndef _PreComp_
|
||||
#endif
|
||||
|
||||
#include "DlgCreateNewPreferencePackImp.h"
|
||||
#include "ui_DlgCreateNewPreferencePack.h"
|
||||
|
||||
#include <QPushButton>
|
||||
|
||||
using namespace Gui::Dialog;
|
||||
|
||||
const auto TemplateRole = Qt::UserRole;
|
||||
|
||||
/* TRANSLATOR Gui::Dialog::DlgCreateNewPreferencePackImp */
|
||||
|
||||
/**
|
||||
* Constructs a Gui::Dialog::DlgCreateNewPreferencePackImp as a child of 'parent'
|
||||
*/
|
||||
DlgCreateNewPreferencePackImp::DlgCreateNewPreferencePackImp(QWidget* parent)
|
||||
: QDialog(parent)
|
||||
, ui(new Ui_DlgCreateNewPreferencePack)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
QRegExp validNames(QString::fromUtf8("[^/\\\\?%*:|\"<>]+"));
|
||||
_nameValidator.setRegExp(validNames);
|
||||
ui->lineEdit->setValidator(&_nameValidator);
|
||||
ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
|
||||
connect(ui->treeWidget, &QTreeWidget::itemChanged, this, &DlgCreateNewPreferencePackImp::onItemChanged);
|
||||
}
|
||||
|
||||
|
||||
DlgCreateNewPreferencePackImp::~DlgCreateNewPreferencePackImp()
|
||||
{
|
||||
}
|
||||
|
||||
void DlgCreateNewPreferencePackImp::setPreferencePackTemplates(const std::vector<Gui::PreferencePackManager::TemplateFile>& availableTemplates)
|
||||
{
|
||||
ui->treeWidget->clear();
|
||||
_groups.clear();
|
||||
|
||||
ui->treeWidget->header()->setDefaultSectionSize(250);
|
||||
|
||||
_templates = availableTemplates;
|
||||
for (const auto &t : _templates) {
|
||||
|
||||
QTreeWidgetItem* group;
|
||||
if (auto foundGroup = _groups.find(t.group); foundGroup != _groups.end()) {
|
||||
group = foundGroup->second;
|
||||
}
|
||||
else {
|
||||
group = new QTreeWidgetItem(ui->treeWidget, QStringList(QString::fromStdString(t.group)));
|
||||
group->setCheckState(0, Qt::Checked);
|
||||
group->setExpanded(true);
|
||||
_groups.insert(std::make_pair(t.group, group));
|
||||
}
|
||||
|
||||
QStringList itemColumns;
|
||||
itemColumns.push_back(QString::fromStdString(t.name));
|
||||
switch (t.type) {
|
||||
case Gui::PreferencePack::Type::Appearance: itemColumns.push_back(tr("Appearance")); break;
|
||||
case Gui::PreferencePack::Type::Behavior: itemColumns.push_back(tr("Behavior")); break;
|
||||
case Gui::PreferencePack::Type::Combination: itemColumns.push_back(tr("Combination")); break;
|
||||
}
|
||||
auto newItem = new QTreeWidgetItem(group, itemColumns);
|
||||
newItem->setCheckState(0, Qt::Checked);
|
||||
if (group->checkState(0) != newItem->checkState(0))
|
||||
group->setCheckState(0, Qt::PartiallyChecked);
|
||||
newItem->setData(0, TemplateRole, QVariant::fromValue(t));
|
||||
group->addChild(newItem);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<Gui::PreferencePackManager::TemplateFile> DlgCreateNewPreferencePackImp::selectedTemplates() const
|
||||
{
|
||||
std::vector<Gui::PreferencePackManager::TemplateFile> results;
|
||||
|
||||
for (const auto& group : _groups)
|
||||
for (int childIndex = 0; childIndex < group.second->childCount(); ++childIndex)
|
||||
if (auto child = group.second->child(childIndex); child->checkState(0) == Qt::Checked)
|
||||
if (child->data(0, TemplateRole).canConvert<Gui::PreferencePackManager::TemplateFile>())
|
||||
results.push_back(child->data(0, TemplateRole).value<Gui::PreferencePackManager::TemplateFile>());
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
std::string DlgCreateNewPreferencePackImp::preferencePackName() const
|
||||
{
|
||||
return ui->lineEdit->text().toStdString();
|
||||
}
|
||||
|
||||
void DlgCreateNewPreferencePackImp::onItemChanged(QTreeWidgetItem* item, int column)
|
||||
{
|
||||
Q_UNUSED(column);
|
||||
const QSignalBlocker blocker(ui->treeWidget);
|
||||
if (auto group = item->parent(); group) {
|
||||
// Child clicked
|
||||
bool firstItemChecked = false;
|
||||
for (int childIndex = 0; childIndex < group->childCount(); ++childIndex) {
|
||||
auto child = group->child(childIndex);
|
||||
if (childIndex == 0) {
|
||||
firstItemChecked = child->checkState(0) == Qt::Checked;
|
||||
}
|
||||
else {
|
||||
bool thisItemChecked = child->checkState(0) == Qt::Checked;
|
||||
if (firstItemChecked != thisItemChecked) {
|
||||
group->setCheckState(0, Qt::PartiallyChecked);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
group->setCheckState(0, firstItemChecked ? Qt::Checked : Qt::Unchecked);
|
||||
}
|
||||
else {
|
||||
// Group clicked:
|
||||
auto groupCheckState = item->checkState(0);
|
||||
for (int childIndex = 0; childIndex < item->childCount(); ++childIndex) {
|
||||
auto child = item->child(childIndex);
|
||||
child->setCheckState(0, groupCheckState);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DlgCreateNewPreferencePackImp::on_lineEdit_textEdited(const QString& text)
|
||||
{
|
||||
ui->buttonBox->button(QDialogButtonBox::Ok)->setDisabled(text.isEmpty());
|
||||
}
|
||||
|
||||
|
||||
#include "moc_DlgCreateNewPreferencePackImp.cpp"
|
||||
78
src/Gui/DlgCreateNewPreferencePackImp.h
Normal file
78
src/Gui/DlgCreateNewPreferencePackImp.h
Normal file
@@ -0,0 +1,78 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2021 Chris Hennes <chennes@pioneerlibrarysystem.org> *
|
||||
* *
|
||||
* This file is part of the FreeCAD CAx development system. *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU Library General Public *
|
||||
* License as published by the Free Software Foundation; either *
|
||||
* version 2 of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This library 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 Library General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Library General Public *
|
||||
* License along with this library; see the file COPYING.LIB. If not, *
|
||||
* write to the Free Software Foundation, Inc., 59 Temple Place, *
|
||||
* Suite 330, Boston, MA 02111-1307, USA *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#ifndef GUI_DIALOG_DLGCREATENEWTHEMEIMP_H
|
||||
#define GUI_DIALOG_DLGCREATENEWTHEMEIMP_H
|
||||
|
||||
#include <memory>
|
||||
#include <QDialog>
|
||||
#include <QRegExpValidator>
|
||||
|
||||
#include "PreferencePackManager.h"
|
||||
|
||||
class QTreeWidgetItem;
|
||||
|
||||
namespace Gui {
|
||||
|
||||
namespace Dialog {
|
||||
|
||||
class Ui_DlgCreateNewPreferencePack;
|
||||
|
||||
/**
|
||||
* \class DlgCreateNewPreferencePackImp
|
||||
*
|
||||
* A dialog to request a preferencePack name and a set of preferencePack templates.
|
||||
*
|
||||
* \author Chris Hennes
|
||||
*/
|
||||
class GuiExport DlgCreateNewPreferencePackImp : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
DlgCreateNewPreferencePackImp(QWidget* parent = nullptr);
|
||||
~DlgCreateNewPreferencePackImp();
|
||||
|
||||
void setPreferencePackTemplates(const std::vector<PreferencePackManager::TemplateFile> &availableTemplates);
|
||||
|
||||
std::vector<PreferencePackManager::TemplateFile> selectedTemplates() const;
|
||||
std::string preferencePackName() const;
|
||||
|
||||
protected Q_SLOTS:
|
||||
|
||||
void onItemChanged(QTreeWidgetItem* item, int column);
|
||||
|
||||
void on_lineEdit_textEdited(const QString &text);
|
||||
|
||||
private:
|
||||
std::unique_ptr<Ui_DlgCreateNewPreferencePack> ui;
|
||||
std::map<std::string, QTreeWidgetItem*> _groups;
|
||||
std::vector<PreferencePackManager::TemplateFile> _templates;
|
||||
QRegExpValidator _nameValidator;
|
||||
};
|
||||
|
||||
} // namespace Dialog
|
||||
} // namespace Gui
|
||||
|
||||
#endif // GUI_DIALOG_DLGCREATENEWTHEMEIMP_H
|
||||
@@ -14,7 +14,16 @@
|
||||
<string>General</string>
|
||||
</property>
|
||||
<layout class="QGridLayout">
|
||||
<property name="margin">
|
||||
<property name="leftMargin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="spacing">
|
||||
@@ -32,7 +41,16 @@
|
||||
<string>Language</string>
|
||||
</property>
|
||||
<layout class="QGridLayout">
|
||||
<property name="margin">
|
||||
<property name="leftMargin">
|
||||
<number>11</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>11</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>11</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>11</number>
|
||||
</property>
|
||||
<property name="spacing">
|
||||
@@ -43,7 +61,16 @@
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<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>
|
||||
@@ -65,6 +92,146 @@
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="title">
|
||||
<string>Preference Packs</string>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QTableWidget" name="PreferencePacks">
|
||||
<property name="editTriggers">
|
||||
<set>QAbstractItemView::NoEditTriggers</set>
|
||||
</property>
|
||||
<property name="showDropIndicator" stdset="0">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="dragDropOverwriteMode">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="selectionMode">
|
||||
<enum>QAbstractItemView::SingleSelection</enum>
|
||||
</property>
|
||||
<property name="selectionBehavior">
|
||||
<enum>QAbstractItemView::SelectRows</enum>
|
||||
</property>
|
||||
<property name="showGrid">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="sortingEnabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="cornerButtonEnabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<attribute name="horizontalHeaderVisible">
|
||||
<bool>true</bool>
|
||||
</attribute>
|
||||
<attribute name="horizontalHeaderCascadingSectionResizes">
|
||||
<bool>true</bool>
|
||||
</attribute>
|
||||
<attribute name="horizontalHeaderMinimumSectionSize">
|
||||
<number>75</number>
|
||||
</attribute>
|
||||
<attribute name="horizontalHeaderDefaultSectionSize">
|
||||
<number>200</number>
|
||||
</attribute>
|
||||
<attribute name="horizontalHeaderStretchLastSection">
|
||||
<bool>true</bool>
|
||||
</attribute>
|
||||
<attribute name="verticalHeaderVisible">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
<attribute name="verticalHeaderMinimumSectionSize">
|
||||
<number>16</number>
|
||||
</attribute>
|
||||
<attribute name="verticalHeaderDefaultSectionSize">
|
||||
<number>24</number>
|
||||
</attribute>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Name</string>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Type</string>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
</column>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QPushButton" name="ApplyPreferencePack">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Run</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="SaveNewPreferencePack">
|
||||
<property name="text">
|
||||
<string>Save new...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="ManagePreferencePacks">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Manage...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="GroupBox3">
|
||||
<property name="title">
|
||||
@@ -74,7 +241,16 @@
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<property name="leftMargin">
|
||||
<number>11</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>11</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>11</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>11</number>
|
||||
</property>
|
||||
<item>
|
||||
@@ -82,7 +258,16 @@
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<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>
|
||||
@@ -131,7 +316,16 @@
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<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>
|
||||
@@ -152,7 +346,16 @@ See the FreeCAD Wiki for details about the image.</string>
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<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>
|
||||
@@ -176,7 +379,16 @@ See the FreeCAD Wiki for details about the image.</string>
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<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>
|
||||
@@ -201,7 +413,16 @@ this according to your screen size or personal taste</string>
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<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>
|
||||
@@ -214,7 +435,7 @@ this according to your screen size or personal taste</string>
|
||||
<item>
|
||||
<widget class="QComboBox" name="treeMode">
|
||||
<property name="toolTip">
|
||||
<string>Customize how tree view is shown in the panel (restart required).
|
||||
<string>Customize how tree view is shown in the panel (restart required).
|
||||
|
||||
'ComboView': combine tree view and property view into one panel.
|
||||
'TreeView and PropertyView': split tree view and property view into separate panel.
|
||||
@@ -233,7 +454,16 @@ this according to your screen size or personal taste</string>
|
||||
<string>Start up</string>
|
||||
</property>
|
||||
<layout class="QGridLayout">
|
||||
<property name="margin">
|
||||
<property name="leftMargin">
|
||||
<number>11</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>11</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>11</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>11</number>
|
||||
</property>
|
||||
<property name="spacing">
|
||||
@@ -262,7 +492,16 @@ display the splash screen</string>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<layout class="QGridLayout">
|
||||
<property name="margin">
|
||||
<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>
|
||||
<property name="spacing">
|
||||
@@ -294,7 +533,16 @@ after FreeCAD launches</string>
|
||||
<string>Python console</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="_4">
|
||||
<property name="margin">
|
||||
<property name="leftMargin">
|
||||
<number>11</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>11</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>11</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>11</number>
|
||||
</property>
|
||||
<property name="spacing">
|
||||
@@ -323,19 +571,6 @@ horizontal space in Python console</string>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>352</width>
|
||||
<height>221</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -353,11 +588,6 @@ horizontal space in Python console</string>
|
||||
<extends>QSpinBox</extends>
|
||||
<header>Gui/PrefWidgets.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>Gui::PrefComboBox</class>
|
||||
<extends>QComboBox</extends>
|
||||
<header>Gui/PrefWidgets.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<tabstops>
|
||||
<tabstop>Languages</tabstop>
|
||||
|
||||
@@ -33,11 +33,16 @@
|
||||
#include "ui_DlgGeneral.h"
|
||||
#include "Action.h"
|
||||
#include "Application.h"
|
||||
#include "Command.h"
|
||||
#include "DockWindowManager.h"
|
||||
#include "MainWindow.h"
|
||||
#include "PrefWidgets.h"
|
||||
#include "PythonConsole.h"
|
||||
#include "Language/Translator.h"
|
||||
#include "Gui/PreferencePackManager.h"
|
||||
#include "DlgPreferencesImp.h"
|
||||
|
||||
#include "DlgCreateNewPreferencePackImp.h"
|
||||
|
||||
using namespace Gui::Dialog;
|
||||
|
||||
@@ -82,6 +87,15 @@ DlgGeneralImp::DlgGeneralImp( QWidget* parent )
|
||||
else
|
||||
ui->AutoloadModuleCombo->addItem(px, it.key(), QVariant(it.value()));
|
||||
}
|
||||
|
||||
recreatePreferencePackMenu();
|
||||
connect(ui->PreferencePacks, &QTableWidget::itemSelectionChanged, this, &DlgGeneralImp::preferencePackSelectionChanged);
|
||||
connect(ui->ApplyPreferencePack, &QPushButton::clicked, this, &DlgGeneralImp::applyPreferencePackClicked);
|
||||
connect(ui->SaveNewPreferencePack, &QPushButton::clicked, this, &DlgGeneralImp::saveAsNewPreferencePack);
|
||||
|
||||
// Future work: the Add-On Manager will be modified to include a section for Preference Packs, at which point this
|
||||
// button will be enabled to open the Add-On Manager to that tab.
|
||||
ui->ManagePreferencePacks->hide();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -299,4 +313,90 @@ void DlgGeneralImp::changeEvent(QEvent *e)
|
||||
}
|
||||
}
|
||||
|
||||
void DlgGeneralImp::recreatePreferencePackMenu()
|
||||
{
|
||||
// Populate the Preference Packs list
|
||||
auto appearancePacks = Application::Instance->prefPackManager()->preferencePackNames(PreferencePack::Type::Appearance);
|
||||
auto behaviorPacks = Application::Instance->prefPackManager()->preferencePackNames(PreferencePack::Type::Behavior);
|
||||
auto combinationPacks = Application::Instance->prefPackManager()->preferencePackNames(PreferencePack::Type::Combination);
|
||||
|
||||
ui->PreferencePacks->setRowCount(appearancePacks.size() + behaviorPacks.size() + combinationPacks.size());
|
||||
|
||||
int row = 0;
|
||||
for (const auto& pack : appearancePacks) {
|
||||
auto name = new QTableWidgetItem(QString::fromStdString(pack));
|
||||
ui->PreferencePacks->setItem(row, 0, name);
|
||||
auto kind = new QTableWidgetItem(tr("Appearance"));
|
||||
ui->PreferencePacks->setItem(row, 1, kind);
|
||||
++row;
|
||||
}
|
||||
for (const auto& pack : behaviorPacks) {
|
||||
auto name = new QTableWidgetItem(QString::fromStdString(pack));
|
||||
ui->PreferencePacks->setItem(row, 0, name);
|
||||
auto kind = new QTableWidgetItem(tr("Behavior"));
|
||||
ui->PreferencePacks->setItem(row, 1, kind);
|
||||
++row;
|
||||
}
|
||||
for (const auto& pack : combinationPacks) {
|
||||
auto name = new QTableWidgetItem(QString::fromStdString(pack));
|
||||
ui->PreferencePacks->setItem(row, 0, name);
|
||||
auto kind = new QTableWidgetItem(tr("Combination"));
|
||||
ui->PreferencePacks->setItem(row, 1, kind);
|
||||
++row;
|
||||
}
|
||||
ui->PreferencePacks->setRangeSelected(QTableWidgetSelectionRange(), true);
|
||||
ui->ApplyPreferencePack->setEnabled(false);
|
||||
}
|
||||
|
||||
void DlgGeneralImp::preferencePackSelectionChanged()
|
||||
{
|
||||
if (ui->PreferencePacks->selectedItems().isEmpty())
|
||||
ui->ApplyPreferencePack->setEnabled(false);
|
||||
else
|
||||
ui->ApplyPreferencePack->setEnabled(true);
|
||||
}
|
||||
|
||||
void DlgGeneralImp::saveAsNewPreferencePack()
|
||||
{
|
||||
// Create and run a modal New PreferencePack dialog box
|
||||
newPreferencePackDialog = std::make_unique<DlgCreateNewPreferencePackImp>(this);
|
||||
newPreferencePackDialog->setPreferencePackTemplates(Application::Instance->prefPackManager()->templateFiles());
|
||||
connect(newPreferencePackDialog.get(), &DlgCreateNewPreferencePackImp::accepted, this, &DlgGeneralImp::newPreferencePackDialogAccepted);
|
||||
newPreferencePackDialog->open();
|
||||
}
|
||||
|
||||
void DlgGeneralImp::newPreferencePackDialogAccepted()
|
||||
{
|
||||
auto preferencePackTemplates = Application::Instance->prefPackManager()->templateFiles();
|
||||
auto selection = newPreferencePackDialog->selectedTemplates();
|
||||
std::vector<PreferencePackManager::TemplateFile> selectedTemplates;
|
||||
std::copy_if(preferencePackTemplates.begin(), preferencePackTemplates.end(), std::back_inserter(selectedTemplates), [selection](PreferencePackManager::TemplateFile& t) {
|
||||
for (const auto& item : selection)
|
||||
if (item.group == t.group && item.name == t.name)
|
||||
return true;
|
||||
return false;
|
||||
});
|
||||
auto preferencePackName = newPreferencePackDialog->preferencePackName();
|
||||
Application::Instance->prefPackManager()->save(preferencePackName, selectedTemplates);
|
||||
Application::Instance->prefPackManager()->rescan();
|
||||
recreatePreferencePackMenu();
|
||||
}
|
||||
|
||||
void DlgGeneralImp::applyPreferencePackClicked()
|
||||
{
|
||||
auto selectedPreferencePacks = ui->PreferencePacks->selectedItems();
|
||||
|
||||
for (const auto pack : selectedPreferencePacks) {
|
||||
if (pack->column() == 0) {
|
||||
auto packName = pack->text().toStdString();
|
||||
if (Application::Instance->prefPackManager()->apply(packName)) {
|
||||
auto parentDialog = qobject_cast<DlgPreferencesImp*> (this->window());
|
||||
if (parentDialog)
|
||||
parentDialog->reload();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#include "moc_DlgGeneralImp.cpp"
|
||||
|
||||
@@ -32,6 +32,7 @@ class QTabWidget;
|
||||
namespace Gui {
|
||||
namespace Dialog {
|
||||
class Ui_DlgGeneral;
|
||||
class DlgCreateNewPreferencePackImp;
|
||||
|
||||
/** This class implements the settings for the application.
|
||||
* You can change window style, size of pixmaps, size of recent file list and so on
|
||||
@@ -51,11 +52,19 @@ public:
|
||||
protected:
|
||||
void changeEvent(QEvent *e);
|
||||
|
||||
protected Q_SLOTS:
|
||||
void preferencePackSelectionChanged();
|
||||
void applyPreferencePackClicked();
|
||||
void recreatePreferencePackMenu();
|
||||
void newPreferencePackDialogAccepted();
|
||||
|
||||
private:
|
||||
void setRecentFileSize();
|
||||
void saveAsNewPreferencePack();
|
||||
|
||||
private:
|
||||
std::unique_ptr<Ui_DlgGeneral> ui;
|
||||
std::unique_ptr<DlgCreateNewPreferencePackImp> newPreferencePackDialog;
|
||||
};
|
||||
|
||||
} // namespace Dialog
|
||||
|
||||
@@ -466,4 +466,17 @@ void DlgPreferencesImp::changeEvent(QEvent *e)
|
||||
}
|
||||
}
|
||||
|
||||
void DlgPreferencesImp::reload()
|
||||
{
|
||||
for (int i = 0; i < ui->tabWidgetStack->count(); i++) {
|
||||
QTabWidget* tabWidget = (QTabWidget*)ui->tabWidgetStack->widget(i);
|
||||
for (int j = 0; j < tabWidget->count(); j++) {
|
||||
PreferencePage* page = qobject_cast<PreferencePage*>(tabWidget->widget(j));
|
||||
if (page)
|
||||
page->loadSettings();
|
||||
}
|
||||
}
|
||||
applyChanges();
|
||||
}
|
||||
|
||||
#include "moc_DlgPreferencesImp.cpp"
|
||||
|
||||
@@ -113,11 +113,13 @@ class GuiExport DlgPreferencesImp : public QDialog
|
||||
public:
|
||||
static void addPage(const std::string& className, const std::string& group);
|
||||
static void removePage(const std::string& className, const std::string& group);
|
||||
static void reloadSettings();
|
||||
|
||||
DlgPreferencesImp(QWidget* parent = 0, Qt::WindowFlags fl = Qt::WindowFlags());
|
||||
~DlgPreferencesImp();
|
||||
|
||||
void accept();
|
||||
void reload();
|
||||
void activateGroupPage(const QString& group, int id);
|
||||
|
||||
protected:
|
||||
@@ -135,11 +137,11 @@ private:
|
||||
/** @name for internal use only */
|
||||
//@{
|
||||
void setupPages();
|
||||
void reloadPages();
|
||||
QTabWidget* createTabForGroup(const std::string& groupName);
|
||||
void createPageInGroup(QTabWidget* tabWidget, const std::string& pageName);
|
||||
void applyChanges();
|
||||
void restoreDefaults();
|
||||
void reloadPages();
|
||||
//@}
|
||||
|
||||
private:
|
||||
|
||||
454
src/Gui/PreferencePackManager.cpp
Normal file
454
src/Gui/PreferencePackManager.cpp
Normal file
@@ -0,0 +1,454 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2021 Chris Hennes <chennes@pioneerlibrarysystem.org> *
|
||||
* *
|
||||
* This file is part of the FreeCAD CAx development system. *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU Library General Public *
|
||||
* License as published by the Free Software Foundation; either *
|
||||
* version 2 of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This library 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 Library General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Library General Public *
|
||||
* License along with this library; see the file COPYING.LIB. If not, *
|
||||
* write to the Free Software Foundation, Inc., 59 Temple Place, *
|
||||
* Suite 330, Boston, MA 02111-1307, USA *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#include "PreCompiled.h"
|
||||
|
||||
#ifndef _PreComp_
|
||||
# include <memory>
|
||||
# include <string_view>
|
||||
# include <mutex>
|
||||
#endif
|
||||
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <QDir>
|
||||
|
||||
#include "PreferencePackManager.h"
|
||||
#include "App/Metadata.h"
|
||||
#include "Base/Parameter.h"
|
||||
#include "Base/Interpreter.h"
|
||||
#include "Base/Console.h"
|
||||
|
||||
#include <App/Application.h>
|
||||
|
||||
#include <ctime> // For generating a timestamped filename
|
||||
|
||||
|
||||
using namespace Gui;
|
||||
using namespace xercesc;
|
||||
namespace fs = boost::filesystem;
|
||||
|
||||
PreferencePack::PreferencePack(const fs::path& path, const App::Metadata& metadata) :
|
||||
_path(path), _metadata(metadata)
|
||||
{
|
||||
if (!fs::exists(_path)) {
|
||||
throw std::runtime_error{ "Cannot access " + path.string() };
|
||||
}
|
||||
|
||||
auto qssPaths = QDir::searchPaths(QString::fromUtf8("qss"));
|
||||
auto cssPaths = QDir::searchPaths(QString::fromUtf8("css"));
|
||||
|
||||
qssPaths.append(QString::fromStdString(_path.string()));
|
||||
cssPaths.append(QString::fromStdString(_path.string()));
|
||||
|
||||
QDir::setSearchPaths(QString::fromUtf8("qss"), qssPaths);
|
||||
QDir::setSearchPaths(QString::fromUtf8("css"), cssPaths);
|
||||
}
|
||||
|
||||
std::string PreferencePack::name() const
|
||||
{
|
||||
return _metadata.name();
|
||||
}
|
||||
|
||||
bool PreferencePack::apply() const
|
||||
{
|
||||
// Run the pre.FCMacro, if it exists: if it raises an exception, abort the process
|
||||
auto preMacroPath = _path / "pre.FCMacro";
|
||||
if (fs::exists(preMacroPath)) {
|
||||
try {
|
||||
Base::Interpreter().runFile(preMacroPath.string().c_str(), false);
|
||||
}
|
||||
catch (...) {
|
||||
Base::Console().Message("PreferencePack application aborted by the preferencePack's pre.FCMacro");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Back up the old config file
|
||||
auto savedPreferencePacksDirectory = fs::path(App::Application::getUserAppDataDir()) / "SavedPreferencePacks";
|
||||
auto backupFile = savedPreferencePacksDirectory / "user.cfg.backup";
|
||||
try {
|
||||
fs::remove(backupFile);
|
||||
}
|
||||
catch (...) {}
|
||||
App::GetApplication().GetUserParameter().SaveDocument(backupFile.string().c_str());
|
||||
|
||||
// Apply the config settings
|
||||
applyConfigChanges();
|
||||
|
||||
// Run the Post.FCMacro, if it exists
|
||||
auto postMacroPath = _path / "post.FCMacro";
|
||||
if (fs::exists(postMacroPath)) {
|
||||
try {
|
||||
Base::Interpreter().runFile(postMacroPath.string().c_str(), false);
|
||||
}
|
||||
catch (...) {
|
||||
Base::Console().Message("PreferencePack application reverted by the preferencePack's post.FCMacro");
|
||||
App::GetApplication().GetUserParameter().LoadDocument(backupFile.string().c_str());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
PreferencePack::Type PreferencePack::type() const
|
||||
{
|
||||
auto typeList = _metadata["type"];
|
||||
if (typeList.empty())
|
||||
return Type::Combination;
|
||||
|
||||
auto typeString = typeList.front().contents;
|
||||
if (typeString == "appearance")
|
||||
return Type::Appearance;
|
||||
else if (typeString == "behavior" || typeString == "behaviour")
|
||||
return Type::Behavior;
|
||||
else
|
||||
return Type::Combination;
|
||||
}
|
||||
|
||||
void PreferencePack::applyConfigChanges() const
|
||||
{
|
||||
auto configFile = _path / (_metadata.name() + ".cfg");
|
||||
if (fs::exists(configFile)) {
|
||||
ParameterManager newParameters;
|
||||
newParameters.LoadDocument(configFile.string().c_str());
|
||||
auto baseAppGroup = App::GetApplication().GetUserParameter().GetGroup("BaseApp");
|
||||
newParameters.GetGroup("BaseApp")->copyTo(baseAppGroup);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
PreferencePackManager::PreferencePackManager()
|
||||
{
|
||||
auto modPath = fs::path(App::Application::getUserAppDataDir()) / "Mod";
|
||||
auto savedPath = fs::path(App::Application::getUserAppDataDir()) / "SavedPreferencePacks";
|
||||
auto resourcePath = fs::path(App::Application::getResourceDir()) / "Gui" / "PreferencePacks";
|
||||
_preferencePackPaths.push_back(resourcePath);
|
||||
_preferencePackPaths.push_back(modPath);
|
||||
_preferencePackPaths.push_back(savedPath);
|
||||
rescan();
|
||||
|
||||
// Housekeeping:
|
||||
DeleteOldBackups();
|
||||
}
|
||||
|
||||
void PreferencePackManager::rescan()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(_mutex);
|
||||
for (const auto& path : _preferencePackPaths) {
|
||||
if (fs::exists(path) && fs::is_directory(path)) {
|
||||
FindPreferencePacksInPackage(path);
|
||||
for (const auto& mod : fs::directory_iterator(path)) {
|
||||
if (fs::is_directory(mod)) {
|
||||
FindPreferencePacksInPackage(mod);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Gui::PreferencePackManager::FindPreferencePacksInPackage(const fs::path& mod)
|
||||
{
|
||||
auto packageMetadataFile = mod / "package.xml";
|
||||
if (fs::exists(packageMetadataFile) && fs::is_regular_file(packageMetadataFile)) {
|
||||
try {
|
||||
App::Metadata metadata(packageMetadataFile);
|
||||
auto content = metadata.content();
|
||||
for (const auto& item : content) {
|
||||
if (item.first == "preferencepack") {
|
||||
PreferencePack newPreferencePack(mod / item.second.name(), item.second);
|
||||
_preferencePacks.insert(std::make_pair(newPreferencePack.name(), newPreferencePack));
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (...) {
|
||||
// Failed to read the metadata, or to create the preferencePack based on it...
|
||||
Base::Console().Error(("Failed to read " + packageMetadataFile.string()).c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<std::string> PreferencePackManager::preferencePackNames(PreferencePack::Type type) const
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(_mutex);
|
||||
std::vector<std::string> names;
|
||||
for (const auto& preferencePack : _preferencePacks)
|
||||
if (preferencePack.second.type() == type)
|
||||
names.push_back(preferencePack.first);
|
||||
return names;
|
||||
}
|
||||
|
||||
bool PreferencePackManager::apply(const std::string& preferencePackName) const
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(_mutex);
|
||||
if (auto preferencePack = _preferencePacks.find(preferencePackName); preferencePack != _preferencePacks.end()) {
|
||||
BackupCurrentConfig();
|
||||
return preferencePack->second.apply();
|
||||
}
|
||||
else {
|
||||
throw std::runtime_error("No such Preference Pack: " + preferencePackName);
|
||||
}
|
||||
}
|
||||
|
||||
void copyTemplateParameters(Base::Reference<ParameterGrp> templateGroup, const std::string& path, Base::Reference<ParameterGrp> outputGroup)
|
||||
{
|
||||
auto userParameterHandle = App::GetApplication().GetParameterGroupByPath(path.c_str());
|
||||
|
||||
auto boolMap = templateGroup->GetBoolMap();
|
||||
for (const auto& kv : boolMap) {
|
||||
auto currentValue = userParameterHandle->GetBool(kv.first.c_str(), kv.second);
|
||||
outputGroup->SetBool(kv.first.c_str(), currentValue);
|
||||
}
|
||||
|
||||
auto intMap = templateGroup->GetIntMap();
|
||||
for (const auto& kv : intMap) {
|
||||
auto currentValue = userParameterHandle->GetInt(kv.first.c_str(), kv.second);
|
||||
outputGroup->SetInt(kv.first.c_str(), currentValue);
|
||||
}
|
||||
|
||||
auto uintMap = templateGroup->GetUnsignedMap();
|
||||
for (const auto& kv : uintMap) {
|
||||
auto currentValue = userParameterHandle->GetUnsigned(kv.first.c_str(), kv.second);
|
||||
outputGroup->SetUnsigned(kv.first.c_str(), currentValue);
|
||||
}
|
||||
|
||||
auto floatMap = templateGroup->GetFloatMap();
|
||||
for (const auto& kv : floatMap) {
|
||||
auto currentValue = userParameterHandle->GetFloat(kv.first.c_str(), kv.second);
|
||||
outputGroup->SetFloat(kv.first.c_str(), currentValue);
|
||||
}
|
||||
|
||||
auto asciiMap = templateGroup->GetASCIIMap();
|
||||
for (const auto& kv : asciiMap) {
|
||||
auto currentValue = userParameterHandle->GetASCII(kv.first.c_str(), kv.second.c_str());
|
||||
outputGroup->SetASCII(kv.first.c_str(), currentValue.c_str());
|
||||
}
|
||||
|
||||
// Recurse...
|
||||
auto templateSubgroups = templateGroup->GetGroups();
|
||||
for (auto& templateSubgroup : templateSubgroups) {
|
||||
std::string sgName = templateSubgroup->GetGroupName();
|
||||
auto outputSubgroupHandle = outputGroup->GetGroup(sgName.c_str());
|
||||
copyTemplateParameters(templateSubgroup, path + "/" + sgName, outputSubgroupHandle);
|
||||
}
|
||||
}
|
||||
|
||||
void copyTemplateParameters(/*const*/ ParameterManager& templateParameterManager, ParameterManager& outputParameterManager)
|
||||
{
|
||||
auto groups = templateParameterManager.GetGroups();
|
||||
for (auto& group : groups) {
|
||||
std::string name = group->GetGroupName();
|
||||
auto groupHandle = outputParameterManager.GetGroup(name.c_str());
|
||||
copyTemplateParameters(group, "User parameter:" + name, groupHandle);
|
||||
}
|
||||
}
|
||||
|
||||
void PreferencePackManager::save(const std::string& name, const std::vector<TemplateFile>& templates)
|
||||
{
|
||||
if (templates.empty())
|
||||
return;
|
||||
|
||||
std::lock_guard<std::mutex> lock(_mutex);
|
||||
auto savedPreferencePacksDirectory = fs::path(App::Application::getUserAppDataDir()) / "SavedPreferencePacks";
|
||||
fs::path preferencePackDirectory(savedPreferencePacksDirectory / name);
|
||||
if (fs::exists(preferencePackDirectory) && !fs::is_directory(preferencePackDirectory))
|
||||
throw std::runtime_error("Cannot create " + savedPreferencePacksDirectory.string() + ": file with that name exists already");
|
||||
|
||||
if (!fs::exists(preferencePackDirectory))
|
||||
fs::create_directories(preferencePackDirectory);
|
||||
|
||||
// Create or update the saved user preferencePacks package.xml metadata file
|
||||
std::unique_ptr<App::Metadata> metadata;
|
||||
if (fs::exists(savedPreferencePacksDirectory / "package.xml")) {
|
||||
metadata = std::make_unique<App::Metadata>(savedPreferencePacksDirectory / "package.xml");
|
||||
}
|
||||
else {
|
||||
// Create and set all of the required metadata to make it easier for PreferencePack authors to copy this
|
||||
// file into their preferencePack distributions.
|
||||
metadata = std::make_unique<App::Metadata>();
|
||||
metadata->setName("User-Saved PreferencePacks");
|
||||
metadata->setDescription("Generated automatically -- edits may be lost when saving new preferencePacks");
|
||||
metadata->setVersion(1);
|
||||
metadata->addMaintainer(App::Meta::Contact("No Maintainer", "email@freecadweb.org"));
|
||||
metadata->addLicense(App::Meta::License("(Unspecified)", "(Unspecified)"));
|
||||
metadata->addUrl(App::Meta::Url("https://github.com/FreeCAD/FreeCAD", App::Meta::UrlType::repository));
|
||||
}
|
||||
App::Metadata newPreferencePackMetadata;
|
||||
newPreferencePackMetadata.setName(name);
|
||||
newPreferencePackMetadata.setVersion(1);
|
||||
|
||||
auto templateType = templates.front().type;
|
||||
for (const auto& t : templates) {
|
||||
if (t.type != templateType) {
|
||||
templateType = PreferencePack::Type::Combination;
|
||||
break;
|
||||
}
|
||||
}
|
||||
std::string typeString;
|
||||
switch (templateType) {
|
||||
case PreferencePack::Type::Appearance: typeString = "appearance"; break;
|
||||
case PreferencePack::Type::Behavior: typeString = "behavior"; break;
|
||||
case PreferencePack::Type::Combination: typeString = "combination"; break;
|
||||
}
|
||||
newPreferencePackMetadata.addGenericMetadata("type", App::Meta::GenericMetadata(typeString));
|
||||
|
||||
metadata->addContentItem("preferencepack", newPreferencePackMetadata);
|
||||
metadata->write(savedPreferencePacksDirectory / "package.xml");
|
||||
|
||||
// Create the config file
|
||||
ParameterManager outputParameterManager;
|
||||
outputParameterManager.CreateDocument();
|
||||
for (const auto& t : templates) {
|
||||
ParameterManager templateParameterManager;
|
||||
templateParameterManager.LoadDocument(t.path.string().c_str());
|
||||
copyTemplateParameters(templateParameterManager, outputParameterManager);
|
||||
}
|
||||
auto cfgFilename = savedPreferencePacksDirectory / name / (name + ".cfg");
|
||||
outputParameterManager.SaveDocument(cfgFilename.string().c_str());
|
||||
}
|
||||
|
||||
// Needed until we support only C++20 and above and can use std::string's built-in ends_with()
|
||||
bool fc_ends_with(std::string_view str, std::string_view suffix)
|
||||
{
|
||||
return str.size() >= suffix.size() && str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0;
|
||||
}
|
||||
|
||||
std::vector<fs::path> scanForTemplateFolders(const std::string& groupName, const fs::path& entry)
|
||||
{
|
||||
// From this location, find the folder(s) called "PreferencePackTemplates"
|
||||
std::vector<fs::path> templateFolders;
|
||||
if (fs::exists(entry)) {
|
||||
if (fs::is_directory(entry)) {
|
||||
if (entry.filename() == "PreferencePackTemplates" ||
|
||||
entry.filename() == "preference_pack_templates") {
|
||||
templateFolders.push_back(entry);
|
||||
}
|
||||
else {
|
||||
std::string subgroupName = groupName + "/" + entry.filename().string();
|
||||
for (const auto& subentry : fs::directory_iterator(entry)) {
|
||||
auto contents = scanForTemplateFolders(subgroupName, subentry);
|
||||
std::copy(contents.begin(), contents.end(), std::back_inserter(templateFolders));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return templateFolders;
|
||||
}
|
||||
|
||||
std::vector<PreferencePackManager::TemplateFile> scanForTemplateFiles(const std::string& groupName, const fs::path& entry)
|
||||
{
|
||||
auto templateFolders = scanForTemplateFolders(groupName, entry);
|
||||
|
||||
std::vector<PreferencePackManager::TemplateFile> templateFiles;
|
||||
for (const auto& dir : templateFolders) {
|
||||
auto templateDirs = std::vector<std::pair<fs::path, PreferencePack::Type>>({
|
||||
std::make_pair(dir / "Appearance", PreferencePack::Type::Appearance),
|
||||
std::make_pair(dir / "appearance", PreferencePack::Type::Appearance),
|
||||
std::make_pair(dir / "Behavior", PreferencePack::Type::Behavior),
|
||||
std::make_pair(dir / "behavior", PreferencePack::Type::Behavior),
|
||||
std::make_pair(dir / "Behaviour", PreferencePack::Type::Behavior),
|
||||
std::make_pair(dir / "behaviour", PreferencePack::Type::Behavior) });
|
||||
for (const auto& templateDir : templateDirs) {
|
||||
if (!fs::exists(templateDir.first) || !fs::is_directory(templateDir.first))
|
||||
continue;
|
||||
for (const auto& entry : fs::directory_iterator(templateDir.first)) {
|
||||
if (entry.path().extension() == ".cfg") {
|
||||
auto name = entry.path().filename().stem().string();
|
||||
std::replace(name.begin(), name.end(), '_', ' ');
|
||||
// Make sure we don't insert the same thing twice...
|
||||
if (std::find_if(templateFiles.begin(), templateFiles.end(), [groupName, name](const auto &rhs)->bool {
|
||||
return groupName == rhs.group && name == rhs.name;
|
||||
} ) != templateFiles.end())
|
||||
continue;
|
||||
templateFiles.push_back({ groupName, name, entry, templateDir.second });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return templateFiles;
|
||||
}
|
||||
|
||||
std::vector<PreferencePackManager::TemplateFile> PreferencePackManager::templateFiles(bool rescan)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(_mutex);
|
||||
if (!_templateFiles.empty() && !rescan)
|
||||
return _templateFiles;
|
||||
|
||||
// Locate all of the template files available on this system
|
||||
// Template files end in ".cfg" -- They are located in:
|
||||
// * $INSTALL_DIR/data/Gui/PreferencePackTemplates/(Appearance|Behavior)/*
|
||||
// * $DATA_DIR/Mod/**/PreferencePackTemplates/(Appearance|Behavior)/*
|
||||
// (alternate spellings are provided for packages using CamelCase and snake_case, and both major English dialects)
|
||||
|
||||
auto resourcePath = fs::path(App::Application::getResourceDir()) / "Gui";
|
||||
auto modPath = fs::path(App::Application::getUserAppDataDir()) / "Mod";
|
||||
|
||||
std::string group = "Built-In";
|
||||
if (fs::exists(resourcePath) && fs::is_directory(resourcePath)) {
|
||||
const auto localFiles = scanForTemplateFiles(group, resourcePath);
|
||||
std::copy(localFiles.begin(), localFiles.end(), std::back_inserter(_templateFiles));
|
||||
}
|
||||
|
||||
if (fs::exists(modPath) && fs::is_directory(modPath)) {
|
||||
for (const auto& mod : fs::directory_iterator(modPath)) {
|
||||
group = mod.path().filename().string();
|
||||
const auto localFiles = scanForTemplateFiles(group, mod);
|
||||
std::copy(localFiles.begin(), localFiles.end(), std::back_inserter(_templateFiles));
|
||||
}
|
||||
}
|
||||
|
||||
return _templateFiles;
|
||||
}
|
||||
|
||||
void Gui::PreferencePackManager::BackupCurrentConfig() const
|
||||
{
|
||||
auto backupDirectory = fs::path(App::Application::getUserAppDataDir()) / "SavedPreferencePacks" / "Backups";
|
||||
fs::create_directories(backupDirectory);
|
||||
|
||||
// Create a timestamped filename:
|
||||
auto time = std::time(nullptr);
|
||||
std::ostringstream timestampStream;
|
||||
timestampStream << "user." << time << ".cfg";
|
||||
auto filename = backupDirectory / timestampStream.str();
|
||||
|
||||
// Save the current config:
|
||||
App::GetApplication().GetUserParameter().SaveDocument(filename.string().c_str());
|
||||
}
|
||||
|
||||
void Gui::PreferencePackManager::DeleteOldBackups() const
|
||||
{
|
||||
constexpr auto oneWeek = 60.0 * 60.0 * 24.0 * 7.0;
|
||||
const auto now = std::time(nullptr);
|
||||
auto backupDirectory = fs::path(App::Application::getUserAppDataDir()) / "SavedPreferencePacks" / "Backups";
|
||||
if (fs::exists(backupDirectory) && fs::is_directory(backupDirectory)) {
|
||||
for (const auto& backup : fs::directory_iterator(backupDirectory)) {
|
||||
if (std::difftime(now, fs::last_write_time(backup)) > oneWeek) {
|
||||
try {
|
||||
fs::remove(backup);
|
||||
}
|
||||
catch (...) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
190
src/Gui/PreferencePackManager.h
Normal file
190
src/Gui/PreferencePackManager.h
Normal file
@@ -0,0 +1,190 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2021 Chris Hennes <chennes@pioneerlibrarysystem.org> *
|
||||
* *
|
||||
* This file is part of the FreeCAD CAx development system. *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU Library General Public *
|
||||
* License as published by the Free Software Foundation; either *
|
||||
* version 2 of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This library 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 Library General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Library General Public *
|
||||
* License along with this library; see the file COPYING.LIB. If not, *
|
||||
* write to the Free Software Foundation, Inc., 59 Temple Place, *
|
||||
* Suite 330, Boston, MA 02111-1307, USA *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef BASE_THEMEMANAGER_H
|
||||
#define BASE_THEMEMANAGER_H
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <mutex>
|
||||
|
||||
#include "App/Metadata.h"
|
||||
|
||||
namespace Gui {
|
||||
|
||||
/**
|
||||
* \class PreferencePack A collection of user preferences stored in files on disk
|
||||
*/
|
||||
class PreferencePack {
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Construct a preferencePack from a directory
|
||||
*
|
||||
* \param path A path to a mod directory that contains a preferencePack
|
||||
* \param metadata The metadata from the package.xml file describing this preferencePack
|
||||
*/
|
||||
PreferencePack(const boost::filesystem::path& path, const App::Metadata& metadata);
|
||||
|
||||
~PreferencePack() = default;
|
||||
|
||||
/**
|
||||
* Get the name of the PreferencePack
|
||||
*/
|
||||
std::string name() const;
|
||||
|
||||
/**
|
||||
* Apply the PreferencePack over the top of the current preferences set
|
||||
* \returns True if the preferencePack was applied, or false if not
|
||||
*/
|
||||
bool apply() const;
|
||||
|
||||
enum class Type {
|
||||
Appearance,
|
||||
Behavior,
|
||||
Combination
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the type of PreferencePack (appearance, behavior, or a combination of the two)
|
||||
*/
|
||||
Type type() const;
|
||||
|
||||
private:
|
||||
|
||||
void applyConfigChanges() const;
|
||||
|
||||
boost::filesystem::path _path;
|
||||
App::Metadata _metadata;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* \class PreferencePackManager handles storable and loadable collections of user preferences
|
||||
*
|
||||
* This class provides some additional utility functions for allowing users to save their current
|
||||
* preferences as a PreferencePack based on a set of template files provided either in the main
|
||||
* FreeCAD distribution, or inside various installed mods.
|
||||
*/
|
||||
class PreferencePackManager {
|
||||
public:
|
||||
PreferencePackManager();
|
||||
~PreferencePackManager() = default;
|
||||
|
||||
/**
|
||||
* Rescan the preferencePack directory and update the available PreferencePacks
|
||||
*/
|
||||
void rescan();
|
||||
|
||||
/**
|
||||
* Get an alphabetical list of names of all installed PreferencePacks of a given type
|
||||
*/
|
||||
std::vector<std::string> preferencePackNames(PreferencePack::Type type) const;
|
||||
|
||||
/**
|
||||
* Apply the named preferencePack
|
||||
* \return True if the preferencePack was applied, or false if it was not
|
||||
*/
|
||||
bool apply(const std::string& preferencePackName) const;
|
||||
|
||||
/**
|
||||
* \struct TemplateFile A file containing a set of preferences that can be saved into
|
||||
* a PreferencePack
|
||||
*
|
||||
* PreferencePacks can contain any parameters at all, but inside FreeCAD there is no
|
||||
* centralized list of all of these parameters, and at any given time the user.cfg file
|
||||
* usually does not store a value for all possible parameters. Instead, it simply allows
|
||||
* calling code to use whatever default values that code sets. This is all completely
|
||||
* hidden from the users: FreeCAD behaves as though those values exist in the config file.
|
||||
*
|
||||
* When a user saves their current configuration as a pack, they likely expect that saved
|
||||
* configuration to include those default values, so that if they later apply their saved
|
||||
* configuration those defaults are restored. To enable this a set of template files
|
||||
* listing default values for various types of parameters can be used. Each file is
|
||||
* presented to the user as a checkable box when saving a new preferences pack, and the
|
||||
* intention is that these files will list out the various user-facing parameters that
|
||||
* someone might want to save into a preferences pack.
|
||||
*
|
||||
* These files are themselves valid user.cfg files, that if loaded and applied will result
|
||||
* in the default values of their contained variables being set. For this to work, these
|
||||
* files should be kept up-to-date with the default values set in the code. They are not
|
||||
* required to contain an exhaustive listing of all possible parameters: in most cases it
|
||||
* is enough that they list the variables that a user would expect for a given name. For
|
||||
* example, "Sketcher Colors.cfg" should list out all of the default colors used in
|
||||
* Sketcher that a user can set in Preferences, but it is not necessary that it contain any
|
||||
* color that is only used internally, and it should not include things like fonts, or
|
||||
* behavior information.
|
||||
*
|
||||
* Template files are always located in a directory hierarchy that differentiates between
|
||||
* templates that only affect appearance, and those that affect behavior.
|
||||
*
|
||||
* The base FreeCAD installation includes default templates in:
|
||||
* $INSTALL_DIR/data/Gui/PreferencePackTemplates/(Appearance|Behavior)/
|
||||
*
|
||||
* External add-ons are also searched for any directory called PreferencePackTemplates or
|
||||
* preference_pack_templates -- either of which is expected to contain appearance and/or
|
||||
* behavior subdirectories. In this way external add-ons can allow a user to easily save
|
||||
* their preferences to a PreferencePack, or even to add additional templates representing
|
||||
* sets of core FreeCAD preferences.
|
||||
*/
|
||||
struct TemplateFile {
|
||||
std::string group; // Generally the Add-On/Mod/Package name
|
||||
std::string name;
|
||||
boost::filesystem::path path;
|
||||
PreferencePack::Type type;
|
||||
};
|
||||
|
||||
/**
|
||||
* Save current settings as a (possibly new) preferencePack
|
||||
*
|
||||
* If the named preferencePack does not exist, this creates it on disk. If it does exist, this overwrites the original.
|
||||
*/
|
||||
void save(const std::string& name, const std::vector<TemplateFile>& templates);
|
||||
|
||||
|
||||
std::vector<TemplateFile> templateFiles(bool rescan = false);
|
||||
|
||||
private:
|
||||
|
||||
void FindPreferencePacksInPackage(const boost::filesystem::path& mod);
|
||||
|
||||
void BackupCurrentConfig() const;
|
||||
|
||||
void DeleteOldBackups() const;
|
||||
|
||||
std::vector<boost::filesystem::path> _preferencePackPaths;
|
||||
std::vector<TemplateFile> _templateFiles;
|
||||
std::map<std::string, PreferencePack> _preferencePacks;
|
||||
mutable std::mutex _mutex;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
Q_DECLARE_METATYPE(Gui::PreferencePackManager::TemplateFile) // So it can be used with QVariant
|
||||
|
||||
|
||||
#endif
|
||||
21
src/Gui/PreferencePackTemplates/Appearance/Arch_Colors.cfg
Normal file
21
src/Gui/PreferencePackTemplates/Appearance/Arch_Colors.cfg
Normal file
@@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
|
||||
<FCParameters>
|
||||
<FCParamGroup Name="Root">
|
||||
<FCParamGroup Name="BaseApp">
|
||||
<FCParamGroup Name="Preferences">
|
||||
<FCParamGroup Name="Mod">
|
||||
<FCParamGroup Name="Arch">
|
||||
<FCUInt Name="WallColor" Value="3604403967"/>
|
||||
<FCUInt Name="StructureColor" Value="2527705855"/>
|
||||
<FCUInt Name="RebarColor" Value="3111475967"/>
|
||||
<FCUInt Name="WindowColor" Value="556614399"/>
|
||||
<FCUInt Name="WindowGlassColor" Value="1572326399"/>
|
||||
<FCUInt Name="PanelColor" Value="3416289279"/>
|
||||
<FCUInt Name="ColorHelpers" Value="674321151"/>
|
||||
<FCUInt Name="defaultSpaceColor" Value="4280090879"/>
|
||||
</FCParamGroup>
|
||||
</FCParamGroup>
|
||||
</FCParamGroup>
|
||||
</FCParamGroup>
|
||||
</FCParamGroup>
|
||||
</FCParameters>
|
||||
26
src/Gui/PreferencePackTemplates/Appearance/CMakeLists.txt
Normal file
26
src/Gui/PreferencePackTemplates/Appearance/CMakeLists.txt
Normal file
@@ -0,0 +1,26 @@
|
||||
|
||||
SET(PreferencePackTemplates_Files
|
||||
Arch_Colors.cfg
|
||||
Console_Colors.cfg
|
||||
Draft_Colors.cfg
|
||||
Editor_Colors.cfg
|
||||
Path_Colors.cfg
|
||||
Sketcher_Colors.cfg
|
||||
Start_Colors.cfg
|
||||
TechDraw_Colors.cfg
|
||||
Window_Colors.cfg
|
||||
)
|
||||
|
||||
ADD_CUSTOM_TARGET(PreferencePackTemplates_data ALL
|
||||
SOURCES ${PreferencePackTemplates_Files}
|
||||
)
|
||||
|
||||
fc_copy_sources(PreferencePackTemplates_data "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_DATADIR}/Gui/PreferencePackTemplates/Appearance"
|
||||
${PreferencePackTemplates_Files})
|
||||
|
||||
INSTALL(
|
||||
FILES
|
||||
${PreferencePackTemplates_Files}
|
||||
DESTINATION
|
||||
${CMAKE_INSTALL_DATADIR}/Gui/PreferencePackTemplates/Appearance
|
||||
)
|
||||
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
|
||||
<FCParameters>
|
||||
<FCParamGroup Name="Root">
|
||||
<FCParamGroup Name="BaseApp">
|
||||
<FCParamGroup Name="Preferences">
|
||||
<FCParamGroup Name="OutputWindow">
|
||||
<FCUInt Name="colorText" Value="4294967295"/>
|
||||
<FCUInt Name="colorLogging" Value="3117350911"/>
|
||||
<FCUInt Name="colorWarning" Value="4290999551"/>
|
||||
<FCUInt Name="colorError" Value="4287006463"/>
|
||||
</FCParamGroup>
|
||||
</FCParamGroup>
|
||||
</FCParamGroup>
|
||||
</FCParamGroup>
|
||||
</FCParameters>
|
||||
17
src/Gui/PreferencePackTemplates/Appearance/Draft_Colors.cfg
Normal file
17
src/Gui/PreferencePackTemplates/Appearance/Draft_Colors.cfg
Normal file
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
|
||||
<FCParameters>
|
||||
<FCParamGroup Name="Root">
|
||||
<FCParamGroup Name="BaseApp">
|
||||
<FCParamGroup Name="Preferences">
|
||||
<FCParamGroup Name="Mod">
|
||||
<FCParamGroup Name="Draft">
|
||||
<FCUInt Name="constructioncolor" Value="746455039"/>
|
||||
<FCInt Name="gridTransparency" Value="0"/>
|
||||
<FCUInt Name="gridColor" Value="842157055"/>
|
||||
<FCUInt Name="snapcolor" Value="4294967295"/>
|
||||
</FCParamGroup>
|
||||
</FCParamGroup>
|
||||
</FCParamGroup>
|
||||
</FCParamGroup>
|
||||
</FCParamGroup>
|
||||
</FCParameters>
|
||||
26
src/Gui/PreferencePackTemplates/Appearance/Editor_Colors.cfg
Normal file
26
src/Gui/PreferencePackTemplates/Appearance/Editor_Colors.cfg
Normal file
@@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
|
||||
<FCParameters>
|
||||
<FCParamGroup Name="Root">
|
||||
<FCParamGroup Name="BaseApp">
|
||||
<FCParamGroup Name="Preferences">
|
||||
<FCParamGroup Name="Editor">
|
||||
<FCUInt Name="Text" Value="4294967040"/>
|
||||
<FCUInt Name="Bookmark" Value="15921664"/>
|
||||
<FCUInt Name="Breakpoint" Value="3992977408"/>
|
||||
<FCUInt Name="Keyword" Value="195493632"/>
|
||||
<FCUInt Name="Comment" Value="14483456"/>
|
||||
<FCUInt Name="Block comment" Value="2526452224"/>
|
||||
<FCUInt Name="Number" Value="1625816832"/>
|
||||
<FCUInt Name="String" Value="4283782400"/>
|
||||
<FCUInt Name="Character" Value="4281611264"/>
|
||||
<FCUInt Name="Class name" Value="4003397632"/>
|
||||
<FCUInt Name="Define name" Value="3784704000"/>
|
||||
<FCUInt Name="Operator" Value="3553875968"/>
|
||||
<FCUInt Name="Python output" Value="3705447680"/>
|
||||
<FCUInt Name="Python error" Value="4287203584"/>
|
||||
<FCUInt Name="Current line highlight" Value="774778368"/>
|
||||
</FCParamGroup>
|
||||
</FCParamGroup>
|
||||
</FCParamGroup>
|
||||
</FCParamGroup>
|
||||
</FCParameters>
|
||||
21
src/Gui/PreferencePackTemplates/Appearance/Path_Colors.cfg
Normal file
21
src/Gui/PreferencePackTemplates/Appearance/Path_Colors.cfg
Normal file
@@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
|
||||
<FCParameters>
|
||||
<FCParamGroup Name="Root">
|
||||
<FCParamGroup Name="BaseApp">
|
||||
<FCParamGroup Name="Preferences">
|
||||
<FCParamGroup Name="Mod">
|
||||
<FCParamGroup Name="Path">
|
||||
<FCUInt Name="DefaultNormalPathColor" Value="11141375"/>
|
||||
<FCUInt Name="DefaultRapidPathColor" Value="2852126975"/>
|
||||
<FCUInt Name="DefaultPathMarkerColor" Value="1442775295"/>
|
||||
<FCUInt Name="DefaultExtentsColor" Value="3823363071"/>
|
||||
<FCUInt Name="DefaultProbePathColor" Value="4294903295"/>
|
||||
<FCUInt Name="DefaultHighlightPathColor" Value="4286382335"/>
|
||||
<FCUInt Name="DefaultBBoxSelectionColor" Value="3372220415"/>
|
||||
<FCUInt Name="DefaultBBoxNormalColor" Value="4294967295"/>
|
||||
</FCParamGroup>
|
||||
</FCParamGroup>
|
||||
</FCParamGroup>
|
||||
</FCParamGroup>
|
||||
</FCParamGroup>
|
||||
</FCParameters>
|
||||
@@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
|
||||
<FCParameters>
|
||||
<FCParamGroup Name="Root">
|
||||
<FCParamGroup Name="BaseApp">
|
||||
<FCParamGroup Name="Preferences">
|
||||
<FCParamGroup Name="View">
|
||||
<FCUInt Name="SketchEdgeColor" Value="4294967295"/>
|
||||
<FCUInt Name="SketchVertexColor" Value="4294967295"/>
|
||||
<FCUInt Name="EditedEdgeColor" Value="4294967295"/>
|
||||
<FCUInt Name="EditedVertexColor" Value="4280680703"/>
|
||||
<FCUInt Name="ConstructionColor" Value="56575"/>
|
||||
<FCUInt Name="ExternalColor" Value="3425924095"/>
|
||||
<FCUInt Name="InvalidSketchColor" Value="4285333759"/>
|
||||
<FCUInt Name="FullyConstrainedColor" Value="16711935"/>
|
||||
<FCUInt Name="InternalAlignedGeoColor" Value="2998042623"/>
|
||||
<FCUInt Name="FullyConstraintElementColor" Value="2161156351"/>
|
||||
<FCUInt Name="FullyConstraintConstructionElementColor" Value="2410282495"/>
|
||||
<FCUInt Name="FullyConstraintInternalAlignmentColor" Value="3739142399"/>
|
||||
<FCUInt Name="FullyConstraintConstructionPointColor" Value="4287987967"/>
|
||||
<FCUInt Name="ConstrainedIcoColor" Value="4280680703"/>
|
||||
<FCUInt Name="NonDrivingConstrDimColor" Value="2555903"/>
|
||||
<FCUInt Name="ConstrainedDimColor" Value="4280680703"/>
|
||||
<FCUInt Name="ExprBasedConstrDimColor" Value="4286523135"/>
|
||||
<FCUInt Name="DeactivatedConstrDimColor" Value="2139062271"/>
|
||||
<FCUInt Name="CursorTextColor" Value="65535"/>
|
||||
<FCUInt Name="CursorCrosshairColor" Value="4294967295"/>
|
||||
<FCUInt Name="CreateLineColor" Value="3435973887"/>
|
||||
</FCParamGroup>
|
||||
</FCParamGroup>
|
||||
</FCParamGroup>
|
||||
</FCParamGroup>
|
||||
</FCParameters>
|
||||
20
src/Gui/PreferencePackTemplates/Appearance/Start_Colors.cfg
Normal file
20
src/Gui/PreferencePackTemplates/Appearance/Start_Colors.cfg
Normal file
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
|
||||
<FCParameters>
|
||||
<FCParamGroup Name="Root">
|
||||
<FCParamGroup Name="BaseApp">
|
||||
<FCParamGroup Name="Preferences">
|
||||
<FCParamGroup Name="Mod">
|
||||
<FCParamGroup Name="Start">
|
||||
<FCUInt Name="BackgroundColor1" Value="1414812927"/>
|
||||
<FCUInt Name="BackgroundTextColor" Value="4294967295"/>
|
||||
<FCUInt Name="PageColor" Value="690563583"/>
|
||||
<FCUInt Name="PageTextColor" Value="3789677055"/>
|
||||
<FCUInt Name="BoxColor" Value="1296911871"/>
|
||||
<FCUInt Name="LinkColor" Value="3099197439"/>
|
||||
<FCUInt Name="BackgroundColor2" Value="2141107711"/>
|
||||
</FCParamGroup>
|
||||
</FCParamGroup>
|
||||
</FCParamGroup>
|
||||
</FCParamGroup>
|
||||
</FCParamGroup>
|
||||
</FCParameters>
|
||||
@@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
|
||||
<FCParameters>
|
||||
<FCParamGroup Name="Root">
|
||||
<FCParamGroup Name="BaseApp">
|
||||
<FCParamGroup Name="Preferences">
|
||||
<FCParamGroup Name="Mod">
|
||||
<FCParamGroup Name="TechDraw">
|
||||
<FCParamGroup Name="Decorations">
|
||||
<FCUInt Name="SectionColor" Value="255"/>
|
||||
<FCUInt Name="CenterColor" Value="255"/>
|
||||
<FCUInt Name="VertexColor" Value="255"/>
|
||||
<FCUInt Name="HighlightColor" Value="255"/>
|
||||
</FCParamGroup>
|
||||
<FCParamGroup Name="Colors">
|
||||
<FCUInt Name="Hatch" Value="255"/>
|
||||
<FCUInt Name="Background" Value="3553874943"/>
|
||||
<FCUInt Name="PreSelectColor" Value="4294902015"/>
|
||||
<FCUInt Name="HiddenColor" Value="255"/>
|
||||
<FCUInt Name="SelectColor" Value="16711935"/>
|
||||
<FCUInt Name="NormalColor" Value="255"/>
|
||||
<FCUInt Name="CutSurfaceColor" Value="3553874943"/>
|
||||
<FCUInt Name="GeomHatch" Value="255"/>
|
||||
<FCUInt Name="FaceColor" Value="4294967295"/>
|
||||
<FCBool Name="ClearFace" Value="1"/>
|
||||
</FCParamGroup>
|
||||
</FCParamGroup>
|
||||
</FCParamGroup>
|
||||
</FCParamGroup>
|
||||
</FCParamGroup>
|
||||
</FCParamGroup>
|
||||
</FCParameters>
|
||||
31
src/Gui/PreferencePackTemplates/Appearance/Window_Colors.cfg
Normal file
31
src/Gui/PreferencePackTemplates/Appearance/Window_Colors.cfg
Normal file
@@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
|
||||
<FCParameters>
|
||||
<FCParamGroup Name="Root">
|
||||
<FCParamGroup Name="BaseApp">
|
||||
<FCParamGroup Name="Preferences">
|
||||
<FCParamGroup Name="View">
|
||||
<FCUInt Name="BacklightColor" Value="3755991039"/>
|
||||
<FCUInt Name="BackgroundColor" Value="336897023"/>
|
||||
<FCUInt Name="BackgroundColor2" Value="1701144063"/>
|
||||
<FCUInt Name="BackgroundColor3" Value="757935615"/>
|
||||
<FCUInt Name="BackgroundColor4" Value="1869583359"/>
|
||||
<FCBool Name="Simple" Value="0"/>
|
||||
<FCBool Name="Gradient" Value="1"/>
|
||||
<FCBool Name="UseBackgroundColorMid" Value="0"/>
|
||||
<FCUInt Name="HighlightColor" Value="4294907903"/>
|
||||
<FCUInt Name="SelectionColor" Value="704588287"/>
|
||||
<FCUInt Name="DefaultShapeColor" Value="3435973887"/>
|
||||
<FCBool Name="RandomColor" Value="0"/>
|
||||
</FCParamGroup>
|
||||
<FCParamGroup Name="TreeView">
|
||||
<FCUInt Name="TreeEditColor" Value="4042260735"/>
|
||||
<FCUInt Name="TreeActiveColor" Value="3537037823"/>
|
||||
</FCParamGroup>
|
||||
<FCParamGroup Name="MainWindow">
|
||||
<FCBool Name="TiledBackground" Value="0"/>
|
||||
<FCText Name="StyleSheet"></FCText>
|
||||
</FCParamGroup>
|
||||
</FCParamGroup>
|
||||
</FCParamGroup>
|
||||
</FCParamGroup>
|
||||
</FCParameters>
|
||||
18
src/Gui/PreferencePackTemplates/Behavior/CMakeLists.txt
Normal file
18
src/Gui/PreferencePackTemplates/Behavior/CMakeLists.txt
Normal file
@@ -0,0 +1,18 @@
|
||||
|
||||
SET(PreferencePackBehaviorTemplates_Files
|
||||
Main_window_layout.cfg
|
||||
)
|
||||
|
||||
ADD_CUSTOM_TARGET(PreferencePackBehaviorTemplates_data ALL
|
||||
SOURCES ${PreferencePackBehaviorTemplates_Files}
|
||||
)
|
||||
|
||||
fc_copy_sources(PreferencePackBehaviorTemplates_data "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_DATADIR}/Gui/PreferencePackTemplates/Behavior"
|
||||
${PreferencePackBehaviorTemplates_Files})
|
||||
|
||||
INSTALL(
|
||||
FILES
|
||||
${PreferencePackBehaviorTemplates_Files}
|
||||
DESTINATION
|
||||
${CMAKE_INSTALL_DATADIR}/Gui/PreferencePackTemplates/Behavior
|
||||
)
|
||||
@@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
|
||||
<FCParameters>
|
||||
<FCParamGroup Name="Root">
|
||||
<FCParamGroup Name="BaseApp">
|
||||
<FCParamGroup Name="MainWindow">
|
||||
<FCParamGroup Name="DockWindows">
|
||||
<FCBool Name="Std_SelectionView" Value="0"/>
|
||||
<FCBool Name="Std_ComboView" Value="1"/>
|
||||
<FCBool Name="Std_ReportView" Value="0"/>
|
||||
<FCBool Name="Std_PythonView" Value="0"/>
|
||||
<FCBool Name="Std_TreeView" Value="0"/>
|
||||
<FCBool Name="Std_PropertyView" Value="0"/>
|
||||
<FCBool Name="Std_DAGView" Value="0"/>
|
||||
</FCParamGroup>
|
||||
<FCParamGroup Name="Toolbars">
|
||||
<FCBool Name="File" Value="1"/>
|
||||
<FCBool Name="Workbench" Value="1"/>
|
||||
<FCBool Name="Macro" Value="1"/>
|
||||
<FCBool Name="View" Value="1"/>
|
||||
<FCBool Name="Structure" Value="1"/>
|
||||
<FCBool Name="Navigation" Value="1"/>
|
||||
</FCParamGroup>
|
||||
</FCParamGroup>
|
||||
</FCParamGroup>
|
||||
</FCParamGroup>
|
||||
</FCParameters>
|
||||
2
src/Gui/PreferencePackTemplates/CMakeLists.txt
Normal file
2
src/Gui/PreferencePackTemplates/CMakeLists.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
add_subdirectory(Appearance)
|
||||
add_subdirectory(Behavior)
|
||||
28
src/Gui/PreferencePacks/CMakeLists.txt
Normal file
28
src/Gui/PreferencePacks/CMakeLists.txt
Normal file
@@ -0,0 +1,28 @@
|
||||
|
||||
SET(PreferencePacks_Files
|
||||
"package.xml"
|
||||
)
|
||||
|
||||
SET(PreferencePacks_Directories
|
||||
"FreeCAD Classic Colors"
|
||||
)
|
||||
|
||||
ADD_CUSTOM_TARGET(PreferencePacks_data ALL
|
||||
SOURCES ${PreferencePacks_Files} ${PreferencePacks_Directories}
|
||||
)
|
||||
|
||||
FILE(COPY ${PreferencePacks_Files} ${PreferencePacks_Directories} DESTINATION "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_DATADIR}/Gui/PreferencePacks")
|
||||
|
||||
INSTALL(
|
||||
FILES
|
||||
${PreferencePacks_Files}
|
||||
DESTINATION
|
||||
${CMAKE_INSTALL_DATADIR}/Gui/PreferencePacks
|
||||
)
|
||||
|
||||
INSTALL(
|
||||
DIRECTORY
|
||||
${PreferencePacks_Directories}
|
||||
DESTINATION
|
||||
${CMAKE_INSTALL_DATADIR}/Gui/PreferencePacks
|
||||
)
|
||||
@@ -0,0 +1,134 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
|
||||
<FCParameters>
|
||||
|
||||
<FCParamGroup Name="Root">
|
||||
<FCParamGroup Name="BaseApp">
|
||||
<FCParamGroup Name="Preferences">
|
||||
<FCParamGroup Name="Mod">
|
||||
<FCParamGroup Name="Arch">
|
||||
<FCUInt Name="WallColor" Value="3604403967"/>
|
||||
<FCUInt Name="StructureColor" Value="2527705855"/>
|
||||
<FCUInt Name="RebarColor" Value="3111475967"/>
|
||||
<FCUInt Name="WindowColor" Value="556614399"/>
|
||||
<FCUInt Name="WindowGlassColor" Value="1572326399"/>
|
||||
<FCUInt Name="PanelColor" Value="3416289279"/>
|
||||
<FCUInt Name="ColorHelpers" Value="674321151"/>
|
||||
<FCUInt Name="defaultSpaceColor" Value="4280090879"/>
|
||||
</FCParamGroup>
|
||||
<FCParamGroup Name="Draft">
|
||||
<FCInt Name="gridTransparency" Value="0"/>
|
||||
<FCUInt Name="constructioncolor" Value="746455039"/>
|
||||
<FCUInt Name="gridColor" Value="842157055"/>
|
||||
<FCUInt Name="snapcolor" Value="4294967295"/>
|
||||
</FCParamGroup>
|
||||
<FCParamGroup Name="Path">
|
||||
<FCUInt Name="DefaultNormalPathColor" Value="11141375"/>
|
||||
<FCUInt Name="DefaultRapidPathColor" Value="2852126975"/>
|
||||
<FCUInt Name="DefaultPathMarkerColor" Value="1442775295"/>
|
||||
<FCUInt Name="DefaultExtentsColor" Value="3823363071"/>
|
||||
<FCUInt Name="DefaultProbePathColor" Value="4294903295"/>
|
||||
<FCUInt Name="DefaultHighlightPathColor" Value="4286382335"/>
|
||||
<FCUInt Name="DefaultBBoxSelectionColor" Value="3372220415"/>
|
||||
<FCUInt Name="DefaultBBoxNormalColor" Value="4294967295"/>
|
||||
</FCParamGroup>
|
||||
<FCParamGroup Name="Start">
|
||||
<FCUInt Name="BackgroundColor1" Value="1331197183"/>
|
||||
<FCUInt Name="BackgroundTextColor" Value="4294703103"/>
|
||||
<FCUInt Name="PageColor" Value="4294967295"/>
|
||||
<FCUInt Name="PageTextColor" Value="255"/>
|
||||
<FCUInt Name="BoxColor" Value="3722305023"/>
|
||||
<FCUInt Name="LinkColor" Value="65535"/>
|
||||
<FCUInt Name="BackgroundColor2" Value="2141107711"/>
|
||||
</FCParamGroup>
|
||||
<FCParamGroup Name="TechDraw">
|
||||
<FCParamGroup Name="Decorations">
|
||||
<FCUInt Name="SectionColor" Value="255"/>
|
||||
<FCUInt Name="CenterColor" Value="255"/>
|
||||
<FCUInt Name="VertexColor" Value="255"/>
|
||||
<FCUInt Name="HighlightColor" Value="255"/>
|
||||
</FCParamGroup>
|
||||
<FCParamGroup Name="Colors">
|
||||
<FCBool Name="ClearFace" Value="1"/>
|
||||
<FCUInt Name="Hatch" Value="255"/>
|
||||
<FCUInt Name="Background" Value="3553874943"/>
|
||||
<FCUInt Name="PreSelectColor" Value="4294902015"/>
|
||||
<FCUInt Name="HiddenColor" Value="255"/>
|
||||
<FCUInt Name="SelectColor" Value="16711935"/>
|
||||
<FCUInt Name="NormalColor" Value="255"/>
|
||||
<FCUInt Name="CutSurfaceColor" Value="3553874943"/>
|
||||
<FCUInt Name="GeomHatch" Value="255"/>
|
||||
<FCUInt Name="FaceColor" Value="4294967295"/>
|
||||
</FCParamGroup>
|
||||
</FCParamGroup>
|
||||
</FCParamGroup>
|
||||
<FCParamGroup Name="OutputWindow">
|
||||
<FCUInt Name="colorText" Value="255"/>
|
||||
<FCUInt Name="colorLogging" Value="65535"/>
|
||||
<FCUInt Name="colorWarning" Value="4289331455"/>
|
||||
<FCUInt Name="colorError" Value="4278190335"/>
|
||||
</FCParamGroup>
|
||||
<FCParamGroup Name="Editor">
|
||||
<FCUInt Name="Text" Value="0"/>
|
||||
<FCUInt Name="Bookmark" Value="16776960"/>
|
||||
<FCUInt Name="Breakpoint" Value="4278190080"/>
|
||||
<FCUInt Name="Keyword" Value="65280"/>
|
||||
<FCUInt Name="Comment" Value="11141120"/>
|
||||
<FCUInt Name="Block comment" Value="2694882304"/>
|
||||
<FCUInt Name="Number" Value="65280"/>
|
||||
<FCUInt Name="String" Value="4278190080"/>
|
||||
<FCUInt Name="Character" Value="4278190080"/>
|
||||
<FCUInt Name="Class name" Value="4289331200"/>
|
||||
<FCUInt Name="Define name" Value="4289331200"/>
|
||||
<FCUInt Name="Operator" Value="2694882304"/>
|
||||
<FCUInt Name="Python output" Value="2863300352"/>
|
||||
<FCUInt Name="Python error" Value="4278190080"/>
|
||||
<FCUInt Name="Current line highlight" Value="3772833792"/>
|
||||
</FCParamGroup>
|
||||
<FCParamGroup Name="View">
|
||||
<FCUInt Name="SketchEdgeColor" Value="4294967295"/>
|
||||
<FCUInt Name="SketchVertexColor" Value="4294967295"/>
|
||||
<FCUInt Name="EditedEdgeColor" Value="4294967295"/>
|
||||
<FCUInt Name="EditedVertexColor" Value="4280680703"/>
|
||||
<FCUInt Name="ConstructionColor" Value="56575"/>
|
||||
<FCUInt Name="ExternalColor" Value="3425924095"/>
|
||||
<FCUInt Name="InvalidSketchColor" Value="4285333759"/>
|
||||
<FCUInt Name="FullyConstrainedColor" Value="16711935"/>
|
||||
<FCUInt Name="InternalAlignedGeoColor" Value="2998042623"/>
|
||||
<FCUInt Name="FullyConstraintElementColor" Value="2161156351"/>
|
||||
<FCUInt Name="FullyConstraintConstructionElementColor" Value="2410282495"/>
|
||||
<FCUInt Name="FullyConstraintInternalAlignmentColor" Value="3739142399"/>
|
||||
<FCUInt Name="FullyConstraintConstructionPointColor" Value="4287987967"/>
|
||||
<FCUInt Name="ConstrainedIcoColor" Value="4280680703"/>
|
||||
<FCUInt Name="NonDrivingConstrDimColor" Value="2555903"/>
|
||||
<FCUInt Name="ConstrainedDimColor" Value="4280680703"/>
|
||||
<FCUInt Name="ExprBasedConstrDimColor" Value="4286523135"/>
|
||||
<FCUInt Name="DeactivatedConstrDimColor" Value="2139062271"/>
|
||||
<FCUInt Name="CursorTextColor" Value="65535"/>
|
||||
<FCUInt Name="CursorCrosshairColor" Value="4294967295"/>
|
||||
<FCUInt Name="CreateLineColor" Value="3435973887"/>
|
||||
<FCBool Name="Simple" Value="0"/>
|
||||
<FCBool Name="Gradient" Value="1"/>
|
||||
<FCBool Name="UseBackgroundColorMid" Value="0"/>
|
||||
<FCBool Name="RandomColor" Value="0"/>
|
||||
<FCUInt Name="BacklightColor" Value="4294967295"/>
|
||||
<FCUInt Name="BackgroundColor" Value="336897023"/>
|
||||
<FCUInt Name="BackgroundColor2" Value="859006463"/>
|
||||
<FCUInt Name="BackgroundColor3" Value="2543299327"/>
|
||||
<FCUInt Name="BackgroundColor4" Value="1869583359"/>
|
||||
<FCUInt Name="HighlightColor" Value="3789624575"/>
|
||||
<FCUInt Name="SelectionColor" Value="481107199"/>
|
||||
<FCUInt Name="DefaultShapeColor" Value="3435973887"/>
|
||||
</FCParamGroup>
|
||||
<FCParamGroup Name="TreeView">
|
||||
<FCUInt Name="TreeEditColor" Value="4294902015"/>
|
||||
<FCUInt Name="TreeActiveColor" Value="3873898495"/>
|
||||
</FCParamGroup>
|
||||
<FCParamGroup Name="MainWindow">
|
||||
<FCBool Name="TiledBackground" Value="0"/>
|
||||
<FCText Name="StyleSheet"></FCText>
|
||||
</FCParamGroup>
|
||||
</FCParamGroup>
|
||||
</FCParamGroup>
|
||||
</FCParamGroup>
|
||||
|
||||
</FCParameters>
|
||||
19
src/Gui/PreferencePacks/package.xml
Normal file
19
src/Gui/PreferencePacks/package.xml
Normal file
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
|
||||
<package format="1">
|
||||
<name>Built-In Preference Packs</name>
|
||||
<description>Preference Packs included with the FreeCAD distribution</description>
|
||||
<version>1.0.0</version>
|
||||
<maintainer email="email@freecadweb.org">No Maintainer</maintainer>
|
||||
<license file="../../LICENSE">LGPL2</license>
|
||||
<url type="repository">https://github.com/FreeCAD/FreeCAD</url>
|
||||
|
||||
<content>
|
||||
<preferencepack>
|
||||
<name>FreeCAD Classic Colors</name>
|
||||
<description>FreeCAD default colors for core app and included Mods.</description>
|
||||
<version>1.0.0</version>
|
||||
<type>appearance</type>
|
||||
</preferencepack>
|
||||
</content>
|
||||
|
||||
</package>
|
||||
Reference in New Issue
Block a user