src/mainwindow.cpp

changeset 355
e81f4ad53efd
parent 354
91053052bb28
child 361
c5e8b68e34f8
--- 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();
+}

mercurial