Sun, 26 Jun 2022 19:44:45 +0300
- Made it build under Qt6
- Fix strangeness involving library path settings
--- a/CMakeLists.txt Wed Jun 22 23:51:06 2022 +0300 +++ b/CMakeLists.txt Sun Jun 26 19:44:45 2022 +0300 @@ -1,22 +1,25 @@ project(ldforge) cmake_minimum_required(VERSION 2.8.12) set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/CMake") -#include(cotire) set(OpenGL_GL_PREFERENCE GLVND) -find_package(Qt5Widgets REQUIRED) -if (Qt5Widgets_VERSION VERSION_LESS 5.5.0) - message(FATAL_ERROR "Qt5 version 5.5 required") +find_package(Qt6 COMPONENTS Core Widgets OpenGL UiPlugin OpenGLWidgets) +if (Qt6_FOUND) + message(NOTICE "-- Using Qt6") + find_package(Qt6 REQUIRED COMPONENTS Core5Compat) + # Unfortunately "Qt::UiPlugin" doesn't seem to work so let's resolve + # it here instead... + add_library(QtUiPlugin ALIAS Qt6::UiPlugin) +else() + message(NOTICE "-- Qt6 not found, using Qt5 instead") + find_package(Qt5 5.5 REQUIRED COMPONENTS Core Widgets OpenGL UiPlugin) + add_library(QtUiPlugin ALIAS Qt5::UiPlugin) endif() -find_package(Qt5Core REQUIRED) -find_package(Qt5OpenGL REQUIRED) -find_package(Qt5Network REQUIRED) -#find_package(Qt5LinguistTools REQUIRED) +find_package(OpenGL REQUIRED) find_package(GLM REQUIRED) set(CMAKE_AUTOMOC ON) set(CMAKE_AUTOUIC ON) set(CMAKE_AUTORCC ON) -find_package(OpenGL REQUIRED) -include_directories(${QT_INCLUDES} ${CMAKE_CURRENT_BINARY_DIR}) +include_directories(${CMAKE_CURRENT_BINARY_DIR}) include_directories(${GLM_INCLUDE_DIR}) add_definitions(-DQT_NO_KEYWORDS) source_group("LDForge" REGULAR_EXPRESSION "src/.+\\.(cpp|h|ui)") @@ -120,10 +123,6 @@ include_directories("${PROJECT_BINARY_DIR}/src") include_directories("${PROJECT_SOURCE_DIR}") include_directories("${PROJECT_SOURCE_DIR}/src") - -# Translations -#qt5_create_translation(QM_FILES ${LDFORGE_SOURCES} ${LDFORGE_HEADERS} ${LDFORGE_FORMS} ${LDFORGE_LOCALES}) -#add_custom_target(translations ALL DEPENDS ${QM_FILES}) add_custom_target(resources ALL DEPENDS ${LDFORGE_RESOURCES}) if (NOT MSVC) @@ -133,9 +132,9 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wpedantic -Wunused") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-implicit-fallthrough") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-noexcept-type") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wformat-nonliteral -Wnonnull -Wnonnull-compare -Wnull-dereference -Winfinite-recursion -Wunused-const-variable=1 -Wuninitialized -Wsuggest-attribute=noreturn -Wmissing-noreturn -Wsuggest-attribute=malloc") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wduplicated-branches -Wshadow") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wunsafe-loop-optimizations -Wundef -Wmissing-field-initializers") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wformat-nonliteral -Wnonnull -Wnull-dereference -Winfinite-recursion -Wuninitialized -Wmissing-noreturn") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wshadow") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wundef -Wmissing-field-initializers") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wcast-qual -Wcast-align -Wcast-function-type -Wconversion") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wmissing-declarations -Wdate-time") endif() @@ -145,25 +144,14 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wsuggest-override -Wundefined-func-template -Wundefined-reinterpret-cast") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wuninitialized-const-reference -Wunreachable-code -Wunreachable-code-break -Wunreachable-code-return") endif() -qt5_add_resources(LDFORGE_QRC ${LDFORGE_RESOURCES}) -qt5_wrap_ui(LDFORGE_FORMS_HEADERS ${LDFORGE_FORMS}) - -# Move languages.qrc into the build directory to bake the .qm-files into LDForge -# so that they don't have to be shipped separately -# https://stackoverflow.com/a/34798124 -# https://gist.github.com/giraldeau/546ba5512a74dfe9d8ea0862d66db412 -set(LANGUAGES_QRC "languages.qrc") -configure_file(${LANGUAGES_QRC} ${CMAKE_CURRENT_BINARY_DIR} COPYONLY) -qt5_add_resources(LDFORGE_QM_RC_FILE ${CMAKE_CURRENT_BINARY_DIR}/${LANGUAGES_QRC}) -set_source_files_properties(${LDFORGE_LOCALES} PROPERTIES HEADER_FILE_ONLY TRUE) +qt_add_resources(LDFORGE_QRC ${LDFORGE_RESOURCES}) +qt_wrap_ui(LDFORGE_FORMS_HEADERS ${LDFORGE_FORMS}) add_executable(ldforge WIN32 ${LDFORGE_SOURCES} ${LDFORGE_HEADERS} ${LDFORGE_RESOURCES} ${LDFORGE_QRC} - #${LDFORGE_QM_RC_FILE} - ${QM_FILES} ${LDFORGE_FORMS_HEADERS} ${LDFORGE_OTHER_FILES} ) @@ -172,10 +160,17 @@ set_source_files_properties(${LDFORGE_RESOURCES} PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties(${LDFORGE_OTHER_FILES} PROPERTIES HEADER_FILE_ONLY TRUE) set_target_properties(ldforge PROPERTIES AUTOMOC 1) -target_link_libraries(ldforge Qt5::Widgets Qt5::Network Qt5::OpenGL ${OPENGL_LIBRARIES}) -target_link_libraries(ldforge ldforgewidgets) +target_link_libraries(ldforge PRIVATE Qt::Core) +target_link_libraries(ldforge PRIVATE Qt::Widgets) +target_link_libraries(ldforge PRIVATE Qt::OpenGL) +target_link_libraries(ldforge PRIVATE ${OPENGL_LIBRARIES}) +target_link_libraries(ldforge PRIVATE ${GLEW_LIBRARIES}) +target_link_libraries(ldforge PRIVATE ldforgewidgets) add_dependencies(ldforge resources) -#cotire(ldforge) +if (Qt6_FOUND) + target_link_libraries(ldforge PRIVATE Qt6::Core5Compat) + target_link_libraries(ldforge PRIVATE Qt6::OpenGLWidgets) +endif() add_custom_target(linelength ALL COMMAND python3
--- a/src/basics.h Wed Jun 22 23:51:06 2022 +0300 +++ b/src/basics.h Sun Jun 26 19:44:45 2022 +0300 @@ -35,6 +35,7 @@ #include <QStringList> #include <QVariant> #include <QVector> +#include <QMdiArea> #include <glm/glm.hpp> #include "geometry.h" #include "functional.h" @@ -43,8 +44,12 @@ template<typename T> using opt = std::optional<T>; +//! \brief Return type of qHash. unsigned int on Qt5, unsigned long on Qt6. +using hash_t = decltype(qHash(0)); + Q_DECLARE_METATYPE(glm::vec3) Q_DECLARE_METATYPE(glm::mat4) +Q_DECLARE_METATYPE(QMdiArea::ViewMode) //! \brief count the amount of elements in a basic array template<typename T, int N> @@ -265,7 +270,7 @@ } template<typename T, glm::qualifier Q> -constexpr unsigned int qHash(const glm::vec<3, T, Q>& key) +constexpr auto qHash(const glm::vec<3, T, Q>& key) { return qHash(key.x) ^ rotl10(qHash(key.y)) ^ rotl20(qHash(key.z)); }
--- a/src/colors.cpp Wed Jun 22 23:51:06 2022 +0300 +++ b/src/colors.cpp Sun Jun 26 19:44:45 2022 +0300 @@ -1,3 +1,5 @@ +#include <QRegExp> +#include <QIODevice> #include "colors.h" const ColorDefinition unknownColor{{}, {}, "Unknown", "???"};
--- a/src/documentmanager.cpp Wed Jun 22 23:51:06 2022 +0300 +++ b/src/documentmanager.cpp Sun Jun 26 19:44:45 2022 +0300 @@ -117,7 +117,7 @@ const OpenType openType ) { QFile file{path}; - const QString name = pathToName(path); + const QString name = pathToName(QFileInfo{path}); file.open(QFile::ReadOnly | QFile::Text); std::unique_ptr<Model> newModel = std::make_unique<Model>(nullptr); QTextStream textStream{&file};
--- a/src/functional.h Wed Jun 22 23:51:06 2022 +0300 +++ b/src/functional.h Sun Jun 26 19:44:45 2022 +0300 @@ -76,14 +76,16 @@ return std::back_inserter(vec); } +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) + // In Qt6 QVector is now a QList instead, so we need to disable this // Constructs a back_inserter for QVector template<typename T> auto makeDefaultInserter(QVector<T>& vec) { return std::back_inserter(vec); } +#endif - // Constructs a back_inserter for QList template<typename T> auto makeDefaultInserter(QList<T>& vec) { @@ -110,12 +112,14 @@ using type = std::vector<TT>; }; +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) // Changes the value type of QVector template<typename T, typename TT> struct ChangeContainerValueType<QVector<T>, TT> { using type = QVector<TT>; }; +#endif // Changes the value type of QSet template<typename T, typename TT>
--- a/src/gl/axesprogram.cpp Wed Jun 22 23:51:06 2022 +0300 +++ b/src/gl/axesprogram.cpp Sun Jun 26 19:44:45 2022 +0300 @@ -16,10 +16,10 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include "gl/partrenderer.h" #include <QPainter> #include <QPainterPath> #include "axesprogram.h" -#include "gl/partrenderer.h" static constexpr char vertexShaderSource[] = R"( #version 330 core
--- a/src/gl/basicshaderprogram.cpp Wed Jun 22 23:51:06 2022 +0300 +++ b/src/gl/basicshaderprogram.cpp Sun Jun 26 19:44:45 2022 +0300 @@ -40,7 +40,6 @@ { if (not this->isInitialized) { - this->initializeOpenGLFunctions(); this->isInitialized = true; this->program = std::make_unique<gl::ShaderProgram>(); gl::buildShaders(this->program.get(), vertexShaderSource, fragmentShaderSource);
--- a/src/gl/basicshaderprogram.h Wed Jun 22 23:51:06 2022 +0300 +++ b/src/gl/basicshaderprogram.h Sun Jun 26 19:44:45 2022 +0300 @@ -11,7 +11,7 @@ //! @brief A collection of a single VAO with a single VBO, //! a vertex shader and a fragment shader. -class BasicShader final : protected QOpenGLFunctions +class BasicShader final { bool isInitialized = false; QOpenGLBuffer buffer;
--- a/src/gl/common.h Wed Jun 22 23:51:06 2022 +0300 +++ b/src/gl/common.h Sun Jun 26 19:44:45 2022 +0300 @@ -20,10 +20,10 @@ #include <QWidget> #include <QColor> #include <QOpenGLBuffer> -#include <QOpenGLFunctions> #include <QOpenGLShader> #include <QOpenGLShaderProgram> #include <QOpenGLVertexArrayObject> +#include <QOpenGLFunctions> #include <glm/gtc/type_ptr.hpp> #include "basics.h" #include "colors.h" @@ -47,6 +47,8 @@ } }; +QOpenGLFunctions& glfunc(); + namespace gl { class ShaderProgram; @@ -84,8 +86,6 @@ } }; -extern QOpenGLFunctions glfunc; - namespace gl { // Different ways to render the scene
--- a/src/gl/compiler.cpp Wed Jun 22 23:51:06 2022 +0300 +++ b/src/gl/compiler.cpp Sun Jun 26 19:44:45 2022 +0300 @@ -16,9 +16,6 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#define GL_GLEXT_PROTOTYPES -#include <GL/glu.h> -#include <GL/glext.h> #include <QMessageBox> #include "gl/compiler.h" #include "documentmanager.h" @@ -213,8 +210,10 @@ shader.program->setAttributeBuffer(0, GL_FLOAT, offsetof(Vertex, position), 3, stride); shader.program->setAttributeBuffer(1, GL_FLOAT, offsetof(Vertex, color), 4, stride); shader.program->setAttributeBuffer(2, GL_FLOAT, offsetof(Vertex, normal), 3, stride); - glVertexAttribIPointer(3, 1, GL_INT, stride, reinterpret_cast<void*>(offsetof(Vertex, id))); - glVertexAttribIPointer(4, 1, GL_INT, stride, reinterpret_cast<void*>(offsetof(Vertex, selected))); + const void* vertexptr = reinterpret_cast<const void*>(offsetof(Vertex, id)); + glfunc().glVertexAttribPointer(3, 1, GL_INT, GL_FALSE, stride, vertexptr); + const void* selectedptr = reinterpret_cast<const void*>(offsetof(Vertex, selected)); + glfunc().glVertexAttribPointer(4, 1, GL_INT, GL_FALSE, stride, selectedptr); shader.vertexArray.release(); shader.buffer.release(); shader.program->release(); @@ -350,7 +349,8 @@ } const GLsizeiptr size = static_cast<int>(vector.size() * sizeof vector[0]); object.buffer.bind(); - glBufferSubData(GL_ARRAY_BUFFER, 0, size, vector.data()); + QOpenGLFunctions glfunc; + glfunc.glBufferSubData(GL_ARRAY_BUFFER, 0, size, vector.data()); object.buffer.release(); } }
--- a/src/gl/compiler.h Wed Jun 22 23:51:06 2022 +0300 +++ b/src/gl/compiler.h Sun Jun 26 19:44:45 2022 +0300 @@ -17,14 +17,13 @@ */ #pragma once -#include "basics.h" -#include "gl/common.h" -#include "types/boundingbox.h" #include <glm/gtc/type_ptr.hpp> #include <QOpenGLVertexArrayObject> #include <QOpenGLBuffer> #include <QOpenGLShaderProgram> -#include <QOpenGLExtraFunctions> +#include "basics.h" +#include "gl/common.h" +#include "types/boundingbox.h" #include "model.h" class Model; @@ -89,7 +88,7 @@ for (gl::ModelShaders::ShaderObject& shader : shaders->shaderObjects) { shader.program->bind(); - const int location = glfunc.glGetUniformLocation(shader.program->programId(), uniformName); + const int location = glfunc().glGetUniformLocation(shader.program->programId(), uniformName); Q_ASSERT(location != -1); shader.program->setUniformValue(location, std::forward<T>(value)); shader.program->release();
--- a/src/gl/partrenderer.cpp Wed Jun 22 23:51:06 2022 +0300 +++ b/src/gl/partrenderer.cpp Sun Jun 26 19:44:45 2022 +0300 @@ -33,7 +33,12 @@ static constexpr double MIN_ZOOM = -3.0; static constexpr double MAX_ZOOM = 3.0; -QOpenGLFunctions glfunc; + +QOpenGLFunctions& glfunc() +{ + static QOpenGLFunctions funcs; + return funcs; +} PartRenderer::PartRenderer( Model* model, @@ -87,11 +92,7 @@ void PartRenderer::initializeGL() { - ::glfunc.initializeOpenGLFunctions(); - if (glGetError() != GL_NO_ERROR) - { - abort(); - } + glfunc().initializeOpenGLFunctions(); gl::initializeModelShaders(&this->shaders); for (RenderLayer* layer : this->activeRenderLayers) { layer->initializeGL(); @@ -468,7 +469,7 @@ this->renderScene(); std::array<GLubyte, 3> data; this->checkForGLErrors(); - glfunc.glReadPixels(where.x(), where.y(), 1, 1, GL_RGB, GL_UNSIGNED_BYTE, &data[0]); + glReadPixels(where.x(), where.y(), 1, 1, GL_RGB, GL_UNSIGNED_BYTE, &data[0]); this->checkForGLErrors(); fbo.release(); this->renderPreferences.style = oldRenderStyle;
--- a/src/libraries.cpp Wed Jun 22 23:51:06 2022 +0300 +++ b/src/libraries.cpp Sun Jun 26 19:44:45 2022 +0300 @@ -30,24 +30,6 @@ } /** - * @brief Yields a begin-terator for the libraries - * @return iterator - */ -QVector<Library>::const_iterator LibrariesModel::begin() const -{ - return this->libraries.begin(); -} - -/** - * @brief Yields an end-iterator for the libraries - * @return iterator - */ -QVector<Library>::const_iterator LibrariesModel::end() const -{ - return this->libraries.end(); -} - -/** * @brief Searches the libraries for the specified file name. * @param fileName File to search for * @return Full path to the file, or empty string if not found. @@ -63,7 +45,7 @@ { QDir directory = library.path; directory.cd(subdirectory); - QFileInfo fileInfo = directory.absoluteFilePath(fileName); + QFileInfo fileInfo{directory.absoluteFilePath(fileName)}; if (fileInfo.exists() && fileInfo.isFile()) { path = fileInfo.absoluteFilePath(); @@ -86,7 +68,7 @@ void LibrariesModel::addLibrary(const Library& library) { Q_EMIT layoutAboutToBeChanged(); - libraries.append(library); + this->libraries.push_back(library); Q_EMIT layoutChanged(); } @@ -94,13 +76,13 @@ * @brief Removes a library by index. Does nothing if the index is not valid. * @param libraryIndex Index of the library */ -void LibrariesModel::removeLibrary(const int libraryIndex) +void LibrariesModel::removeLibrary(const std::size_t libraryIndex) { Q_ASSERT(isValidIndex(libraryIndex)); if (isValidIndex(libraryIndex)) { Q_EMIT layoutAboutToBeChanged(); - libraries.remove(libraryIndex); + this->libraries.erase(this->libraries.begin() + static_cast<long>(libraryIndex)); Q_EMIT layoutChanged(); } } @@ -111,7 +93,7 @@ * @param libraryIndex Index of the library * @return const reference */ -const Library& LibrariesModel::library(int libraryIndex) const +const Library& LibrariesModel::library(std::size_t libraryIndex) const { Q_ASSERT(isValidIndex(libraryIndex)); return this->libraries[libraryIndex]; @@ -122,7 +104,7 @@ * @param libraryIndex Index of the library * @param path New path */ -void LibrariesModel::setLibraryPath(int libraryIndex, const QDir& path) +void LibrariesModel::setLibraryPath(std::size_t libraryIndex, const QDir& path) { if (this->isValidIndex(libraryIndex)) { @@ -136,7 +118,7 @@ * @param libraryIndex Index of the library * @param role New role */ -void LibrariesModel::setLibraryRole(int libraryIndex, const Library::Role role) +void LibrariesModel::setLibraryRole(std::size_t libraryIndex, const Library::Role role) { if (this->isValidIndex(libraryIndex)) { @@ -167,12 +149,12 @@ /** * @returns the amount of libraries */ -int LibrariesModel::count() const +std::size_t LibrariesModel::count() const { return this->libraries.size(); } -void LibrariesModel::moveLibrary(const int libraryFromIndex, const int libraryToIndex) +void LibrariesModel::moveLibrary(const std::size_t libraryFromIndex, const std::size_t libraryToIndex) { if (isValidIndex(libraryFromIndex) and (isValidIndex(libraryToIndex) or libraryToIndex == count()) and @@ -180,15 +162,17 @@ { Q_EMIT layoutAboutToBeChanged(); const Library library = this->library(libraryFromIndex); - if (libraryToIndex > libraryFromIndex) + const auto from = this->libraries.begin() + signed_cast(libraryFromIndex); + const auto to = this->libraries.begin() + signed_cast(libraryToIndex); + if (to > from) { - this->libraries.insert(libraryToIndex, library); - this->libraries.removeAt(libraryFromIndex); + this->libraries.insert(to, library); + this->libraries.erase(from); } else if (libraryToIndex < libraryFromIndex) { - this->libraries.removeAt(libraryFromIndex); - this->libraries.insert(libraryToIndex, library); + this->libraries.erase(from); + this->libraries.insert(to, library); } Q_EMIT layoutChanged(); } @@ -199,7 +183,7 @@ * @param libraryIndex Index to check * @returns whether or not it is valid */ -bool LibrariesModel::isValidIndex(const int libraryIndex) const +bool LibrariesModel::isValidIndex(const std::size_t libraryIndex) const { return libraryIndex >= 0 && libraryIndex < this->libraries.size(); } @@ -275,7 +259,7 @@ { const int row = index.row(); const Column column = static_cast<Column>(index.column()); - const Library& library = this->library(row); + const Library& library = this->library(static_cast<std::size_t>(row)); switch (column) { case RoleColumn: @@ -320,7 +304,7 @@ */ int LibrariesModel::rowCount(const QModelIndex&) const { - return this->count(); + return static_cast<int>(this->count()); } /** @@ -337,11 +321,11 @@ * to update the table widget know when libraries are changed. * @param libraryIndex Index of the library. */ -void LibrariesModel::signalLibraryChange(int libraryIndex) +void LibrariesModel::signalLibraryChange(std::size_t libraryIndex) { Q_ASSERT(isValidIndex(libraryIndex)); - const QModelIndex topLeft = this->index(libraryIndex, 0); - const QModelIndex bottomRight = this->index(libraryIndex, columnCount({}) - 1); + const QModelIndex topLeft = this->index(static_cast<int>(libraryIndex), 0); + const QModelIndex bottomRight = this->index(static_cast<int>(libraryIndex), columnCount({}) - 1); Q_EMIT dataChanged(topLeft, bottomRight); } @@ -378,3 +362,26 @@ { return one.role == other.role and one.path == other.path; } + +/* +QDataStream &operator<<(QDataStream& stream, const Libraries& libs) +{ + const auto size = static_cast<std::uint32_t>(libs.size()); + stream << size; + for (std::uint32_t i = 0; i < size; ++i) { + stream << libs[i]; + } + return stream; +} + +QDataStream &operator>>(QDataStream& stream, Libraries& libs) +{ + std::uint32_t size; + stream >> size; + libs.resize(size); + for (std::uint32_t i = 0; i < size; ++i) { + stream >> libs[i]; + } + return stream; +} +*/
--- a/src/libraries.h Wed Jun 22 23:51:06 2022 +0300 +++ b/src/libraries.h Sun Jun 26 19:44:45 2022 +0300 @@ -45,8 +45,10 @@ QDataStream &operator<<(QDataStream&, const Library&); QDataStream &operator>>(QDataStream&, Library&); -using Libraries = QVector<Library>; -Q_DECLARE_METATYPE(Libraries) +using Libraries = QList<Library>; +//QDataStream &operator<<(QDataStream&, const Libraries&); +//QDataStream &operator>>(QDataStream&, Libraries&); +//Q_DECLARE_METATYPE(Libraries) class Configuration; @@ -55,18 +57,18 @@ Q_OBJECT public: LibrariesModel(QObject* parent = nullptr); - QVector<Library>::const_iterator begin() const; - QVector<Library>::const_iterator end() const; + auto begin() const { return this->libraries.begin(); } + auto end() const { return this->libraries.end(); } QString findFile(QString fileName) const; void addLibrary(const Library& library); - void removeLibrary(const int libraryIndex); - const Library& library(int libraryIndex) const; - void setLibraryPath(int libraryIndex, const QDir& path); - void setLibraryRole(int libraryIndex, const Library::Role role); + void removeLibrary(const std::size_t libraryIndex); + const Library& library(std::size_t libraryIndex) const; + void setLibraryPath(std::size_t libraryIndex, const QDir& path); + void setLibraryRole(std::size_t libraryIndex, const Library::Role role); void restoreFromSettings(); void storeToSettings(); - int count() const; - void moveLibrary(const int libraryFromIndex, const int libraryToIndex); + std::size_t count() const; + void moveLibrary(const std::size_t libraryFromIndex, const std::size_t libraryToIndex); // Definitions for QAbstractTableModel Qt::ItemFlags flags(const QModelIndex& index) const override; QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override; @@ -76,7 +78,7 @@ int role = Qt::DisplayRole) const override; int rowCount(const QModelIndex&) const override; int columnCount(const QModelIndex&) const override; - bool isValidIndex(const int libraryIndex) const; + bool isValidIndex(const std::size_t libraryIndex) const; ColorTable loadColorTable(QTextStream& errors) const; private: enum Column @@ -84,6 +86,6 @@ RoleColumn, PathColumn }; - void signalLibraryChange(int library); + void signalLibraryChange(std::size_t library); Libraries libraries; };
--- a/src/main.cpp Wed Jun 22 23:51:06 2022 +0300 +++ b/src/main.cpp Sun Jun 26 19:44:45 2022 +0300 @@ -72,10 +72,16 @@ QCoreApplication::setOrganizationName("hecknology.net"); QCoreApplication::setOrganizationDomain("hecknology.net"); qRegisterMetaType<Message>(); + qRegisterMetaType<Library>(); + qRegisterMetaType<QList<Library>>(); + qRegisterMetaType<QMdiArea::ViewMode>(); + qRegisterMetaType<gl::RenderStyle>(); +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) qRegisterMetaTypeStreamOperators<Library>("Library"); qRegisterMetaTypeStreamOperators<Libraries>("Libraries"); qRegisterMetaTypeStreamOperators<gl::RenderStyle>(); qRegisterMetaTypeStreamOperators<QMdiArea::ViewMode>(); +#endif } template<typename BaseType, typename MemberType, typename DataType> @@ -153,7 +159,7 @@ { if (not locale.isEmpty()) { const QString localeCode = ::localeCode(locale); - QLocale::setDefault({localeCode}); + QLocale::setDefault(QLocale{localeCode}); qApp->removeTranslator(translator); const QString path = LOCALE_DIR.filePath(localeCode + ".qm"); const bool loadSuccessful = translator->load(path);
--- a/src/mainwindow.h Wed Jun 22 23:51:06 2022 +0300 +++ b/src/mainwindow.h Sun Jun 26 19:44:45 2022 +0300 @@ -21,7 +21,6 @@ #include <QTranslator> #include <QSettings> #include <QKeySequence> -#include "configuration.h" #include "documentmanager.h" #include "libraries.h" #include "uiutilities.h"
--- a/src/model.h Wed Jun 22 23:51:06 2022 +0300 +++ b/src/model.h Sun Jun 26 19:44:45 2022 +0300 @@ -198,7 +198,7 @@ constexpr auto operator<=>(const ModelId& other) const = default; }; -constexpr unsigned int qHash(ModelId id) +constexpr auto qHash(ModelId id) { return qHash(id.value); }
--- a/src/parser.cpp Wed Jun 22 23:51:06 2022 +0300 +++ b/src/parser.cpp Sun Jun 26 19:44:45 2022 +0300 @@ -16,6 +16,8 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include <QRegExp> +#include <QIODevice> #include "model.h" #include "parser.h" #include "ldrawalgorithm.h" @@ -201,7 +203,7 @@ line = line.trimmed(); try { - const QStringList tokens = line.split(QRegExp{R"(\s+)"}); + const QStringList tokens = line.simplified().split(" "); if (tokens.empty() or tokens == QStringList{{""}}) { return Empty{};
--- a/src/settings.h Wed Jun 22 23:51:06 2022 +0300 +++ b/src/settings.h Sun Jun 26 19:44:45 2022 +0300 @@ -42,7 +42,7 @@ SETTING(LogOpenGLDebugMessages, false) // File management options -SETTING(Libraries, QVector<Library>{}) +SETTING(Libraries, Libraries{}) // End of setting definitions // ----------------------------------------------------------------------------- @@ -74,7 +74,7 @@ template<class X> inline void setSetting(const SettingType_t<X>& value) { - if (value == settingDefaultValue<X>()) { + if (false/*value == settingDefaultValue<X>()*/) { QSettings{}.remove(settingName<X>); } else {
--- a/src/settingseditor/keyboardshortcutseditor.cpp Wed Jun 22 23:51:06 2022 +0300 +++ b/src/settingseditor/keyboardshortcutseditor.cpp Sun Jun 26 19:44:45 2022 +0300 @@ -10,7 +10,7 @@ int KeyboardShortcutsEditor::rowCount(const QModelIndex&) const { - return this->actions.size(); + return static_cast<int>(this->actions.size()); } int KeyboardShortcutsEditor::columnCount(const QModelIndex&) const @@ -22,7 +22,7 @@ const QModelIndex& index, int role) const { - QAction* const action = this->actions[index.row()]; + QAction* const action = this->actions[static_cast<std::size_t>(index.row())]; const Column column = static_cast<Column>(index.column()); switch(role) {
--- a/src/settingseditor/keyboardshortcutseditor.h Wed Jun 22 23:51:06 2022 +0300 +++ b/src/settingseditor/keyboardshortcutseditor.h Sun Jun 26 19:44:45 2022 +0300 @@ -17,5 +17,5 @@ QVariant data(const QModelIndex& index, int role) const override; QVariant headerData(int section, Qt::Orientation orientation, int role) const override; private: - const QVector<QAction*> actions; + const std::vector<QAction*> actions; };
--- a/src/settingseditor/librarieseditor.cpp Wed Jun 22 23:51:06 2022 +0300 +++ b/src/settingseditor/librarieseditor.cpp Sun Jun 26 19:44:45 2022 +0300 @@ -6,7 +6,6 @@ LibrariesEditor::LibrariesEditor(QWidget* parent) : QWidget{parent}, - libraries{this}, ui{*new Ui_LibrariesEditor} { this->ui.setupUi(this); @@ -20,13 +19,13 @@ &QPushButton::clicked, this, &LibrariesEditor::addNewLibrary); - this->ui.librariesTable->setModel(&this->libraries); this->ui.librariesTable->setContextMenuPolicy(Qt::CustomContextMenu); connect( this->ui.librariesTable, &QWidget::customContextMenuRequested, this, &LibrariesEditor::showContextMenu); + this->setEnabled(false); } LibrariesEditor::~LibrariesEditor() @@ -45,33 +44,36 @@ void LibrariesEditor::addNewLibrary() { - const QDir dir{this->ui.newLibraryPath->text()}; - if (not dir.exists()) - { - QMessageBox::critical( + if (LibrariesModel* model = this->currentModel()) { + const QDir dir{this->ui.newLibraryPath->text()}; + if (not dir.exists()) + { + QMessageBox::critical( this, tr("Library does not exist"), tr("The directory %1 does not exist.").arg(quoted(dir.path())) - ); - } - else - { - if (not dir.isReadable()) + ); + } + else { - QMessageBox::warning(this, + if (not dir.isReadable()) + { + QMessageBox::warning(this, tr("Unreadable library"), tr("The directory %1 cannot be read.").arg(quoted(dir.path())) - ); + ); + } + model->addLibrary({Library::OfficialLibrary, dir}); + this->ui.newLibraryPath->clear(); } - this->libraries.addLibrary({Library::OfficialLibrary, dir}); - this->ui.newLibraryPath->clear(); } } void LibrariesEditor::showContextMenu(const QPoint position) { - const int libraryIndex = this->currentLibraryIndex(); - if (this->libraries.isValidIndex(libraryIndex)) + const std::size_t libraryIndex = this->currentLibraryIndex(); + LibrariesModel* model = this->currentModel(); + if (model != nullptr and model->isValidIndex(libraryIndex)) { QMenu* contextMenu = new QMenu{this}; QAction* removeAction = new QAction{tr("Remove library")}; @@ -115,36 +117,58 @@ void LibrariesEditor::setCurrentLibraryRole() { - const int libraryIndex = currentLibraryIndex(); - QObject* senderObject = sender(); - QAction* senderAction = qobject_cast<QAction*>(senderObject); - const Library::Role role = senderAction->data().value<Library::Role>(); - this->libraries.setLibraryRole(libraryIndex, role); + if (LibrariesModel* model = this->currentModel()) { + const std::size_t libraryIndex = currentLibraryIndex(); + QObject* senderObject = sender(); + QAction* senderAction = qobject_cast<QAction*>(senderObject); + const Library::Role role = senderAction->data().value<Library::Role>(); + model->setLibraryRole(libraryIndex, role); + } } void LibrariesEditor::removeCurrentLibrary() { - this->libraries.removeLibrary(currentLibraryIndex()); + if (LibrariesModel* model = this->currentModel()) { + model->removeLibrary(currentLibraryIndex()); + } } void LibrariesEditor::moveCurrentLibraryUp() { - const int libraryIndex = this->currentLibraryIndex(); - this->libraries.moveLibrary(libraryIndex, libraryIndex - 1); + if (LibrariesModel* model = this->currentModel()) { + const std::size_t libraryIndex = this->currentLibraryIndex(); + model->moveLibrary(libraryIndex, libraryIndex - 1); + } } void LibrariesEditor::moveCurrentLibraryDown() { - const int libraryIndex = this->currentLibraryIndex(); - this->libraries.moveLibrary(libraryIndex + 1, libraryIndex); + if (LibrariesModel* model = this->currentModel()) { + const std::size_t libraryIndex = this->currentLibraryIndex(); + model->moveLibrary(libraryIndex + 1, libraryIndex); + } } -int LibrariesEditor::currentLibraryIndex() const +LibrariesModel *LibrariesEditor::currentModel() { - return this->ui.librariesTable->selectionModel()->currentIndex().row(); + return qobject_cast<LibrariesModel*>(this->ui.librariesTable->model()); +} + +std::size_t LibrariesEditor::currentLibraryIndex() const +{ + const int row = this->ui.librariesTable->selectionModel()->currentIndex().row(); + return static_cast<std::size_t>(row); } void LibrariesEditor::saveSettings() { - this->libraries.storeToSettings(); + if (LibrariesModel* model = this->currentModel()) { + model->storeToSettings(); + } } + +void LibrariesEditor::setModel(LibrariesModel *model) +{ + this->ui.librariesTable->setModel(model); + this->setEnabled(model != nullptr); +}
--- a/src/settingseditor/librarieseditor.h Wed Jun 22 23:51:06 2022 +0300 +++ b/src/settingseditor/librarieseditor.h Sun Jun 26 19:44:45 2022 +0300 @@ -10,6 +10,7 @@ LibrariesEditor(QWidget* parent = nullptr); ~LibrariesEditor(); void saveSettings(); + void setModel(LibrariesModel *model); private Q_SLOTS: void searchPathForNewLibrary(); void addNewLibrary(); @@ -24,7 +25,7 @@ RoleColumn, PathColumn }; - LibrariesModel libraries; class Ui_LibrariesEditor& ui; - int currentLibraryIndex() const; + LibrariesModel* currentModel(); + std::size_t currentLibraryIndex() const; };
--- a/src/settingseditor/settingseditor.cpp Wed Jun 22 23:51:06 2022 +0300 +++ b/src/settingseditor/settingseditor.cpp Sun Jun 26 19:44:45 2022 +0300 @@ -22,6 +22,7 @@ this->ui.viewModeButtonGroup->setId(this->ui.viewModeSubWindows, int{QMdiArea::SubWindowView}); this->loadLocales(); this->setDefaults(); + this->librariesEditor.setModel(&libraries); QVBoxLayout* layout = new QVBoxLayout{this}; layout->addWidget(&librariesEditor); this->ui.tabLdrawLibraries->setLayout(layout); @@ -77,6 +78,7 @@ void SettingsEditor::setDefaults() { + this->libraries.restoreFromSettings(); this->setCurrentLanguage(setting<Setting::Locale>()); this->ui.mainColorButton->setColor(setting<Setting::MainColor>()); this->ui.backgroundColorButton->setColor(setting<Setting::BackgroundColor>());
--- a/src/settingseditor/settingseditor.h Wed Jun 22 23:51:06 2022 +0300 +++ b/src/settingseditor/settingseditor.h Sun Jun 26 19:44:45 2022 +0300 @@ -4,7 +4,6 @@ #include "librarieseditor.h" #include "libraries.h" #include "uiutilities.h" -#include "configuration.h" class SettingsEditor : public QDialog {
--- a/src/uiutilities.cpp Wed Jun 22 23:51:06 2022 +0300 +++ b/src/uiutilities.cpp Sun Jun 26 19:44:45 2022 +0300 @@ -17,11 +17,12 @@ */ #include <QStyleFactory> +#include <QWidget> #include "uiutilities.h" -QVector<QAction*> uiutilities::collectActions(QObject* subject) +std::vector<QAction*> uiutilities::collectActions(QObject* subject) { - QVector<QAction*> actions; + std::vector<QAction*> actions; for (QAction* action : subject->findChildren<QAction*>()) { if (not action->text().isEmpty() @@ -34,7 +35,7 @@ return actions; } -uiutilities::KeySequenceMap uiutilities::makeKeySequenceMap(const QVector<QAction*>& actions) +uiutilities::KeySequenceMap uiutilities::makeKeySequenceMap(const std::vector<QAction*>& actions) { KeySequenceMap result; for (QAction* action : actions) @@ -51,4 +52,4 @@ widget->setAutoFillBackground(true); widget->setStyle(QStyleFactory::create("Fusion")); widget->update(); -} \ No newline at end of file +}
--- a/src/uiutilities.h Wed Jun 22 23:51:06 2022 +0300 +++ b/src/uiutilities.h Sun Jun 26 19:44:45 2022 +0300 @@ -22,7 +22,7 @@ namespace uiutilities { using KeySequenceMap = QMap<QString, QKeySequence>; - QVector<QAction*> collectActions(QObject* subject); - KeySequenceMap makeKeySequenceMap(const QVector<QAction*>& actions); + std::vector<QAction *> collectActions(QObject* subject); + KeySequenceMap makeKeySequenceMap(const std::vector<QAction*>& actions); void colorizeWidget(QWidget* widget, const QColor& color); }
--- a/src/vertexmap.cpp Wed Jun 22 23:51:06 2022 +0300 +++ b/src/vertexmap.cpp Sun Jun 26 19:44:45 2022 +0300 @@ -1,7 +1,7 @@ #include "vertexmap.h" #include "gl/common.h" -unsigned int hashVertex(const glm::vec3& vec) +hash_t hashVertex(const glm::vec3& vec) { return qHash(glm::ivec3{ int(vec.x * 10000), @@ -130,7 +130,7 @@ return glm::mat4{{a, 0}, {-c, 0}, {d, 0}, {}}; }); points(element, [&](const glm::vec3 point) { - const unsigned int hash = hashVertex(point); + const hash_t hash = hashVertex(point); VertexInfo& info = this->map[hash]; info.point = point; info.objects.insert(this->model->idAt(i));
--- a/src/vertexmap.h Wed Jun 22 23:51:06 2022 +0300 +++ b/src/vertexmap.h Sun Jun 26 19:44:45 2022 +0300 @@ -26,9 +26,9 @@ Q_SIGNAL void verticesChanged(); private: const Model* const model; - QSet<unsigned int> vertexHashes; + QSet<hash_t> vertexHashes; std::vector<glm::vec3> vertices; - std::map<unsigned int, VertexInfo> map; + std::map<hash_t, VertexInfo> map; }; #endif // VERTEXMAP_H
--- a/widgets/CMakeLists.txt Wed Jun 22 23:51:06 2022 +0300 +++ b/widgets/CMakeLists.txt Sun Jun 26 19:44:45 2022 +0300 @@ -1,5 +1,4 @@ -find_package(Qt5 REQUIRED COMPONENTS UiPlugin) -qt5_wrap_ui(LDFORGEWIDGETS_FORMS +qt_wrap_ui(LDFORGEWIDGETS_FORMS vec3editor.ui multiplyfactordialog.ui matrixeditor.ui @@ -21,14 +20,14 @@ ${LDFORGEWIDGETS_FORMS} ) -get_target_property(Qt5UiPlugin_INCLUDES Qt5::UiPlugin INTERFACE_INCLUDE_DIRECTORIES) -target_include_directories(ldforgewidgets PUBLIC ${Qt5UiPlugin_INCLUDES}) +get_target_property(UIPLUGIN_INCLUDES QtUiPlugin INTERFACE_INCLUDE_DIRECTORIES) +target_include_directories(ldforgewidgets PUBLIC "${UIPLUGIN_INCLUDES}") target_include_directories(ldforgewidgets PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}") target_include_directories(ldforgewidgets PUBLIC "${CMAKE_CURRENT_BINARY_DIR}") -target_link_libraries(ldforgewidgets Qt5::Widgets) +target_link_libraries(ldforgewidgets Qt::Widgets) set_target_properties(ldforgewidgets PROPERTIES AUTOMOC 1) -get_target_property(QT_QMAKE_EXECUTABLE Qt5::qmake LOCATION) +get_target_property(QT_QMAKE_EXECUTABLE Qt::qmake LOCATION) execute_process(COMMAND ${QT_QMAKE_EXECUTABLE} -query QT_INSTALL_PLUGINS OUTPUT_VARIABLE QT_INSTALL_PLUGINS OUTPUT_STRIP_TRAILING_WHITESPACE )
--- a/widgets/doublespinbox.cpp Wed Jun 22 23:51:06 2022 +0300 +++ b/widgets/doublespinbox.cpp Sun Jun 26 19:44:45 2022 +0300 @@ -24,7 +24,7 @@ DoubleSpinBox::DoubleSpinBox(QWidget* parent) : QDoubleSpinBox {parent} { - this->setLocale({"C"}); + this->setLocale(QLocale{"C"}); this->setRange(-1e6, 1e6); this->setDecimals(4); }