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) ...@@ -19,7 +19,7 @@ endif(MSVC)
if(NOT MSVC) if(NOT MSVC)
set(CMAKE_CXX_FLAGS "-std=c++0x ${CMAKE_CXX_FLAGS}") set(CMAKE_CXX_FLAGS "-std=c++0x ${CMAKE_CXX_FLAGS}")
if(CMAKE_BUILD_TYPE MATCHES Debug) 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()
endif() endif()
......
...@@ -16,6 +16,7 @@ set(SOURCES ...@@ -16,6 +16,7 @@ set(SOURCES
aboutdialog.cpp aboutdialog.cpp
debuggerwindow.cpp debuggerwindow.cpp
statusbar.cpp statusbar.cpp
debuggerview.cpp
) )
set(EXTRA_LIBS set(EXTRA_LIBS
...@@ -42,6 +43,7 @@ set(MOC_HEADERS ...@@ -42,6 +43,7 @@ set(MOC_HEADERS
tabwidgetelement.h tabwidgetelement.h
debuggerwindow.h debuggerwindow.h
statusbar.h statusbar.h
debuggerview.h
) )
set(FORMS 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: ...@@ -34,7 +34,6 @@ public:
inline void setDocumentId(int id) { if (e_state==Idle) documentId_ = id; } inline void setDocumentId(int id) { if (e_state==Idle) documentId_ = id; }
inline int documentId() const { return documentId_; } inline int documentId() const { return documentId_; }
inline void setMainWidget(QWidget * w) { w_mainWidget = w; } inline void setMainWidget(QWidget * w) { w_mainWidget = w; }
inline void setDebuggerWindow(class DebuggerWindow * w) { w_debuggerWindow = w; }
void setTerminal(Term * t, QDockWidget * w); void setTerminal(Term * t, QDockWidget * w);
void setBytecodeRun(KPlugin * run); void setBytecodeRun(KPlugin * run);
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
#include "mainwindow.h" #include "mainwindow.h"
#include "extensionsystem/pluginmanager.h" #include "extensionsystem/pluginmanager.h"
#include "widgets/secondarywindow.h" #include "widgets/secondarywindow.h"
#include "debuggerwindow.h" #include "debuggerview.h"
#include "ui_mainwindow.h" #include "ui_mainwindow.h"
#include "statusbar.h" #include "statusbar.h"
#ifdef Q_OS_MACX #ifdef Q_OS_MACX
...@@ -363,7 +363,7 @@ QString Plugin::initialize(const QStringList & parameters) ...@@ -363,7 +363,7 @@ QString Plugin::initialize(const QStringList & parameters)
debuggerPlace_->setVisible(false); debuggerPlace_->setVisible(false);
debugger_ = new DebuggerWindow(plugin_kumirCodeRun); debugger_ = new DebuggerView(plugin_kumirCodeRun);
Widgets::SecondaryWindow * debuggerWindow = new Widgets::SecondaryWindow( Widgets::SecondaryWindow * debuggerWindow = new Widgets::SecondaryWindow(
debugger_, debugger_,
debuggerPlace_, debuggerPlace_,
...@@ -385,57 +385,56 @@ QString Plugin::initialize(const QStringList & parameters) ...@@ -385,57 +385,56 @@ QString Plugin::initialize(const QStringList & parameters)
connect(debuggerWindow->toggleViewAction(), SIGNAL(toggled(bool)), connect(debuggerWindow->toggleViewAction(), SIGNAL(toggled(bool)),
mainWindow_->ui->actionVariables, SLOT(setChecked(bool))); mainWindow_->ui->actionVariables, SLOT(setChecked(bool)));
connect(kumirRunner, SIGNAL(debuggerReset()), // connect(kumirRunner, SIGNAL(debuggerReset()),
debugger_, SLOT(reset())); // debugger_, SLOT(reset()));
connect(kumirRunner, SIGNAL(debuggerPopContext()), // connect(kumirRunner, SIGNAL(debuggerPopContext()),
debugger_, SLOT(popContext())); // debugger_, SLOT(popContext()));
connect(kumirRunner, // connect(kumirRunner,
SIGNAL(debuggerPushContext(QString,QStringList,QStringList,QList<int>)), // SIGNAL(debuggerPushContext(QString,QStringList,QStringList,QList<int>)),
debugger_, // debugger_,
SLOT(pushContext(QString,QStringList,QStringList,QList<int>))); // SLOT(pushContext(QString,QStringList,QStringList,QList<int>)));
connect(kumirRunner, // connect(kumirRunner,
SIGNAL(debuggerUpdateLocalVariable(QString,QString)), // SIGNAL(debuggerUpdateLocalVariable(QString,QString)),
debugger_, // debugger_,
SLOT(updateLocalVariable(QString,QString))); // SLOT(updateLocalVariable(QString,QString)));
connect(kumirRunner, // connect(kumirRunner,
SIGNAL(debuggerUpdateGlobalVariable(QString,QString,QString)), // SIGNAL(debuggerUpdateGlobalVariable(QString,QString,QString)),
debugger_, // debugger_,
SLOT(updateGlobalVariable(QString,QString,QString))); // SLOT(updateGlobalVariable(QString,QString,QString)));
connect(kumirRunner, // connect(kumirRunner,
SIGNAL(debuggerUpdateLocalTableBounds(QString,QList<int>)), // SIGNAL(debuggerUpdateLocalTableBounds(QString,QList<int>)),
debugger_, // debugger_,
SLOT(updateLocalTableBounds(QString,QList<int>))); // SLOT(updateLocalTableBounds(QString,QList<int>)));
connect(kumirRunner, // connect(kumirRunner,
SIGNAL(debuggerUpdateGlobalTableBounds(QString,QString,QList<int>)), // SIGNAL(debuggerUpdateGlobalTableBounds(QString,QString,QList<int>)),
debugger_, // debugger_,
SLOT(updateGlobalTableBounds(QString,QString,QList<int>))); // SLOT(updateGlobalTableBounds(QString,QString,QList<int>)));
connect(kumirRunner, // connect(kumirRunner,
SIGNAL(debuggerSetLocalReference(QString,QString,QList<int>,int,QString)), // SIGNAL(debuggerSetLocalReference(QString,QString,QList<int>,int,QString)),
debugger_, // debugger_,
SLOT(setLocalReference(QString,QString,QList<int>,int,QString))); // SLOT(setLocalReference(QString,QString,QList<int>,int,QString)));
connect(kumirRunner, // connect(kumirRunner,
SIGNAL(debuggerForceUpdateValues()), // SIGNAL(debuggerForceUpdateValues()),
debugger_, // debugger_,
SLOT(updateAllValues())); // SLOT(updateAllValues()));
connect(kumirRunner, // connect(kumirRunner,
SIGNAL(debuggerUpdateLocalTableValue(QString,QList<int>)), // SIGNAL(debuggerUpdateLocalTableValue(QString,QList<int>)),
debugger_, // debugger_,
SLOT(updateLocalTableValue(QString,QList<int>))); // SLOT(updateLocalTableValue(QString,QList<int>)));
connect(kumirRunner, // connect(kumirRunner,
SIGNAL(debuggerUpdateGlobalTableValue(QString,QString,QList<int>)), // SIGNAL(debuggerUpdateGlobalTableValue(QString,QString,QList<int>)),
debugger_, // debugger_,
SLOT(updateGlobalTableValue(QString,QString,QList<int>))); // SLOT(updateGlobalTableValue(QString,QString,QList<int>)));
connect(kumirRunner, // connect(kumirRunner,
SIGNAL(debuggerSetGlobals(QString,QStringList,QStringList,QList<int>)), // SIGNAL(debuggerSetGlobals(QString,QStringList,QStringList,QList<int>)),
debugger_, // debugger_,
SLOT(setGlobals(QString,QStringList,QStringList,QList<int>)) // SLOT(setGlobals(QString,QStringList,QStringList,QList<int>))
); // );
connect(kumirProgram_, SIGNAL(activateDocumentTab(int)), connect(kumirProgram_, SIGNAL(activateDocumentTab(int)),
mainWindow_, SLOT(activateDocumentTab(int))); mainWindow_, SLOT(activateDocumentTab(int)));
kumirProgram_->setDebuggerWindow(debugger_);
...@@ -562,6 +561,7 @@ void Plugin::changeGlobalState(ExtensionSystem::GlobalState old, ExtensionSystem ...@@ -562,6 +561,7 @@ void Plugin::changeGlobalState(ExtensionSystem::GlobalState old, ExtensionSystem
mainWindow_->setFocusOnCentralWidget(); mainWindow_->setFocusOnCentralWidget();
mainWindow_->unlockActions(); mainWindow_->unlockActions();
debugger_->reset(); debugger_->reset();
debugger_->setDebuggerEnabled(false);
} }
else if (state==ExtensionSystem::GS_Observe) { else if (state==ExtensionSystem::GS_Observe) {
// m_kumirStateLabel->setText(tr("Observe")); // m_kumirStateLabel->setText(tr("Observe"));
...@@ -577,6 +577,7 @@ void Plugin::changeGlobalState(ExtensionSystem::GlobalState old, ExtensionSystem ...@@ -577,6 +577,7 @@ void Plugin::changeGlobalState(ExtensionSystem::GlobalState old, ExtensionSystem
else if (state==ExtensionSystem::GS_Pause) { else if (state==ExtensionSystem::GS_Pause) {
// m_kumirStateLabel->setText(tr("Pause")); // m_kumirStateLabel->setText(tr("Pause"));
mainWindow_->lockActions(); mainWindow_->lockActions();
debugger_->setDebuggerEnabled(true);
} }
else if (state==ExtensionSystem::GS_Input) { else if (state==ExtensionSystem::GS_Input) {
// m_kumirStateLabel->setText(tr("Pause")); // m_kumirStateLabel->setText(tr("Pause"));
......
...@@ -85,7 +85,7 @@ protected: ...@@ -85,7 +85,7 @@ protected:
Term * m_terminal; Term * m_terminal;
QMap<QString,QObject*> m_browserObjects; QMap<QString,QObject*> m_browserObjects;
KumirProgram * kumirProgram_; KumirProgram * kumirProgram_;
class DebuggerWindow * debugger_; class DebuggerView * debugger_;
DocBookViewer::DocBookView * helpViewer_; DocBookViewer::DocBookView * helpViewer_;
QSplitter * bottomSplitter_; QSplitter * bottomSplitter_;
Shared::CoursesInterface* courseManager_; Shared::CoursesInterface* courseManager_;
......
...@@ -11,6 +11,7 @@ set(SOURCES ...@@ -11,6 +11,7 @@ set(SOURCES
commonrun.cpp commonrun.cpp
util.cpp util.cpp
guirun.cpp guirun.cpp
kumvariablesmodel.cpp
) )
set(HEADERS set(HEADERS
...@@ -22,6 +23,7 @@ set(MOC_HEADERS ...@@ -22,6 +23,7 @@ set(MOC_HEADERS
run.h run.h
commonrun.h commonrun.h
guirun.h guirun.h
kumvariablesmodel.h
) )
qt4_wrap_cpp(MOC_SOURCES ${MOC_HEADERS}) 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 @@ ...@@ -14,7 +14,7 @@
namespace KumirCodeRun { namespace KumirCodeRun {
Plugin::Plugin() KumirRunPlugin::KumirRunPlugin()
: ExtensionSystem::KPlugin() : ExtensionSystem::KPlugin()
, pRun_(new Run(this)) , pRun_(new Run(this))
, common_(nullptr) , common_(nullptr)
...@@ -70,22 +70,22 @@ Plugin::Plugin() ...@@ -70,22 +70,22 @@ Plugin::Plugin()
Qt::DirectConnection); Qt::DirectConnection);
} }
unsigned long int Plugin::stepsCounted() const unsigned long int KumirRunPlugin::stepsCounted() const
{ {
return pRun_->vm->stepsDone(); return pRun_->vm->stepsDone();
} }
int Plugin::currentLineNo() const int KumirRunPlugin::currentLineNo() const
{ {
return pRun_->effectiveLineNo(); 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); 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; bool ok = false;
if (format==Shared::FormatBinary) { if (format==Shared::FormatBinary) {
...@@ -104,12 +104,12 @@ bool Plugin::loadProgram(const QString & filename, const QByteArray & source, Sh ...@@ -104,12 +104,12 @@ bool Plugin::loadProgram(const QString & filename, const QByteArray & source, Sh
return ok; return ok;
} }
QString Plugin::error() const QString KumirRunPlugin::error() const
{ {
return pRun_->error(); return pRun_->error();
} }
QMap<QString,QVariant> Plugin::getScalarLocalValues(int frameNo) const QMap<QString,QVariant> KumirRunPlugin::getScalarLocalValues(int frameNo) const
{ {
pRun_->lockVMMutex(); pRun_->lockVMMutex();
QMap<QString,QVariant> result; QMap<QString,QVariant> result;
...@@ -132,12 +132,12 @@ QMap<QString,QVariant> Plugin::getScalarLocalValues(int frameNo) const ...@@ -132,12 +132,12 @@ QMap<QString,QVariant> Plugin::getScalarLocalValues(int frameNo) const
return result; return result;
} }
QVariant Plugin::valueStackTopItem() const QVariant KumirRunPlugin::valueStackTopItem() const
{ {
return pRun_->valueStackTopItem(); return pRun_->valueStackTopItem();
} }
QMap<QString,QVariant> Plugin::getScalarGlobalValues(const QString & moduleName) const QMap<QString,QVariant> KumirRunPlugin::getScalarGlobalValues(const QString & moduleName) const
{ {
pRun_->lockVMMutex(); pRun_->lockVMMutex();
QMap<QString,QVariant> result; QMap<QString,QVariant> result;
...@@ -268,7 +268,7 @@ QVariantList getTableValues( ...@@ -268,7 +268,7 @@ QVariantList getTableValues(
return result; return result;
} }
QVariantList Plugin::getLocalTableValues( QVariantList KumirRunPlugin::getLocalTableValues(
int frameNo, int frameNo,
int maxCount, int maxCount,
const QString &name, const QString &name,
...@@ -292,7 +292,7 @@ QVariantList Plugin::getLocalTableValues( ...@@ -292,7 +292,7 @@ QVariantList Plugin::getLocalTableValues(
return result; return result;
} }
QVariant Plugin::getLocalTableValue( QVariant KumirRunPlugin::getLocalTableValue(
int frameNo, int frameNo,
const QString &name, const QString &name,
const QList<int> &indeces const QList<int> &indeces
...@@ -318,7 +318,7 @@ QVariant Plugin::getLocalTableValue( ...@@ -318,7 +318,7 @@ QVariant Plugin::getLocalTableValue(
return result; return result;
} }
QVariantList Plugin::getGlobalTableValues( QVariantList KumirRunPlugin::getGlobalTableValues(
const QString & moduleName, const QString & moduleName,
int maxCount, int maxCount,
const QString &name, const QString &name,
...@@ -342,7 +342,7 @@ QVariantList Plugin::getGlobalTableValues( ...@@ -342,7 +342,7 @@ QVariantList Plugin::getGlobalTableValues(
return result; return result;
} }