aboutsummaryrefslogtreecommitdiffstats
path: root/SQLiteStudio3/guiSQLiteStudio/formmanager.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'SQLiteStudio3/guiSQLiteStudio/formmanager.cpp')
-rw-r--r--SQLiteStudio3/guiSQLiteStudio/formmanager.cpp185
1 files changed, 185 insertions, 0 deletions
diff --git a/SQLiteStudio3/guiSQLiteStudio/formmanager.cpp b/SQLiteStudio3/guiSQLiteStudio/formmanager.cpp
new file mode 100644
index 0000000..9df36d0
--- /dev/null
+++ b/SQLiteStudio3/guiSQLiteStudio/formmanager.cpp
@@ -0,0 +1,185 @@
+#include "formmanager.h"
+#include "services/config.h"
+#include "services/pluginmanager.h"
+#include "sqlitestudio.h"
+#include "uiloader.h"
+#include "common/unused.h"
+#include "common/global.h"
+#include <QFile>
+#include <QDir>
+#include <QRegularExpression>
+#include <QApplication>
+#include <QDebug>
+
+FormManager::FormManager()
+{
+ init();
+}
+
+FormManager::~FormManager()
+{
+ if (uiLoader)
+ {
+ delete uiLoader;
+ uiLoader = nullptr;
+ }
+}
+
+QWidget* FormManager::createWidget(const QString& name)
+{
+ if (!widgetNameToFullPath.contains(name))
+ {
+ qCritical() << "Asked for widget name which isn't managed by FormManager:" << name << ", while available widgets are:"
+ << widgetNameToFullPath.keys();
+ return nullptr;
+ }
+ return createWidgetByFullPath(widgetNameToFullPath[name]);
+}
+
+bool FormManager::hasWidget(const QString& name)
+{
+ return widgetNameToFullPath.contains(name);
+}
+
+QStringList FormManager::getAvailableForms() const
+{
+ return widgetNameToFullPath.keys();
+}
+
+QWidget* FormManager::createWidgetByFullPath(const QString& path)
+{
+ QWidget* widget = uiLoader->load(path);
+ if (!widget)
+ {
+ qCritical() << "Error occured while loading ui file:" << path << ". Error message: "
+ << uiLoader->errorString();
+ return nullptr;
+ }
+ return widget;
+}
+
+void FormManager::rescanResources(Plugin* plugin, PluginType* pluginType)
+{
+ UNUSED(pluginType);
+ rescanResources(plugin->getName());
+}
+
+void FormManager::rescanResources(const QString& pluginName)
+{
+ if (PLUGINS->isBuiltIn(pluginName))
+ return;
+
+ for (const QString& widgetName : resourceForms)
+ widgetNameToFullPath.remove(widgetName);
+
+ resourceForms.clear();
+ loadRecurently(":/forms", "");
+}
+
+void FormManager::pluginsAboutToMassUnload()
+{
+ disconnect(PLUGINS, SIGNAL(loaded(Plugin*,PluginType*)), this, SLOT(rescanResources(Plugin*,PluginType*)));
+ disconnect(PLUGINS, SIGNAL(unloaded(QString,PluginType*)), this, SLOT(rescanResources(QString)));
+}
+
+void FormManager::pluginsInitiallyLoaded()
+{
+ load();
+
+ connect(PLUGINS, SIGNAL(loaded(Plugin*,PluginType*)), this, SLOT(rescanResources(Plugin*,PluginType*)));
+ connect(PLUGINS, SIGNAL(unloaded(QString,PluginType*)), this, SLOT(rescanResources(QString)));
+ connect(PLUGINS, SIGNAL(aboutToQuit()), this, SLOT(pluginsAboutToMassUnload()));
+ disconnect(PLUGINS, SIGNAL(pluginsInitiallyLoaded()), this, SLOT(pluginsInitiallyLoaded()));
+}
+
+void FormManager::init()
+{
+ uiLoader = new UiLoader();
+
+ if (PLUGINS->arePluginsInitiallyLoaded())
+ pluginsInitiallyLoaded();
+ else
+ connect(PLUGINS, SIGNAL(pluginsInitiallyLoaded()), this, SLOT(pluginsInitiallyLoaded()));
+}
+
+void FormManager::load()
+{
+ QStringList dirs;
+ dirs += qApp->applicationDirPath() + "/forms";
+ dirs += ":/forms";
+ dirs += QDir(CFG->getConfigDir()).absoluteFilePath("forms");
+
+ QString envDirs = SQLITESTUDIO->getEnv("SQLITESTUDIO_FORMS");
+ if (!envDirs.isNull())
+ dirs += envDirs.split(PATH_LIST_SEPARATOR);
+
+ dirs += PLUGINS->getPluginDirs();
+
+#ifdef FORMS_DIR
+ dirs += STRINGIFY(FORMS_DIR);
+#endif
+
+ foreach (QString dirPath, dirs)
+ loadRecurently(dirPath, "");
+}
+
+void FormManager::loadRecurently(const QString& path, const QString& prefix)
+{
+ static const QStringList fileExtensions = {"*.ui", "*.UI"};
+
+ QDir dir(path);
+ QString fullPath;
+ QString widgetName;
+ foreach (QFileInfo entry, dir.entryInfoList(fileExtensions, QDir::AllDirs|QDir::Files|QDir::NoDotAndDotDot|QDir::Readable))
+ {
+ fullPath = entry.absoluteFilePath();
+ if (entry.isDir())
+ {
+ loadRecurently(fullPath, prefix+entry.fileName()+"_");
+ continue;
+ }
+
+ qDebug() << "Loading form file:" << fullPath;
+
+ widgetName = getWidgetName(fullPath);
+ if (widgetName.isNull())
+ continue;
+
+ if (widgetNameToFullPath.contains(widgetName))
+ {
+ qCritical() << "Widget named" << widgetName << "was already loaded by FormManager from file" << widgetNameToFullPath[widgetName]
+ << "therefore file" << fullPath << "will be ignored";
+ continue;
+ }
+
+ widgetNameToFullPath[widgetName] = fullPath;
+ if (fullPath.startsWith(":/"))
+ resourceForms << widgetName;
+ }
+}
+
+QString FormManager::getWidgetName(const QString& path)
+{
+ static const QRegularExpression re(R"(<widget class\=\"\w+\" name\=\"(\w+)\">)");
+
+ QFile file(path);
+ if (!file.open(QIODevice::ReadOnly))
+ {
+ qWarning() << "Could not open" << path << "for reading. Form file ignored.";
+ return QString::null;
+ }
+
+ QString contents = file.readAll();
+ file.close();
+
+ QRegularExpressionMatch match = re.match(contents);
+ if (!match.hasMatch())
+ {
+ qWarning() << "Could not match widget in" << path << " document. File ignored.";
+ return QString::null;
+ }
+
+ QString widgetName = match.captured(1);
+
+ return widgetName;
+}