[GUI] Add autoload option to Workbench preferences page (#4957)
* Add autoload option to Workbench preferences page * Address bugs identified in the forum. * Add forward declaration of QCheckBox
This commit is contained in:
@@ -2173,6 +2173,21 @@ void Application::runApplication(void)
|
||||
SoDebugError::setHandlerCallback( messageHandlerCoin, 0 );
|
||||
#endif
|
||||
|
||||
// Now run the background autoload, for workbenches that should be loaded at startup, but not
|
||||
// displayed to the user immediately
|
||||
std::string autoloadCSV = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/General")->
|
||||
GetASCII("BackgroundAutoloadModules", "");
|
||||
|
||||
// Tokenize the comma-separated list and load the requested workbenches if they exist in this installation
|
||||
std::vector<std::string> backgroundAutoloadedModules;
|
||||
std::stringstream stream(autoloadCSV);
|
||||
std::string workbench;
|
||||
while (std::getline(stream, workbench, ','))
|
||||
if (wb.contains(QString::fromLatin1(workbench.c_str())))
|
||||
app.activateWorkbench(workbench.c_str());
|
||||
|
||||
// Reactivate the startup workbench
|
||||
app.activateWorkbench(start.c_str());
|
||||
|
||||
Instance->d->startingUp = false;
|
||||
|
||||
|
||||
@@ -14,53 +14,37 @@
|
||||
<string>Unloaded Workbenches</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<item row="2" column="0">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="loadButton">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Load the selected workbenches, adding their preference windows to the preferences dialog.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Load Selected</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QListWidget" name="workbenchList">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
<widget class="QTableWidget" name="workbenchTable">
|
||||
<property name="showGrid">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>150</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Available unloaded workbenches</p></body></html></string>
|
||||
</property>
|
||||
<property name="selectionMode">
|
||||
<enum>QAbstractItemView::ExtendedSelection</enum>
|
||||
<property name="sortingEnabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<attribute name="verticalHeaderVisible">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Workbench Name</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Autoload?</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Load Now</string>
|
||||
</property>
|
||||
</column>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
@@ -78,26 +62,13 @@
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string><html><head/><body><p>To preserve resources, FreeCAD does not load workbenches until they are used. Loading them may provide access to additional preferences related to their functionality.</p><p>The following workbenches are available in your installation, but are not yet loaded:</p></body></html></string>
|
||||
<string><html><head/><body><p>To preserve resources, FreeCAD does not load workbenches until they are used. Loading them may provide access to additional preferences related to their functionality.</p><p>The following workbenches are available in your installation:</p></body></html></string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<spacer>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>429</width>
|
||||
<height>37</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<layoutdefault spacing="6" margin="11"/>
|
||||
|
||||
@@ -32,6 +32,10 @@
|
||||
#include "WorkbenchManager.h"
|
||||
#include "Workbench.h"
|
||||
|
||||
#include <QCheckBox>
|
||||
|
||||
#include <sstream>
|
||||
|
||||
using namespace Gui::Dialog;
|
||||
|
||||
const uint DlgSettingsLazyLoadedImp::WorkbenchNameRole = Qt::UserRole;
|
||||
@@ -46,8 +50,6 @@ DlgSettingsLazyLoadedImp::DlgSettingsLazyLoadedImp( QWidget* parent )
|
||||
, ui(new Ui_DlgSettingsLazyLoaded)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
buildUnloadedWorkbenchList();
|
||||
connect(ui->loadButton, SIGNAL(clicked()), this, SLOT(onLoadClicked()));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -60,22 +62,45 @@ DlgSettingsLazyLoadedImp::~DlgSettingsLazyLoadedImp()
|
||||
|
||||
void DlgSettingsLazyLoadedImp::saveSettings()
|
||||
{
|
||||
|
||||
std::ostringstream csv;
|
||||
for (const auto& checkbox : _autoloadCheckboxes) {
|
||||
if (checkbox.second->isChecked()) {
|
||||
if (!csv.str().empty())
|
||||
csv << ",";
|
||||
csv << checkbox.first.toStdString();
|
||||
}
|
||||
}
|
||||
App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/General")->
|
||||
SetASCII("BackgroundAutoloadModules", csv.str().c_str());
|
||||
}
|
||||
|
||||
void DlgSettingsLazyLoadedImp::loadSettings()
|
||||
{
|
||||
|
||||
// There are two different "autoload" settings: the first, in FreeCAD since 2004,
|
||||
// controls the module the user sees first when starting FreeCAD, and defaults to the Start workbench
|
||||
std::string start = App::Application::Config()["StartWorkbench"];
|
||||
_startupModule = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/General")->
|
||||
GetASCII("AutoloadModule", start.c_str());
|
||||
|
||||
// The second autoload setting does a background autoload of any number of other modules
|
||||
std::string autoloadCSV = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/General")->
|
||||
GetASCII("BackgroundAutoloadModules", "");
|
||||
|
||||
// Tokenize the comma-separated list
|
||||
_backgroundAutoloadedModules.clear();
|
||||
std::stringstream stream(autoloadCSV);
|
||||
std::string workbench;
|
||||
while (std::getline(stream, workbench, ','))
|
||||
_backgroundAutoloadedModules.push_back(workbench);
|
||||
|
||||
|
||||
buildUnloadedWorkbenchList();
|
||||
}
|
||||
|
||||
void DlgSettingsLazyLoadedImp::onLoadClicked()
|
||||
void DlgSettingsLazyLoadedImp::onLoadClicked(const QString &wbName)
|
||||
{
|
||||
Workbench* originalActiveWB = WorkbenchManager::instance()->active();
|
||||
auto selection = ui->workbenchList->selectedItems();
|
||||
for (const auto& item : selection) {
|
||||
auto name = item->data(WorkbenchNameRole).toString().toStdString();
|
||||
Application::Instance->activateWorkbench(name.c_str());
|
||||
}
|
||||
Application::Instance->activateWorkbench(wbName.toStdString().c_str());
|
||||
Application::Instance->activateWorkbench(originalActiveWB->name().c_str());
|
||||
buildUnloadedWorkbenchList();
|
||||
}
|
||||
@@ -86,21 +111,87 @@ Build the list of unloaded workbenches.
|
||||
*/
|
||||
void DlgSettingsLazyLoadedImp::buildUnloadedWorkbenchList()
|
||||
{
|
||||
ui->workbenchList->clear();
|
||||
QStringList workbenches = Application::Instance->workbenches();
|
||||
workbenches.sort();
|
||||
|
||||
ui->workbenchTable->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft);
|
||||
ui->workbenchTable->setRowCount(0);
|
||||
_autoloadCheckboxes.clear(); // setRowCount(0) just invalidated all of these pointers
|
||||
ui->workbenchTable->setColumnCount(4);
|
||||
ui->workbenchTable->setSelectionMode(QAbstractItemView::SelectionMode::NoSelection);
|
||||
ui->workbenchTable->horizontalHeader()->setSectionResizeMode(0, QHeaderView::ResizeMode::ResizeToContents);
|
||||
ui->workbenchTable->horizontalHeader()->setSectionResizeMode(1, QHeaderView::ResizeMode::Stretch);
|
||||
ui->workbenchTable->horizontalHeader()->setSectionResizeMode(2, QHeaderView::ResizeMode::ResizeToContents);
|
||||
ui->workbenchTable->horizontalHeader()->setSectionResizeMode(3, QHeaderView::ResizeMode::ResizeToContents);
|
||||
QStringList columnHeaders;
|
||||
columnHeaders << QString() << tr("Workbench") << tr("Autoload") << QString();
|
||||
ui->workbenchTable->setHorizontalHeaderLabels(columnHeaders);
|
||||
|
||||
unsigned int rowNumber = 0;
|
||||
for (const auto& wbName : workbenches) {
|
||||
const auto& wb = WorkbenchManager::instance()->getWorkbench(wbName.toStdString());
|
||||
if (!wb) {
|
||||
auto wbIcon = Application::Instance->workbenchIcon(wbName);
|
||||
auto wbDisplayName = Application::Instance->workbenchMenuText(wbName);
|
||||
auto wbTooltip = Application::Instance->workbenchToolTip(wbName);
|
||||
QListWidgetItem *wbRow = new QListWidgetItem(wbIcon, wbDisplayName);
|
||||
wbRow->setData(WorkbenchNameRole, QVariant(wbName)); // Store the actual internal name for easier loading
|
||||
wbRow->setToolTip(wbTooltip);
|
||||
ui->workbenchList->addItem(wbRow); // Transfers ownership to the QListWidget
|
||||
if (wbName.toStdString() == "NoneWorkbench")
|
||||
continue; // Do not list the default empty Workbench
|
||||
|
||||
ui->workbenchTable->insertRow(rowNumber);
|
||||
auto wbTooltip = Application::Instance->workbenchToolTip(wbName);
|
||||
|
||||
// Column 1: Workbench Icon
|
||||
auto wbIcon = Application::Instance->workbenchIcon(wbName);
|
||||
auto iconLabel = new QLabel();
|
||||
iconLabel->setPixmap(wbIcon.scaled(QSize(20,20), Qt::AspectRatioMode::KeepAspectRatio, Qt::TransformationMode::SmoothTransformation));
|
||||
iconLabel->setToolTip(wbTooltip);
|
||||
iconLabel->setContentsMargins(5, 3, 3, 3); // Left, top, right, bottom
|
||||
ui->workbenchTable->setCellWidget(rowNumber, 0, iconLabel);
|
||||
|
||||
// Column 2: Workbench Display Name
|
||||
auto wbDisplayName = Application::Instance->workbenchMenuText(wbName);
|
||||
auto textLabel = new QLabel(wbDisplayName);
|
||||
textLabel->setToolTip(wbTooltip);
|
||||
ui->workbenchTable->setCellWidget(rowNumber, 1, textLabel);
|
||||
|
||||
// Column 3: Autoloaded checkbox
|
||||
//
|
||||
// To get the checkbox centered, we have to jump through some hoops...
|
||||
QWidget* checkWidget = new QWidget(this);
|
||||
auto autoloadCheckbox = new QCheckBox(this);
|
||||
autoloadCheckbox->setToolTip(tr("If checked") +
|
||||
QString::fromUtf8(", ") + wbDisplayName + QString::fromUtf8(" ") +
|
||||
tr("will be loaded automatically when FreeCAD starts up"));
|
||||
QHBoxLayout* checkLayout = new QHBoxLayout(checkWidget);
|
||||
checkLayout->addWidget(autoloadCheckbox);
|
||||
checkLayout->setAlignment(Qt::AlignCenter);
|
||||
checkLayout->setContentsMargins(0, 0, 0, 0);
|
||||
|
||||
// Figure out whether to check and/or disable this checkbox:
|
||||
if (wbName.toStdString() == _startupModule) {
|
||||
autoloadCheckbox->setChecked(true);
|
||||
autoloadCheckbox->setEnabled(false);
|
||||
autoloadCheckbox->setToolTip(tr("This is the current startup module, and must be autoloaded. See Preferences/General/Autoload to change."));
|
||||
}
|
||||
else if (std::find(_backgroundAutoloadedModules.begin(), _backgroundAutoloadedModules.end(),
|
||||
wbName.toStdString()) != _backgroundAutoloadedModules.end()) {
|
||||
autoloadCheckbox->setChecked(true);
|
||||
_autoloadCheckboxes.insert(std::make_pair(wbName, autoloadCheckbox));
|
||||
}
|
||||
else {
|
||||
_autoloadCheckboxes.insert(std::make_pair(wbName, autoloadCheckbox));
|
||||
}
|
||||
ui->workbenchTable->setCellWidget(rowNumber, 2, checkWidget);
|
||||
|
||||
// Column 4: Load button/loaded indicator
|
||||
if (WorkbenchManager::instance()->getWorkbench(wbName.toStdString())) {
|
||||
auto label = new QLabel(tr("Loaded"));
|
||||
label->setAlignment(Qt::AlignCenter);
|
||||
ui->workbenchTable->setCellWidget(rowNumber, 3, label);
|
||||
}
|
||||
else {
|
||||
auto button = new QPushButton(tr("Load now"));
|
||||
connect(button, &QPushButton::clicked, this, [this,wbName]() { onLoadClicked(wbName); });
|
||||
ui->workbenchTable->setCellWidget(rowNumber, 3, button);
|
||||
}
|
||||
|
||||
++rowNumber;
|
||||
}
|
||||
ui->workbenchList->sortItems();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -27,6 +27,8 @@
|
||||
#include "PropertyPage.h"
|
||||
#include <memory>
|
||||
|
||||
class QCheckBox;
|
||||
|
||||
namespace Gui {
|
||||
namespace Dialog {
|
||||
class Ui_DlgSettingsLazyLoaded;
|
||||
@@ -49,7 +51,7 @@ public:
|
||||
void loadSettings();
|
||||
|
||||
protected Q_SLOTS:
|
||||
void onLoadClicked();
|
||||
void onLoadClicked(const QString& wbName);
|
||||
|
||||
protected:
|
||||
void buildUnloadedWorkbenchList();
|
||||
@@ -58,6 +60,10 @@ protected:
|
||||
private:
|
||||
std::unique_ptr<Ui_DlgSettingsLazyLoaded> ui;
|
||||
static const uint WorkbenchNameRole;
|
||||
|
||||
std::vector<std::string> _backgroundAutoloadedModules;
|
||||
std::string _startupModule;
|
||||
std::map<QString, QCheckBox*> _autoloadCheckboxes;
|
||||
};
|
||||
|
||||
} // namespace Dialog
|
||||
|
||||
Reference in New Issue
Block a user