diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml index c1aab868..f4a26893 100644 --- a/.github/workflows/cmake.yml +++ b/.github/workflows/cmake.yml @@ -3,6 +3,8 @@ name: CMake on: push: branches: + - master + - devel - cmake - svgscene - rv-core @@ -26,6 +28,12 @@ jobs: build_type: "Release", cc: "gcc", cxx: "g++", qt_version: "5.11.2" } + - { + name: "Ubuntu Latest GCC + Qt6", + os: ubuntu-latest, + build_type: "Release", + cc: "gcc", cxx: "g++", qt_version: "6.2.1" + } - { name: "Ubuntu 18 GCC", os: ubuntu-18.04, diff --git a/CMakeLists.txt b/CMakeLists.txt index fb010c76..423e285b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -165,12 +165,25 @@ if("${WASM}" OR "${FORCE_ELFLIB_STATIC}" OR NOT "${LibElf_FOUND}") add_subdirectory("external/libelf") endif() -find_package(Qt5 - REQUIRED COMPONENTS Core Widgets Gui Test - OPTIONAL_COMPONENTS PrintSupport) +# Detect Qt used qt version +# Based on article https://www.steinzone.de/wordpress/how-to-support-both-qt5-and-qt6-using-cmake/ +# Cannot use version-less approach due to Qt 5.9.5 support constraint. +find_package(OpenGL) -message(STATUS "Qt5 version: ${Qt5Core_VERSION}") -message(STATUS "Qt5 print support: ${Qt5PrintSupport_FOUND}") +find_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED) +# Normally, we would use variable Qt5 or Qt6 to reference the Qt library. Here we do that through +# this variable based on detected version major of Qt. +set(QtLib "Qt${QT_VERSION_MAJOR}") +find_package(${QtLib} + REQUIRED COMPONENTS Core Widgets Gui Test + OPTIONAL_COMPONENTS PrintSupport) + +message(STATUS "${QtLib} version: ${${QtLib}Core_VERSION}") +message(STATUS "${QtLib} print support: ${${QtLib}PrintSupport_FOUND}") + + +# Qt 5.9.5 is the oldest supported +add_compile_definitions(QT_DISABLE_DEPRECATED_BEFORE=0x050905) add_subdirectory("external/svgscene") diff --git a/external/svgscene/CMakeLists.txt b/external/svgscene/CMakeLists.txt index 89ade4ee..c835535e 100644 --- a/external/svgscene/CMakeLists.txt +++ b/external/svgscene/CMakeLists.txt @@ -1,43 +1,48 @@ cmake_minimum_required(VERSION 3.10) project(svgscene) -find_package(Qt5 - REQUIRED COMPONENTS Core Widgets Gui) + +find_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED) +# Normally, we would use variable Qt5 or Qt6 to reference the Qt library. Here we do that through +# this variable based on detected version major of Qt. +set(QtLib "Qt${QT_VERSION_MAJOR}") +find_package(${QtLib} + REQUIRED COMPONENTS Core Widgets Gui) set(CMAKE_AUTOMOC ON) set(CMAKE_AUTORCC ON) set(CMAKE_AUTOUIC ON) add_library(svgscene STATIC - src/svgscene/components/groupitem.cpp - src/svgscene/components/groupitem.h - src/svgscene/components/hyperlinkitem.cpp - src/svgscene/components/hyperlinkitem.h - src/svgscene/components/simpletextitem.cpp - src/svgscene/components/simpletextitem.h - src/svgscene/graphicsview/svggraphicsview.cpp - src/svgscene/graphicsview/svggraphicsview.h - src/svgscene/svgdocument.cpp - src/svgscene/svgdocument.h - src/svgscene/svggraphicsscene.cpp - src/svgscene/svggraphicsscene.h - src/svgscene/svghandler.cpp - src/svgscene/svghandler.h - src/svgscene/svgmetadata.cpp - src/svgscene/svgmetadata.h - src/svgscene/svgspec.h - src/svgscene/utils/logging.h - src/svgscene/utils/memory_ownership.h - ) + src/svgscene/components/groupitem.cpp + src/svgscene/components/groupitem.h + src/svgscene/components/hyperlinkitem.cpp + src/svgscene/components/hyperlinkitem.h + src/svgscene/components/simpletextitem.cpp + src/svgscene/components/simpletextitem.h + src/svgscene/graphicsview/svggraphicsview.cpp + src/svgscene/graphicsview/svggraphicsview.h + src/svgscene/svgdocument.cpp + src/svgscene/svgdocument.h + src/svgscene/svggraphicsscene.cpp + src/svgscene/svggraphicsscene.h + src/svgscene/svghandler.cpp + src/svgscene/svghandler.h + src/svgscene/svgmetadata.cpp + src/svgscene/svgmetadata.h + src/svgscene/svgspec.h + src/svgscene/utils/logging.h + src/svgscene/utils/memory_ownership.h + ) target_link_libraries(svgscene - PRIVATE Qt5::Core Qt5::Gui Qt5::Widgets) + PRIVATE ${QtLib}::Core ${QtLib}::Gui ${QtLib}::Widgets) target_include_directories(svgscene PUBLIC src PRIVATE src/svgscene) add_executable(svgscene-example EXCLUDE_FROM_ALL - src/example/main.cpp - src/example/mainwindow.cpp - src/example/mainwindow.h - src/example/mainwindow.ui - ) + src/example/main.cpp + src/example/mainwindow.cpp + src/example/mainwindow.h + src/example/mainwindow.ui + ) target_link_libraries(svgscene-example - PRIVATE Qt5::Core Qt5::Gui Qt5::Widgets svgscene) \ No newline at end of file + PRIVATE ${QtLib}::Core ${QtLib}::Gui ${QtLib}::Widgets svgscene) \ No newline at end of file diff --git a/external/svgscene/src/svgscene/graphicsview/svggraphicsview.cpp b/external/svgscene/src/svgscene/graphicsview/svggraphicsview.cpp index 7c16be1d..75a14d85 100644 --- a/external/svgscene/src/svgscene/graphicsview/svggraphicsview.cpp +++ b/external/svgscene/src/svgscene/graphicsview/svggraphicsview.cpp @@ -36,7 +36,7 @@ void SvgGraphicsView::paintEvent(QPaintEvent *event) { } void SvgGraphicsView::wheelEvent(QWheelEvent *ev) { - if (ev->orientation() == Qt::Vertical) { + if (ev->angleDelta().y() != 0) { // vertical orientation if (ev->modifiers() == Qt::ControlModifier) { double delta = ev->angleDelta().y(); zoom(delta / 10, ev->pos()); diff --git a/src/assembler/CMakeLists.txt b/src/assembler/CMakeLists.txt index 66cd0e77..bdc5da50 100644 --- a/src/assembler/CMakeLists.txt +++ b/src/assembler/CMakeLists.txt @@ -17,4 +17,4 @@ add_library(assembler STATIC ${assembler_SOURCES} ${assembler_HEADERS}) target_link_libraries(assembler - PRIVATE Qt5::Core) + PRIVATE ${QtLib}::Core) diff --git a/src/assembler/fixmatheval.cpp b/src/assembler/fixmatheval.cpp index 8977a5ab..30919b44 100644 --- a/src/assembler/fixmatheval.cpp +++ b/src/assembler/fixmatheval.cpp @@ -184,7 +184,7 @@ bool FmeExpression::parse(const QString &expression, QString &error) { bool is_unary = true; QString optxtx; for (i = 0; true; i++) { - QChar ch = 0; + QChar ch {}; if (i < expression.size()) { ch = expression.at(i); } diff --git a/src/assembler/simpleasm.cpp b/src/assembler/simpleasm.cpp index f56e4f38..3d0423a6 100644 --- a/src/assembler/simpleasm.cpp +++ b/src/assembler/simpleasm.cpp @@ -454,36 +454,56 @@ bool SimpleAsm::process_line( } s = s.mid(1, s.count() - 2); for (pos = 0; pos < s.count(); pos++) { - QChar ch = s.at(pos); - if (ch == '\\') { - ch = 0; - if (pos + 1 < s.count()) { - switch (s.at(++pos).toLatin1()) { - case '\\': ch = '\\'; break; - case '0': ch = 0x00; break; - case 'r': ch = 0x0d; break; - case 'n': ch = 0x0a; break; - case 't': ch = 0x09; break; - case 'b': ch = 0x08; break; - case '"': ch = '"'; break; - default: ch = 0; + // target byte is in ASCII encoding + uint8_t target_byte = 0x00; + + QChar host_char = s.at(pos); + if (host_char == '\\') { + // if the host encoding recognizes this as a backslash (escape char) + + // handle end of the string check + if (pos + 1 >= s.count()) { + error = "ascii - invalid escape sequence at the end of the string"; + emit report_message(messagetype::MSG_ERROR, filename, line_number, 0, error, ""); + error_occured = true; + if (error_ptr != nullptr) { + *error_ptr = error; } + return false; } - if (ch == '\0') { - error = "ascii - incorrect escape sequence"; - emit report_message( - messagetype::MSG_ERROR, filename, line_number, 0, - error, ""); + + // compare the host_char in host encoding but emit byte in ASCII encoding + host_char = s.at(++pos); + if (host_char == '0') { + target_byte = 0x00; + } else if (host_char == 'b') { + target_byte = 0x08; + } else if (host_char == 't') { + target_byte = 0x09; + } else if (host_char == 'n') { + target_byte = 0x0A; + } else if (host_char == 'r') { + target_byte = 0x0D; + } else if (host_char == '"') { + target_byte = 0x22; + } else if (host_char == '\\') { + target_byte = 0x5C; + } else { + error = QString("ascii - incorrect escape sequence '\\") + host_char + "'"; + emit report_message(messagetype::MSG_ERROR, filename, line_number, 0, error, ""); error_occured = true; if (error_ptr != nullptr) { *error_ptr = error; } return false; } + } else { + // otherwise convert it to ASCII and write it as-is + target_byte = host_char.toLatin1(); } + if (!fatal_occured) { - mem->write_u8( - address, (uint8_t)ch.toLatin1(), ae::INTERNAL); + mem->write_u8(address, target_byte, ae::INTERNAL); } address += 1; } diff --git a/src/cli/CMakeLists.txt b/src/cli/CMakeLists.txt index dbd39006..a1444181 100644 --- a/src/cli/CMakeLists.txt +++ b/src/cli/CMakeLists.txt @@ -23,7 +23,7 @@ add_executable(cli ${cli_SOURCES} ${cli_HEADERS}) target_link_libraries(cli - PRIVATE Qt5::Core machine assembler) + PRIVATE ${QtLib}::Core machine assembler) target_compile_definitions(cli PRIVATE APP_ORGANIZATION=\"${MAIN_PROJECT_ORGANIZATION}\" diff --git a/src/common/polyfills/CMakeLists.txt b/src/common/polyfills/CMakeLists.txt index e1f22bf8..d31c939b 100644 --- a/src/common/polyfills/CMakeLists.txt +++ b/src/common/polyfills/CMakeLists.txt @@ -1,14 +1,17 @@ project(polyfills - DESCRIPTION "Helper code to unify access to compiler intrinsics and + DESCRIPTION "Helper code to unify access to compiler intrinsics and provide fallback implementations.") set(polyfills_HEADERS - endian_detection.h - mulh64.h - clz32.h - byteswap.h - qstring_hash.h - ) + endian_detection.h + mulh64.h + clz32.h + byteswap.h + qstring_hash.h + qt5/qfontmetrics.h + qt5/qlinef.h + qt5/qtableview.h + ) # ============================================================================= # Target for usage of this header library @@ -26,12 +29,12 @@ if(NOT "${WASM}") set(CMAKE_AUTOMOC ON) add_executable(mulh64_test - mulh64.h - mulh64.test.h - mulh64.test.cpp - ) - target_link_libraries(mulh64_test PRIVATE Qt5::Test) + mulh64.h + mulh64.test.h + mulh64.test.cpp + ) + target_link_libraries(mulh64_test PRIVATE ${QtLib}::Test) add_test(NAME mulh64 - COMMAND mulh64_test) + COMMAND mulh64_test) endif() diff --git a/src/common/polyfills/qt5/qfontmetrics.h b/src/common/polyfills/qt5/qfontmetrics.h new file mode 100644 index 00000000..ae07ab62 --- /dev/null +++ b/src/common/polyfills/qt5/qfontmetrics.h @@ -0,0 +1,12 @@ +#ifndef POLYFILLS_QFONTMETRICS_H +#define POLYFILLS_QFONTMETRICS_H + +int QFontMetrics_horizontalAdvance(const QFontMetrics &self, const QString &str, int len = -1) { +#if QT_VERSION >= QT_VERSION_CHECK(5, 11, 0) + return self.horizontalAdvance(str, len); +#else + return self.width(str, len); +#endif +} + +#endif // QTMIPS_QFONTMETRICS_H diff --git a/src/common/polyfills/qt5/qlinef.h b/src/common/polyfills/qt5/qlinef.h new file mode 100644 index 00000000..d1a6f3a0 --- /dev/null +++ b/src/common/polyfills/qt5/qlinef.h @@ -0,0 +1,15 @@ +#ifndef POLYFILLS_QLINEF_H +#define POLYFILLS_QLINEF_H + +#include + +QLineF::IntersectType +QLineF_intersect(const QLineF &l1, const QLineF &l2, QPointF *intersectionPoint) { +#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) + return l1.intersects(l2, intersectionPoint); +#else + return l1.intersect(l2, intersectionPoint); +#endif +} + +#endif // QTMIPS_QLINEF_H diff --git a/src/common/polyfills/qt5/qtableview.h b/src/common/polyfills/qt5/qtableview.h new file mode 100644 index 00000000..e2f2c86b --- /dev/null +++ b/src/common/polyfills/qt5/qtableview.h @@ -0,0 +1,23 @@ +#ifndef POLYFILLS_QTABLEVIEW_H +#define POLYFILLS_QTABLEVIEW_H + +#include + +/** + * QTableView polyfill + * + * initViewItemOption is protected, therefore the whole class needs to be wrapped. + */ +class Poly_QTableView : public QTableView { +public: + explicit Poly_QTableView(QWidget *parent) : QTableView(parent) {} + +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) +protected: + void initViewItemOption(QStyleOptionViewItem *viewOpts) { + *viewOpts = QTableView::viewOptions(); + } +#endif +}; + +#endif // QTMIPS_QTABLEVIEW_H diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt index b007be8c..161e8b5f 100644 --- a/src/gui/CMakeLists.txt +++ b/src/gui/CMakeLists.txt @@ -139,8 +139,8 @@ add_executable(gui ${gui_RESOURCES}) target_include_directories(gui PUBLIC . coreview) target_link_libraries(gui - PRIVATE Qt5::Core Qt5::Widgets Qt5::Gui - PRIVATE machine os_emulation assembler svgscene) + PRIVATE ${QtLib}::Core ${QtLib}::Widgets ${QtLib}::Gui + PRIVATE machine os_emulation assembler svgscene) target_compile_definitions(gui PRIVATE APP_ORGANIZATION=\"${MAIN_PROJECT_ORGANIZATION}\" @@ -152,9 +152,9 @@ target_compile_definitions(gui set_target_properties(gui PROPERTIES OUTPUT_NAME "${MAIN_PROJECT_NAME_LOWER}_${PROJECT_NAME}") -if(${Qt5PrintSupport_FOUND}) - target_link_libraries(gui PRIVATE Qt5::PrintSupport) - target_compile_definitions(gui PRIVATE WITH_PRINTING=1) +if(${${QtLib}PrintSupport_FOUND}) + target_link_libraries(gui PRIVATE ${QtLib}::PrintSupport) + target_compile_definitions(gui PRIVATE WITH_PRINTING=1) endif() # MACOS diff --git a/src/gui/coreview/deprecated/connection.cpp b/src/gui/coreview/deprecated/connection.cpp index 96e99526..49fd4b4e 100644 --- a/src/gui/coreview/deprecated/connection.cpp +++ b/src/gui/coreview/deprecated/connection.cpp @@ -1,5 +1,6 @@ #include "connection.h" +#include "common/polyfills/qt5/qlinef.h" #include "machine/simulator_exception.h" #include @@ -124,8 +125,8 @@ void Connection::recalc_line() { points.append(ax_start.p1()); QLineF cur_l = ax_start; - for (int i = 0; i < break_axes.size(); i++) { - if (recalc_line_add_point(cur_l, break_axes[i])) cur_l = break_axes[i]; + for (auto &break_axe : break_axes) { + if (recalc_line_add_point(cur_l, break_axe)) cur_l = break_axe; } recalc_line_add_point(cur_l, ax_end); @@ -134,7 +135,7 @@ void Connection::recalc_line() { bool Connection::recalc_line_add_point(const QLineF &l1, const QLineF &l2) { QPointF intersec; - if (l1.intersect(l2, &intersec) == QLineF::NoIntersection) { return false; } + if (QLineF_intersect(l1, l2, &intersec) == QLineF::NoIntersection) { return false; } points.append(intersec); return true; } @@ -144,8 +145,9 @@ Bus::Bus(const Connector *start, const Connector *end, unsigned width) : Connect } Bus::~Bus() { - for (int i = 0; i < conns.size(); i++) - delete conns[i].c; + for (auto &conn : conns) { + delete conn.c; + } } void Bus::setAxes(QVector axes) { @@ -154,7 +156,7 @@ void Bus::setAxes(QVector axes) { } const Connector *Bus::new_connector(qreal x, qreal y, enum Connector::Axis axis) { - Connector *c = new Connector(axis); + auto *c = new Connector(axis); conns.append({ .c = c, .p = QPoint(x, y) }); conns_update(); return c; @@ -173,7 +175,11 @@ static qreal cu_closest(const QLineF &l, const QPointF &p, QPointF *intersec) { QLineF nline = normal.translated(-normal.p1()).translated(p); // And now found intersection SANITY_ASSERT( +#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) + l.intersects(nline, intersec) != QLineF::NoIntersection, +#else l.intersect(nline, intersec) != QLineF::NoIntersection, +#endif "We are calculating intersection with normal vector and that should " "always have intersection"); // Now check if that point belongs to given line diff --git a/src/gui/memorytableview.cpp b/src/gui/memorytableview.cpp index 48c1b658..e5724150 100644 --- a/src/gui/memorytableview.cpp +++ b/src/gui/memorytableview.cpp @@ -1,5 +1,6 @@ #include "memorytableview.h" +#include "common/polyfills/qt5/qfontmetrics.h" #include "hinttabledelegate.h" #include "memorymodel.h" @@ -9,9 +10,9 @@ #include #include #include +#include -MemoryTableView::MemoryTableView(QWidget *parent, QSettings *settings) - : Super(parent) { +MemoryTableView::MemoryTableView(QWidget *parent, QSettings *settings) : Super(parent) { setItemDelegate(new HintTableDelegate); connect( verticalScrollBar(), &QAbstractSlider::valueChanged, this, @@ -20,8 +21,7 @@ MemoryTableView::MemoryTableView(QWidget *parent, QSettings *settings) this, &MemoryTableView::adjust_scroll_pos_queue, this, &MemoryTableView::adjust_scroll_pos_process, Qt::QueuedConnection); this->settings = settings; - initial_address - = machine::Address(settings->value("DataViewAddr0", 0).toULongLong()); + initial_address = machine::Address(settings->value("DataViewAddr0", 0).toULongLong()); adjust_scroll_pos_in_progress = false; setTextElideMode(Qt::ElideNone); } @@ -31,36 +31,33 @@ void MemoryTableView::addr0_save_change(machine::Address val) { } void MemoryTableView::adjustColumnCount() { - MemoryModel *m = dynamic_cast(model()); - if (m == nullptr) { - return; - } + auto *m = dynamic_cast(model()); + if (m == nullptr) { return; } - HintTableDelegate *delegate - = dynamic_cast(itemDelegate()); - if (delegate == nullptr) { - return; - } + auto *delegate = dynamic_cast(itemDelegate()); + if (delegate == nullptr) { return; } if (horizontalHeader()->count() >= 2) { QModelIndex idx; QFontMetrics fm(*m->getFont()); idx = m->index(0, 0); + + QStyleOptionViewItem viewOpts; + + initViewItemOption(&viewOpts); + // int width0_dh = itemDelegate(idx)->sizeHint(viewOptions(), // idx).get_width() + 2; - int width0_dh - = delegate->sizeHintForText(viewOptions(), idx, "0x00000000").width() - + 2; + int width0_dh = delegate->sizeHintForText(viewOpts, idx, "0x00000000").width() + 2; horizontalHeader()->setSectionResizeMode(0, QHeaderView::Fixed); horizontalHeader()->resizeSection(0, width0_dh); idx = m->index(0, 1); QString t = ""; t.fill(QChar('0'), m->cellSizeBytes() * 2); - int width1_dh - = delegate->sizeHintForText(viewOptions(), idx, t).width() + 2; - if (width1_dh < fm.width("+99")) { - width1_dh = fm.width("+99"); + int width1_dh = delegate->sizeHintForText(viewOpts, idx, t).width() + 2; + if (width1_dh < QFontMetrics_horizontalAdvance(fm, "+99")) { + width1_dh = QFontMetrics_horizontalAdvance(fm, "+99"); } horizontalHeader()->setSectionResizeMode(1, QHeaderView::Fixed); horizontalHeader()->resizeSection(1, width1_dh); @@ -75,9 +72,7 @@ void MemoryTableView::adjustColumnCount() { } else { cells = w / (width1 + 4); } - if (cells != m->cellsPerRow()) { - m->setCellsPerRow(cells); - } + if (cells != m->cellsPerRow()) { m->setCellsPerRow(cells); } for (unsigned int i = 1; i < m->cellsPerRow() + 1; i++) { horizontalHeader()->setSectionResizeMode(i, QHeaderView::Fixed); horizontalHeader()->resizeSection(i, width1); @@ -97,7 +92,7 @@ void MemoryTableView::set_cell_size(int index) { machine::Address address; int row; bool keep_row0 = false; - MemoryModel *m = dynamic_cast(model()); + auto *m = dynamic_cast(model()); if (m != nullptr) { keep_row0 = m->get_row_address(address, rowAt(0)); m->set_cell_size(index); @@ -119,22 +114,18 @@ void MemoryTableView::adjust_scroll_pos_check() { void MemoryTableView::adjust_scroll_pos_process() { adjust_scroll_pos_in_progress = false; machine::Address address; - MemoryModel *m = dynamic_cast(model()); - if (m == nullptr) { - return; - } + auto *m = dynamic_cast(model()); + if (m == nullptr) { return; } QModelIndex prev_index = currentIndex(); - machine::Address row_bytes - = machine::Address(m->cellSizeBytes() * m->cellsPerRow()); + machine::Address row_bytes = machine::Address(m->cellSizeBytes() * m->cellsPerRow()); machine::Address index0_offset = m->getIndex0Offset(); do { int row = rowAt(0); int prev_row = row; if (row < m->rowCount() / 8) { - if ((row == 0) && (index0_offset < row_bytes) - && (!index0_offset.is_null())) { + if ((row == 0) && (index0_offset < row_bytes) && (!index0_offset.is_null())) { m->adjustRowAndOffset(row, machine::Address::null()); } else if (index0_offset > row_bytes) { m->get_row_address(address, row); @@ -149,8 +140,7 @@ void MemoryTableView::adjust_scroll_pos_process() { break; } scrollTo(m->index(row, 0), QAbstractItemView::PositionAtTop); - setCurrentIndex( - m->index(prev_index.row() + row - prev_row, prev_index.column())); + setCurrentIndex(m->index(prev_index.row() + row - prev_row, prev_index.column())); emit m->update_all(); } while (false); m->get_row_address(address, rowAt(0)); @@ -159,7 +149,7 @@ void MemoryTableView::adjust_scroll_pos_process() { } void MemoryTableView::resizeEvent(QResizeEvent *event) { - MemoryModel *m = dynamic_cast(model()); + auto *m = dynamic_cast(model()); machine::Address address; bool keep_row0 = false; @@ -179,11 +169,9 @@ void MemoryTableView::resizeEvent(QResizeEvent *event) { } void MemoryTableView::go_to_address(machine::Address address) { - MemoryModel *m = dynamic_cast(model()); + auto *m = dynamic_cast(model()); int row; - if (m == nullptr) { - return; - } + if (m == nullptr) { return; } m->adjustRowAndOffset(row, address); scrollTo(m->index(row, 0), QAbstractItemView::PositionAtTop); setCurrentIndex(m->index(row, 1)); @@ -193,16 +181,10 @@ void MemoryTableView::go_to_address(machine::Address address) { void MemoryTableView::focus_address(machine::Address address) { int row; - MemoryModel *m = dynamic_cast(model()); - if (m == nullptr) { - return; - } - if (!m->get_row_for_address(row, address)) { - go_to_address(address); - } - if (!m->get_row_for_address(row, address)) { - return; - } + auto *m = dynamic_cast(model()); + if (m == nullptr) { return; } + if (!m->get_row_for_address(row, address)) { go_to_address(address); } + if (!m->get_row_for_address(row, address)) { return; } setCurrentIndex(m->index(row, 1)); } diff --git a/src/gui/memorytableview.h b/src/gui/memorytableview.h index c9699b54..30ef3768 100644 --- a/src/gui/memorytableview.h +++ b/src/gui/memorytableview.h @@ -1,17 +1,17 @@ #ifndef MEMORYTABLEVIEW_H #define MEMORYTABLEVIEW_H +#include "common/polyfills/qt5/qtableview.h" #include "machine/memory/address.h" #include #include #include -#include -class MemoryTableView : public QTableView { +class MemoryTableView : public Poly_QTableView { Q_OBJECT - using Super = QTableView; + using Super = Poly_QTableView; public: MemoryTableView(QWidget *parent, QSettings *settings); diff --git a/src/gui/newdialog.cpp b/src/gui/newdialog.cpp index 8ebd9830..cfce9624 100644 --- a/src/gui/newdialog.cpp +++ b/src/gui/newdialog.cpp @@ -286,7 +286,8 @@ void NewDialog::osemu_exception_stop_change(bool v) { void NewDialog::browse_osemu_fs_root() { QFileDialog osemu_fs_root_dialog(this); - osemu_fs_root_dialog.setFileMode(QFileDialog::DirectoryOnly); + osemu_fs_root_dialog.setFileMode(QFileDialog::Directory); + osemu_fs_root_dialog.setOption(QFileDialog::ShowDirsOnly, true); if (osemu_fs_root_dialog.exec()) { QString path = osemu_fs_root_dialog.selectedFiles()[0]; ui->osemu_fs_root->setText(path); diff --git a/src/gui/programtableview.cpp b/src/gui/programtableview.cpp index e478dec1..60e57e6b 100644 --- a/src/gui/programtableview.cpp +++ b/src/gui/programtableview.cpp @@ -5,13 +5,12 @@ #include #include -#include #include #include #include +#include -ProgramTableView::ProgramTableView(QWidget *parent, QSettings *settings) - : Super(parent) { +ProgramTableView::ProgramTableView(QWidget *parent, QSettings *settings) : Super(parent) { setItemDelegate(new HintTableDelegate); connect( verticalScrollBar(), &QAbstractSlider::valueChanged, this, @@ -20,8 +19,7 @@ ProgramTableView::ProgramTableView(QWidget *parent, QSettings *settings) this, &ProgramTableView::adjust_scroll_pos_queue, this, &ProgramTableView::adjust_scroll_pos_process, Qt::QueuedConnection); this->settings = settings; - initial_address = machine::Address( - settings->value("ProgramViewAddr0", 0).toULongLong()); + initial_address = machine::Address(settings->value("ProgramViewAddr0", 0).toULongLong()); adjust_scroll_pos_in_progress = false; need_addr0_save = false; setTextElideMode(Qt::ElideNone); @@ -37,46 +35,38 @@ void ProgramTableView::adjustColumnCount() { int cwidth_dh; int totwidth; - ProgramModel *m = dynamic_cast(model()); + auto *m = dynamic_cast(model()); - if (m == nullptr) { - return; - } + if (m == nullptr) { return; } - HintTableDelegate *delegate - = dynamic_cast(itemDelegate()); - if (delegate == nullptr) { - return; - } + auto *delegate = dynamic_cast(itemDelegate()); + if (delegate == nullptr) { return; } + + QStyleOptionViewItem viewOpts; + + initViewItemOption(&viewOpts); idx = m->index(0, 0); - cwidth_dh = delegate->sizeHintForText(viewOptions(), idx, "Bp").width() + 2; + cwidth_dh = delegate->sizeHintForText(viewOpts, idx, "Bp").width() + 2; horizontalHeader()->setSectionResizeMode(0, QHeaderView::Fixed); horizontalHeader()->resizeSection(0, cwidth_dh); totwidth = cwidth_dh; idx = m->index(0, 1); - cwidth_dh - = delegate->sizeHintForText(viewOptions(), idx, "0x00000000").width() - + 2; + cwidth_dh = delegate->sizeHintForText(viewOpts, idx, "0x00000000").width() + 2; horizontalHeader()->setSectionResizeMode(1, QHeaderView::Fixed); horizontalHeader()->resizeSection(1, cwidth_dh); totwidth += cwidth_dh; idx = m->index(0, 2); - cwidth_dh - = delegate->sizeHintForText(viewOptions(), idx, "00000000").width() + 2; + cwidth_dh = delegate->sizeHintForText(viewOpts, idx, "00000000").width() + 2; horizontalHeader()->setSectionResizeMode(2, QHeaderView::Fixed); horizontalHeader()->resizeSection(2, cwidth_dh); totwidth += cwidth_dh; horizontalHeader()->setSectionResizeMode(3, QHeaderView::Stretch); idx = m->index(0, 3); - totwidth - += delegate - ->sizeHintForText(viewOptions(), idx, "BEQ $18, $17, 0x80020058") - .width() - + 2; + totwidth += delegate->sizeHintForText(viewOpts, idx, "BEQ $18, $17, 0x80020058").width() + 2; totwidth += verticalHeader()->width(); setColumnHidden(2, totwidth > width()); @@ -96,10 +86,8 @@ void ProgramTableView::adjust_scroll_pos_check() { void ProgramTableView::adjust_scroll_pos_process() { adjust_scroll_pos_in_progress = false; machine::Address address; - ProgramModel *m = dynamic_cast(model()); - if (m == nullptr) { - return; - } + auto *m = dynamic_cast(model()); + if (m == nullptr) { return; } QModelIndex prev_index = currentIndex(); machine::Address row_bytes = machine::Address(m->cellSizeBytes()); @@ -109,8 +97,7 @@ void ProgramTableView::adjust_scroll_pos_process() { int row = rowAt(0); int prev_row = row; if (row < m->rowCount() / 8) { - if ((row == 0) && (index0_offset < row_bytes) - && (!index0_offset.is_null())) { + if ((row == 0) && (index0_offset < row_bytes) && (!index0_offset.is_null())) { m->adjustRowAndOffset(row, machine::Address::null()); } else if (index0_offset >= row_bytes) { m->get_row_address(address, row); @@ -125,19 +112,16 @@ void ProgramTableView::adjust_scroll_pos_process() { break; } scrollTo(m->index(row, 0), QAbstractItemView::PositionAtTop); - setCurrentIndex( - m->index(prev_index.row() + row - prev_row, prev_index.column())); + setCurrentIndex(m->index(prev_index.row() + row - prev_row, prev_index.column())); emit m->update_all(); } while (false); m->get_row_address(address, rowAt(0)); - if (need_addr0_save) { - addr0_save_change(address); - } + if (need_addr0_save) { addr0_save_change(address); } emit address_changed(address.get_raw()); } void ProgramTableView::resizeEvent(QResizeEvent *event) { - ProgramModel *m = dynamic_cast(model()); + auto *m = dynamic_cast(model()); machine::Address address; bool keep_row0 = false; @@ -157,17 +141,13 @@ void ProgramTableView::resizeEvent(QResizeEvent *event) { } void ProgramTableView::go_to_address_priv(machine::Address address) { - ProgramModel *m = dynamic_cast(model()); + auto *m = dynamic_cast(model()); int row; - if (m == nullptr) { - return; - } + if (m == nullptr) { return; } m->adjustRowAndOffset(row, address); scrollTo(m->index(row, 0), QAbstractItemView::PositionAtTop); setCurrentIndex(m->index(row, 1)); - if (need_addr0_save) { - addr0_save_change(address); - } + if (need_addr0_save) { addr0_save_change(address); } emit m->update_all(); } @@ -178,16 +158,10 @@ void ProgramTableView::go_to_address(machine::Address address) { void ProgramTableView::focus_address(machine::Address address) { int row; - ProgramModel *m = dynamic_cast(model()); - if (m == nullptr) { - return; - } - if (!m->get_row_for_address(row, address)) { - go_to_address_priv(address); - } - if (!m->get_row_for_address(row, address)) { - return; - } + auto *m = dynamic_cast(model()); + if (m == nullptr) { return; } + if (!m->get_row_for_address(row, address)) { go_to_address_priv(address); } + if (!m->get_row_for_address(row, address)) { return; } setCurrentIndex(m->index(row, 1)); } diff --git a/src/gui/programtableview.h b/src/gui/programtableview.h index 19da8750..b6a047b5 100644 --- a/src/gui/programtableview.h +++ b/src/gui/programtableview.h @@ -1,17 +1,17 @@ #ifndef PROGRAMTABLEVIEW_H #define PROGRAMTABLEVIEW_H +#include "common/polyfills/qt5/qtableview.h" #include "machine/memory/address.h" #include #include #include -#include -class ProgramTableView : public QTableView { +class ProgramTableView : public Poly_QTableView { Q_OBJECT - using Super = QTableView; + using Super = Poly_QTableView; public: ProgramTableView(QWidget *parent, QSettings *settings); diff --git a/src/gui/statictable.cpp b/src/gui/statictable.cpp index 01f16c1e..4eafadcd 100644 --- a/src/gui/statictable.cpp +++ b/src/gui/statictable.cpp @@ -58,12 +58,15 @@ QSize StaticTableLayout::minimumSize() const { for (int i = 0; i < items.size(); i++) { QSize ss; for (int y = 0; y < items[i].size(); y++) { - ss = cch_minSize.size.expandedTo( - items[i][y]->minimumSize() + QSize(shspace, 0)); + ss = cch_minSize.size.expandedTo(items[i][y]->minimumSize() + QSize(shspace, 0)); } cch_minSize.size = cch_minSize.size.expandedTo(ss - QSize(shspace, 0)); } - cch_minSize.size += QSize(2 * margin(), 2 * margin()); + + int left, top, right, bottom; + getContentsMargins(&left, &top, &right, &bottom); + cch_minSize.size += QSize(left + right, top + bottom); + return cch_minSize.size; } diff --git a/src/machine/CMakeLists.txt b/src/machine/CMakeLists.txt index fbc3a8e9..7df3f67b 100644 --- a/src/machine/CMakeLists.txt +++ b/src/machine/CMakeLists.txt @@ -79,14 +79,14 @@ add_library(machine STATIC ${machine_SOURCES} ${machine_HEADERS}) target_link_libraries(machine - PRIVATE Qt5::Core - PUBLIC libelf) + PRIVATE ${QtLib}::Core + PUBLIC libelf) if (NOT ${WASM}) # Machine tests (not available on WASM) # add_executable(machine_unit_tests ${machine_TESTS}) # target_link_libraries(machine_unit_tests -# PRIVATE machine Qt5::Core Qt5::Test) + # PRIVATE machine ${QtLib}::Core ${QtLib}::Test) # # add_test(NAME machine_unit_tests # COMMAND machine_unit_tests) @@ -98,6 +98,6 @@ if (NOT ${WASM}) execute/alu.h ) target_link_libraries(alu_test - PRIVATE Qt5::Core Qt5::Test) + PRIVATE ${QtLib}::Core ${QtLib}::Test) add_test(NAME alu COMMAND alu_test) endif () diff --git a/src/machine/cop0state.cpp b/src/machine/cop0state.cpp index 004163aa..765c38b2 100644 --- a/src/machine/cop0state.cpp +++ b/src/machine/cop0state.cpp @@ -99,28 +99,28 @@ void Cop0State::setup_core(Core *core) { uint32_t Cop0State::read_cop0reg(uint8_t rd, uint8_t sel) const { SANITY_ASSERT( - rd < 32, QString("Trying to read from cop0 register ") + QString(rd) - + ',' + QString(sel)); + rd < 32, QString("Trying to read from cop0 register ") + QString::number(rd) + ',' + + QString::number(sel)); SANITY_ASSERT( - sel < 8, QString("Trying to read from cop0 register ") + QString(rd) - + ',' + QString(sel)); + sel < 8, QString("Trying to read from cop0 register ") + QString::number(rd) + ',' + + QString::number(sel)); enum Cop0Registers reg = cop0reg_map[rd][sel]; SANITY_ASSERT( - reg != 0, QString("Cop0 register ") + QString(rd) + ',' + QString(sel) + reg != 0, QString("Cop0 register ") + QString::number(rd) + ',' + QString::number(sel) + "unsupported"); return read_cop0reg(reg); } void Cop0State::write_cop0reg(uint8_t rd, uint8_t sel, RegisterValue value) { SANITY_ASSERT( - rd < 32, QString("Trying to write to cop0 register ") + QString(rd) - + ',' + QString(sel)); + rd < 32, QString("Trying to write to cop0 register ") + QString::number(rd) + ',' + + QString::number(sel)); SANITY_ASSERT( - sel < 8, QString("Trying to write to cop0 register ") + QString(rd) - + ',' + QString(sel)); + sel < 8, QString("Trying to write to cop0 register ") + QString::number(rd) + ',' + + QString::number(sel)); enum Cop0Registers reg = cop0reg_map[rd][sel]; SANITY_ASSERT( - reg != 0, QString("Cop0 register ") + QString(rd) + ',' + QString(sel) + reg != 0, QString("Cop0 register ") + QString::number(rd) + ',' + QString::number(sel) + "unsupported"); write_cop0reg(reg, value); } @@ -128,14 +128,14 @@ void Cop0State::write_cop0reg(uint8_t rd, uint8_t sel, RegisterValue value) { uint32_t Cop0State::read_cop0reg(enum Cop0Registers reg) const { SANITY_ASSERT( reg != Unsupported && reg < COP0REGS_CNT, - QString("Trying to read from cop0 register ") + QString(reg)); + QString("Trying to read from cop0 register ") + QString::number(reg)); return (this->*cop0reg_desc[reg].reg_read)(reg); } void Cop0State::write_cop0reg(enum Cop0Registers reg, RegisterValue value) { SANITY_ASSERT( reg != Unsupported && reg < COP0REGS_CNT, - QString("Trying to write to cop0 register ") + QString(reg)); + QString("Trying to write to cop0 register ") + QString::number(reg)); (this->*cop0reg_desc[reg].reg_write)(reg, value.as_u32()); } diff --git a/src/machine/memory/backend/memory.cpp b/src/machine/memory/backend/memory.cpp index 237d6fbb..078222e0 100644 --- a/src/machine/memory/backend/memory.cpp +++ b/src/machine/memory/backend/memory.cpp @@ -17,13 +17,11 @@ MemorySection::MemorySection(const MemorySection &other) : BackendMemory(other.simulated_machine_endian) , dt(other.dt) {} -WriteResult MemorySection::write( - Offset destination, - const void *source, - size_t size, - WriteOptions options) { +WriteResult MemorySection::write(Offset dst_offset, const void *source, size_t size, WriteOptions options) { UNUSED(options) + size_t destination = static_cast(dst_offset); + if (destination >= length()) { throw SIMULATOR_EXCEPTION( OutOfMemoryAccess, "Trying to write outside of the memory section", @@ -31,8 +29,7 @@ WriteResult MemorySection::write( } // Size the can be read from this section - const size_t available_size - = std::min(destination + size, length()) - destination; + const size_t available_size = std::min(destination + size, length()) - destination; // TODO, make swap conditional for big endian machines bool changed = memcmp(source, &dt[destination], available_size) != 0; @@ -43,13 +40,11 @@ WriteResult MemorySection::write( return { .n_bytes = available_size, .changed = changed }; } -ReadResult MemorySection::read( - void *destination, - Offset source, - size_t size, - ReadOptions options) const { +ReadResult MemorySection::read(void *destination, Offset src_offset, size_t size, ReadOptions options) const { UNUSED(options) + size_t source = static_cast(src_offset); + size = std::min(source + size, length()) - source; if (source >= length()) { diff --git a/src/machine/memory/backend/serialport.cpp b/src/machine/memory/backend/serialport.cpp index a3c64cd3..6f57a1db 100644 --- a/src/machine/memory/backend/serialport.cpp +++ b/src/machine/memory/backend/serialport.cpp @@ -131,10 +131,7 @@ uint32_t SerialPort::read_reg(Offset source, AccessEffects type) const { rx_queue_check_internal(); break; case SERP_TX_ST_REG_o: value = tx_st_reg | SERP_TX_ST_REG_READY_m; break; - default: - printf( - "WARNING: Serial port - read out of range (at 0x%ld).\n", source); - break; + default: printf("WARNING: Serial port - read out of range (at 0x%lu).\n", source); break; } emit read_notification(source, value); @@ -163,9 +160,7 @@ bool SerialPort::write_reg(Offset destination, uint32_t value) { update_tx_irq(); return true; default: - printf( - "WARNING: Serial port - write out of range (at 0x%ld).\n", - destination); + printf("WARNING: Serial port - write out of range (at 0x%lu).\n", destination); return false; } }(); diff --git a/src/machine/registers.h b/src/machine/registers.h index b384810a..914f570a 100644 --- a/src/machine/registers.h +++ b/src/machine/registers.h @@ -34,8 +34,8 @@ inline RegisterId::RegisterId(uint8_t value) : data(value) { // Main advantege is, that possible errors will appear when creating the // value, which is probably close to the bug source. SANITY_ASSERT( - data < REGISTER_COUNT, - QString("Trying to create register id for out-of-bounds register ") + QString(data)); + data < REGISTER_COUNT, QString("Trying to create register id for out-of-bounds register ") + + QString::number(data)); } inline RegisterId::RegisterId() : RegisterId(0) {} diff --git a/src/os_emulation/CMakeLists.txt b/src/os_emulation/CMakeLists.txt index 96dac5a2..84d2a310 100644 --- a/src/os_emulation/CMakeLists.txt +++ b/src/os_emulation/CMakeLists.txt @@ -16,4 +16,4 @@ add_library(os_emulation STATIC ${os_emulation_SOURCES} ${os_emulation_HEADERS}) target_link_libraries(os_emulation - PRIVATE Qt5::Core) \ No newline at end of file + PRIVATE ${QtLib}::Core) \ No newline at end of file