Merge pull request #9117 from Ondsel-Development/wb_pref_fixes
Wb pref fixes
This commit is contained in:
@@ -800,36 +800,12 @@ void WorkbenchGroup::setWorkbenchData(int index, const QString& wb)
|
||||
|
||||
void WorkbenchGroup::refreshWorkbenchList()
|
||||
{
|
||||
QStringList items = Application::Instance->workbenches();
|
||||
QStringList enabled_wbs_list = DlgSettingsWorkbenchesImp::getEnabledWorkbenches();
|
||||
QStringList disabled_wbs_list = DlgSettingsWorkbenchesImp::getDisabledWorkbenches();
|
||||
QStringList enable_wbs;
|
||||
|
||||
// Go through the list of enabled workbenches and verify that they really exist because
|
||||
// it might be possible that a workbench has been removed after setting up the list of
|
||||
// enabled workbenches.
|
||||
for (const auto& it : enabled_wbs_list) {
|
||||
int index = items.indexOf(it);
|
||||
if (index >= 0) {
|
||||
enable_wbs << it;
|
||||
items.removeAt(index);
|
||||
}
|
||||
}
|
||||
|
||||
// Filter out the actively disabled workbenches
|
||||
for (const auto& it : disabled_wbs_list) {
|
||||
int index = items.indexOf(it);
|
||||
if (index >= 0) {
|
||||
items.removeAt(index);
|
||||
}
|
||||
}
|
||||
|
||||
// Now add the remaining workbenches of 'items'. They have been added to the application
|
||||
// after setting up the list of enabled workbenches.
|
||||
enable_wbs.append(items);
|
||||
// Resize the action group.
|
||||
QList<QAction*> workbenches = groupAction()->actions();
|
||||
int numActions = workbenches.size();
|
||||
int extend = enable_wbs.size() - numActions;
|
||||
int extend = enabled_wbs_list.size() - numActions;
|
||||
if (extend > 0) {
|
||||
for (int i=0; i<extend; i++) {
|
||||
QAction* action = groupAction()->addAction(QLatin1String(""));
|
||||
@@ -840,7 +816,7 @@ void WorkbenchGroup::refreshWorkbenchList()
|
||||
|
||||
// Show all enabled wb
|
||||
int index = 0;
|
||||
for (const auto& it : enable_wbs) {
|
||||
for (const auto& it : enabled_wbs_list) {
|
||||
setWorkbenchData(index++, it);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1377,8 +1377,6 @@ PyObject* Application::sShowPreferences(PyObject * /*self*/, PyObject *args)
|
||||
wc.restoreCursor();
|
||||
cDlg.exec();
|
||||
wc.setWaitCursor();
|
||||
cDlg.isRebootRequired(); //The user may have applied first, then clicked the cancel button so it's not in the if(cDlg.exec())
|
||||
wc.setWaitCursor();
|
||||
|
||||
Py_Return;
|
||||
}
|
||||
|
||||
@@ -385,7 +385,6 @@ void StdCmdDlgPreferences::activated(int iMsg)
|
||||
if (cDlg.exec()) {
|
||||
cDlg.activeGroupPage(groupName, index);
|
||||
}
|
||||
cDlg.isRebootRequired(); //The user may have applied first, then clicked the cancel button so it's not in the if(cDlg.exec())
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
||||
@@ -71,7 +71,7 @@ DlgPreferencesImp* DlgPreferencesImp::_activeDialog = nullptr;
|
||||
*/
|
||||
DlgPreferencesImp::DlgPreferencesImp(QWidget* parent, Qt::WindowFlags fl)
|
||||
: QDialog(parent, fl), ui(new Ui_DlgPreferences),
|
||||
invalidParameter(false), canEmbedScrollArea(true), rebootRequired(false)
|
||||
invalidParameter(false), canEmbedScrollArea(true), restartRequired(false)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
QFontMetrics fm(font());
|
||||
@@ -337,8 +337,16 @@ void DlgPreferencesImp::accept()
|
||||
{
|
||||
this->invalidParameter = false;
|
||||
applyChanges();
|
||||
if (!this->invalidParameter)
|
||||
if (!this->invalidParameter) {
|
||||
QDialog::accept();
|
||||
restartIfRequired();
|
||||
}
|
||||
}
|
||||
|
||||
void DlgPreferencesImp::reject()
|
||||
{
|
||||
QDialog::reject();
|
||||
restartIfRequired();
|
||||
}
|
||||
|
||||
void DlgPreferencesImp::onButtonBoxClicked(QAbstractButton* btn)
|
||||
@@ -464,7 +472,7 @@ void DlgPreferencesImp::applyChanges()
|
||||
auto page = qobject_cast<PreferencePage*>(tabWidget->widget(j));
|
||||
if (page) {
|
||||
page->saveSettings();
|
||||
rebootRequired = rebootRequired || page->isRebootRequired();
|
||||
restartRequired = restartRequired || page->isRestartRequired();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -477,9 +485,9 @@ void DlgPreferencesImp::applyChanges()
|
||||
}
|
||||
}
|
||||
|
||||
void DlgPreferencesImp::isRebootRequired()
|
||||
void DlgPreferencesImp::restartIfRequired()
|
||||
{
|
||||
if (rebootRequired) {
|
||||
if (restartRequired) {
|
||||
QMessageBox* restartBox = new QMessageBox();
|
||||
restartBox->setIcon(QMessageBox::Warning);
|
||||
restartBox->setWindowTitle(tr("Restart required"));
|
||||
@@ -498,6 +506,7 @@ void DlgPreferencesImp::isRebootRequired()
|
||||
QTimer::singleShot(1000, []()
|
||||
{
|
||||
QStringList args = QApplication::arguments();
|
||||
args.pop_front();
|
||||
if (getMainWindow()->close())
|
||||
QProcess::startDetached(QApplication::applicationFilePath(), args);
|
||||
});
|
||||
|
||||
@@ -124,10 +124,10 @@ public:
|
||||
~DlgPreferencesImp() override;
|
||||
|
||||
void accept() override;
|
||||
void reject() override;
|
||||
void reload();
|
||||
void activateGroupPage(const QString& group, int index);
|
||||
void activeGroupPage(QString& group, int& index) const;
|
||||
void isRebootRequired();
|
||||
|
||||
protected:
|
||||
void changeEvent(QEvent *e) override;
|
||||
@@ -150,6 +150,7 @@ private:
|
||||
void applyChanges();
|
||||
void restoreDefaults();
|
||||
QString longestGroupName() const;
|
||||
void restartIfRequired();
|
||||
//@}
|
||||
|
||||
private:
|
||||
@@ -163,7 +164,7 @@ private:
|
||||
std::unique_ptr<Ui_DlgPreferences> ui;
|
||||
bool invalidParameter;
|
||||
bool canEmbedScrollArea;
|
||||
bool rebootRequired;
|
||||
bool restartRequired;
|
||||
|
||||
static const int GroupNameRole; /**< A name for our Qt::UserRole, used when storing user data in a list item */
|
||||
|
||||
|
||||
@@ -253,7 +253,7 @@ DlgSettingsWorkbenchesImp::~DlgSettingsWorkbenchesImp()
|
||||
|
||||
void DlgSettingsWorkbenchesImp::saveSettings()
|
||||
{
|
||||
std::ostringstream enabledStr, disabledStr, autoloadStr;
|
||||
std::ostringstream orderedStr, disabledStr, autoloadStr;
|
||||
|
||||
auto addStrToOss = [](std::string wbName, std::ostringstream& oss) {
|
||||
if (!oss.str().empty())
|
||||
@@ -268,7 +268,7 @@ void DlgSettingsWorkbenchesImp::saveSettings()
|
||||
std::string wbName = wbItem->objectName().toStdString();
|
||||
|
||||
if (wbItem->isEnabled()) {
|
||||
addStrToOss(wbName, enabledStr);
|
||||
addStrToOss(wbName, orderedStr);
|
||||
}
|
||||
else {
|
||||
addStrToOss(wbName, disabledStr);
|
||||
@@ -279,14 +279,17 @@ void DlgSettingsWorkbenchesImp::saveSettings()
|
||||
}
|
||||
}
|
||||
|
||||
if (enabledStr.str().empty()) //make sure that we have at least one enabled workbench.
|
||||
enabledStr << "NoneWorkbench";
|
||||
if (orderedStr.str().empty()) //make sure that we have at least one enabled workbench. This should not be necessary because startup wb cannot be disabled.
|
||||
orderedStr << "NoneWorkbench";
|
||||
else {
|
||||
addStrToOss("NoneWorkbench", disabledStr); //Note, NoneWorkbench is not in the table so it's not added before.
|
||||
if (!disabledStr.str().empty())
|
||||
disabledStr << ",";
|
||||
disabledStr << "NoneWorkbench";
|
||||
}
|
||||
|
||||
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Workbenches");
|
||||
hGrp->SetASCII("Enabled", enabledStr.str().c_str());
|
||||
|
||||
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Workbenches");
|
||||
hGrp->SetASCII("Ordered", orderedStr.str().c_str());
|
||||
hGrp->SetASCII("Disabled", disabledStr.str().c_str());
|
||||
|
||||
App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/General")->
|
||||
@@ -342,26 +345,16 @@ void DlgSettingsWorkbenchesImp::buildWorkbenchList()
|
||||
{
|
||||
QSignalBlocker sigblk(ui->wbList);
|
||||
|
||||
QStringList workbenches = Application::Instance->workbenches();
|
||||
QStringList enabledWbs = getEnabledWorkbenches();
|
||||
QStringList disabledWbs = getDisabledWorkbenches();
|
||||
|
||||
//First we add the enabled wbs in their saved order.
|
||||
for (const auto& wbName : enabledWbs) {
|
||||
if (workbenches.contains(wbName)) {
|
||||
addWorkbench(wbName, true);
|
||||
}
|
||||
else {
|
||||
Base::Console().Warning("Ignoring unknown %s workbench found in user preferences.", wbName.toStdString().c_str());
|
||||
}
|
||||
addWorkbench(wbName, true);
|
||||
}
|
||||
//Second we add workbench in alphabetical order that are either Disabled, or !enabled && !disabled, ie newly added wb.
|
||||
for (const auto& wbName : workbenches) {
|
||||
if (disabledWbs.contains(wbName)) {
|
||||
addWorkbench(wbName, false);
|
||||
}
|
||||
else if (!enabledWbs.contains(wbName)) {
|
||||
Base::Console().Warning("Adding unknown %s workbench.", wbName.toStdString().c_str());
|
||||
//Second we add workbenches that are disabled in alphabetical order.
|
||||
for (const auto& wbName : disabledWbs) {
|
||||
if (wbName.toStdString() != "NoneWorkbench") {
|
||||
addWorkbench(wbName, false);
|
||||
}
|
||||
}
|
||||
@@ -369,9 +362,6 @@ void DlgSettingsWorkbenchesImp::buildWorkbenchList()
|
||||
|
||||
void DlgSettingsWorkbenchesImp::addWorkbench(const QString& wbName, bool enabled)
|
||||
{
|
||||
if (wbName.toStdString() == "NoneWorkbench")
|
||||
return; // Do not list the default empty Workbench
|
||||
|
||||
bool isStartupWb = wbName.toStdString() == _startupModule;
|
||||
bool autoLoad = std::find(_backgroundAutoloadedModules.begin(), _backgroundAutoloadedModules.end(),
|
||||
wbName.toStdString()) != _backgroundAutoloadedModules.end();
|
||||
@@ -383,47 +373,72 @@ void DlgSettingsWorkbenchesImp::addWorkbench(const QString& wbName, bool enabled
|
||||
ui->wbList->setItemWidget(wItem, widget);
|
||||
}
|
||||
|
||||
|
||||
QStringList DlgSettingsWorkbenchesImp::getEnabledWorkbenches()
|
||||
{
|
||||
QString enabled_wbs;
|
||||
QStringList disabled_wbs_list = getDisabledWorkbenches();
|
||||
QStringList enabled_wbs_list;
|
||||
QStringList wbs_ordered_list;
|
||||
QString wbs_ordered;
|
||||
ParameterGrp::handle hGrp;
|
||||
QString allWorkbenches = QString::fromLatin1("ALL");
|
||||
|
||||
hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Workbenches");
|
||||
enabled_wbs = QString::fromStdString(hGrp->GetASCII("Enabled", allWorkbenches.toStdString().c_str()).c_str());
|
||||
hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Workbenches");
|
||||
wbs_ordered = QString::fromStdString(hGrp->GetASCII("Ordered", ""));
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5,15,0)
|
||||
enabled_wbs_list = enabled_wbs.split(QLatin1String(","), Qt::SkipEmptyParts);
|
||||
wbs_ordered_list = wbs_ordered.split(QLatin1String(","), Qt::SkipEmptyParts);
|
||||
#else
|
||||
enabled_wbs_list = enabled_wbs.split(QLatin1String(","), QString::SkipEmptyParts);
|
||||
wbs_ordered_list = wbs_ordered.split(QLatin1String(","), QString::SkipEmptyParts);
|
||||
#endif
|
||||
|
||||
if (enabled_wbs_list.at(0) == allWorkbenches) {
|
||||
enabled_wbs_list.removeFirst();
|
||||
QStringList workbenches = Application::Instance->workbenches();
|
||||
for (QStringList::Iterator it = workbenches.begin(); it != workbenches.end(); ++it) {
|
||||
enabled_wbs_list.append(*it);
|
||||
QStringList workbenches = Application::Instance->workbenches();
|
||||
workbenches.sort();
|
||||
|
||||
//First we add the wb that are ordered.
|
||||
for(auto& wbName : wbs_ordered_list) {
|
||||
if (workbenches.contains(wbName) && !disabled_wbs_list.contains(wbName)) { //Some wb may have been removed
|
||||
enabled_wbs_list.append(wbName);
|
||||
}
|
||||
else {
|
||||
Base::Console().Log("Ignoring unknown %s workbench found in user preferences.\n", wbName.toStdString().c_str());
|
||||
}
|
||||
enabled_wbs_list.sort();
|
||||
}
|
||||
|
||||
//Then we add the wbs that are not ordered and not disabled in alphabetical order
|
||||
for(auto& wbName : workbenches) {
|
||||
if (!enabled_wbs_list.contains(wbName) && !disabled_wbs_list.contains(wbName))
|
||||
enabled_wbs_list.append(wbName);
|
||||
}
|
||||
|
||||
return enabled_wbs_list;
|
||||
}
|
||||
|
||||
QStringList DlgSettingsWorkbenchesImp::getDisabledWorkbenches()
|
||||
{
|
||||
QString disabled_wbs;
|
||||
QStringList unfiltered_disabled_wbs_list;
|
||||
QStringList disabled_wbs_list;
|
||||
ParameterGrp::handle hGrp;
|
||||
|
||||
hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Workbenches");
|
||||
disabled_wbs = QString::fromStdString(hGrp->GetASCII("Disabled", ""));
|
||||
hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Workbenches");
|
||||
disabled_wbs = QString::fromStdString(hGrp->GetASCII("Disabled", "NoneWorkbench,TestWorkbench"));
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5,15,0)
|
||||
disabled_wbs_list = disabled_wbs.split(QLatin1String(","), Qt::SkipEmptyParts);
|
||||
unfiltered_disabled_wbs_list = disabled_wbs.split(QLatin1String(","), Qt::SkipEmptyParts);
|
||||
#else
|
||||
disabled_wbs_list = disabled_wbs.split(QLatin1String(","), QString::SkipEmptyParts);
|
||||
unfiltered_disabled_wbs_list = disabled_wbs.split(QLatin1String(","), QString::SkipEmptyParts);
|
||||
#endif
|
||||
|
||||
QStringList workbenches = Application::Instance->workbenches();
|
||||
|
||||
for (auto& wbName : unfiltered_disabled_wbs_list) {
|
||||
if (workbenches.contains(wbName)) { //Some wb may have been removed
|
||||
disabled_wbs_list.append(wbName);
|
||||
}
|
||||
else {
|
||||
Base::Console().Log("Ignoring unknown %s workbench found in user preferences.\n", wbName.toStdString().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
disabled_wbs_list.sort();
|
||||
|
||||
return disabled_wbs_list;
|
||||
}
|
||||
|
||||
@@ -461,7 +476,7 @@ void DlgSettingsWorkbenchesImp::loadWorkbenchSelector()
|
||||
|
||||
void DlgSettingsWorkbenchesImp::wbToggled(const QString& wbName, bool enabled)
|
||||
{
|
||||
requireReboot();
|
||||
requireRestart();
|
||||
|
||||
setStartWorkbenchComboItems();
|
||||
|
||||
@@ -535,7 +550,7 @@ void DlgSettingsWorkbenchesImp::setStartWorkbenchComboItems()
|
||||
|
||||
void DlgSettingsWorkbenchesImp::wbItemMoved()
|
||||
{
|
||||
requireReboot();
|
||||
requireRestart();
|
||||
for (int i = 0; i < ui->wbList->count(); i++) {
|
||||
wbListItem* wbItem = dynamic_cast<wbListItem*>(ui->wbList->itemWidget(ui->wbList->item(i)));
|
||||
if (wbItem) {
|
||||
@@ -563,13 +578,13 @@ void DlgSettingsWorkbenchesImp::onStartWbChanged(int index)
|
||||
void DlgSettingsWorkbenchesImp::onWbSelectorChanged(int index)
|
||||
{
|
||||
Q_UNUSED(index);
|
||||
requireReboot();
|
||||
requireRestart();
|
||||
}
|
||||
|
||||
void DlgSettingsWorkbenchesImp::onWbByTabToggled(bool val)
|
||||
{
|
||||
Q_UNUSED(val);
|
||||
requireReboot();
|
||||
requireRestart();
|
||||
}
|
||||
|
||||
#include "moc_DlgSettingsWorkbenchesImp.cpp"
|
||||
|
||||
@@ -98,7 +98,7 @@ void PropertyPage::onReset()
|
||||
// ----------------------------------------------------------------
|
||||
|
||||
/** Construction */
|
||||
PreferencePage::PreferencePage(QWidget* parent) : QWidget(parent), rebootRequired(false)
|
||||
PreferencePage::PreferencePage(QWidget* parent) : QWidget(parent), restartRequired(false)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -107,14 +107,14 @@ void PreferencePage::changeEvent(QEvent* event)
|
||||
QWidget::changeEvent(event);
|
||||
}
|
||||
|
||||
bool PreferencePage::isRebootRequired()
|
||||
bool PreferencePage::isRestartRequired() const
|
||||
{
|
||||
return rebootRequired;
|
||||
return restartRequired;
|
||||
}
|
||||
|
||||
void PreferencePage::requireReboot()
|
||||
void PreferencePage::requireRestart()
|
||||
{
|
||||
rebootRequired = true;
|
||||
restartRequired = true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -73,8 +73,8 @@ public:
|
||||
explicit PreferencePage(QWidget* parent = nullptr);
|
||||
~PreferencePage() override = default;
|
||||
|
||||
bool isRebootRequired();
|
||||
void requireReboot();
|
||||
bool isRestartRequired() const;
|
||||
void requireRestart();
|
||||
|
||||
public Q_SLOTS:
|
||||
virtual void loadSettings()=0;
|
||||
@@ -84,7 +84,7 @@ protected:
|
||||
void changeEvent(QEvent* event) override = 0;
|
||||
|
||||
private:
|
||||
bool rebootRequired;
|
||||
bool restartRequired;
|
||||
};
|
||||
|
||||
/** Subclass that embeds a form from a UI file.
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
""" Defines the Addon class to encapsulate information about FreeCAD Addons """
|
||||
|
||||
import os
|
||||
import re
|
||||
from urllib.parse import urlparse
|
||||
from typing import Dict, Set, List, Optional
|
||||
from threading import Lock
|
||||
@@ -592,6 +593,9 @@ class Addon:
|
||||
"The existence of this file prevents FreeCAD from loading this Addon. To re-enable, delete the file."
|
||||
)
|
||||
|
||||
if self.contains_workbench():
|
||||
self.disable_workbench()
|
||||
|
||||
def enable(self):
|
||||
"""Re-enable loading this addon by deleting the stopfile"""
|
||||
|
||||
@@ -601,6 +605,113 @@ class Addon:
|
||||
except FileNotFoundError:
|
||||
pass
|
||||
|
||||
if self.contains_workbench():
|
||||
self.enable_workbench()
|
||||
|
||||
def enable_workbench(self):
|
||||
wbName = self.get_workbench_name()
|
||||
|
||||
# Remove from the list of disabled.
|
||||
self.remove_from_disabled_wbs(wbName)
|
||||
|
||||
def disable_workbench(self):
|
||||
pref = fci.ParamGet("User parameter:BaseApp/Preferences/Workbenches")
|
||||
wbName = self.get_workbench_name()
|
||||
|
||||
# Add the wb to the list of disabled if it was not already
|
||||
disabled_wbs = pref.GetString("Disabled", "NoneWorkbench,TestWorkbench")
|
||||
# print(f"start disabling {disabled_wbs}")
|
||||
disabled_wbs_list = disabled_wbs.split(",")
|
||||
if not (wbName in disabled_wbs_list):
|
||||
disabled_wbs += "," + wbName
|
||||
pref.SetString("Disabled", disabled_wbs)
|
||||
# print(f"done disabling : {disabled_wbs} \n")
|
||||
|
||||
def desinstall_workbench(self):
|
||||
pref = fci.ParamGet("User parameter:BaseApp/Preferences/Workbenches")
|
||||
wbName = self.get_workbench_name()
|
||||
|
||||
# Remove from the list of ordered.
|
||||
ordered_wbs = pref.GetString("Ordered", "")
|
||||
# print(f"start remove from ordering {ordered_wbs}")
|
||||
ordered_wbs_list = ordered_wbs.split(",")
|
||||
ordered_wbs = ""
|
||||
for wb in ordered_wbs_list:
|
||||
if wb != wbName:
|
||||
if ordered_wbs != "":
|
||||
ordered_wbs += ","
|
||||
ordered_wbs += wb
|
||||
pref.SetString("Ordered", ordered_wbs)
|
||||
# print(f"end remove from ordering {ordered_wbs}")
|
||||
|
||||
# Remove from the list of disabled.
|
||||
self.remove_from_disabled_wbs(wbName)
|
||||
|
||||
def remove_from_disabled_wbs(self, wbName: str):
|
||||
pref = fci.ParamGet("User parameter:BaseApp/Preferences/Workbenches")
|
||||
|
||||
disabled_wbs = pref.GetString("Disabled", "NoneWorkbench,TestWorkbench")
|
||||
# print(f"start enabling : {disabled_wbs}")
|
||||
disabled_wbs_list = disabled_wbs.split(",")
|
||||
disabled_wbs = ""
|
||||
for wb in disabled_wbs_list:
|
||||
if wb != wbName:
|
||||
if disabled_wbs != "":
|
||||
disabled_wbs += ","
|
||||
disabled_wbs += wb
|
||||
pref.SetString("Disabled", disabled_wbs)
|
||||
# print(f"Done enabling {disabled_wbs} \n")
|
||||
|
||||
def get_workbench_name(self) -> str:
|
||||
"""Find the name of the workbench class (ie the name under which it's
|
||||
registered in freecad core)'"""
|
||||
wb_name = ""
|
||||
|
||||
if self.repo_type == Addon.Kind.PACKAGE:
|
||||
for wb in self.metadata.content[
|
||||
"workbench"
|
||||
]: # we may have more than one wb.
|
||||
if wb_name != "":
|
||||
wb_name += ","
|
||||
wb_name += wb.classname
|
||||
if self.repo_type == Addon.Kind.WORKBENCH or wb_name == "":
|
||||
wb_name = self.try_find_wbname_in_files()
|
||||
if wb_name == "":
|
||||
wb_name = self.name
|
||||
return wb_name
|
||||
|
||||
def try_find_wbname_in_files(self) -> str:
|
||||
"""Attempt to locate a line with an addWorkbench command in the workbench's
|
||||
Python files. If it is directly instantiating a workbench, then we can use
|
||||
the line to determine classname for this workbench. If it uses a variable,
|
||||
or if the line doesn't exist at all, an empty string is returned."""
|
||||
mod_dir = os.path.join(self.mod_directory, self.name)
|
||||
|
||||
for root, _, files in os.walk(mod_dir):
|
||||
for f in files:
|
||||
current_file = os.path.join(root, f)
|
||||
if not os.path.isdir(current_file):
|
||||
filename, extension = os.path.splitext(current_file)
|
||||
if extension == ".py":
|
||||
wb_classname = self._find_classname_in_file(current_file)
|
||||
print(f"Current file: {current_file} ")
|
||||
if wb_classname:
|
||||
print(f"Found name {wb_classname} \n")
|
||||
return wb_classname
|
||||
return ""
|
||||
|
||||
@staticmethod
|
||||
def _find_classname_in_file(current_file) -> str:
|
||||
try:
|
||||
with open(current_file, "r", encoding="utf-8") as python_file:
|
||||
content = python_file.read()
|
||||
search_result = re.search(r"Gui.addWorkbench\s*\(\s*(\w+)\s*\(\s*\)\s*\)", content)
|
||||
if search_result:
|
||||
return search_result.group(1)
|
||||
except OSError:
|
||||
pass
|
||||
return ""
|
||||
|
||||
|
||||
# @dataclass(frozen)
|
||||
class MissingDependencies:
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
# * <https://www.gnu.org/licenses/>. *
|
||||
# * *
|
||||
# ***************************************************************************
|
||||
|
||||
import tempfile
|
||||
import unittest
|
||||
import os
|
||||
import sys
|
||||
@@ -32,14 +32,12 @@ from addonmanager_macro import Macro
|
||||
|
||||
|
||||
class TestAddon(unittest.TestCase):
|
||||
|
||||
MODULE = "test_addon" # file name without extension
|
||||
|
||||
def setUp(self):
|
||||
self.test_dir = os.path.join(os.path.dirname(__file__), "..", "data")
|
||||
|
||||
def test_display_name(self):
|
||||
|
||||
# Case 1: No display name set elsewhere: name == display_name
|
||||
addon = Addon(
|
||||
"FreeCAD",
|
||||
@@ -82,7 +80,6 @@ class TestAddon(unittest.TestCase):
|
||||
self.assertEqual(expected_tags, tags)
|
||||
|
||||
def test_contains_functions(self):
|
||||
|
||||
# Test package.xml combinations:
|
||||
|
||||
# Workbenches
|
||||
@@ -200,7 +197,6 @@ class TestAddon(unittest.TestCase):
|
||||
self.assertTrue(addon.__dict__, second_addon.__dict__)
|
||||
|
||||
def test_dependency_resolution(self):
|
||||
|
||||
addonA = Addon(
|
||||
"AddonA",
|
||||
"https://github.com/FreeCAD/FakeAddonA",
|
||||
@@ -302,3 +298,114 @@ class TestAddon(unittest.TestCase):
|
||||
"TagC" in addon.tags,
|
||||
"Found 'TagA' in tags, it should have been excluded by version requirement",
|
||||
)
|
||||
|
||||
def test_try_find_wbname_in_files_empty_dir(self):
|
||||
with tempfile.TemporaryDirectory() as mod_dir:
|
||||
# Arrange
|
||||
test_addon = Addon("test")
|
||||
test_addon.mod_directory = mod_dir
|
||||
os.mkdir(os.path.join(mod_dir, test_addon.name))
|
||||
|
||||
# Act
|
||||
wb_name = test_addon.try_find_wbname_in_files()
|
||||
|
||||
# Assert
|
||||
self.assertEqual(wb_name, "")
|
||||
|
||||
def test_try_find_wbname_in_files_non_python_ignored(self):
|
||||
with tempfile.TemporaryDirectory() as mod_dir:
|
||||
# Arrange
|
||||
test_addon = Addon("test")
|
||||
test_addon.mod_directory = mod_dir
|
||||
base_path = os.path.join(mod_dir, test_addon.name)
|
||||
os.mkdir(base_path)
|
||||
file_path = os.path.join(base_path, "test.txt")
|
||||
with open(file_path, "w", encoding="utf-8") as f:
|
||||
f.write("Gui.addWorkbench(TestWorkbench())")
|
||||
|
||||
# Act
|
||||
wb_name = test_addon.try_find_wbname_in_files()
|
||||
|
||||
# Assert
|
||||
self.assertEqual(wb_name, "")
|
||||
|
||||
def test_try_find_wbname_in_files_simple(self):
|
||||
with tempfile.TemporaryDirectory() as mod_dir:
|
||||
# Arrange
|
||||
test_addon = Addon("test")
|
||||
test_addon.mod_directory = mod_dir
|
||||
base_path = os.path.join(mod_dir, test_addon.name)
|
||||
os.mkdir(base_path)
|
||||
file_path = os.path.join(base_path, "test.py")
|
||||
with open(file_path, "w", encoding="utf-8") as f:
|
||||
f.write("Gui.addWorkbench(TestWorkbench())")
|
||||
|
||||
# Act
|
||||
wb_name = test_addon.try_find_wbname_in_files()
|
||||
|
||||
# Assert
|
||||
self.assertEqual(wb_name, "TestWorkbench")
|
||||
|
||||
def test_try_find_wbname_in_files_subdir(self):
|
||||
with tempfile.TemporaryDirectory() as mod_dir:
|
||||
# Arrange
|
||||
test_addon = Addon("test")
|
||||
test_addon.mod_directory = mod_dir
|
||||
base_path = os.path.join(mod_dir, test_addon.name)
|
||||
os.mkdir(base_path)
|
||||
subdir = os.path.join(base_path, "subdirectory")
|
||||
os.mkdir(subdir)
|
||||
file_path = os.path.join(subdir, "test.py")
|
||||
with open(file_path, "w", encoding="utf-8") as f:
|
||||
f.write("Gui.addWorkbench(TestWorkbench())")
|
||||
|
||||
# Act
|
||||
wb_name = test_addon.try_find_wbname_in_files()
|
||||
|
||||
# Assert
|
||||
self.assertEqual(wb_name, "TestWorkbench")
|
||||
|
||||
def test_try_find_wbname_in_files_variable_used(self):
|
||||
with tempfile.TemporaryDirectory() as mod_dir:
|
||||
# Arrange
|
||||
test_addon = Addon("test")
|
||||
test_addon.mod_directory = mod_dir
|
||||
base_path = os.path.join(mod_dir, test_addon.name)
|
||||
os.mkdir(base_path)
|
||||
file_path = os.path.join(base_path, "test.py")
|
||||
with open(file_path, "w", encoding="utf-8") as f:
|
||||
f.write("Gui.addWorkbench(wb)")
|
||||
|
||||
# Act
|
||||
wb_name = test_addon.try_find_wbname_in_files()
|
||||
|
||||
# Assert
|
||||
self.assertEqual(wb_name, "")
|
||||
|
||||
def test_try_find_wbname_in_files_variants(self):
|
||||
variants = [
|
||||
"Gui.addWorkbench(TestWorkbench())",
|
||||
"Gui.addWorkbench (TestWorkbench())",
|
||||
"Gui.addWorkbench( TestWorkbench() )",
|
||||
"Gui.addWorkbench(TestWorkbench( ))",
|
||||
"Gui.addWorkbench( TestWorkbench( ) )",
|
||||
"Gui.addWorkbench( TestWorkbench ( ) )",
|
||||
"Gui.addWorkbench ( TestWorkbench ( ) )",
|
||||
]
|
||||
for variant in variants:
|
||||
with self.subTest(variant=variant):
|
||||
with tempfile.TemporaryDirectory() as mod_dir:
|
||||
# Arrange
|
||||
test_addon = Addon("test")
|
||||
test_addon.mod_directory = mod_dir
|
||||
base_path = os.path.join(mod_dir, test_addon.name)
|
||||
os.mkdir(base_path)
|
||||
file_path = os.path.join(base_path, "test.py")
|
||||
with open(file_path, "w", encoding="utf-8") as f:
|
||||
f.write(variant)
|
||||
|
||||
# Act
|
||||
wb_name = test_addon.try_find_wbname_in_files()
|
||||
|
||||
# Assert
|
||||
self.assertEqual(wb_name, "TestWorkbench")
|
||||
|
||||
@@ -153,6 +153,11 @@ class AddonInstaller(QtCore.QObject):
|
||||
success = self._install_by_git()
|
||||
elif method_to_use == InstallationMethod.COPY:
|
||||
success = self._install_by_copy()
|
||||
if (
|
||||
hasattr(self.addon_to_install, "contains_workbench")
|
||||
and self.addon_to_install.contains_workbench()
|
||||
):
|
||||
self.addon_to_install.enable_workbench()
|
||||
except utils.ProcessInterrupted:
|
||||
pass
|
||||
if success:
|
||||
|
||||
@@ -113,6 +113,11 @@ class AddonUninstaller(QObject):
|
||||
self.run_uninstall_script(path_to_remove)
|
||||
self.remove_extra_files(path_to_remove)
|
||||
success = utils.rmdir(path_to_remove)
|
||||
if (
|
||||
hasattr(self.addon_to_remove, "contains_workbench")
|
||||
and self.addon_to_remove.contains_workbench()
|
||||
):
|
||||
self.addon_to_remove.desinstall_workbench()
|
||||
except OSError as e:
|
||||
error_message = str(e)
|
||||
else:
|
||||
|
||||
Reference in New Issue
Block a user