Gui: Add importing CFG to PrefPack dialog
This commit is contained in:
@@ -103,22 +103,22 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="Gui::PrefCheckBox" name="SubstituteDecimal">
|
||||
<property name="toolTip">
|
||||
<string>If enabled, numerical keypad decimal separator will be substituted with locale separator</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Substitute decimal separator (needs restart)</string>
|
||||
</property>
|
||||
<property name="prefEntry" stdset="0">
|
||||
<cstring>SubstituteDecimalSeparator</cstring>
|
||||
</property>
|
||||
<property name="prefPath" stdset="0">
|
||||
<cstring>General</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
<widget class="Gui::PrefCheckBox" name="SubstituteDecimal">
|
||||
<property name="toolTip">
|
||||
<string>If enabled, numerical keypad decimal separator will be substituted with locale separator</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Substitute decimal separator (needs restart)</string>
|
||||
</property>
|
||||
<property name="prefEntry" stdset="0">
|
||||
<cstring>SubstituteDecimalSeparator</cstring>
|
||||
</property>
|
||||
<property name="prefPath" stdset="0">
|
||||
<cstring>General</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
@@ -170,24 +170,24 @@
|
||||
<attribute name="horizontalHeaderCascadingSectionResizes">
|
||||
<bool>true</bool>
|
||||
</attribute>
|
||||
<attribute name="horizontalHeaderDefaultSectionSize">
|
||||
<number>100</number>
|
||||
</attribute>
|
||||
<attribute name="horizontalHeaderMinimumSectionSize">
|
||||
<number>30</number>
|
||||
</attribute>
|
||||
<attribute name="horizontalHeaderDefaultSectionSize">
|
||||
<number>100</number>
|
||||
</attribute>
|
||||
<attribute name="horizontalHeaderStretchLastSection">
|
||||
<bool>true</bool>
|
||||
</attribute>
|
||||
<attribute name="verticalHeaderVisible">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
<attribute name="verticalHeaderDefaultSectionSize">
|
||||
<number>24</number>
|
||||
</attribute>
|
||||
<attribute name="verticalHeaderMinimumSectionSize">
|
||||
<number>16</number>
|
||||
</attribute>
|
||||
<attribute name="verticalHeaderDefaultSectionSize">
|
||||
<number>24</number>
|
||||
</attribute>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Name</string>
|
||||
@@ -232,6 +232,13 @@
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="ImportConfig">
|
||||
<property name="text">
|
||||
<string>Import config...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="SaveNewPreferencePack">
|
||||
<property name="text">
|
||||
@@ -556,7 +563,7 @@ after FreeCAD launches</string>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<item row="2" column="0">
|
||||
<widget class="Gui::PrefCheckBox" name="SplashScreen">
|
||||
<property name="toolTip">
|
||||
<string>A Splash screen is a small loading window that is shown
|
||||
@@ -577,7 +584,7 @@ display the splash screen</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
|
||||
@@ -24,7 +24,11 @@
|
||||
#include "PreCompiled.h"
|
||||
#ifndef _PreComp_
|
||||
# include <QApplication>
|
||||
# include <QFileDialog>
|
||||
# include <QLocale>
|
||||
# include <QMessageBox>
|
||||
# include <algorithm>
|
||||
# include <boost/filesystem.hpp>
|
||||
#endif
|
||||
|
||||
#include "DlgGeneralImp.h"
|
||||
@@ -39,8 +43,8 @@
|
||||
#include "PreferencePackManager.h"
|
||||
#include "Language/Translator.h"
|
||||
|
||||
|
||||
using namespace Gui::Dialog;
|
||||
namespace fs = boost::filesystem;
|
||||
|
||||
/* TRANSLATOR Gui::Dialog::DlgGeneralImp */
|
||||
|
||||
@@ -86,6 +90,8 @@ DlgGeneralImp::DlgGeneralImp( QWidget* parent )
|
||||
}
|
||||
|
||||
recreatePreferencePackMenu();
|
||||
|
||||
connect(ui->ImportConfig, &QPushButton::clicked, this, &DlgGeneralImp::onImportConfigClicked);
|
||||
connect(ui->SaveNewPreferencePack, &QPushButton::clicked, this, &DlgGeneralImp::saveAsNewPreferencePack);
|
||||
|
||||
ui->ManagePreferencePacks->setToolTip(tr("Manage preference packs"));
|
||||
@@ -448,6 +454,29 @@ void DlgGeneralImp::onManagePreferencePacksClicked()
|
||||
this->preferencePackManagementDialog->show();
|
||||
}
|
||||
|
||||
void DlgGeneralImp::onImportConfigClicked()
|
||||
{
|
||||
auto path = fs::path(QFileDialog::getOpenFileName(this,
|
||||
tr("Choose a FreeCAD config file to import"),
|
||||
QString(),
|
||||
QString::fromUtf8("*.cfg")).toStdString());
|
||||
if (!path.empty()) {
|
||||
// Create a name from the filename:
|
||||
auto packName = path.filename().stem().string();
|
||||
std::replace(packName.begin(), packName.end(), '_', ' ');
|
||||
auto existingPacks = Application::Instance->prefPackManager()->preferencePackNames();
|
||||
if (std::find(existingPacks.begin(), existingPacks.end(), packName)
|
||||
!= existingPacks.end()) {
|
||||
auto result = QMessageBox::question(
|
||||
this, tr("File exists"),
|
||||
tr("A preference pack with that name already exists. Overwrite?"));
|
||||
if (result == QMessageBox::No) return; // Maybe someday ask for a new name?
|
||||
}
|
||||
Application::Instance->prefPackManager()->importConfig(packName, path);
|
||||
recreatePreferencePackMenu();
|
||||
}
|
||||
}
|
||||
|
||||
void DlgGeneralImp::onLoadPreferencePackClicked(const std::string& packName)
|
||||
{
|
||||
if (Application::Instance->prefPackManager()->apply(packName)) {
|
||||
|
||||
@@ -59,6 +59,7 @@ protected Q_SLOTS:
|
||||
void recreatePreferencePackMenu();
|
||||
void newPreferencePackDialogAccepted();
|
||||
void onManagePreferencePacksClicked();
|
||||
void onImportConfigClicked();
|
||||
|
||||
private:
|
||||
void setRecentFileSize();
|
||||
|
||||
@@ -160,7 +160,72 @@ void PreferencePackManager::rescan()
|
||||
}
|
||||
}
|
||||
|
||||
void Gui::PreferencePackManager::FindPreferencePacksInPackage(const fs::path& mod)
|
||||
void Gui::PreferencePackManager::AddPackToMetadata(const std::string &packName) const
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(_mutex);
|
||||
auto savedPreferencePacksDirectory =
|
||||
fs::path(App::Application::getUserAppDataDir()) / "SavedPreferencePacks";
|
||||
fs::path preferencePackDirectory(savedPreferencePacksDirectory / packName);
|
||||
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 {
|
||||
metadata = std::make_unique<App::Metadata>();
|
||||
metadata->setName("User-Saved Preference Packs");
|
||||
std::stringstream str;
|
||||
str << "Generated automatically -- edits may be lost when saving new preference packs. To "
|
||||
<< "distribute one or more of these packs:\n"
|
||||
<< " 1) copy the entire SavedPreferencePacks directory to a convenient location,\n"
|
||||
<< " 2) rename the directory (usually to the name of the preference pack you are "
|
||||
<< "distributing),\n"
|
||||
<< " 3) delete any subfolders containing packs you don't want to distribute,\n"
|
||||
<< " 4) use git to initialize the directory as a git repository,\n"
|
||||
<< " 5) push it to a remote git host,\n"
|
||||
<< " 6) activate Developer Mode in the Addon Manager,\n"
|
||||
<< " 7) use Developer Tools in the Addon Manager to update the metadata file,\n"
|
||||
<< " 8) add, commit, and push the updated package.xml file,\n"
|
||||
<< " 9) add your remote host to the custom repositories list in the Addon Manager"
|
||||
<< " preferences,\n"
|
||||
<< " 10) use the Addon Manager to install your preference pack locally for testing.";
|
||||
metadata->setDescription(str.str());
|
||||
metadata->addLicense(App::Meta::License("All Rights Reserved", fs::path()));
|
||||
}
|
||||
for (const auto &item : metadata->content()) {
|
||||
if (item.first == "preferencepack") {
|
||||
if (item.second.name() == packName) {
|
||||
// A pack with this name exists already, bail out
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
App::Metadata newPreferencePackMetadata;
|
||||
newPreferencePackMetadata.setName(packName);
|
||||
|
||||
metadata->addContentItem("preferencepack", newPreferencePackMetadata);
|
||||
metadata->write(savedPreferencePacksDirectory / "package.xml");
|
||||
}
|
||||
|
||||
void Gui::PreferencePackManager::importConfig(const std::string& packName,
|
||||
const boost::filesystem::path& path)
|
||||
{
|
||||
AddPackToMetadata(packName);
|
||||
|
||||
auto savedPreferencePacksDirectory =
|
||||
fs::path(App::Application::getUserAppDataDir()) / "SavedPreferencePacks";
|
||||
auto cfgFilename = savedPreferencePacksDirectory / packName / (packName + ".cfg");
|
||||
fs::copy_file(path, cfgFilename, fs::copy_option::overwrite_if_exists);
|
||||
rescan();
|
||||
}
|
||||
|
||||
void Gui::PreferencePackManager::FindPreferencePacksInPackage(const fs::path &mod)
|
||||
{
|
||||
auto packageMetadataFile = mod / "package.xml";
|
||||
static const auto modDirectory = fs::path(App::Application::getUserAppDataDir()) / "Mod" / "SavedPreferencePacks";
|
||||
@@ -366,37 +431,7 @@ void PreferencePackManager::save(const std::string& name, const std::vector<Temp
|
||||
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(static_cast<App::Meta::Version>(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(static_cast<App::Meta::Version>(1));
|
||||
|
||||
metadata->addContentItem("preferencepack", newPreferencePackMetadata);
|
||||
metadata->write(savedPreferencePacksDirectory / "package.xml");
|
||||
AddPackToMetadata(name);
|
||||
|
||||
// Create the config file
|
||||
ParameterManager outputParameterManager;
|
||||
@@ -406,6 +441,8 @@ void PreferencePackManager::save(const std::string& name, const std::vector<Temp
|
||||
templateParameterManager.LoadDocument(t.path.string().c_str());
|
||||
copyTemplateParameters(templateParameterManager, outputParameterManager);
|
||||
}
|
||||
auto savedPreferencePacksDirectory =
|
||||
fs::path(App::Application::getUserAppDataDir()) / "SavedPreferencePacks";
|
||||
auto cfgFilename = savedPreferencePacksDirectory / name / (name + ".cfg");
|
||||
outputParameterManager.SaveDocument(cfgFilename.string().c_str());
|
||||
}
|
||||
|
||||
@@ -156,9 +156,6 @@ namespace Gui {
|
||||
* 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/
|
||||
*
|
||||
@@ -189,6 +186,11 @@ namespace Gui {
|
||||
*/
|
||||
std::vector<boost::filesystem::path> configBackups() const;
|
||||
|
||||
/**
|
||||
* Import an existing config file as a preference pack with a given name.
|
||||
*/
|
||||
void importConfig(const std::string &packName, const boost::filesystem::path &path);
|
||||
|
||||
private:
|
||||
|
||||
void FindPreferencePacksInPackage(const boost::filesystem::path& mod);
|
||||
@@ -197,6 +199,8 @@ namespace Gui {
|
||||
|
||||
void DeleteOldBackups() const;
|
||||
|
||||
void AddPackToMetadata(const std::string &packName) const;
|
||||
|
||||
std::vector<boost::filesystem::path> _preferencePackPaths;
|
||||
std::vector<TemplateFile> _templateFiles;
|
||||
std::map<std::string, PreferencePack> _preferencePacks;
|
||||
|
||||
Reference in New Issue
Block a user