|
@@ -0,0 +1,295 @@
|
|
|
+#include "imagehostpage.h"
|
|
|
+
|
|
|
+#include <QFormLayout>
|
|
|
+#include <QVBoxLayout>
|
|
|
+#include <QHBoxLayout>
|
|
|
+#include <QGroupBox>
|
|
|
+#include <QLineEdit>
|
|
|
+#include <QPushButton>
|
|
|
+#include <QLabel>
|
|
|
+#include <QComboBox>
|
|
|
+#include <QCheckBox>
|
|
|
+
|
|
|
+#include <widgets/widgetsfactory.h>
|
|
|
+#include <core/editorconfig.h>
|
|
|
+#include <core/configmgr.h>
|
|
|
+#include <utils/widgetutils.h>
|
|
|
+#include <imagehost/imagehostmgr.h>
|
|
|
+#include <widgets/messageboxhelper.h>
|
|
|
+
|
|
|
+#include "editorpage.h"
|
|
|
+#include "newimagehostdialog.h"
|
|
|
+
|
|
|
+using namespace vnotex;
|
|
|
+
|
|
|
+ImageHostPage::ImageHostPage(QWidget *p_parent)
|
|
|
+ : SettingsPage(p_parent)
|
|
|
+{
|
|
|
+ setupUI();
|
|
|
+}
|
|
|
+
|
|
|
+void ImageHostPage::setupUI()
|
|
|
+{
|
|
|
+ m_mainLayout = new QVBoxLayout(this);
|
|
|
+
|
|
|
+ // New Image Host.
|
|
|
+ {
|
|
|
+ auto layout = new QHBoxLayout();
|
|
|
+ m_mainLayout->addLayout(layout);
|
|
|
+
|
|
|
+ auto newBtn = new QPushButton(tr("New Image Host"), this);
|
|
|
+ connect(newBtn, &QPushButton::clicked,
|
|
|
+ this, &ImageHostPage::newImageHost);
|
|
|
+ layout->addWidget(newBtn);
|
|
|
+ layout->addStretch();
|
|
|
+ }
|
|
|
+
|
|
|
+ auto box = setupGeneralBox(this);
|
|
|
+ m_mainLayout->addWidget(box);
|
|
|
+}
|
|
|
+
|
|
|
+QGroupBox *ImageHostPage::setupGeneralBox(QWidget *p_parent)
|
|
|
+{
|
|
|
+ auto box = new QGroupBox(tr("General"), p_parent);
|
|
|
+ auto layout = WidgetsFactory::createFormLayout(box);
|
|
|
+
|
|
|
+ {
|
|
|
+ m_defaultImageHostComboBox = WidgetsFactory::createComboBox(box);
|
|
|
+
|
|
|
+ // Add items in loadInternal().
|
|
|
+
|
|
|
+ const QString label(tr("Default image host:"));
|
|
|
+ layout->addRow(label, m_defaultImageHostComboBox);
|
|
|
+ addSearchItem(label, m_defaultImageHostComboBox);
|
|
|
+ connect(m_defaultImageHostComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged),
|
|
|
+ this, &ImageHostPage::pageIsChanged);
|
|
|
+ }
|
|
|
+
|
|
|
+ {
|
|
|
+ const QString label(tr("Clear obsolete image"));
|
|
|
+ m_clearObsoleteImageCheckBox = WidgetsFactory::createCheckBox(label, box);
|
|
|
+ m_clearObsoleteImageCheckBox->setToolTip(tr("Clear unused images at image host (based on current file only)"));
|
|
|
+ layout->addRow(m_clearObsoleteImageCheckBox);
|
|
|
+ addSearchItem(label, m_clearObsoleteImageCheckBox->toolTip(), m_clearObsoleteImageCheckBox);
|
|
|
+ connect(m_clearObsoleteImageCheckBox, &QCheckBox::stateChanged,
|
|
|
+ this, &ImageHostPage::pageIsChanged);
|
|
|
+ }
|
|
|
+
|
|
|
+ return box;
|
|
|
+}
|
|
|
+
|
|
|
+void ImageHostPage::addWidgetToLayout(QWidget *p_widget)
|
|
|
+{
|
|
|
+ m_mainLayout->addWidget(p_widget);
|
|
|
+}
|
|
|
+
|
|
|
+void ImageHostPage::loadInternal()
|
|
|
+{
|
|
|
+ const auto &hosts = ImageHostMgr::getInst().getImageHosts();
|
|
|
+ const auto &editorConfig = ConfigMgr::getInst().getEditorConfig();
|
|
|
+
|
|
|
+ {
|
|
|
+ m_defaultImageHostComboBox->clear();
|
|
|
+
|
|
|
+ m_defaultImageHostComboBox->addItem(tr("Local"));
|
|
|
+ for (const auto &host : hosts) {
|
|
|
+ m_defaultImageHostComboBox->addItem(host->getName(), host->getName());
|
|
|
+ }
|
|
|
+
|
|
|
+ auto defaultHost = ImageHostMgr::getInst().getDefaultImageHost();
|
|
|
+ if (defaultHost) {
|
|
|
+ int idx = m_defaultImageHostComboBox->findData(defaultHost->getName());
|
|
|
+ Q_ASSERT(idx > 0);
|
|
|
+ m_defaultImageHostComboBox->setCurrentIndex(idx);
|
|
|
+ } else {
|
|
|
+ m_defaultImageHostComboBox->setCurrentIndex(0);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ m_clearObsoleteImageCheckBox->setChecked(editorConfig.isClearObsoleteImageAtImageHostEnabled());
|
|
|
+
|
|
|
+ // Clear all the boxes before.
|
|
|
+ {
|
|
|
+ auto boxes = findChildren<QGroupBox *>(QString(), Qt::FindDirectChildrenOnly);
|
|
|
+ for (auto box : boxes) {
|
|
|
+ if (box->objectName().isEmpty()) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ m_mainLayout->removeWidget(box);
|
|
|
+ box->deleteLater();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // Setup boxes.
|
|
|
+ for (const auto &host : hosts) {
|
|
|
+ auto box = setupGroupBoxForImageHost(host, this);
|
|
|
+ addWidgetToLayout(box);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+bool ImageHostPage::saveInternal()
|
|
|
+{
|
|
|
+ auto &hostMgr = ImageHostMgr::getInst();
|
|
|
+ auto &editorConfig = ConfigMgr::getInst().getEditorConfig();
|
|
|
+
|
|
|
+ Q_ASSERT(m_hostToFields.size() == hostMgr.getImageHosts().size());
|
|
|
+
|
|
|
+ bool hasError = false;
|
|
|
+
|
|
|
+ hostMgr.setDefaultImageHost(m_defaultImageHostComboBox->currentData().toString());
|
|
|
+
|
|
|
+ editorConfig.setClearObsoleteImageAtImageHostEnabled(m_clearObsoleteImageCheckBox->isChecked());
|
|
|
+
|
|
|
+ for (auto it = m_hostToFields.constBegin(); it != m_hostToFields.constEnd(); ++it) {
|
|
|
+ auto host = it.key();
|
|
|
+ const auto &fields = it.value();
|
|
|
+ Q_ASSERT(!fields.isEmpty());
|
|
|
+
|
|
|
+ // Name.
|
|
|
+ {
|
|
|
+ auto box = dynamic_cast<QGroupBox *>(fields[0]->parent());
|
|
|
+ Q_ASSERT(box);
|
|
|
+ auto nameLineEdit = box->findChild<QLineEdit *>(QStringLiteral("_name"), Qt::FindDirectChildrenOnly);
|
|
|
+ Q_ASSERT(nameLineEdit);
|
|
|
+ const auto &newName = nameLineEdit->text();
|
|
|
+ if (newName != host->getName()) {
|
|
|
+ if (!hostMgr.renameImageHost(host, newName)) {
|
|
|
+ setError(tr("Failed to rename image host (%1) to (%2).").arg(host->getName(), newName));
|
|
|
+ hasError = true;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ box->setObjectName(newName);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // Configs.
|
|
|
+ const auto configObj = fieldsToConfig(fields);
|
|
|
+ host->setConfig(configObj);
|
|
|
+ }
|
|
|
+
|
|
|
+ hostMgr.saveImageHosts();
|
|
|
+
|
|
|
+ // No need to notify editor since ImageHostMgr will signal out.
|
|
|
+ // EditorPage::notifyEditorConfigChange();
|
|
|
+ return !hasError;
|
|
|
+}
|
|
|
+
|
|
|
+QString ImageHostPage::title() const
|
|
|
+{
|
|
|
+ return tr("Image Host");
|
|
|
+}
|
|
|
+
|
|
|
+void ImageHostPage::newImageHost()
|
|
|
+{
|
|
|
+ NewImageHostDialog dialog(this);
|
|
|
+ if (dialog.exec()) {
|
|
|
+ auto box = setupGroupBoxForImageHost(dialog.getNewImageHost(), this);
|
|
|
+ addWidgetToLayout(box);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+QGroupBox *ImageHostPage::setupGroupBoxForImageHost(ImageHost *p_host, QWidget *p_parent)
|
|
|
+{
|
|
|
+ auto box = new QGroupBox(p_parent);
|
|
|
+ box->setObjectName(p_host->getName());
|
|
|
+ auto layout = WidgetsFactory::createFormLayout(box);
|
|
|
+
|
|
|
+ // Add Test and Delete button.
|
|
|
+ {
|
|
|
+ auto btnLayout = new QHBoxLayout();
|
|
|
+ btnLayout->addStretch();
|
|
|
+
|
|
|
+ layout->addRow(btnLayout);
|
|
|
+
|
|
|
+ auto testBtn = new QPushButton(tr("Test"), box);
|
|
|
+ btnLayout->addWidget(testBtn);
|
|
|
+ connect(testBtn, &QPushButton::clicked,
|
|
|
+ this, [this, box]() {
|
|
|
+ const auto name = box->objectName();
|
|
|
+ testImageHost(name);
|
|
|
+ });
|
|
|
+
|
|
|
+ auto deleteBtn = new QPushButton(tr("Delete"), box);
|
|
|
+ btnLayout->addWidget(deleteBtn);
|
|
|
+ connect(deleteBtn, &QPushButton::clicked,
|
|
|
+ this, [this, box]() {
|
|
|
+ const auto name = box->objectName();
|
|
|
+ removeImageHost(name);
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ layout->addRow(tr("Type:"), new QLabel(ImageHost::typeString(p_host->getType()), box));
|
|
|
+
|
|
|
+ auto nameLineEdit = WidgetsFactory::createLineEdit(p_host->getName(), box);
|
|
|
+ nameLineEdit->setObjectName(QStringLiteral("_name"));
|
|
|
+ layout->addRow(tr("Name:"), nameLineEdit);
|
|
|
+ m_hostToFields[p_host].append(nameLineEdit);
|
|
|
+ connect(nameLineEdit, &QLineEdit::textChanged,
|
|
|
+ this, &ImageHostPage::pageIsChanged);
|
|
|
+
|
|
|
+ const auto configObj = p_host->getConfig();
|
|
|
+ const auto keys = configObj.keys();
|
|
|
+ for (const auto &key : keys) {
|
|
|
+ Q_ASSERT(key != "_name");
|
|
|
+ auto configLineEdit = WidgetsFactory::createLineEdit(configObj[key].toString(), box);
|
|
|
+ configLineEdit->setObjectName(key);
|
|
|
+ layout->addRow(tr("%1:").arg(key), configLineEdit);
|
|
|
+ m_hostToFields[p_host].append(configLineEdit);
|
|
|
+ connect(configLineEdit, &QLineEdit::textChanged,
|
|
|
+ this, &ImageHostPage::pageIsChanged);
|
|
|
+ }
|
|
|
+
|
|
|
+ return box;
|
|
|
+}
|
|
|
+
|
|
|
+void ImageHostPage::removeImageHost(const QString &p_hostName)
|
|
|
+{
|
|
|
+ int ret = MessageBoxHelper::questionOkCancel(MessageBoxHelper::Type::Question,
|
|
|
+ tr("Delete image host (%1)?").arg(p_hostName));
|
|
|
+ if (ret != QMessageBox::Ok) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ auto &hostMgr = ImageHostMgr::getInst();
|
|
|
+ auto host = hostMgr.find(p_hostName);
|
|
|
+ Q_ASSERT(host);
|
|
|
+ hostMgr.removeImageHost(host);
|
|
|
+
|
|
|
+ // Remove the group box and related fields.
|
|
|
+ m_hostToFields.remove(host);
|
|
|
+
|
|
|
+ auto box = findChild<QGroupBox *>(p_hostName, Qt::FindDirectChildrenOnly);
|
|
|
+ Q_ASSERT(box);
|
|
|
+ m_mainLayout->removeWidget(box);
|
|
|
+ box->deleteLater();
|
|
|
+}
|
|
|
+
|
|
|
+QJsonObject ImageHostPage::fieldsToConfig(const QVector<QLineEdit *> &p_fields) const
|
|
|
+{
|
|
|
+ QJsonObject configObj;
|
|
|
+ for (auto field : p_fields) {
|
|
|
+ configObj[field->objectName()] = field->text();
|
|
|
+ }
|
|
|
+
|
|
|
+ return configObj;
|
|
|
+}
|
|
|
+
|
|
|
+void ImageHostPage::testImageHost(const QString &p_hostName)
|
|
|
+{
|
|
|
+ auto &hostMgr = ImageHostMgr::getInst();
|
|
|
+ auto host = hostMgr.find(p_hostName);
|
|
|
+ Q_ASSERT(host);
|
|
|
+
|
|
|
+ auto it = m_hostToFields.find(host);
|
|
|
+ Q_ASSERT(it != m_hostToFields.end());
|
|
|
+
|
|
|
+ const auto configObj = fieldsToConfig(it.value());
|
|
|
+ QString msg;
|
|
|
+ bool ret = host->testConfig(configObj, msg);
|
|
|
+ MessageBoxHelper::notify(ret ? MessageBoxHelper::Information : MessageBoxHelper::Warning,
|
|
|
+ tr("Test %1.").arg(ret ? tr("succeeded") : tr("failed")),
|
|
|
+ QString(),
|
|
|
+ msg);
|
|
|
+}
|