1 /*
2     SPDX-FileCopyrightText: 2007 Hamish Rodda <rodda@kde.org>
3     SPDX-FileCopyrightText: 2008 Vladimir Prus <ghost@cs.msu.su>
4     SPDX-FileCopyrightText: 2009 Niko Sams <niko.sams@gmail.com>
5 
6     SPDX-License-Identifier: GPL-2.0-or-later
7 */
8 
9 #ifndef KDEVPLATFORM_VARIABLECOLLECTION_H
10 #define KDEVPLATFORM_VARIABLECOLLECTION_H
11 
12 #include <QPointer>
13 
14 #include <KLocalizedString>
15 #include <KTextEditor/TextHintInterface>
16 
17 #include <debugger/debuggerexport.h>
18 #include "../util/treemodel.h"
19 #include "../util/treeitem.h"
20 #include "../../interfaces/idocument.h"
21 #include "../../interfaces/idebugcontroller.h"
22 
23 namespace KDevMI { namespace GDB {
24     class GdbTest;
25 }
26 }
27 
28 namespace KDevelop
29 {
30 class VariableToolTip;
31 class IDebugSession;
32 
33 class KDEVPLATFORMDEBUGGER_EXPORT Variable : public TreeItem
34 {
35     Q_OBJECT
36     friend class KDevMI::GDB::GdbTest;
37 public:
38 protected:
39     Variable(TreeModel* model, TreeItem* parent,
40              const QString& expression,
41              const QString& display = {});
42 
43 public:
44     enum format_t { Natural, Binary, Octal, Decimal, Hexadecimal };
45     static format_t str2format(const QString& str);
46     static QString format2str(format_t format);
47 
48     QString expression() const;
49     bool inScope() const;
50     void setInScope(bool v);
51     void setValue(const QString &v);
52     QString value() const;
53     void setType(const QString& type);
54     QString type() const;
55     void setTopLevel(bool v);
56     void setShowError(bool v);
57     bool showError();
58 
59     using TreeItem::setHasMore;
60     using TreeItem::setHasMoreInitial;
61     using TreeItem::appendChild;
62     using TreeItem::deleteChildren;
63     using TreeItem::isExpanded;
64     using TreeItem::parent;
65 
66     using TreeItem::model;
67 
68     ~Variable() override;
69 
70     /* Connects this variable to debugger, fetching the current value and
71        otherwise preparing this variable to be displayed everywhere.
72        The attempt may fail, for example if the expression is invalid.
73        Calls slot 'callbackMethod' in 'callback' to notify of the result.
74        The slot should be taking 'bool ok' parameter.  */
75     virtual void attachMaybe(QObject *callback = nullptr, const char *callbackMethod = nullptr) = 0;
76 
canSetFormat()77     virtual bool canSetFormat() const { return false; }
78 
79     void setFormat(format_t format);
format()80     format_t format() const { return m_format; }
81     virtual void formatChanged();
82 
83     // get/set 'changed' state, if the variable changed it will be highlighted
isChanged()84     bool isChanged() const { return m_changed; }
85     void setChanged(bool c);
86     void resetChanged();
87 
88 public Q_SLOTS:
89     void die();
90 
91 protected:
topLevel()92     bool topLevel() const { return m_topLevel; }
93 
94 private: // TreeItem overrides
95     QVariant data(int column, int role) const override;
96 
97 private:
98     bool isPotentialProblematicValue() const;
99 
100     QString m_expression;
101     bool m_inScope;
102     bool m_topLevel;
103     bool m_changed;
104     bool m_showError;
105 
106     format_t m_format;
107 };
108 
109 class KDEVPLATFORMDEBUGGER_EXPORT TooltipRoot : public TreeItem
110 {
111     Q_OBJECT
112 public:
TooltipRoot(TreeModel * model)113     explicit TooltipRoot(TreeModel* model)
114     : TreeItem(model)
115     {}
116 
init(Variable * var)117     void init(Variable *var)
118     {
119         appendChild(var);
120     }
121 
fetchMoreChildren()122     void fetchMoreChildren() override {}
123 };
124 
125 class KDEVPLATFORMDEBUGGER_EXPORT Watches : public TreeItem
126 {
127     Q_OBJECT
128     friend class KDevMI::GDB::GdbTest;
129 public:
130     Watches(TreeModel* model, TreeItem* parent);
131     Variable* add(const QString& expression);
132 
133     void reinstall();
134 
135     Variable *addFinishResult(const QString& convenienceVarible);
136     void removeFinishResult();
137     void resetChanged();
138 
139     using TreeItem::childCount;
140     friend class VariableCollection;
141     friend class IVariableController;
142 private:
143 
144     QVariant data(int column, int role) const override;
145 
fetchMoreChildren()146     void fetchMoreChildren() override {}
147 
148     Variable* finishResult_;
149 };
150 
151 class KDEVPLATFORMDEBUGGER_EXPORT Locals : public TreeItem
152 {
153     Q_OBJECT
154 public:
155     Locals(TreeModel* model, TreeItem* parent, const QString &name);
156     QList<Variable*> updateLocals(const QStringList& locals);
157     void resetChanged();
158 
159     using TreeItem::deleteChildren;
160     using TreeItem::setHasMore;
161 
162     friend class VariableCollection;
163     friend class IVariableController;
164 
165 private:
fetchMoreChildren()166     void fetchMoreChildren() override {}
167 };
168 
169 class KDEVPLATFORMDEBUGGER_EXPORT VariablesRoot : public TreeItem
170 {
171     Q_OBJECT
172 public:
173     explicit VariablesRoot(TreeModel* model);
174 
watches()175     Watches *watches() const { return m_watches; }
176     Locals *locals(const QString &name = QStringLiteral("Locals"));
177     QHash<QString, Locals*> allLocals() const;
178 
fetchMoreChildren()179     void fetchMoreChildren() override {}
180 
181     void resetChanged();
182 
183 private:
184     Watches *m_watches;
185     QHash<QString, Locals*> m_locals;
186 };
187 
188 class VariableProvider : public KTextEditor::TextHintProvider
189 {
190 public:
191     explicit VariableProvider(VariableCollection* collection);
192     QString textHint(KTextEditor::View* view, const KTextEditor::Cursor& position) override;
193 
194 private:
195     VariableCollection* m_collection;
196 };
197 
198 class KDEVPLATFORMDEBUGGER_EXPORT VariableCollection : public TreeModel
199 {
200     Q_OBJECT
201 
202 public:
203     enum Column {
204         NameColumn,
205         ValueColumn,
206         TypeColumn
207     };
208 
209     explicit VariableCollection(IDebugController* parent);
210     ~VariableCollection() override;
211 
root()212     VariablesRoot* root() const { return m_universe; }
watches()213     Watches* watches() const { return m_universe->watches(); }
214     Locals* locals(const QString &name = QString()) const;
allLocals()215     QHash<QString, Locals*> allLocals() const { return m_universe->allLocals(); }
216 
217 public Q_SLOTS:
218     void variableWidgetShown();
219     void variableWidgetHidden();
220 
221 private Q_SLOTS:
222     void updateAutoUpdate(KDevelop::IDebugSession* session = nullptr);
223 
224     void textDocumentCreated( KDevelop::IDocument*);
225     void viewCreated(KTextEditor::Document*, KTextEditor::View*);
226 
227 private:
228     VariablesRoot* m_universe;
229     QPointer<VariableToolTip> m_activeTooltip;
230     bool m_widgetVisible;
231 
232     friend class VariableProvider;
233     VariableProvider m_textHintProvider;
234 
235     QVector<KTextEditor::View*> m_textHintProvidedViews;
236 };
237 
238 }
239 
240 #endif
241