diff -r 91053052bb28 -r e81f4ad53efd src/mainwindow.cpp --- 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 +#include +#include static constexpr MemberData 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(ext)); + } + glWidget.hide(); + return extensionsList; +} + +void MainWindow::showAboutDialog() +{ + QDialog dialog{this}; + Ui_About ui; + ui.setupUi(&dialog); + const char* glVersion = reinterpret_cast(glGetString(GL_VERSION)); + const QString extensions = getGLExtensions(this).join(" "); + for (QTextBrowser* browser : dialog.findChildren()) { + 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(); +}