Added save file dialog and option to run with temp config file

This commit is contained in:
GPayne
2022-02-24 23:16:17 -07:00
parent 0632fe0c6c
commit 3a529c30e7
5 changed files with 117 additions and 60 deletions

View File

@@ -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__

View File

@@ -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 = {

View File

@@ -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();

View File

@@ -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();
}

View File

@@ -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;