mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-02-28 07:59:37 -06:00
Added save file dialog and option to run with temp config file
This commit is contained in:
@@ -27,14 +27,17 @@
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
#include <sgctedit/display.h>
|
||||
#include <sgctedit/orientation.h>
|
||||
#include <sgct/config.h>
|
||||
#include <QFileDialog>
|
||||
#include <QFrame>
|
||||
#include <QLabel>
|
||||
#include <QLayout>
|
||||
#include <QPushButton>
|
||||
#include <QVector>
|
||||
#include <filesystem>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
@@ -49,23 +52,44 @@ using ProjectionOptions = std::variant<
|
||||
sgct::config::SpoutOutputProjection
|
||||
>;
|
||||
|
||||
struct SgctConfigElements {
|
||||
std::vector<sgct::config::Window>& windowList;
|
||||
sgct::config::Cluster& cluster;
|
||||
};
|
||||
|
||||
struct UserConfigurationElements {
|
||||
std::vector<QRect>& monitorList;
|
||||
std::shared_ptr<Display> display;
|
||||
Orientation* orientation;
|
||||
const std::string configSavePath;
|
||||
};
|
||||
|
||||
class FileSupport : public QWidget {
|
||||
Q_OBJECT
|
||||
public:
|
||||
FileSupport(QVBoxLayout* parentLayout, std::vector<QRect>& monitorList,
|
||||
std::shared_ptr<Display> display, Orientation* orientation,
|
||||
std::vector<sgct::config::Window>& windowList, sgct::config::Cluster& cluster,
|
||||
std::function<void(bool)> cb);
|
||||
/**
|
||||
* Constructor for FileSupport class, which saves the window configuration settings
|
||||
* into the SGCT json structure according to the sgct code
|
||||
*
|
||||
* \param parentLayout Qt vertical (QVBoxLayout) layout where controls are added
|
||||
* \param cfgElements struct of elements needed to read user settings from GUI
|
||||
* \param sgctElements struct of the window and cluster objects needed for saving
|
||||
* \param finishedCallback function to be called when user has selected to either
|
||||
* save changes to file, apply and run without saving, or cancel
|
||||
*/
|
||||
FileSupport(QVBoxLayout* parentLayout, UserConfigurationElements& cfgElements,
|
||||
SgctConfigElements& sgctElements, std::function<void(bool)> finishedCallback);
|
||||
std::string saveFilename();
|
||||
|
||||
private slots:
|
||||
void filenameEdited(const QString& newString);
|
||||
void cancel();
|
||||
void save();
|
||||
void apply();
|
||||
|
||||
private:
|
||||
bool isWindowFullscreen(unsigned int monitorIdx, sgct::ivec2 wDims);
|
||||
std::optional<unsigned int> findGuiWindow();
|
||||
void saveConfigToSgctFormat();
|
||||
void saveCluster();
|
||||
void saveWindows();
|
||||
void saveUser();
|
||||
@@ -80,13 +104,15 @@ private:
|
||||
QHBoxLayout* _layoutButtonBox = nullptr;
|
||||
QPushButton* _saveButton = nullptr;
|
||||
QPushButton* _cancelButton = nullptr;
|
||||
QPushButton* _applyButton = nullptr;
|
||||
std::shared_ptr<Display> _displayWidget;
|
||||
Orientation* _orientationWidget;
|
||||
std::vector<QRect>& _monitors;
|
||||
sgct::config::Cluster& _cluster;
|
||||
std::vector<sgct::config::Window>& _windowList;
|
||||
QLineEdit* _lineFilename = nullptr;
|
||||
std::function<void(bool)> _finishedCallback;
|
||||
const std::string _userConfigPath;
|
||||
std::string _saveTarget;
|
||||
};
|
||||
|
||||
#endif // __OPENSPACE_UI_LAUNCHER___FILESUPPORT___H__
|
||||
|
||||
@@ -57,9 +57,12 @@ public:
|
||||
* objects that will be modified by the window configuration settings
|
||||
* \param screenList A QList containing a QScreen object for each monitor in the
|
||||
* system
|
||||
* \param userConfigPath A string containing the file path of the user config
|
||||
* directory where all window configs are stored
|
||||
*/
|
||||
SgctEdit(QWidget* parent, std::vector<sgct::config::Window>& windowList,
|
||||
sgct::config::Cluster& cluster, const QList<QScreen*>& screenList);
|
||||
sgct::config::Cluster& cluster, const QList<QScreen*>& screenList,
|
||||
const std::string userConfigPath);
|
||||
~SgctEdit();
|
||||
/**
|
||||
* Used to determine if the window configuration was saved to file, or canceled
|
||||
@@ -89,6 +92,7 @@ private:
|
||||
Orientation* _orientationWidget = nullptr;
|
||||
sgct::config::Cluster& _cluster;
|
||||
std::vector<sgct::config::Window>& _windowList;
|
||||
const std::string _userConfigPath;
|
||||
bool _saveSelected = false;
|
||||
unsigned int _nMaxWindows = 3;
|
||||
const std::array<QColor, 4> _colorsForWindows = {
|
||||
|
||||
@@ -500,6 +500,8 @@ void LauncherWindow::populateWindowConfigsList(std::string preset) {
|
||||
);
|
||||
}
|
||||
|
||||
//Always add the .cfg sgct default as first item
|
||||
_windowConfigBox->insertItem(0, QString::fromStdString(_sgctConfigName));
|
||||
// Try to find the requested configuration file and set it as the current one. As we
|
||||
// have support for function-generated configuration files that will not be in the
|
||||
// list we need to add a preset that doesn't exist a file for
|
||||
@@ -509,8 +511,11 @@ void LauncherWindow::populateWindowConfigsList(std::string preset) {
|
||||
}
|
||||
else {
|
||||
// Add the requested preset at the top
|
||||
_windowConfigBox->insertItem(0, QString::fromStdString(preset));
|
||||
_windowConfigBox->setCurrentIndex(0);
|
||||
_windowConfigBox->insertItem(1, QString::fromStdString(preset));
|
||||
//Increment the user config count because there is an additional option added
|
||||
//before the user config options
|
||||
_userConfigCount++;
|
||||
_windowConfigBox->setCurrentIndex(1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -559,19 +564,26 @@ void LauncherWindow::openWindowEditor() {
|
||||
}
|
||||
sgct::config::Cluster cluster;
|
||||
std::vector<sgct::config::Window> windowList;
|
||||
SgctEdit editor(this, windowList, cluster, screenList);
|
||||
SgctEdit editor(this, windowList, cluster, screenList, _userConfigPath);
|
||||
editor.exec();
|
||||
if (editor.wasSaved()) {
|
||||
std::string fullFilename = editor.saveFilename() + ".json";
|
||||
const std::string path = _userConfigPath + fullFilename;
|
||||
std::string ext = ".json";
|
||||
std::string savePath = editor.saveFilename();
|
||||
if (savePath.size() >= ext.size()
|
||||
&& !(savePath.substr(savePath.size() - ext.size()).compare(ext) == 0))
|
||||
{
|
||||
savePath += ext;
|
||||
}
|
||||
if (cluster.nodes.size() == 0) {
|
||||
cluster.nodes.push_back(sgct::config::Node());
|
||||
}
|
||||
for (auto w : windowList) {
|
||||
cluster.nodes[0].windows.push_back(w);
|
||||
}
|
||||
saveWindowConfig(this, path, cluster);
|
||||
populateWindowConfigsList(fullFilename);
|
||||
saveWindowConfig(this, savePath, cluster);
|
||||
//Truncate path to convert this back to path relative to _userConfigPath
|
||||
savePath = savePath.substr(_userConfigPath.size());
|
||||
populateWindowConfigsList(savePath);
|
||||
}
|
||||
else {
|
||||
const std::string current = _windowConfigBox->currentText().toStdString();
|
||||
|
||||
@@ -24,50 +24,37 @@
|
||||
|
||||
#include "sgctedit/filesupport.h"
|
||||
|
||||
FileSupport::FileSupport(QVBoxLayout* parentLayout, std::vector<QRect>& monitorList,
|
||||
std::shared_ptr<Display> display, Orientation* orientation,
|
||||
std::vector<sgct::config::Window>& windowList,
|
||||
sgct::config::Cluster& cluster, std::function<void(bool)> cb)
|
||||
: _displayWidget(display)
|
||||
, _orientationWidget(orientation)
|
||||
, _monitors(monitorList)
|
||||
, _cluster(cluster)
|
||||
, _windowList(windowList)
|
||||
, _finishedCallback(cb)
|
||||
FileSupport::FileSupport(QVBoxLayout* parentLayout,
|
||||
UserConfigurationElements& cfgElements,
|
||||
SgctConfigElements& sgctElements,
|
||||
std::function<void(bool)> finishedCallback)
|
||||
: _displayWidget(cfgElements.display)
|
||||
, _orientationWidget(cfgElements.orientation)
|
||||
, _monitors(cfgElements.monitorList)
|
||||
, _cluster(sgctElements.cluster)
|
||||
, _windowList(sgctElements.windowList)
|
||||
, _finishedCallback(finishedCallback)
|
||||
, _userConfigPath(cfgElements.configSavePath)
|
||||
{
|
||||
QVBoxLayout* layoutFullVertical = new QVBoxLayout;
|
||||
_lineFilename = new QLineEdit;
|
||||
_lineFilename->setFixedWidth(190);
|
||||
{
|
||||
QHBoxLayout* layoutFilename = new QHBoxLayout;
|
||||
QLabel* labelFilename = new QLabel;
|
||||
QString fileTip = "Enter a filename for this custom configuration to be saved "
|
||||
"as a .json file in the user/config/ directory";
|
||||
labelFilename->setToolTip(fileTip);
|
||||
_lineFilename->setToolTip(fileTip);
|
||||
labelFilename->setText("Filename: ");
|
||||
layoutFilename->addStretch(1);
|
||||
layoutFilename->addWidget(labelFilename);
|
||||
layoutFilename->addWidget(_lineFilename);
|
||||
layoutFilename->addStretch(1);
|
||||
layoutFullVertical->addLayout(layoutFilename);
|
||||
}
|
||||
_saveButton = new QPushButton("Save");
|
||||
_saveButton->setToolTip("Save global orientation changes");
|
||||
_saveButton = new QPushButton("Save As");
|
||||
_saveButton->setToolTip("Save configuration changes (opens file chooser dialog)");
|
||||
connect(_saveButton, &QPushButton::released, this, &FileSupport::save);
|
||||
_saveButton->setEnabled(false);
|
||||
_cancelButton = new QPushButton("Cancel");
|
||||
_cancelButton->setToolTip("Cancel global orientation changes");
|
||||
_cancelButton->setToolTip("Cancel changes");
|
||||
connect(_cancelButton, &QPushButton::released, this, &FileSupport::cancel);
|
||||
_applyButton = new QPushButton("Apply Without Saving");
|
||||
_applyButton->setToolTip("Apply configuration changes without saving to file");
|
||||
connect(_applyButton, &QPushButton::released, this, &FileSupport::apply);
|
||||
{
|
||||
QHBoxLayout* layoutButtonBox = new QHBoxLayout;
|
||||
layoutButtonBox->addStretch(1);
|
||||
layoutButtonBox->addWidget(_saveButton);
|
||||
layoutButtonBox->addWidget(_cancelButton);
|
||||
layoutButtonBox->addWidget(_saveButton);
|
||||
layoutButtonBox->addWidget(_applyButton);
|
||||
layoutFullVertical->addLayout(layoutButtonBox);
|
||||
}
|
||||
parentLayout->addLayout(layoutFullVertical);
|
||||
connect(_lineFilename, &QLineEdit::textEdited, this, &FileSupport::filenameEdited);
|
||||
}
|
||||
|
||||
void FileSupport::saveCluster() {
|
||||
@@ -251,21 +238,42 @@ ProjectionOptions FileSupport::saveProjectionNoSpout(
|
||||
}
|
||||
}
|
||||
|
||||
void FileSupport::filenameEdited(const QString& newString) {
|
||||
_saveButton->setEnabled(!newString.isEmpty());
|
||||
}
|
||||
|
||||
std::string FileSupport::saveFilename() {
|
||||
return _lineFilename->text().toStdString();
|
||||
return _saveTarget;
|
||||
}
|
||||
|
||||
void FileSupport::save() {
|
||||
saveCluster();
|
||||
saveWindows();
|
||||
saveUser();
|
||||
_finishedCallback(true);
|
||||
QString fileName = QFileDialog::getSaveFileName(this,
|
||||
"Save Window Configuration File", QString::fromStdString(_userConfigPath),
|
||||
"Window Configuration (*.json);;(*.json)", nullptr,
|
||||
QFileDialog::DontUseNativeDialog);
|
||||
if (fileName.length() != 0) {
|
||||
_saveTarget = fileName.toStdString();
|
||||
saveConfigToSgctFormat();
|
||||
_finishedCallback(true);
|
||||
}
|
||||
}
|
||||
|
||||
void FileSupport::cancel() {
|
||||
_finishedCallback(false);
|
||||
}
|
||||
|
||||
void FileSupport::apply() {
|
||||
std::string userCfgTempDir = _userConfigPath;
|
||||
if (userCfgTempDir.back() != '/') {
|
||||
userCfgTempDir += "/";
|
||||
}
|
||||
userCfgTempDir += "temp";
|
||||
if (!std::filesystem::is_directory(userCfgTempDir)) {
|
||||
std::filesystem::create_directories(absPath(userCfgTempDir));
|
||||
}
|
||||
_saveTarget = userCfgTempDir + "/" + "apply-without-saving.json";
|
||||
saveConfigToSgctFormat();
|
||||
_finishedCallback(true);
|
||||
}
|
||||
|
||||
void FileSupport::saveConfigToSgctFormat() {
|
||||
saveCluster();
|
||||
saveWindows();
|
||||
saveUser();
|
||||
}
|
||||
|
||||
@@ -23,12 +23,15 @@
|
||||
****************************************************************************************/
|
||||
|
||||
#include "sgctedit/sgctedit.h"
|
||||
#include <QFileDialog>
|
||||
|
||||
SgctEdit::SgctEdit(QWidget* parent, std::vector<sgct::config::Window>& windowList,
|
||||
sgct::config::Cluster& cluster, const QList<QScreen*>& screenList)
|
||||
sgct::config::Cluster& cluster, const QList<QScreen*>& screenList,
|
||||
const std::string userConfigPath)
|
||||
: QDialog(parent)
|
||||
, _cluster(cluster)
|
||||
, _windowList(windowList)
|
||||
, _userConfigPath(userConfigPath)
|
||||
{
|
||||
systemMonitorConfiguration(screenList);
|
||||
setWindowTitle("Window Configuration Editor");
|
||||
@@ -79,13 +82,17 @@ void SgctEdit::createWidgets() {
|
||||
{
|
||||
layoutMainV->addLayout(layoutMainH);
|
||||
_orientationWidget->addControlsToParentLayout(layoutMainV);
|
||||
_fileSupportWidget = new FileSupport(
|
||||
layoutMainV,
|
||||
SgctConfigElements sgctCfg = {_windowList, _cluster};
|
||||
UserConfigurationElements userCfg = {
|
||||
_monitorSizeList,
|
||||
_displayWidget,
|
||||
_orientationWidget,
|
||||
_windowList,
|
||||
_cluster,
|
||||
_userConfigPath
|
||||
};
|
||||
_fileSupportWidget = new FileSupport(
|
||||
layoutMainV,
|
||||
userCfg,
|
||||
sgctCfg,
|
||||
[this](bool accepted) {
|
||||
if (accepted) {
|
||||
_saveSelected = true;
|
||||
|
||||
Reference in New Issue
Block a user