Commit df223bcb authored by Victor Yacovlev's avatar Victor Yacovlev

Everywhere: working MVC implementation of variables debugger view

parent 9724ad00
......@@ -19,7 +19,7 @@ endif(MSVC)
if(NOT MSVC)
set(CMAKE_CXX_FLAGS "-std=c++0x ${CMAKE_CXX_FLAGS}")
if(CMAKE_BUILD_TYPE MATCHES Debug)
set(CMAKE_CXX_FLAGS "-Werror -Wreturn-type ${CMAKE_CXX_FLAGS}")
set(CMAKE_CXX_FLAGS "-Werror -Wreturn-type -O0 ${CMAKE_CXX_FLAGS}")
endif()
endif()
......
......@@ -16,6 +16,7 @@ set(SOURCES
aboutdialog.cpp
debuggerwindow.cpp
statusbar.cpp
debuggerview.cpp
)
set(EXTRA_LIBS
......@@ -42,6 +43,7 @@ set(MOC_HEADERS
tabwidgetelement.h
debuggerwindow.h
statusbar.h
debuggerview.h
)
set(FORMS
......
#include "debuggerview.h"
namespace CoreGUI {
DebuggerView::DebuggerView(Shared::RunInterface * runner, QWidget *parent)
: QTreeView(parent)
, runner_(runner)
, debuggerEnabled_(false)
{
setHeaderHidden(true);
}
void DebuggerView::setDebuggerEnabled(bool enabled)
{
debuggerEnabled_ = enabled;
if (enabled && runner_ && runner_->debuggerVariablesViewModel()) {
QAbstractItemModel * newModel = runner_->debuggerVariablesViewModel();
if (model() != newModel) {
setModel(runner_->debuggerVariablesViewModel());
connect(model(), SIGNAL(rowsInserted(QModelIndex,int,int)),
this, SLOT(handleRowsInserted(QModelIndex,int,int)));
for (int column = 0; column < model()->columnCount(); ++column)
resizeColumnToContents(column);
handleRowsInserted(QModelIndex(),
model()->rowCount() - 1,
model()->rowCount() - 1);
}
}
else {
if (model()) {
disconnect(model(), SIGNAL(rowsInserted(QModelIndex,int,int)),
this, SLOT(handleRowsInserted(QModelIndex,int,int)));
}
setModel(0);
}
}
void DebuggerView::paintEvent(QPaintEvent *event)
{
if (debuggerEnabled_ && model()) {
QTreeView::paintEvent(event);
}
else {
static const QString message =
tr("Current values available only while running program in step-by-step mode");
event->accept();
QPainter p(viewport());
QStyleOptionFrame opt;
opt.initFrom(viewport());
opt.rect = viewport()->rect();
opt.palette.setCurrentColorGroup(QPalette::Disabled);
style()->drawPrimitive(QStyle::PE_Frame, &opt, &p, viewport());
QTextOption textOpt;
textOpt.setAlignment(Qt::AlignCenter);
textOpt.setWrapMode(QTextOption::WordWrap);
p.setPen(QPen(opt.palette.buttonText().color()));
p.drawText(viewport()->rect().adjusted(5,5,-10,-10),
message,
textOpt
);
}
}
void DebuggerView::handleRowsInserted(const QModelIndex &index, int start, int end)
{
if (!index.isValid() && start == end) { // top level context
const QModelIndex elementIndex = model()->index(start, 0, index);
if (elementIndex.isValid()) {
setExpanded(elementIndex, true);
}
}
}
void DebuggerView::handleRowsRemoved(const QModelIndex &index, int start, int end)
{
}
} // namespace CoreGUI
#ifndef COREGUI_DEBUGGERVIEW_H
#define COREGUI_DEBUGGERVIEW_H
#include "interfaces/runinterface.h"
#include <QTreeView>
namespace CoreGUI {
class DebuggerView : public QTreeView
{
Q_OBJECT
public:
explicit DebuggerView(Shared::RunInterface * runner, QWidget *parent = 0);
signals:
public slots:
void setDebuggerEnabled(bool enabled);
private slots:
void handleRowsInserted(const QModelIndex & index, int start, int end);
void handleRowsRemoved(const QModelIndex & index, int start, int end);
private /*methods*/:
void paintEvent(QPaintEvent *event);
private /*fields*/:
Shared::RunInterface * runner_;
bool debuggerEnabled_;
};
} // namespace CoreGUI
#endif // COREGUI_DEBUGGERVIEW_H
......@@ -34,7 +34,6 @@ public:
inline void setDocumentId(int id) { if (e_state==Idle) documentId_ = id; }
inline int documentId() const { return documentId_; }
inline void setMainWidget(QWidget * w) { w_mainWidget = w; }
inline void setDebuggerWindow(class DebuggerWindow * w) { w_debuggerWindow = w; }
void setTerminal(Term * t, QDockWidget * w);
void setBytecodeRun(KPlugin * run);
......
......@@ -2,7 +2,7 @@
#include "mainwindow.h"
#include "extensionsystem/pluginmanager.h"
#include "widgets/secondarywindow.h"
#include "debuggerwindow.h"
#include "debuggerview.h"
#include "ui_mainwindow.h"
#include "statusbar.h"
#ifdef Q_OS_MACX
......@@ -363,7 +363,7 @@ QString Plugin::initialize(const QStringList & parameters)
debuggerPlace_->setVisible(false);
debugger_ = new DebuggerWindow(plugin_kumirCodeRun);
debugger_ = new DebuggerView(plugin_kumirCodeRun);
Widgets::SecondaryWindow * debuggerWindow = new Widgets::SecondaryWindow(
debugger_,
debuggerPlace_,
......@@ -385,57 +385,56 @@ QString Plugin::initialize(const QStringList & parameters)
connect(debuggerWindow->toggleViewAction(), SIGNAL(toggled(bool)),
mainWindow_->ui->actionVariables, SLOT(setChecked(bool)));
connect(kumirRunner, SIGNAL(debuggerReset()),
debugger_, SLOT(reset()));
connect(kumirRunner, SIGNAL(debuggerPopContext()),
debugger_, SLOT(popContext()));
connect(kumirRunner,
SIGNAL(debuggerPushContext(QString,QStringList,QStringList,QList<int>)),
debugger_,
SLOT(pushContext(QString,QStringList,QStringList,QList<int>)));
connect(kumirRunner,
SIGNAL(debuggerUpdateLocalVariable(QString,QString)),
debugger_,
SLOT(updateLocalVariable(QString,QString)));
connect(kumirRunner,
SIGNAL(debuggerUpdateGlobalVariable(QString,QString,QString)),
debugger_,
SLOT(updateGlobalVariable(QString,QString,QString)));
connect(kumirRunner,
SIGNAL(debuggerUpdateLocalTableBounds(QString,QList<int>)),
debugger_,
SLOT(updateLocalTableBounds(QString,QList<int>)));
connect(kumirRunner,
SIGNAL(debuggerUpdateGlobalTableBounds(QString,QString,QList<int>)),
debugger_,
SLOT(updateGlobalTableBounds(QString,QString,QList<int>)));
connect(kumirRunner,
SIGNAL(debuggerSetLocalReference(QString,QString,QList<int>,int,QString)),
debugger_,
SLOT(setLocalReference(QString,QString,QList<int>,int,QString)));
connect(kumirRunner,
SIGNAL(debuggerForceUpdateValues()),
debugger_,
SLOT(updateAllValues()));
connect(kumirRunner,
SIGNAL(debuggerUpdateLocalTableValue(QString,QList<int>)),
debugger_,
SLOT(updateLocalTableValue(QString,QList<int>)));
connect(kumirRunner,
SIGNAL(debuggerUpdateGlobalTableValue(QString,QString,QList<int>)),
debugger_,
SLOT(updateGlobalTableValue(QString,QString,QList<int>)));
connect(kumirRunner,
SIGNAL(debuggerSetGlobals(QString,QStringList,QStringList,QList<int>)),
debugger_,
SLOT(setGlobals(QString,QStringList,QStringList,QList<int>))
);
// connect(kumirRunner, SIGNAL(debuggerReset()),
// debugger_, SLOT(reset()));
// connect(kumirRunner, SIGNAL(debuggerPopContext()),
// debugger_, SLOT(popContext()));
// connect(kumirRunner,
// SIGNAL(debuggerPushContext(QString,QStringList,QStringList,QList<int>)),
// debugger_,
// SLOT(pushContext(QString,QStringList,QStringList,QList<int>)));
// connect(kumirRunner,
// SIGNAL(debuggerUpdateLocalVariable(QString,QString)),
// debugger_,
// SLOT(updateLocalVariable(QString,QString)));
// connect(kumirRunner,
// SIGNAL(debuggerUpdateGlobalVariable(QString,QString,QString)),
// debugger_,
// SLOT(updateGlobalVariable(QString,QString,QString)));
// connect(kumirRunner,
// SIGNAL(debuggerUpdateLocalTableBounds(QString,QList<int>)),
// debugger_,
// SLOT(updateLocalTableBounds(QString,QList<int>)));
// connect(kumirRunner,
// SIGNAL(debuggerUpdateGlobalTableBounds(QString,QString,QList<int>)),
// debugger_,
// SLOT(updateGlobalTableBounds(QString,QString,QList<int>)));
// connect(kumirRunner,
// SIGNAL(debuggerSetLocalReference(QString,QString,QList<int>,int,QString)),
// debugger_,
// SLOT(setLocalReference(QString,QString,QList<int>,int,QString)));
// connect(kumirRunner,
// SIGNAL(debuggerForceUpdateValues()),
// debugger_,
// SLOT(updateAllValues()));
// connect(kumirRunner,
// SIGNAL(debuggerUpdateLocalTableValue(QString,QList<int>)),
// debugger_,
// SLOT(updateLocalTableValue(QString,QList<int>)));
// connect(kumirRunner,
// SIGNAL(debuggerUpdateGlobalTableValue(QString,QString,QList<int>)),
// debugger_,
// SLOT(updateGlobalTableValue(QString,QString,QList<int>)));
// connect(kumirRunner,
// SIGNAL(debuggerSetGlobals(QString,QStringList,QStringList,QList<int>)),
// debugger_,
// SLOT(setGlobals(QString,QStringList,QStringList,QList<int>))
// );
connect(kumirProgram_, SIGNAL(activateDocumentTab(int)),
mainWindow_, SLOT(activateDocumentTab(int)));
kumirProgram_->setDebuggerWindow(debugger_);
......@@ -562,6 +561,7 @@ void Plugin::changeGlobalState(ExtensionSystem::GlobalState old, ExtensionSystem
mainWindow_->setFocusOnCentralWidget();
mainWindow_->unlockActions();
debugger_->reset();
debugger_->setDebuggerEnabled(false);
}
else if (state==ExtensionSystem::GS_Observe) {
// m_kumirStateLabel->setText(tr("Observe"));
......@@ -577,6 +577,7 @@ void Plugin::changeGlobalState(ExtensionSystem::GlobalState old, ExtensionSystem
else if (state==ExtensionSystem::GS_Pause) {
// m_kumirStateLabel->setText(tr("Pause"));
mainWindow_->lockActions();
debugger_->setDebuggerEnabled(true);
}
else if (state==ExtensionSystem::GS_Input) {
// m_kumirStateLabel->setText(tr("Pause"));
......
......@@ -85,7 +85,7 @@ protected:
Term * m_terminal;
QMap<QString,QObject*> m_browserObjects;
KumirProgram * kumirProgram_;
class DebuggerWindow * debugger_;
class DebuggerView * debugger_;
DocBookViewer::DocBookView * helpViewer_;
QSplitter * bottomSplitter_;
Shared::CoursesInterface* courseManager_;
......
......@@ -11,6 +11,7 @@ set(SOURCES
commonrun.cpp
util.cpp
guirun.cpp
kumvariablesmodel.cpp
)
set(HEADERS
......@@ -22,6 +23,7 @@ set(MOC_HEADERS
run.h
commonrun.h
guirun.h
kumvariablesmodel.h
)
qt4_wrap_cpp(MOC_SOURCES ${MOC_HEADERS})
......
This diff is collapsed.
#ifndef KUMIRCODERUN_KUMVARIABLESMODEL_H
#define KUMIRCODERUN_KUMVARIABLESMODEL_H
#define DO_NOT_DECLARE_STATIC
#include "vm/vm.hpp"
#include <QAbstractItemModel>
#include <QVector>
#include <QString>
#include <QVariant>
#include <QHash>
namespace KumirCodeRun {
typedef const std::vector<VM::Variable> TableOfVariables;
class KumVariableItem {
friend class KumVariablesModel;
public:
enum Type {
GlobalsTable, LocalsTable, Variable, ArrayItem
};
inline Type itemType() const { return type_; }
inline int numberInTable() const { return tableNumber_; }
inline TableOfVariables * table() const { return table_; }
inline const VM::Variable * variable() const { return variable_; }
inline QVector<int> arrayIndeces() const { return indeces_; }
QString name() const;
QString variableTypeName() const;
QString valueRepresentation() const;
QString arrayRepresentation() const;
bool hasValue() const;
bool isReference() const;
private:
explicit KumVariableItem(TableOfVariables * table, int row);
explicit KumVariableItem(TableOfVariables * table, int row,
const QString & name);
explicit KumVariableItem(const VM::Variable * variable, int row,
TableOfVariables * table);
explicit KumVariableItem(const VM::Variable * variable, int row,
const QVector<int> & indeces);
QString array1Representation(const QVector<int> & indeces, int maxItems, int & readItems) const;
QString array2Representation(const QVector<int> & indeces, int maxItems, int & readItems) const;
QString array3Representation(const QVector<int> & indeces, int maxItems, int & readItems) const;
Type type_;
const VM::Variable * variable_;
TableOfVariables * table_;
int tableNumber_;
QVector<int> indeces_;
QString algorithmName_;
};
class KumVariablesModel : public QAbstractItemModel
{
friend class Run;
Q_OBJECT
public:
QModelIndex index(int row, int column, const QModelIndex &parent) const;
QModelIndex parent(const QModelIndex &child) const;
int rowCount(const QModelIndex &parent) const;
int columnCount(const QModelIndex &parent) const;
QVariant data(const QModelIndex &index, int role) const;
Qt::ItemFlags flags(const QModelIndex &index) const;
signals:
public slots:
protected:
explicit KumVariablesModel(VM::KumirVM * vm,
VM::CriticalSectionLocker * mutex,
QObject *parent = 0);
QModelIndex valueIndex(int row, int column, TableOfVariables * table) const;
QModelIndex arrayIndex(int row, int column, const VM::Variable * variable, const QVector<int> & prevIndeces) const;
QModelIndex topLevelIndex(int row) const;
void clear();
void emitValueChanged(const VM::Variable & variable, const QVector<int> & indeces);
private:
VM::KumirVM * vm_;
VM::CriticalSectionLocker * mutex_;
QHash<QModelIndex, QModelIndex> parents_;
mutable QList<KumVariableItem*> cache_;
mutable QHash<KumVariableItem*, QModelIndex> modelIndeces_;
};
} // namespace KumirCodeRun
#endif // KUMIRCODERUN_KUMVARIABLESMODEL_H
......@@ -14,7 +14,7 @@
namespace KumirCodeRun {
Plugin::Plugin()
KumirRunPlugin::KumirRunPlugin()
: ExtensionSystem::KPlugin()
, pRun_(new Run(this))
, common_(nullptr)
......@@ -70,22 +70,22 @@ Plugin::Plugin()
Qt::DirectConnection);
}
unsigned long int Plugin::stepsCounted() const
unsigned long int KumirRunPlugin::stepsCounted() const
{
return pRun_->vm->stepsDone();
}
int Plugin::currentLineNo() const
int KumirRunPlugin::currentLineNo() const
{
return pRun_->effectiveLineNo();
}
QPair<quint32,quint32> Plugin::currentColumn() const
QPair<quint32,quint32> KumirRunPlugin::currentColumn() const
{
return QPair<quint32,quint32>(pRun_->vm->effectiveColumn().first, pRun_->vm->effectiveColumn().second);
}
bool Plugin::loadProgram(const QString & filename, const QByteArray & source, Shared::ProgramFormat format)
bool KumirRunPlugin::loadProgram(const QString & filename, const QByteArray & source, Shared::ProgramFormat format)
{
bool ok = false;
if (format==Shared::FormatBinary) {
......@@ -104,12 +104,12 @@ bool Plugin::loadProgram(const QString & filename, const QByteArray & source, Sh
return ok;
}
QString Plugin::error() const
QString KumirRunPlugin::error() const
{
return pRun_->error();
}
QMap<QString,QVariant> Plugin::getScalarLocalValues(int frameNo) const
QMap<QString,QVariant> KumirRunPlugin::getScalarLocalValues(int frameNo) const
{
pRun_->lockVMMutex();
QMap<QString,QVariant> result;
......@@ -132,12 +132,12 @@ QMap<QString,QVariant> Plugin::getScalarLocalValues(int frameNo) const
return result;
}
QVariant Plugin::valueStackTopItem() const
QVariant KumirRunPlugin::valueStackTopItem() const
{
return pRun_->valueStackTopItem();
}
QMap<QString,QVariant> Plugin::getScalarGlobalValues(const QString & moduleName) const
QMap<QString,QVariant> KumirRunPlugin::getScalarGlobalValues(const QString & moduleName) const
{
pRun_->lockVMMutex();
QMap<QString,QVariant> result;
......@@ -268,7 +268,7 @@ QVariantList getTableValues(
return result;
}
QVariantList Plugin::getLocalTableValues(
QVariantList KumirRunPlugin::getLocalTableValues(
int frameNo,
int maxCount,
const QString &name,
......@@ -292,7 +292,7 @@ QVariantList Plugin::getLocalTableValues(
return result;
}
QVariant Plugin::getLocalTableValue(
QVariant KumirRunPlugin::getLocalTableValue(
int frameNo,
const QString &name,
const QList<int> &indeces
......@@ -318,7 +318,7 @@ QVariant Plugin::getLocalTableValue(
return result;
}
QVariantList Plugin::getGlobalTableValues(
QVariantList KumirRunPlugin::getGlobalTableValues(
const QString & moduleName,
int maxCount,
const QString &name,
......@@ -342,7 +342,7 @@ QVariantList Plugin::getGlobalTableValues(
return result;
}
QVariant Plugin::getGlobalTableValue(
QVariant KumirRunPlugin::getGlobalTableValue(
const QString & moduleName,
const QString &name,
const QList<int> &indeces
......@@ -370,7 +370,7 @@ QVariant Plugin::getGlobalTableValue(
void Plugin::runContinuous()
void KumirRunPlugin::runContinuous()
{
if (done_) {
pRun_->setEntryPointToMain();
......@@ -380,7 +380,7 @@ void Plugin::runContinuous()
pRun_->runContinuous();
}
void Plugin::runBlind()
void KumirRunPlugin::runBlind()
{
if (done_) {
pRun_->setEntryPointToMain();
......@@ -390,17 +390,17 @@ void Plugin::runBlind()
pRun_->runBlind();
}
void Plugin::runStepInto()
void KumirRunPlugin::runStepInto()
{
pRun_->runStepIn();
}
void Plugin::runStepOut()
void KumirRunPlugin::runStepOut()
{
pRun_->runStepOut();
}
void Plugin::runStepOver()
void KumirRunPlugin::runStepOver()
{
if (done_) {
pRun_->setEntryPointToMain();
......@@ -410,7 +410,7 @@ void Plugin::runStepOver()
pRun_->runStepOver();
}
void Plugin::runTesting()
void KumirRunPlugin::runTesting()
{
if (done_) {
pRun_->setEntryPointToTest();
......@@ -420,18 +420,18 @@ void Plugin::runTesting()
pRun_->runBlind();
}
bool Plugin::isTestingRun() const
bool KumirRunPlugin::isTestingRun() const
{
return pRun_->isTestingRun();
}
void Plugin::terminate()
void KumirRunPlugin::terminate()
{
pRun_->stop();
}
void Plugin::handleThreadFinished()
void KumirRunPlugin::handleThreadFinished()
{
if (pRun_->error().length()>0) {
done_ = true;
......@@ -450,7 +450,7 @@ void Plugin::handleThreadFinished()
}
}
void Plugin::handleLineChanged(int lineNo, quint32 colStart, quint32 colEnd)
void KumirRunPlugin::handleLineChanged(int lineNo, quint32 colStart, quint32 colEnd)
{
emit lineChanged(lineNo, colStart, colEnd);
}
......@@ -480,7 +480,7 @@ struct GuiFunctors {
Gui::PauseFunctor pause;
};
Plugin::~Plugin()
KumirRunPlugin::~KumirRunPlugin()
{
if (pRun_->isRunning()) {
pRun_->stop();
......@@ -496,7 +496,7 @@ Plugin::~Plugin()
}
void Plugin::prepareCommonRun()
void KumirRunPlugin::prepareCommonRun()
{
common_ = new CommonFunctors;
common_->reset.setCallFunctor(&common_->call);
......@@ -506,7 +506,7 @@ void Plugin::prepareCommonRun()
pRun_->vm->setFunctor(&common_->fromString);
}
void Plugin::prepareConsoleRun()
void KumirRunPlugin::prepareConsoleRun()
{