Move the about dialog to MainWindow. The hack to retrieve GL extensions is made a bit cleaner

Sat, 08 Apr 2023 16:59:55 +0300

author
Teemu Piippo <teemu.s.piippo@gmail.com>
date
Sat, 08 Apr 2023 16:59:55 +0300
changeset 355
e81f4ad53efd
parent 354
91053052bb28
child 356
65b4741b302d

Move the about dialog to MainWindow. The hack to retrieve GL extensions is made a bit cleaner

CMakeLists.txt file | annotate | diff | comparison | revisions
src/main.cpp file | annotate | diff | comparison | revisions
src/mainwindow.cpp file | annotate | diff | comparison | revisions
src/mainwindow.h file | annotate | diff | comparison | revisions
--- a/CMakeLists.txt	Sat Apr 08 16:41:40 2023 +0300
+++ b/CMakeLists.txt	Sat Apr 08 16:59:55 2023 +0300
@@ -109,6 +109,7 @@
 	src/mainwindow.h
 	src/messagelog.h
 	src/model.h
+	src/modelsubwindow.h
 	src/parser.h
 	src/polygoncache.h
 	src/settings.h
--- a/src/main.cpp	Sat Apr 08 16:41:40 2023 +0300
+++ b/src/main.cpp	Sat Apr 08 16:59:55 2023 +0300
@@ -7,7 +7,6 @@
 #include <QScrollBar>
 #include <QStackedWidget>
 #include <QTranslator>
-#include <ui_about.h>
 #include "src/gl/partrenderer.h"
 #include "src/layers/axeslayer.h"
 #include "src/layers/edittools.h"
@@ -15,6 +14,7 @@
 #include "src/ldrawalgorithm.h"
 #include "src/mainwindow.h"
 #include "src/messagelog.h"
+#include "src/modelsubwindow.h"
 #include "src/settings.h"
 #include "src/settingseditor/settingseditor.h"
 #include "src/ui/circletooloptionswidget.h"
@@ -26,23 +26,6 @@
 
 static const QDir LOCALE_DIR {":/locale"};
 
-class ModelSubWindow : public QMdiSubWindow
-{
-	Q_OBJECT
-public:
-	const ModelId modelId;
-	explicit ModelSubWindow(ModelId modelId, QWidget* widget = nullptr) :
-		QMdiSubWindow{widget},
-		modelId{modelId}
-	{
-	}
-protected:
-	void closeEvent(QCloseEvent* event) override
-	{
-		event->ignore();
-	}
-};
-
 class ModelData : public QObject
 {
 	Q_OBJECT
@@ -301,45 +284,6 @@
 	}
 }
 
-static void about(QWidget* parent)
-{
-	QDialog dialog{parent};
-	Ui_About ui;
-	ui.setupUi(&dialog);
-	const char* glVersion = reinterpret_cast<const char*>(glGetString(GL_VERSION));
-	const QString extensions = []{
-		GLint numExtensions;
-		glGetIntegerv(GL_NUM_EXTENSIONS, &numExtensions);
-		QStringList extensionsList;
-		for (GLint i = 0; i < numExtensions; i++) {
-			const GLubyte* ext = glGetStringi(GL_EXTENSIONS, i);
-			extensionsList.push_back(reinterpret_cast<const char*>(ext));
-		}
-		return extensionsList.join(" ");
-	}();
-	for (QTextBrowser* browser : dialog.findChildren<QTextBrowser*>()) {
-		browser->setHtml(
-			browser->toHtml()
-			.replace("%APPNAME%", CMAKE_PROJECT_NAME)
-			.replace("%COPYRIGHT%", COPYRIGHT)
-			.replace("%QTVERSION%", qVersion())
-			.replace("%VERSION%", detailedVersionString(QLocale::LongFormat))
-			.replace("%REVDATE%", revisionDateString(QLocale::LongFormat))
-			.replace("%BUILDTYPE%", CMAKE_BUILD_TYPE)
-			.replace("%COMPILER_ID%", CMAKE_CXX_COMPILER_ID)
-			.replace("%COMPILER_VERSION%", CMAKE_CXX_COMPILER_VERSION)
-			.replace("%COMPILER_FLAGS%", CMAKE_CXX_FLAGS)
-			.replace("%COMPILER_CPU%", CMAKE_SYSTEM_PROCESSOR)
-			.replace("%COMPILER_SYSTEM%", CMAKE_SYSTEM)
-			.replace("%GLMVERSIONSTRING%", GLM_VERSION_MESSAGE)
-			.replace("%GL_VERSION%", glVersion)
-			.replace("%GL_EXTENSIONS%", extensions)
-		);
-	}
-	dialog.setWindowTitle(QObject::tr("About %1").arg(CMAKE_PROJECT_NAME));
-	dialog.exec();
-}
-
 template<class SubWindow, class... Args>
 SubWindow* createSubWindow(QMdiArea* mdiArea, Args&&... args)
 {
@@ -734,7 +678,6 @@
 		updateTitle();
 	});
 	mainWindow.messageLog->setModel(&messageLog);
-	QObject::connect(mainWindow.actionAboutQt, &QAction::triggered, &app, &QApplication::aboutQt);
 	QObject::connect(&documents, &DocumentManager::message, &messageLog, &MessageLog::addMessage);
 	QObject::connect(&messageLog, &MessageLog::rowsAboutToBeInserted, [&mainWindow]{
 		const auto bar = mainWindow.messageLog->verticalScrollBar();
@@ -765,18 +708,7 @@
 				}
 			}
 		});
-	QObject::connect(
-		mainWindow.actionAbout,
-		&QAction::triggered,
-		[&mainWindow]{
-			// Make sure that there's an OpenGL context active, otherwise
-			// we cannot obtain OpenGL information
-			if (mainWindow.mdiArea->findChildren<ModelSubWindow*>().empty()) {
-				mainWindow.actionNew->trigger();
-			}
-			about(&mainWindow);
-		}
-	);
+	QObject::connect(mainWindow.actionAboutQt, &QAction::triggered, &app, &QApplication::aboutQt);
 	QObject::connect(
 		mainWindow.modelEdit,
 		&QPlainTextEdit::textChanged,
--- a/src/mainwindow.cpp	Sat Apr 08 16:41:40 2023 +0300
+++ b/src/mainwindow.cpp	Sat Apr 08 16:59:55 2023 +0300
@@ -1,4 +1,9 @@
-#include "mainwindow.h"
+#include "src/mainwindow.h"
+#include "src/modelsubwindow.h"
+#include "src/version.h"
+#include <QTextBrowser>
+#include <QOpenGLWidget>
+#include <ui_about.h>
 
 static constexpr MemberData<MainWindow, QAction*, gl::RenderStyle> renderStyleButtons[] = {
 	{ offsetof(MainWindow, actionRenderStyleNormal), gl::RenderStyle::Normal },
@@ -20,6 +25,7 @@
 			this->setRenderStyle(newStyle);
 		});
 	}
+	this->connect(this->actionAbout, &QAction::triggered, this, &MainWindow::showAboutDialog);
 }
 
 void MainWindow::setRenderStyle(gl::RenderStyle style)
@@ -31,3 +37,53 @@
 		action->setChecked(style == buttonRenderStyle);
 	}
 }
+
+static QStringList getGLExtensions(QWidget* parent)
+{
+	// We need to have GL activated at least once in order to able to retrieve
+	// GL extensions properly. To make sure this is the case, we create a
+	// temporary, plain OpenGL widget. While it is active, we call glewInit().
+	// If this is not done, this function will crash.
+	QOpenGLWidget glWidget{parent};
+	glWidget.show();
+	glewInit();
+	GLint numExtensions;
+	glGetIntegerv(GL_NUM_EXTENSIONS, &numExtensions);
+	QStringList extensionsList;
+	for (GLint i = 0; i < numExtensions; i++) {
+		const GLubyte* ext = glGetStringi(GL_EXTENSIONS, i);
+		extensionsList.push_back(reinterpret_cast<const char*>(ext));
+	}
+	glWidget.hide();
+	return extensionsList;
+}
+
+void MainWindow::showAboutDialog()
+{
+	QDialog dialog{this};
+	Ui_About ui;
+	ui.setupUi(&dialog);
+	const char* glVersion = reinterpret_cast<const char*>(glGetString(GL_VERSION));
+	const QString extensions = getGLExtensions(this).join(" ");
+	for (QTextBrowser* browser : dialog.findChildren<QTextBrowser*>()) {
+		browser->setHtml(
+			browser->toHtml()
+			.replace("%APPNAME%", CMAKE_PROJECT_NAME)
+			.replace("%COPYRIGHT%", COPYRIGHT)
+			.replace("%QTVERSION%", qVersion())
+			.replace("%VERSION%", detailedVersionString(QLocale::LongFormat))
+			.replace("%REVDATE%", revisionDateString(QLocale::LongFormat))
+			.replace("%BUILDTYPE%", CMAKE_BUILD_TYPE)
+			.replace("%COMPILER_ID%", CMAKE_CXX_COMPILER_ID)
+			.replace("%COMPILER_VERSION%", CMAKE_CXX_COMPILER_VERSION)
+			.replace("%COMPILER_FLAGS%", CMAKE_CXX_FLAGS)
+			.replace("%COMPILER_CPU%", CMAKE_SYSTEM_PROCESSOR)
+			.replace("%COMPILER_SYSTEM%", CMAKE_SYSTEM)
+			.replace("%GLMVERSIONSTRING%", GLM_VERSION_MESSAGE)
+			.replace("%GL_VERSION%", glVersion)
+			.replace("%GL_EXTENSIONS%", extensions)
+		);
+	}
+	dialog.setWindowTitle(QObject::tr("About %1").arg(CMAKE_PROJECT_NAME));
+	dialog.exec();
+}
--- a/src/mainwindow.h	Sat Apr 08 16:41:40 2023 +0300
+++ b/src/mainwindow.h	Sat Apr 08 16:59:55 2023 +0300
@@ -14,6 +14,8 @@
 	void renderStyleSelected(gl::RenderStyle newStyle);
 public Q_SLOTS:
 	void setRenderStyle(gl::RenderStyle style);
+private Q_SLOTS:
+	void showAboutDialog();
 };
 
 #endif // MAINWINDOW_H

mercurial