diff options
author | Pavel Pisa <pisa@cmp.felk.cvut.cz> | 2019-07-17 18:02:32 +0200 |
---|---|---|
committer | Pavel Pisa <pisa@cmp.felk.cvut.cz> | 2019-07-17 18:02:32 +0200 |
commit | 1d989de07fde1e5bef27336ede1497c88fa9249a (patch) | |
tree | 9b940f2b478520f13a204b67e2da861a72d1c0dc | |
parent | 54ac86405049364df763e8ce002cf7aed4b69bed (diff) | |
download | qtmips-1d989de07fde1e5bef27336ede1497c88fa9249a.tar.gz qtmips-1d989de07fde1e5bef27336ede1497c88fa9249a.tar.bz2 qtmips-1d989de07fde1e5bef27336ede1497c88fa9249a.zip |
Implemented message window to report compilation errors.
Signed-off-by: Pavel Pisa <pisa@cmp.felk.cvut.cz>
-rw-r--r-- | qtmips_asm/messagetype.h | 51 | ||||
-rw-r--r-- | qtmips_asm/qtmips_asm.pro | 3 | ||||
-rw-r--r-- | qtmips_gui/MainWindow.ui | 9 | ||||
-rw-r--r-- | qtmips_gui/mainwindow.cpp | 131 | ||||
-rw-r--r-- | qtmips_gui/mainwindow.h | 10 | ||||
-rw-r--r-- | qtmips_gui/messagesdock.cpp | 87 | ||||
-rw-r--r-- | qtmips_gui/messagesdock.h | 66 | ||||
-rw-r--r-- | qtmips_gui/messagesmodel.cpp | 149 | ||||
-rw-r--r-- | qtmips_gui/messagesmodel.h | 71 | ||||
-rw-r--r-- | qtmips_gui/messagesview.cpp | 70 | ||||
-rw-r--r-- | qtmips_gui/messagesview.h | 59 | ||||
-rw-r--r-- | qtmips_gui/qtmips_gui.pro | 10 |
12 files changed, 673 insertions, 43 deletions
diff --git a/qtmips_asm/messagetype.h b/qtmips_asm/messagetype.h new file mode 100644 index 0000000..a3a1c49 --- /dev/null +++ b/qtmips_asm/messagetype.h @@ -0,0 +1,51 @@ +// SPDX-License-Identifier: GPL-2.0+ +/******************************************************************************* + * QtMips - MIPS 32-bit Architecture Subset Simulator + * + * Implemented to support following courses: + * + * B35APO - Computer Architectures + * https://cw.fel.cvut.cz/wiki/courses/b35apo + * + * B4M35PAP - Advanced Computer Architectures + * https://cw.fel.cvut.cz/wiki/courses/b4m35pap/start + * + * Copyright (c) 2017-2019 Karel Koci<cynerd@email.cz> + * Copyright (c) 2019 Pavel Pisa <pisa@cmp.felk.cvut.cz> + * + * Faculty of Electrical Engineering (http://www.fel.cvut.cz) + * Czech Technical University (http://www.cvut.cz/) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + ******************************************************************************/ + +#ifndef MESSAGETYPE_H +#define MESSAGETYPE_H + +namespace messagetype { + +enum Type { + START, + FINISH, + INFO, + WARNING, + ERROR, +}; + +} + +#endif /*MESSAGETYPE*/ diff --git a/qtmips_asm/qtmips_asm.pro b/qtmips_asm/qtmips_asm.pro index 20b988f..d096961 100644 --- a/qtmips_asm/qtmips_asm.pro +++ b/qtmips_asm/qtmips_asm.pro @@ -17,4 +17,5 @@ SOURCES += \ fixmatheval.cpp HEADERS += \ - fixmatheval.h + fixmatheval.h \ + messagetype.h diff --git a/qtmips_gui/MainWindow.ui b/qtmips_gui/MainWindow.ui index cd898ae..aa01737 100644 --- a/qtmips_gui/MainWindow.ui +++ b/qtmips_gui/MainWindow.ui @@ -83,6 +83,7 @@ <addaction name="actionLcdDisplay"/> <addaction name="actionCop0State"/> <addaction name="actionCore_View_show"/> + <addaction name="actionMessages"/> </widget> <widget class="QMenu" name="menuMachine"> <property name="title"> @@ -527,6 +528,14 @@ <string>Core View</string> </property> </action> + <action name="actionMessages"> + <property name="text"> + <string>Messages</string> + </property> + <property name="toolTip"> + <string>Show compile/build messages</string> + </property> + </action> <action name="actionMnemonicRegisters"> <property name="checkable"> <bool>true</bool> diff --git a/qtmips_gui/mainwindow.cpp b/qtmips_gui/mainwindow.cpp index 775d926..0498ff3 100644 --- a/qtmips_gui/mainwindow.cpp +++ b/qtmips_gui/mainwindow.cpp @@ -94,6 +94,8 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { lcd_display->hide(); cop0dock = new Cop0Dock(this); cop0dock->hide(); + messages = new MessagesDock(this, settings); + messages->hide(); // Execution speed actions speed_group = new QActionGroup(this); @@ -128,6 +130,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { connect(ui->actionLcdDisplay, SIGNAL(triggered(bool)), this, SLOT(show_lcd_display())); connect(ui->actionCop0State, SIGNAL(triggered(bool)), this, SLOT(show_cop0dock())); connect(ui->actionCore_View_show, SIGNAL(triggered(bool)), this, SLOT(show_hide_coreview(bool))); + connect(ui->actionMessages, SIGNAL(triggered(bool)), this, SLOT(show_messages())); connect(ui->actionAbout, SIGNAL(triggered(bool)), this, SLOT(about_qtmips())); connect(ui->actionAboutQt, SIGNAL(triggered(bool)), this, SLOT(about_qt())); connect(ui->ips1, SIGNAL(toggled(bool)), this, SLOT(set_speed())); @@ -137,6 +140,12 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { connect(ui->ipsUnlimited, SIGNAL(toggled(bool)), this, SLOT(set_speed())); connect(ui->ipsMax, SIGNAL(toggled(bool)), this, SLOT(set_speed())); + connect(this, SIGNAL(report_message(messagetype::Type,QString,int,int,QString,QString)), + messages, SLOT(insert_line(messagetype::Type,QString,int,int,QString,QString))); + connect(this, SIGNAL(clear_messages()), messages, SLOT(clear_messages())); + connect(messages, SIGNAL(message_selected(messagetype::Type,QString,int,int,QString,QString)), + this, SLOT(message_selected(messagetype::Type,QString,int,int,QString,QString))); + // Restore application state from settings restoreState(settings->value("windowState").toByteArray()); restoreGeometry(settings->value("windowGeometry").toByteArray()); @@ -359,6 +368,7 @@ SHOW_HANDLER(peripherals, Qt::RightDockWidgetArea) SHOW_HANDLER(terminal, Qt::RightDockWidgetArea) SHOW_HANDLER(lcd_display, Qt::RightDockWidgetArea) SHOW_HANDLER(cop0dock, Qt::RightDockWidgetArea) +SHOW_HANDLER(messages, Qt::BottomDockWidgetArea) #undef SHOW_HANDLER void MainWindow::show_symbol_dialog(){ @@ -529,6 +539,37 @@ void MainWindow::update_open_file_list() { settings->setValue("openSrcFiles", open_src_files); } +SrcEditor *MainWindow::source_editor_for_file(QString filename, bool open) { + if ((central_window == nullptr) || (settings == nullptr)) + return nullptr; + bool found = false; + SrcEditor *editor = nullptr; + for (int i = 0; i < central_window->count(); i++) { + QWidget *w = central_window->widget(i); + editor = dynamic_cast<SrcEditor *>(w); + if (editor == nullptr) + continue; + if (editor->filename() == filename) { + found = true; + break; + } + } + if (found) + return editor; + + if (!open) + return nullptr; + + editor = new SrcEditor(); + if (!editor->loadFile(filename)) { + delete editor; + return nullptr; + } + add_src_editor_to_tabs(editor); + update_open_file_list(); + return editor; +} + void MainWindow::new_source() { SrcEditor *editor = new SrcEditor(); add_src_editor_to_tabs(editor); @@ -633,6 +674,23 @@ void MainWindow::close_source() { update_open_file_list(); } +void MainWindow::message_selected(messagetype::Type type, QString file, int line, + int column, QString text, QString hint) { + + (void)type; + (void)column; + (void)text; + (void)hint; + + SrcEditor *editor = source_editor_for_file(file, true); + if (editor == nullptr) + return; + editor->setCursorToLine(line); + editor->setFocus(); + if (central_window != nullptr) + central_window->setCurrentWidget(editor); +} + class SymbolTableDb : public fixmatheval::FmeSymbolDb { public: SymbolTableDb(const machine::SymbolTable *symtab); @@ -683,12 +741,15 @@ void MainWindow::compile_source() { QMessageBox::critical(this, "QtMips Error", tr("No physical addresspace to store program.")); return; } + QString filename = current_srceditor->filename(); machine->cache_sync(); SrcEditor *editor = current_srceditor; QTextDocument *doc = editor->document(); std::uint32_t address = 0x80020000; machine::RelocExpressionList reloc; + emit clear_messages(); + int ln = 1; for ( QTextBlock block = doc->begin(); block.isValid(); block = block.next(), ln++) { QString error; @@ -740,10 +801,9 @@ void MainWindow::compile_source() { ok = expression.eval(value, &symtab, error); if (!ok) { error_line = ln; - editor->setCursorToLine(error_line); - QMessageBox::critical(this, "QtMips Error", - tr("line %1 .orig %2 parse error.") - .arg(QString::number(ln), line)); + emit report_message(messagetype::ERROR, filename, ln, 0, + tr("line %1 .orig %2 parse error.") + .arg(QString::number(ln), line), ""); break; } address = value; @@ -753,11 +813,10 @@ void MainWindow::compile_source() { QStringList operands = line.mid(op.size()).split(","); if ((operands.count() > 2) || (operands.count() < 1)) { error_line = ln; - editor->setCursorToLine(error_line); - QMessageBox::critical(this, "QtMips Error", - tr("line %1 .set or .equ incorrect arguments number.") - .arg(QString::number(ln))); - break; + emit report_message(messagetype::ERROR, filename, ln, 0, + tr("line %1 .set or .equ incorrect arguments number.") + .arg(QString::number(ln)), ""); + continue; } QString name = operands.at(0).trimmed(); if ((name == "noat") || (name == "noreored")) @@ -771,11 +830,10 @@ void MainWindow::compile_source() { ok = expression.eval(value, &symtab, error); if (!ok) { error_line = ln; - editor->setCursorToLine(error_line); - QMessageBox::critical(this, "QtMips Error", + emit report_message(messagetype::ERROR, filename, ln, 0, tr("line %1 .set or .equ %2 parse error.") - .arg(QString::number(ln), operands.at(1))); - break; + .arg(QString::number(ln), operands.at(1)), ""); + continue; } } machine->set_symbol(name, value, 0); @@ -803,11 +861,10 @@ void MainWindow::compile_source() { address, &reloc, ln, true); if (size < 0) { error_line = ln; - editor->setCursorToLine(error_line); - QMessageBox::critical(this, "QtMips Error", + emit report_message(messagetype::ERROR, filename, ln, 0, tr("line %1 instruction %2 parse error - %3.") - .arg(QString::number(ln), line, error)); - break; + .arg(QString::number(ln), line, error), ""); + continue; } std::uint32_t *p = inst; for (ssize_t l = 0; l < size; l += 4) { @@ -819,36 +876,27 @@ void MainWindow::compile_source() { QString error; fixmatheval::FmeExpression expression; if (!expression.parse(r->expression, error)) { - if (!error_line) { - error_line = r->line; - editor->setCursorToLine(error_line); - QMessageBox::critical(this, "QtMips Error", - tr("expression parse error %1 at line %2, expression %3.") - .arg(error, QString::number(r->line), expression.dump())); - } + error_line = r->line; + emit report_message(messagetype::ERROR, filename, ln, 0, + tr("expression parse error %1 at line %2, expression %3.") + .arg(error, QString::number(r->line), expression.dump()), ""); } else { fixmatheval::FmeValue value; if (!expression.eval(value, &symtab, error)) { - if (!error_line) { - error_line = r->line; - editor->setCursorToLine(error_line); - QMessageBox::critical(this, "QtMips Error", - tr("expression evalution error %1 at line %2 , expression %3.") - .arg(error, QString::number(r->line), expression.dump())); - } + error_line = r->line; + emit report_message(messagetype::ERROR, filename, ln, 0, + tr("expression evalution error %1 at line %2 , expression %3.") + .arg(error, QString::number(r->line), expression.dump()), ""); } else { if (false) - QMessageBox::information(this, "QtMips info", - expression.dump() + " -> " + QString::number(value)); + emit report_message(messagetype::INFO, filename, ln, 0, + expression.dump() + " -> " + QString::number(value), ""); machine::Instruction inst(mem->read_word(r->location, true)); if (!inst.update(value, r)) { - if (!error_line) { - error_line = r->line; - editor->setCursorToLine(error_line); - QMessageBox::critical(this, "QtMips Error", - tr("instruction update error %1 at line %2, expression %3 -> value %4.") - .arg(error, QString::number(r->line), expression.dump(), QString::number(value))); - } + error_line = r->line; + emit report_message(messagetype::ERROR, filename, ln, 0, + tr("instruction update error %1 at line %2, expression %3 -> value %4.") + .arg(error, QString::number(r->line), expression.dump(), QString::number(value)), ""); } mem->write_word(r->location, inst.data()); } @@ -859,4 +907,7 @@ void MainWindow::compile_source() { } emit mem->external_change_notify(mem, 0, 0xffffffff, true); + + if (error_line != 0) + show_messages(); } diff --git a/qtmips_gui/mainwindow.h b/qtmips_gui/mainwindow.h index bd1aa80..95b3b59 100644 --- a/qtmips_gui/mainwindow.h +++ b/qtmips_gui/mainwindow.h @@ -50,6 +50,7 @@ #include "terminaldock.h" #include "lcddisplaydock.h" #include "cop0dock.h" +#include "messagesdock.h" #include "qtmipsmachine.h" #include "machineconfig.h" @@ -67,6 +68,11 @@ public: bool configured(); +signals: + void report_message(messagetype::Type type, QString file, int line, + int column, QString text, QString hint); + void clear_messages(); + public slots: // Actions signals void new_machine(); @@ -89,6 +95,7 @@ public slots: void show_cop0dock(); void show_hide_coreview(bool show); void show_symbol_dialog(); + void show_messages(); // Actions - help menu void about_qtmips(); void about_qt(); @@ -101,6 +108,7 @@ public slots: void central_tab_changed(int index); void tab_widget_destroyed(QObject *obj); void view_mnemonics_registers(bool enable); + void message_selected(messagetype::Type type, QString file, int line, int column, QString text, QString hint); protected: void closeEvent(QCloseEvent *event); @@ -126,6 +134,7 @@ private: TerminalDock *terminal; LcdDisplayDock *lcd_display; Cop0Dock *cop0dock; + MessagesDock *messages; bool coreview_shown; SrcEditor *current_srceditor; @@ -138,6 +147,7 @@ private: void show_dockwidget(QDockWidget *w, Qt::DockWidgetArea area = Qt::RightDockWidgetArea); void add_src_editor_to_tabs(SrcEditor *editor); void update_open_file_list(); + SrcEditor *source_editor_for_file(QString filename, bool open); }; #endif // MAINWINDOW_H diff --git a/qtmips_gui/messagesdock.cpp b/qtmips_gui/messagesdock.cpp new file mode 100644 index 0000000..d897e3f --- /dev/null +++ b/qtmips_gui/messagesdock.cpp @@ -0,0 +1,87 @@ +// SPDX-License-Identifier: GPL-2.0+ +/******************************************************************************* + * QtMips - MIPS 32-bit Architecture Subset Simulator + * + * Implemented to support following courses: + * + * B35APO - Computer Architectures + * https://cw.fel.cvut.cz/wiki/courses/b35apo + * + * B4M35PAP - Advanced Computer Architectures + * https://cw.fel.cvut.cz/wiki/courses/b4m35pap/start + * + * Copyright (c) 2017-2019 Karel Koci<cynerd@email.cz> + * Copyright (c) 2019 Pavel Pisa <pisa@cmp.felk.cvut.cz> + * + * Faculty of Electrical Engineering (http://www.fel.cvut.cz) + * Czech Technical University (http://www.cvut.cz/) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + ******************************************************************************/ + +#include <QWidget> +#include <QPushButton> +#include <QVBoxLayout> +#include <QTableView> +#include <QComboBox> +#include <QHeaderView> +#include <QMessageBox> +#include <QSettings> + +#include "messagesdock.h" +#include "messagesmodel.h" +#include "messagesview.h" +#include "messagetype.h" +#include "hexlineedit.h" + + + +MessagesDock::MessagesDock(QWidget *parent, QSettings *settings) : Super(parent) { + setObjectName("Messages"); + setWindowTitle("Messages"); + + this->settings = settings; + + QWidget *content = new QWidget(); + + QListView *messages_content = new MessagesView(0, settings); + MessagesModel *messages_model = new MessagesModel(0); + messages_content->setModel(messages_model); + + QVBoxLayout *layout = new QVBoxLayout; + layout->addWidget(messages_content); + + content->setLayout(layout); + + setWidget(content); + + connect(this, SIGNAL(report_message(messagetype::Type,QString,int,int,QString,QString)), + messages_model, SLOT(insert_line(messagetype::Type,QString,int,int,QString,QString))); + connect(this, SIGNAL(pass_clear_messages()), messages_model, SLOT(clear_messages())); + connect(messages_content, SIGNAL(activated(QModelIndex)), messages_model, SLOT(activated(QModelIndex))); + connect(messages_model, SIGNAL(message_selected(messagetype::Type,QString,int,int,QString,QString)), + this, SIGNAL(message_selected(messagetype::Type,QString,int,int,QString,QString))); +} + +void MessagesDock::insert_line(messagetype::Type type, QString file, int line, + int column, QString text, QString hint) { + report_message(type, file, line, column, text, hint); +} + +void MessagesDock::clear_messages() { + emit pass_clear_messages(); +} diff --git a/qtmips_gui/messagesdock.h b/qtmips_gui/messagesdock.h new file mode 100644 index 0000000..6cbf36e --- /dev/null +++ b/qtmips_gui/messagesdock.h @@ -0,0 +1,66 @@ +// SPDX-License-Identifier: GPL-2.0+ +/******************************************************************************* + * QtMips - MIPS 32-bit Architecture Subset Simulator + * + * Implemented to support following courses: + * + * B35APO - Computer Architectures + * https://cw.fel.cvut.cz/wiki/courses/b35apo + * + * B4M35PAP - Advanced Computer Architectures + * https://cw.fel.cvut.cz/wiki/courses/b4m35pap/start + * + * Copyright (c) 2017-2019 Karel Koci<cynerd@email.cz> + * Copyright (c) 2019 Pavel Pisa <pisa@cmp.felk.cvut.cz> + * + * Faculty of Electrical Engineering (http://www.fel.cvut.cz) + * Czech Technical University (http://www.cvut.cz/) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + ******************************************************************************/ + +#ifndef MESSAGESDOCK_H +#define MESSAGESDOCK_H + +#include <QDockWidget> +#include <QLabel> +#include <QComboBox> +#include <QSettings> +#include <messagesmodel.h> + +class MessagesDock : public QDockWidget { + Q_OBJECT + + using Super = QDockWidget; + +public: + MessagesDock(QWidget *parent, QSettings *settings); + +public slots: + void insert_line(messagetype::Type type, QString file, int line, int column, QString text, QString hint); + void clear_messages(); + +signals: + void report_message(messagetype::Type type, QString file, int line, int column, QString text, QString hint); + void pass_clear_messages(); + void message_selected(messagetype::Type type, QString file, int line, int column, QString text, QString hint); + +private: + QSettings *settings; +}; + +#endif // MESSAGESDOCK_H diff --git a/qtmips_gui/messagesmodel.cpp b/qtmips_gui/messagesmodel.cpp new file mode 100644 index 0000000..6138e01 --- /dev/null +++ b/qtmips_gui/messagesmodel.cpp @@ -0,0 +1,149 @@ +// SPDX-License-Identifier: GPL-2.0+ +/******************************************************************************* + * QtMips - MIPS 32-bit Architecture Subset Simulator + * + * Implemented to support following courses: + * + * B35APO - Computer Architectures + * https://cw.fel.cvut.cz/wiki/courses/b35apo + * + * B4M35PAP - Advanced Computer Architectures + * https://cw.fel.cvut.cz/wiki/courses/b4m35pap/start + * + * Copyright (c) 2017-2019 Karel Koci<cynerd@email.cz> + * Copyright (c) 2019 Pavel Pisa <pisa@cmp.felk.cvut.cz> + * + * Faculty of Electrical Engineering (http://www.fel.cvut.cz) + * Czech Technical University (http://www.cvut.cz/) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + ******************************************************************************/ + +#include <QBrush> + +#include "messagesmodel.h" + +class MessagesEntry { +public: + inline MessagesEntry(messagetype::Type type, QString file, int line, + int column, QString text, QString hint) { + + this->type = type; + this->file = file; + this->line = line; + this->column = column; + this->text = text; + this->hint = hint; + } + messagetype::Type type; + QString file; + int line; + int column; + QString text; + QString hint; +}; + + +MessagesModel::MessagesModel(QObject *parent) : Super(parent) { + +} + +int MessagesModel::rowCount(const QModelIndex & /*parent*/) const { + return messages.count(); +} + +int MessagesModel::columnCount(const QModelIndex & /*parent*/) const { + return 1; +} + +QVariant MessagesModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if(orientation == Qt::Horizontal) { + if(role == Qt::DisplayRole) { + switch (section) { + case 0: + return tr("Type"); + case 1: + return tr("Source"); + case 2: + return tr("Line"); + case 3: + return tr("Column"); + case 4: + return tr("Text"); + default: + return tr(""); + } + } + } + return Super::headerData(section, orientation, role); +} + +QVariant MessagesModel::data(const QModelIndex &index, int role) const { + if (index.row() >= rowCount()) + return QVariant(); + + if (role == Qt::DisplayRole || role == Qt::EditRole) + { + MessagesEntry *ent = messages.at(index.row()); + QString ret = ""; + if (!ent->file.isEmpty()) + ret += ent->file + ":"; + if (ent->line) + ret += QString::number(ent->line) + ":"; + if (ent->column) + ret += QString::number(ent->column) + ":"; + ret += ent->text; + return ret; + } + if (role == Qt::BackgroundRole) { + MessagesEntry *ent = messages.at(index.row()); + switch (ent->type) { + case messagetype::ERROR: + return QBrush(QColor(255, 230, 230)); + case messagetype::WARNING: + return QBrush(QColor(255, 255, 220)); + default: + return QVariant(); + } + } + return QVariant(); +} + +void MessagesModel::insert_line(messagetype::Type type, QString file, int line, + int column, QString text, QString hint) { + + beginInsertRows(QModelIndex(), rowCount(), rowCount()); + messages.append(new MessagesEntry(type, file, line, column, text, hint)); + endInsertRows(); +} + +void MessagesModel::clear_messages() { + beginRemoveRows(QModelIndex(), 0, rowCount() - 1); + while (!messages.isEmpty()) { + delete messages.takeFirst(); + } + endRemoveRows(); +} + +void MessagesModel::activated(QModelIndex index) { + if (index.row() >= rowCount()) + return; + + MessagesEntry *ent = messages.at(index.row()); + emit message_selected(ent->type, ent->file, ent->line, ent->column, ent->text, ent->hint); +} diff --git a/qtmips_gui/messagesmodel.h b/qtmips_gui/messagesmodel.h new file mode 100644 index 0000000..d9c35e5 --- /dev/null +++ b/qtmips_gui/messagesmodel.h @@ -0,0 +1,71 @@ +// SPDX-License-Identifier: GPL-2.0+ +/******************************************************************************* + * QtMips - MIPS 32-bit Architecture Subset Simulator + * + * Implemented to support following courses: + * + * B35APO - Computer Architectures + * https://cw.fel.cvut.cz/wiki/courses/b35apo + * + * B4M35PAP - Advanced Computer Architectures + * https://cw.fel.cvut.cz/wiki/courses/b4m35pap/start + * + * Copyright (c) 2017-2019 Karel Koci<cynerd@email.cz> + * Copyright (c) 2019 Pavel Pisa <pisa@cmp.felk.cvut.cz> + * + * Faculty of Electrical Engineering (http://www.fel.cvut.cz) + * Czech Technical University (http://www.cvut.cz/) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + ******************************************************************************/ + +#ifndef MESSAGESMODEL_H +#define MESSAGESMODEL_H + +#include <QAbstractListModel> +#include <QFont> +#include <QVector> + +#include "messagetype.h" + +class MessagesEntry; + +class MessagesModel : public QAbstractListModel +{ + Q_OBJECT + + using Super = QAbstractListModel; +public: + MessagesModel(QObject *parent); + int rowCount(const QModelIndex &parent = QModelIndex()) const override ; + int columnCount(const QModelIndex &parent = QModelIndex()) const override; + QVariant headerData(int section, Qt::Orientation orientation, int role) const override; + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + +public slots: + void insert_line(messagetype::Type type, QString file, int line, int column, QString text, QString hint); + void clear_messages(); + void activated(QModelIndex index); + +signals: + void message_selected(messagetype::Type type, QString file, int line, int column, QString text, QString hint); + +private: + QVector<MessagesEntry *> messages; +}; + +#endif // MESSAGESMODEL_H diff --git a/qtmips_gui/messagesview.cpp b/qtmips_gui/messagesview.cpp new file mode 100644 index 0000000..5bb651e --- /dev/null +++ b/qtmips_gui/messagesview.cpp @@ -0,0 +1,70 @@ +// SPDX-License-Identifier: GPL-2.0+ +/******************************************************************************* + * QtMips - MIPS 32-bit Architecture Subset Simulator + * + * Implemented to support following courses: + * + * B35APO - Computer Architectures + * https://cw.fel.cvut.cz/wiki/courses/b35apo + * + * B4M35PAP - Advanced Computer Architectures + * https://cw.fel.cvut.cz/wiki/courses/b4m35pap/start + * + * Copyright (c) 2017-2019 Karel Koci<cynerd@email.cz> + * Copyright (c) 2019 Pavel Pisa <pisa@cmp.felk.cvut.cz> + * + * Faculty of Electrical Engineering (http://www.fel.cvut.cz) + * Czech Technical University (http://www.cvut.cz/) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + ******************************************************************************/ + +#include <QHeaderView> +#include <QFontMetrics> +#include <QScrollBar> +#include <QKeyEvent> +#include <QClipboard> +#include <QApplication> +#include "messagesview.h" +#include "messagesmodel.h" + +MessagesView::MessagesView(QWidget *parent, QSettings *settings) : Super(parent) { + this->settings = settings; +} + +void MessagesView::resizeEvent(QResizeEvent *event) { + MessagesModel *m = dynamic_cast<MessagesModel*>(model()); + + Super::resizeEvent(event); +} + +void MessagesView::keyPressEvent(QKeyEvent *event) { + if(event->matches(QKeySequence::Copy)) { + QString text; + QItemSelectionRange range = selectionModel()->selection().first(); + for (auto i = range.top(); i <= range.bottom(); ++i) + { + QStringList rowContents; + for (auto j = range.left(); j <= range.right(); ++j) + rowContents << model()->index(i,j).data().toString(); + text += rowContents.join("\t"); + text += "\n"; + } + QApplication::clipboard()->setText(text); + } else + Super::keyPressEvent(event); +} diff --git a/qtmips_gui/messagesview.h b/qtmips_gui/messagesview.h new file mode 100644 index 0000000..ee8e7ed --- /dev/null +++ b/qtmips_gui/messagesview.h @@ -0,0 +1,59 @@ +// SPDX-License-Identifier: GPL-2.0+ +/******************************************************************************* + * QtMips - MIPS 32-bit Architecture Subset Simulator + * + * Implemented to support following courses: + * + * B35APO - Computer Architectures + * https://cw.fel.cvut.cz/wiki/courses/b35apo + * + * B4M35PAP - Advanced Computer Architectures + * https://cw.fel.cvut.cz/wiki/courses/b4m35pap/start + * + * Copyright (c) 2017-2019 Karel Koci<cynerd@email.cz> + * Copyright (c) 2019 Pavel Pisa <pisa@cmp.felk.cvut.cz> + * + * Faculty of Electrical Engineering (http://www.fel.cvut.cz) + * Czech Technical University (http://www.cvut.cz/) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + ******************************************************************************/ + +#ifndef MESSAGESVIEW_H +#define MESSAGESVIEW_H + +#include <QObject> +#include <QSettings> +#include <QListView> +#include <QSharedPointer> + +class MessagesView : public QListView +{ + Q_OBJECT + + using Super = QListView; + +public: + MessagesView(QWidget *parent, QSettings *settings); + + void resizeEvent(QResizeEvent *event) override; +protected: + void keyPressEvent(QKeyEvent *event) override; + QSettings *settings; +}; + +#endif // MESSAGESVIEW_H diff --git a/qtmips_gui/qtmips_gui.pro b/qtmips_gui/qtmips_gui.pro index 8e27fe2..0f8cab0 100644 --- a/qtmips_gui/qtmips_gui.pro +++ b/qtmips_gui/qtmips_gui.pro @@ -76,7 +76,10 @@ SOURCES += \ hinttabledelegate.cpp \ coreview/minimux.cpp \ srceditor.cpp \ - highlighter.cpp + highlighter.cpp \ + messagesdock.cpp \ + messagesmodel.cpp \ + messagesview.cpp HEADERS += \ mainwindow.h \ @@ -121,7 +124,10 @@ HEADERS += \ hinttabledelegate.h \ coreview/minimux.h \ srceditor.h \ - highlighter.h + highlighter.h \ + messagesdock.h \ + messagesmodel.h \ + messagesview.h wasm: SOURCES += \ qhtml5file_html5.cpp |