diff --git a/3rdparty/QtPropertyBrowser/CMakeLists.txt b/3rdparty/QtPropertyBrowser/CMakeLists.txt index a86b5c6b29..65101760e6 100644 --- a/3rdparty/QtPropertyBrowser/CMakeLists.txt +++ b/3rdparty/QtPropertyBrowser/CMakeLists.txt @@ -1,11 +1,3 @@ CMAKE_MINIMUM_REQUIRED(VERSION 3.13) - PROJECT(QtPropertyBrowser) - -##################### Look for required libraries ###################### - -# Add QT dependencies -FIND_PACKAGE(Qt5Widgets REQUIRED) - -######################### Add Primary Targets ########################## ADD_SUBDIRECTORY(src) diff --git a/3rdparty/QtPropertyBrowser/src/CMakeLists.txt b/3rdparty/QtPropertyBrowser/src/CMakeLists.txt index 9d02d58d12..ad67f6f7da 100644 --- a/3rdparty/QtPropertyBrowser/src/CMakeLists.txt +++ b/3rdparty/QtPropertyBrowser/src/CMakeLists.txt @@ -23,8 +23,13 @@ set(_RESOURCES qtpropertybrowser.qrc ) -QT5_WRAP_UI(_UI_SRCS ${_UI_FORMS}) -QT5_ADD_RESOURCES(_QRC_SRCS ${_RESOURCES}) +if (Qt6_FOUND) + QT6_WRAP_UI(_UI_SRCS ${_UI_FORMS}) + QT6_ADD_RESOURCES(_QRC_SRCS ${_RESOURCES}) +else() + QT5_WRAP_UI(_UI_SRCS ${_UI_FORMS}) + QT5_ADD_RESOURCES(_QRC_SRCS ${_RESOURCES}) +endif() set(TARGET_NAME ${PROJECT_NAME}) @@ -34,8 +39,14 @@ add_library(${TARGET_NAME} STATIC ${_QRC_SRCS} ) +target_compile_options(${TARGET_NAME} PRIVATE -Wno-deprecated-declarations) + if (MSVC) target_compile_options(${TARGET_NAME} PRIVATE /wd4457 /wd4718) endif() -target_link_libraries(${TARGET_NAME} Qt5::Widgets) +if (Qt6_FOUND) + target_link_libraries(${TARGET_NAME} Qt6::Widgets) +else() + target_link_libraries(${TARGET_NAME} Qt5::Widgets) +endif() diff --git a/3rdparty/QtPropertyBrowser/src/qt5compat.h b/3rdparty/QtPropertyBrowser/src/qt5compat.h new file mode 100644 index 0000000000..969e74458c --- /dev/null +++ b/3rdparty/QtPropertyBrowser/src/qt5compat.h @@ -0,0 +1,12 @@ +#pragma once +#include + +#if QT_VERSION_MAJOR >= 6 +#include +#include + +// QRegExp / QRegExpValidator aliases +using QRegExp = QRegularExpression; +using QRegExpValidator = QRegularExpressionValidator; + +#endif diff --git a/3rdparty/QtPropertyBrowser/src/qteditorfactory.cpp b/3rdparty/QtPropertyBrowser/src/qteditorfactory.cpp index 4920f472b3..d3a0b1ef1f 100644 --- a/3rdparty/QtPropertyBrowser/src/qteditorfactory.cpp +++ b/3rdparty/QtPropertyBrowser/src/qteditorfactory.cpp @@ -1545,7 +1545,11 @@ QtCharEdit::QtCharEdit(QWidget *parent) { QHBoxLayout *layout = new QHBoxLayout(this); layout->addWidget(m_lineEdit); +#if QT_VERSION_MAJOR >= 6 + layout->setContentsMargins(0,0,0,0); +#else layout->setMargin(0); +#endif m_lineEdit->installEventFilter(this); m_lineEdit->setReadOnly(true); m_lineEdit->setFocusProxy(this); @@ -1669,7 +1673,13 @@ void QtCharEdit::keyReleaseEvent(QKeyEvent *e) void QtCharEdit::paintEvent(QPaintEvent *) { QStyleOption opt; +#if QT_VERSION_MAJOR >= 6 + opt.rect = this->rect(); + opt.state = isEnabled() ? QStyle::State_Enabled : QStyle::State_None; + opt.palette = this->palette(); +#else opt.init(this); +#endif QPainter p(this); style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); } @@ -2240,7 +2250,13 @@ bool QtColorEditWidget::eventFilter(QObject *obj, QEvent *ev) void QtColorEditWidget::paintEvent(QPaintEvent *) { QStyleOption opt; +#if QT_VERSION_MAJOR >= 6 + opt.rect = this->rect(); + opt.state = isEnabled() ? QStyle::State_Enabled : QStyle::State_None; + opt.palette = this->palette(); +#else opt.init(this); +#endif QPainter p(this); style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); } @@ -2462,7 +2478,13 @@ bool QtFontEditWidget::eventFilter(QObject *obj, QEvent *ev) void QtFontEditWidget::paintEvent(QPaintEvent *) { QStyleOption opt; +#if QT_VERSION_MAJOR >= 6 + opt.rect = this->rect(); + opt.state = isEnabled() ? QStyle::State_Enabled : QStyle::State_None; + opt.palette = this->palette(); +#else opt.init(this); +#endif QPainter p(this); style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); } diff --git a/3rdparty/QtPropertyBrowser/src/qtpropertybrowser.h b/3rdparty/QtPropertyBrowser/src/qtpropertybrowser.h index 1ca8783078..17e012cfdb 100644 --- a/3rdparty/QtPropertyBrowser/src/qtpropertybrowser.h +++ b/3rdparty/QtPropertyBrowser/src/qtpropertybrowser.h @@ -41,6 +41,8 @@ #ifndef QTPROPERTYBROWSER_H #define QTPROPERTYBROWSER_H +#include "qt5compat.h" + #include #include diff --git a/3rdparty/QtPropertyBrowser/src/qtpropertybrowserutils.cpp b/3rdparty/QtPropertyBrowser/src/qtpropertybrowserutils.cpp index cd19583583..6f28fcd27b 100644 --- a/3rdparty/QtPropertyBrowser/src/qtpropertybrowserutils.cpp +++ b/3rdparty/QtPropertyBrowser/src/qtpropertybrowserutils.cpp @@ -262,7 +262,13 @@ void QtBoolEdit::mousePressEvent(QMouseEvent *event) void QtBoolEdit::paintEvent(QPaintEvent *) { QStyleOption opt; +#if QT_VERSION_MAJOR >= 6 + opt.rect = this->rect(); + opt.state = isEnabled() ? QStyle::State_Enabled : QStyle::State_None; + opt.palette = this->palette(); +#else opt.init(this); +#endif QPainter p(this); style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); } @@ -274,7 +280,11 @@ QtKeySequenceEdit::QtKeySequenceEdit(QWidget *parent) { QHBoxLayout *layout = new QHBoxLayout(this); layout->addWidget(m_lineEdit); +#if QT_VERSION_MAJOR >= 6 + layout->setContentsMargins(0,0,0,0); +#else layout->setMargin(0); +#endif m_lineEdit->installEventFilter(this); m_lineEdit->setReadOnly(true); m_lineEdit->setFocusProxy(this); @@ -408,7 +418,13 @@ void QtKeySequenceEdit::keyReleaseEvent(QKeyEvent *e) void QtKeySequenceEdit::paintEvent(QPaintEvent *) { QStyleOption opt; +#if QT_VERSION_MAJOR >= 6 + opt.rect = this->rect(); + opt.state = isEnabled() ? QStyle::State_Enabled : QStyle::State_None; + opt.palette = this->palette(); +#else opt.init(this); +#endif QPainter p(this); style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); } diff --git a/3rdparty/QtPropertyBrowser/src/qtpropertymanager.cpp b/3rdparty/QtPropertyBrowser/src/qtpropertymanager.cpp index ef627e9c28..2626af9383 100644 --- a/3rdparty/QtPropertyBrowser/src/qtpropertymanager.cpp +++ b/3rdparty/QtPropertyBrowser/src/qtpropertymanager.cpp @@ -1229,7 +1229,11 @@ class QtStringPropertyManagerPrivate struct Data { - Data() : regExp(QString(QLatin1Char('*')), Qt::CaseSensitive, QRegExp::Wildcard) +#if QT_VERSION_MAJOR >= 6 + Data() : regExp(QRegularExpression(QStringLiteral(".*"))) +#else + Data() : regExp(QString(QLatin1Char('*')), Qt::CaseSensitive, QRegExp::Wildcard) +#endif { } QString val; @@ -1357,7 +1361,11 @@ void QtStringPropertyManager::setValue(QtProperty *property, const QString &val) if (data.val == val) return; +#if QT_VERSION_MAJOR >= 6 + if (data.regExp.isValid() && !data.regExp.match(val).hasMatch()) +#else if (data.regExp.isValid() && !data.regExp.exactMatch(val)) +#endif return; data.val = val; @@ -5854,8 +5862,13 @@ void QtFontPropertyManager::setValue(QtProperty *property, const QFont &val) return; const QFont oldVal = it.value(); +#if QT_VERSION_MAJOR >= 6 + if (oldVal == val && oldVal.resolve(val) == val) + return; +#else if (oldVal == val && oldVal.resolve() == val.resolve()) return; +#endif it.value() = val; diff --git a/3rdparty/QtPropertyBrowser/src/qttreepropertybrowser.cpp b/3rdparty/QtPropertyBrowser/src/qttreepropertybrowser.cpp index 1ed0c98303..e1661e374a 100644 --- a/3rdparty/QtPropertyBrowser/src/qttreepropertybrowser.cpp +++ b/3rdparty/QtPropertyBrowser/src/qttreepropertybrowser.cpp @@ -132,9 +132,9 @@ class QtPropertyEditorView : public QTreeWidget protected: void mouseMoveEvent(QMouseEvent *event) override; void leaveEvent(QEvent *event) override; - void keyPressEvent(QKeyEvent *event) override; - void mousePressEvent(QMouseEvent *event) override; - void drawRow(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override; + void keyPressEvent(QKeyEvent *event); + void mousePressEvent(QMouseEvent *event); + void drawRow(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const; Q_SIGNALS: void hoverPropertyChanged(QtBrowserItem *item); @@ -160,7 +160,8 @@ void QtPropertyEditorView::drawRow(QPainter *painter, const QStyleOptionViewItem hasValue = property->hasValue(); } if (!hasValue && m_editorPrivate->markPropertiesWithoutValue()) { - const QColor c = option.palette.color(QPalette::Dark); + QColor c = m_editorPrivate->calculatedBackgroundColor(m_editorPrivate->indexToBrowserItem(index)); + if (!c.isValid()) c = option.palette.color(QPalette::Dark); painter->fillRect(option.rect, c); opt.palette.setColor(QPalette::AlternateBase, c); } else { @@ -379,7 +380,8 @@ void QtPropertyEditorDelegate::paint(QPainter *painter, const QStyleOptionViewIt } QColor c; if (!hasValue && m_editorPrivate->markPropertiesWithoutValue()) { - c = opt.palette.color(QPalette::Dark); + c = m_editorPrivate->calculatedBackgroundColor(m_editorPrivate->indexToBrowserItem(index)); + if (!c.isValid()) c = opt.palette.color(QPalette::Dark); opt.palette.setColor(QPalette::Text, opt.palette.color(QPalette::BrightText)); } else { c = m_editorPrivate->calculatedBackgroundColor(m_editorPrivate->indexToBrowserItem(index)); @@ -486,7 +488,11 @@ static QIcon drawIndicatorIcon(const QPalette &palette, QStyle *style) void QtTreePropertyBrowserPrivate::init(QWidget *parent) { QHBoxLayout *layout = new QHBoxLayout(parent); +#if QT_VERSION_MAJOR >= 6 + layout->setContentsMargins(0,0,0,0); +#else layout->setMargin(0); +#endif m_treeWidget = new QtPropertyEditorView(parent); m_treeWidget->setEditorPrivate(this); m_treeWidget->setIconSize(QSize(18, 18)); @@ -610,7 +616,6 @@ void QtTreePropertyBrowserPrivate::propertyInserted(QtBrowserItem *index, QtBrow newItem->setFlags(newItem->flags() | Qt::ItemIsEditable); newItem->setExpanded(true); - updateItem(newItem); } diff --git a/3rdparty/QtPropertyBrowser/src/qtvariantproperty.cpp b/3rdparty/QtPropertyBrowser/src/qtvariantproperty.cpp index c003f3e48e..a03f7a4261 100644 --- a/3rdparty/QtPropertyBrowser/src/qtvariantproperty.cpp +++ b/3rdparty/QtPropertyBrowser/src/qtvariantproperty.cpp @@ -986,8 +986,13 @@ QtVariantPropertyManager::QtVariantPropertyManager(QObject *parent) QtStringPropertyManager *stringPropertyManager = new QtStringPropertyManager(this); d_ptr->m_typeToPropertyManager[QVariant::String] = stringPropertyManager; d_ptr->m_typeToValueType[QVariant::String] = QVariant::String; +#if QT_VERSION_MAJOR >= 6 + d_ptr->m_typeToAttributeToAttributeType[QVariant::String][d_ptr->m_regExpAttribute] = + QMetaType::QRegularExpression; // int value for the type +#else d_ptr->m_typeToAttributeToAttributeType[QVariant::String][d_ptr->m_regExpAttribute] = QVariant::RegExp; +#endif connect(stringPropertyManager, SIGNAL(valueChanged(QtProperty *, const QString &)), this, SLOT(slotValueChanged(QtProperty *, const QString &))); connect(stringPropertyManager, SIGNAL(regExpChanged(QtProperty *, const QRegExp &)), diff --git a/3rdparty/python-console/CMakeLists.txt b/3rdparty/python-console/CMakeLists.txt index 89433edc4d..b5c7975f86 100644 --- a/3rdparty/python-console/CMakeLists.txt +++ b/3rdparty/python-console/CMakeLists.txt @@ -2,7 +2,13 @@ cmake_minimum_required( VERSION 2.8 ) project( PythonInterpreter ) set(CMAKE_CXX_STANDARD 11) -find_package(Qt5 COMPONENTS Core Widgets REQUIRED) +find_package(Qt6 COMPONENTS Core Widgets REQUIRED) +if (Qt6_FOUND) + message(STATUS "Using Qt6") +else() + message(STATUS "Using Qt5") + find_package(Qt5 COMPONENTS Core Widgets REQUIRED) +endif() find_package( PythonLibs REQUIRED ) include_directories( ${PYTHON_INCLUDE_DIRS} ) @@ -10,7 +16,12 @@ include_directories( ${PYTHON_INCLUDE_DIRS} ) add_executable( test_python_interpreter test_python_interpreter.cpp Interpreter.cpp ) target_link_libraries( test_python_interpreter ${PYTHON_LIBRARIES} ) -qt5_wrap_cpp( Console_MOC Console.h ) +if (Qt6_FOUND) + qt6_wrap_cpp( Console_MOC Console.h ) +else() + qt5_wrap_cpp( Console_MOC Console.h ) +endif() + add_executable( test_console test_console.cpp Console.cpp ${Console_MOC} ColumnFormatter.cpp @@ -22,7 +33,12 @@ add_executable( test_console test_console.cpp ParseMessage.cpp ) target_compile_definitions( test_console PRIVATE QT_NO_KEYWORDS) -target_link_libraries( test_console Qt5::Widgets ${PYTHON_LIBRARIES} ) + +if (Qt6_FOUND) + target_link_libraries( test_console Qt6::Widgets ${PYTHON_LIBRARIES} ) +else() + target_link_libraries( test_console Qt5::Widgets ${PYTHON_LIBRARIES} ) +endif() add_executable( test_parse_helper test_parse_helper.cpp ParseHelper.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 562c718db0..9c4f3a1d80 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -197,8 +197,14 @@ else() endif() if (BUILD_GUI) - # Find the Qt5 libraries - find_package(Qt5 COMPONENTS Core Widgets OpenGL REQUIRED) + # Find the Qt6/5 libraries + find_package(Qt6 COMPONENTS Core Widgets OpenGL OpenGLWidgets QUIET) + if (Qt6_FOUND) + message(STATUS "Using Qt6") + else() + message(STATUS "Using Qt5") + find_package(Qt5 COMPONENTS Core Widgets OpenGL REQUIRED) + endif() # For higher quality backtraces set(CMAKE_ENABLE_EXPORTS ON) diff --git a/gui/CMakeLists.txt b/gui/CMakeLists.txt index ff5d92081a..d8b9f89790 100644 --- a/gui/CMakeLists.txt +++ b/gui/CMakeLists.txt @@ -27,10 +27,17 @@ set(GUI_SOURCES ${family}/mainwindow.h ) -qt5_add_resources(GUI_QT_RESOURCES - base.qrc - ${family}/nextpnr.qrc -) +if (Qt6_FOUND) + qt6_add_resources(GUI_QT_RESOURCES + base.qrc + ${family}/nextpnr.qrc + ) +else() + qt5_add_resources(GUI_QT_RESOURCES + base.qrc + ${family}/nextpnr.qrc + ) +endif() add_library(nextpnr-${target}-gui OBJECT ${GUI_SOURCES} @@ -54,14 +61,17 @@ target_include_directories(nextpnr-${target}-gui PRIVATE ${CMAKE_SOURCE_DIR}/3rdparty/qtimgui ) -target_link_libraries(nextpnr-${target}-gui PUBLIC - Qt5::Widgets -) +if (Qt6_FOUND) + target_link_libraries(nextpnr-${target}-gui PUBLIC Qt6::Widgets) + target_link_libraries(nextpnr-${target}-gui PRIVATE Qt6::OpenGL Qt6::OpenGLWidgets) +else() + target_link_libraries(nextpnr-${target}-gui PUBLIC Qt5::Widgets) + target_link_libraries(nextpnr-${target}-gui PRIVATE Qt5::OpenGL) +endif() target_link_libraries(nextpnr-${target}-gui PRIVATE nextpnr-${target}-defs nextpnr_version - Qt5::OpenGL QtPropertyBrowser pybind11::headers ) diff --git a/gui/application.cc b/gui/application.cc index b04d4a2f21..a558135638 100644 --- a/gui/application.cc +++ b/gui/application.cc @@ -96,6 +96,7 @@ Application::Application(int &argc, char **argv, bool noantialiasing) : QApplica QSurfaceFormat fmt; if (!noantialiasing) fmt.setSamples(10); + fmt.setRenderableType(QSurfaceFormat::OpenGL); fmt.setProfile(QSurfaceFormat::CoreProfile); // macOS is very picky about this version matching // the version of openGL used in ImGuiRenderer diff --git a/gui/designwidget.cc b/gui/designwidget.cc index c14b7423d5..dfe110e323 100644 --- a/gui/designwidget.cc +++ b/gui/designwidget.cc @@ -20,6 +20,7 @@ #include "designwidget.h" #include +#include #include #include #include diff --git a/gui/fpgaviewwidget.cc b/gui/fpgaviewwidget.cc index 3787536f30..aeb5ac88a8 100644 --- a/gui/fpgaviewwidget.cc +++ b/gui/fpgaviewwidget.cc @@ -22,7 +22,6 @@ #include #include -#include #include #include #include @@ -36,6 +35,12 @@ #include "log.h" #include "mainwindow.h" +#if QT_VERSION_MAJOR >= 6 +#define EVENT_POS(event) ((event)->position()) +#else +#define EVENT_POS(event) ((event)->pos()) +#endif + NEXTPNR_NAMESPACE_BEGIN FPGAViewWidget::FPGAViewWidget(QWidget *parent) @@ -728,7 +733,7 @@ void FPGAViewWidget::mousePressEvent(QMouseEvent *event) lastDragPos_ = event->pos(); } if (btn_left && !shift) { - auto world = mouseToWorldCoordinates(event->x(), event->y()); + auto world = mouseToWorldCoordinates(EVENT_POS(event).x(), EVENT_POS(event).y()); auto closestOr = pickElement(world.x(), world.y()); if (!closestOr) { // If we clicked on empty space and aren't holding down ctrl, @@ -765,8 +770,8 @@ void FPGAViewWidget::mouseMoveEvent(QMouseEvent *event) bool btn_left = event->buttons() & Qt::LeftButton; if (btn_right || btn_mid || (btn_left && shift)) { - const int dx = event->x() - lastDragPos_.x(); - const int dy = event->y() - lastDragPos_.y(); + const int dx = EVENT_POS(event).x() - lastDragPos_.x(); + const int dy = EVENT_POS(event).y() - lastDragPos_.y(); lastDragPos_ = event->pos(); auto world = mouseToWorldDimensions(dx, dy); @@ -776,7 +781,7 @@ void FPGAViewWidget::mouseMoveEvent(QMouseEvent *event) return; } - auto world = mouseToWorldCoordinates(event->x(), event->y()); + auto world = mouseToWorldCoordinates(EVENT_POS(event).x(), EVENT_POS(event).y()); auto closestOr = pickElement(world.x(), world.y()); // No elements? No decal. if (!closestOr) { @@ -794,8 +799,8 @@ void FPGAViewWidget::mouseMoveEvent(QMouseEvent *event) QMutexLocker locked(&rendererArgsLock_); rendererArgs_->hoveredDecal = closest.decal(ctx_); rendererArgs_->changed = true; - rendererArgs_->x = event->x(); - rendererArgs_->y = event->y(); + rendererArgs_->x = EVENT_POS(event).x(); + rendererArgs_->y = EVENT_POS(event).y(); if (closest.type == ElementType::BEL) { rendererArgs_->hintText = std::string("BEL\n") + ctx_->getBelName(closest.bel).str(ctx_); CellInfo *cell = ctx_->getBoundBelCell(closest.bel);