kde-extraapps/kdevplatform/debugger/interfaces/ibreakpointcontroller.cpp
2015-07-26 14:23:17 +03:00

218 lines
7.3 KiB
C++

/* This file is part of the KDE project
Copyright (C) 2002 Matthias Hoelzer-Kluepfel <hoelzer@kde.org>
Copyright (C) 2002 John Firebaugh <jfirebaugh@kde.org>
Copyright (C) 2006, 2008 Vladimir Prus <ghost@cs.msu.su>
Copyright (C) 2007 Hamish Rodda <rodda@kde.org>
Copyright (C) 2009 Niko Sams <niko.sams@gmail.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "ibreakpointcontroller.h"
#include <KDE/KDebug> // remove later
#include <KNotification>
#include <KLocalizedString>
#include <KGlobal>
#include <KParts/MainWindow>
#include "idebugsession.h"
#include "../../interfaces/icore.h"
#include "../breakpoint/breakpointmodel.h"
#include "../../interfaces/idebugcontroller.h"
#include "../breakpoint/breakpoint.h"
#include "../../interfaces/iuicontroller.h"
namespace KDevelop {
IBreakpointController::IBreakpointController(KDevelop::IDebugSession* parent)
: QObject(parent), m_dontSendChanges(0)
{
connect(breakpointModel(),
SIGNAL(breakpointChanged(KDevelop::Breakpoint*,KDevelop::Breakpoint::Column)),
SLOT(breakpointChanged(KDevelop::Breakpoint*,KDevelop::Breakpoint::Column)));
connect(breakpointModel(), SIGNAL(breakpointDeleted(KDevelop::Breakpoint*)),
SLOT(breakpointDeleted(KDevelop::Breakpoint*)));
connect(parent, SIGNAL(stateChanged(KDevelop::IDebugSession::DebuggerState)),
SLOT(debuggerStateChanged(KDevelop::IDebugSession::DebuggerState)));
}
IDebugSession* IBreakpointController::debugSession() const
{
return static_cast<IDebugSession*>(const_cast<QObject*>(QObject::parent()));
}
BreakpointModel* IBreakpointController::breakpointModel() const
{
if (!ICore::self()) return 0;
return ICore::self()->debugController()->breakpointModel();
}
void IBreakpointController::debuggerStateChanged(IDebugSession::DebuggerState state)
{
BreakpointModel* model = breakpointModel();
if (!model)
return;
if (state == IDebugSession::StartingState || state == IDebugSession::EndedState) {
//breakpoint state changes when session started or stopped
foreach (Breakpoint *breakpoint, model->breakpoints()) {
if (state == IDebugSession::StartingState) {
//when starting everything is dirty
m_dirty[breakpoint].insert(Breakpoint::LocationColumn);
if (!breakpoint->condition().isEmpty()) {
m_dirty[breakpoint].insert(Breakpoint::ConditionColumn);
}
if (!breakpoint->enabled()) {
m_dirty[breakpoint].insert(KDevelop::Breakpoint::EnableColumn);
}
}
breakpointStateChanged(breakpoint);
}
}
}
void IBreakpointController::sendMaybeAll()
{
BreakpointModel* model = breakpointModel();
if (!model)
return;
foreach (Breakpoint *breakpoint, model->breakpoints()) {
sendMaybe(breakpoint);
}
}
void IBreakpointController::breakpointChanged(KDevelop::Breakpoint* breakpoint, KDevelop::Breakpoint::Column column)
{
if (m_dontSendChanges) return;
if (column != Breakpoint::StateColumn) {
m_dirty[breakpoint].insert(column);
if (m_errors.contains(breakpoint)) m_errors[breakpoint].remove(column);
breakpointStateChanged(breakpoint);
if (debugSession()->isRunning()) {
sendMaybe(breakpoint);
}
}
kDebug() << column << m_dirty;
}
void IBreakpointController::breakpointDeleted(KDevelop::Breakpoint* breakpoint)
{
kDebug() << breakpoint;
sendMaybe(breakpoint);
}
Breakpoint::BreakpointState IBreakpointController::breakpointState(const Breakpoint* breakpoint) const
{
if (debugSession()->state() != IDebugSession::ActiveState
&& debugSession()->state() != IDebugSession::PausedState
) {
return Breakpoint::NotStartedState;
}
if (!m_dirty.contains(breakpoint) || m_dirty[breakpoint].isEmpty()) {
if (m_pending.contains(breakpoint)) {
return Breakpoint::PendingState;
}
return Breakpoint::CleanState;
}
return Breakpoint::DirtyState;
}
int IBreakpointController::breakpointHitCount(const KDevelop::Breakpoint* breakpoint) const
{
if (m_hitCount.contains(breakpoint)) {
return m_hitCount[breakpoint];
}
return 0;
}
void IBreakpointController::breakpointStateChanged(Breakpoint* breakpoint)
{
if (breakpoint->deleted()) return;
m_dontSendChanges++;
breakpoint->reportChange(Breakpoint::StateColumn);
m_dontSendChanges--;
}
void IBreakpointController::setHitCount(Breakpoint* breakpoint, int count)
{
m_hitCount[breakpoint] = count;
m_dontSendChanges++;
breakpoint->reportChange(Breakpoint::HitCountColumn);
m_dontSendChanges--;
}
void IBreakpointController::error(Breakpoint* breakpoint, const QString &msg, Breakpoint::Column column)
{
m_dontSendChanges++;
m_errorText.insert(breakpoint, msg);
m_errors[breakpoint].insert(column);
breakpoint->reportChange(column);
breakpoint->reportChange(Breakpoint::StateColumn);
breakpointModel()->errorEmit(breakpoint, msg, Breakpoint::LocationColumn);
m_dontSendChanges--;
}
void IBreakpointController::hit(KDevelop::Breakpoint* breakpoint, const QString &msg)
{
kDebug() << breakpoint;
breakpointModel()->hitEmit(breakpoint);
KNotification* ev = 0;
switch(breakpoint->kind()) {
case Breakpoint::CodeBreakpoint:
ev = new KNotification("BreakpointHit", ICore::self()->uiController()->activeMainWindow());
ev->setText(i18n("Breakpoint hit: %1", breakpoint->location()) + msg);
break;
case Breakpoint::WriteBreakpoint:
case Breakpoint::ReadBreakpoint:
case Breakpoint::AccessBreakpoint:
ev = new KNotification("WatchpointHit", ICore::self()->uiController()->activeMainWindow());
ev->setText(i18n("Watchpoint hit: %1", breakpoint->location()) + msg);
break;
default:
Q_ASSERT(0);
break;
}
if (ev) {
ev->setPixmap(KIcon("script-error").pixmap(QSize(22,22)));
ev->setComponentData(KGlobal::mainComponent());
ev->sendEvent();
}
}
QSet<Breakpoint::Column> IBreakpointController::breakpointErrors(const Breakpoint* breakpoint) const
{
if (!m_errors.contains(breakpoint)) return QSet<Breakpoint::Column>();
return m_errors[breakpoint];
}
QString IBreakpointController::breakpointErrorText(const KDevelop::Breakpoint* breakpoint) const
{
if (!m_errorText.contains(breakpoint)) return QString();
return m_errorText[breakpoint];
}
}
#include "moc_ibreakpointcontroller.cpp"