File indexing completed on 2024-05-12 04:37:36
0001 /* 0002 SPDX-FileCopyrightText: 2009 Niko Sams <niko.sams@gmail.com> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "ivariablecontroller.h" 0008 0009 #include "idebugsession.h" 0010 #include "../../interfaces/icore.h" 0011 #include "../../interfaces/idebugcontroller.h" 0012 #include "../variable/variablecollection.h" 0013 #include <debug.h> 0014 #include "iframestackmodel.h" 0015 0016 0017 namespace KDevelop { 0018 0019 class IVariableControllerPrivate 0020 { 0021 public: 0022 QFlags<IVariableController::UpdateType> autoUpdate; 0023 int activeThread = -1; 0024 int activeFrame = -1; 0025 }; 0026 0027 IVariableController::IVariableController(IDebugSession* parent) 0028 : QObject(parent) 0029 , d_ptr(new IVariableControllerPrivate) 0030 { 0031 connect(parent, &IDebugSession::stateChanged, 0032 this, &IVariableController::stateChanged); 0033 } 0034 0035 IVariableController::~IVariableController() = default; 0036 0037 VariableCollection* IVariableController::variableCollection() 0038 { 0039 if (!ICore::self()) return nullptr; 0040 return ICore::self()->debugController()->variableCollection(); 0041 } 0042 0043 IDebugSession* IVariableController::session() const 0044 { 0045 return static_cast<IDebugSession*>(parent()); 0046 } 0047 0048 void IVariableController::stateChanged(IDebugSession::DebuggerState state) 0049 { 0050 Q_D(IVariableController); 0051 0052 if (!ICore::self() || ICore::self()->shuttingDown()) { 0053 return; 0054 } 0055 0056 if (state == IDebugSession::ActiveState) { 0057 //variables are now outdated, update them 0058 d->activeThread = -1; 0059 d->activeFrame = -1; 0060 } else if (state == IDebugSession::EndedState || state == IDebugSession::NotStartedState) { 0061 // Remove all locals. 0062 const auto locals = variableCollection()->allLocals(); 0063 for (Locals* l : locals) { 0064 l->deleteChildren(); 0065 l->setHasMore(false); 0066 } 0067 0068 for (int i=0; i < variableCollection()->watches()->childCount(); ++i) { 0069 auto *var = qobject_cast<Variable*>(variableCollection()->watches()->child(i)); 0070 if (var) { 0071 var->setInScope(false); 0072 } 0073 } 0074 } 0075 } 0076 0077 void IVariableController::updateIfFrameOrThreadChanged() 0078 { 0079 Q_D(IVariableController); 0080 0081 IFrameStackModel *sm = session()->frameStackModel(); 0082 if (sm->currentThread() != d->activeThread || sm->currentFrame() != d->activeFrame) { 0083 variableCollection()->root()->resetChanged(); 0084 update(); 0085 } 0086 } 0087 0088 void IVariableController::handleEvent(IDebugSession::event_t event) 0089 { 0090 Q_D(IVariableController); 0091 0092 if (!variableCollection()) return; 0093 0094 switch (event) { 0095 case IDebugSession::thread_or_frame_changed: 0096 qCDebug(DEBUGGER) << d->autoUpdate; 0097 if (!(d->autoUpdate & UpdateLocals)) { 0098 const auto locals = variableCollection()->allLocals(); 0099 for (Locals* l : locals) { 0100 if (!l->isExpanded() && !l->childCount()) { 0101 l->setHasMore(true); 0102 } 0103 } 0104 } 0105 if (d->autoUpdate != UpdateNone) { 0106 updateIfFrameOrThreadChanged(); 0107 } 0108 0109 // update our cache of active thread/frame regardless of d->autoUpdate 0110 // to keep them synced when user currently hides the variable list 0111 d->activeThread = session()->frameStackModel()->currentThread(); 0112 d->activeFrame = session()->frameStackModel()->currentFrame(); 0113 break; 0114 0115 default: 0116 break; 0117 } 0118 } 0119 0120 void IVariableController::setAutoUpdate(QFlags<UpdateType> autoUpdate) 0121 { 0122 Q_D(IVariableController); 0123 0124 IDebugSession::DebuggerState state = session()->state(); 0125 d->autoUpdate = autoUpdate; 0126 qCDebug(DEBUGGER) << d->autoUpdate; 0127 if (d->autoUpdate != UpdateNone && state == IDebugSession::PausedState) { 0128 update(); 0129 } 0130 } 0131 0132 QFlags<IVariableController::UpdateType> IVariableController::autoUpdate() 0133 { 0134 Q_D(IVariableController); 0135 0136 return d->autoUpdate; 0137 } 0138 0139 } 0140 0141 #include "moc_ivariablecontroller.cpp"