1 /* 2 * Copyright Johannes Sixt 3 * This file is licensed under the GNU General Public License Version 2. 4 * See the file COPYING in the toplevel directory of the source directory. 5 */ 6 7 #ifndef EXPRWND_H 8 #define EXPRWND_H 9 10 #include <QTreeWidget> 11 #include <QLineEdit> 12 #include <QPixmap> 13 #include <list> 14 15 class ProgramTypeTable; 16 class TypeInfo; 17 struct ExprValue; 18 class ExprWnd; 19 class QStringList; 20 21 /*! \brief a variable's value is the tree of sub-variables */ 22 class VarTree : public QTreeWidgetItem 23 { 24 public: 25 enum VarKind { VKsimple, VKpointer, VKstruct, VKarray, 26 VKdummy //!< used to update only children 27 }; 28 VarKind m_varKind; 29 enum NameKind { NKplain, NKstatic, NKtype, 30 NKanonymous, //!< an anonymous struct or union 31 NKaddress //!< a dereferenced pointer 32 }; 33 NameKind m_nameKind; 34 const TypeInfo* m_type; //!< the type of struct if it could be derived 35 int m_exprIndex; //!< used in struct value update 36 bool m_exprIndexUseGuard; //!< ditto; if guard expr should be used 37 QString m_partialValue; //!< while struct value update is in progress 38 39 VarTree(VarTree* parent, ExprValue* v); 40 VarTree(ExprWnd* parent, ExprValue* v); 41 virtual ~VarTree(); 42 public: 43 QString computeExpr() const; 44 bool isToplevelExpr() const; 45 /** is this element an ancestor of (or equal to) child? */ 46 bool isAncestorEq(const VarTree* child) const; 47 /** update the regular value; returns whether a repaint is necessary */ 48 bool updateValue(const QString& newValue); 49 /** update the "quick member" value; returns whether repaint is necessary */ 50 bool updateStructValue(const QString& newValue); 51 /** find out the type of this value using the child values */ 52 void inferTypesOfChildren(ProgramTypeTable& typeTable); 53 /** get the type from base class part */ 54 const TypeInfo* inferTypeFromBaseClass(); 55 /** returns whether the pointer is a wchar_t */ 56 bool isWcharT() const; 57 getText()58 QString getText() const { return text(0); } 59 using QTreeWidgetItem::setText; setText(const QString & t)60 void setText(const QString& t) { QTreeWidgetItem::setText(0, t); } setPixmap(const QPixmap & p)61 void setPixmap(const QPixmap& p) { QTreeWidgetItem::setIcon(0, QIcon(p)); } value()62 QString value() const { return m_baseValue; } 63 QString displayedValue() const; child(int i)64 VarTree* child(int i) const { return static_cast<VarTree*>(QTreeWidgetItem::child(i)); } 65 66 virtual QVariant data(int column, int role) const; 67 68 private: 69 void updateValueText(); 70 QString m_baseValue; //!< The "normal value" that the driver reported 71 QString m_structValue; //!< The "quick member" value 72 bool m_baseChanged : 1; 73 bool m_structChanged : 1; 74 }; 75 76 /** 77 * Represents the value tree that is parsed by the debugger drivers. 78 */ 79 struct ExprValue 80 { 81 QString m_name; 82 QString m_value; 83 VarTree::VarKind m_varKind; 84 VarTree::NameKind m_nameKind; 85 ExprValue* m_child; /* the first child expression */ 86 ExprValue* m_next; /* the next sibling expression */ 87 bool m_initiallyExpanded; 88 89 ExprValue(const QString& name, VarTree::NameKind kind); 90 ~ExprValue(); 91 valueExprValue92 const QString& value() const { 93 return m_value; 94 } 95 96 void appendChild(ExprValue* newChild); 97 int childCount() const; 98 }; 99 100 101 class ValueEdit : public QLineEdit 102 { 103 Q_OBJECT 104 public: 105 ValueEdit(ExprWnd* parent); 106 ~ValueEdit(); 107 108 void terminate(bool commit); 109 VarTree* m_item; 110 bool m_finished; 111 protected: 112 void keyPressEvent(QKeyEvent *e); 113 void focusOutEvent(QFocusEvent* ev); 114 void paintEvent(QPaintEvent* e); 115 public slots: 116 void slotSelectionChanged(); 117 signals: 118 void done(VarTree*, const QString&); 119 }; 120 121 122 class ExprWnd : public QTreeWidget 123 { 124 Q_OBJECT 125 public: 126 ExprWnd(QWidget* parent, const QString& colHeader); 127 ~ExprWnd(); 128 129 /** returns the list with the expressions at the topmost level */ 130 QStringList exprList() const; 131 /** appends a copy of expr to the end of the tree at the topmost level; 132 * returns a pointer to the inserted top-level item */ 133 VarTree* insertExpr(ExprValue* expr, ProgramTypeTable& typeTable); 134 /** updates an existing expression */ 135 void updateExpr(ExprValue* expr, ProgramTypeTable& typeTable); 136 void updateExpr(VarTree* display, ExprValue* newValues, ProgramTypeTable& typeTable); 137 /** updates the value and repaints it for a single item (not the children) */ 138 void updateSingleExpr(VarTree* display, ExprValue* newValues); 139 /** updates only the value of the node */ 140 void updateStructValue(VarTree* display); 141 /** get a top-level expression by name */ 142 VarTree* topLevelExprByName(const QString& name) const; 143 /** return a member of the struct that pointer \a v refers to */ 144 static VarTree* ptrMemberByName(VarTree* v, const QString& name); 145 /** return a member of the struct \a v */ 146 static VarTree* memberByName(VarTree* v, const QString& name); 147 /** removes an expression; must be on the topmost level*/ 148 void removeExpr(VarTree* item); 149 /** clears the list of pointers needing updates */ 150 void clearPendingUpdates(); 151 /** returns a pointer to update (or 0) and removes it from the list */ 152 VarTree* nextUpdatePtr(); 153 VarTree* nextUpdateType(); 154 VarTree* nextUpdateStruct(); 155 void editValue(VarTree* item, const QString& text); 156 /** tells whether the a value is currently edited */ 157 bool isEditing() const; 158 selectedItem()159 VarTree* selectedItem() const { return static_cast<VarTree*>(QTreeWidget::currentItem()); } topLevelItem(int i)160 VarTree* topLevelItem(int i) const { return static_cast<VarTree*>(QTreeWidget::topLevelItem(i)); } 161 162 protected: 163 void updateExprRec(VarTree* display, ExprValue* newValues, ProgramTypeTable& typeTable); 164 void replaceChildren(VarTree* display, ExprValue* newValues); 165 void collectUnknownTypes(VarTree* item); 166 void checkUnknownType(VarTree* item); 167 static QString formatWCharPointer(QString value); 168 QPixmap m_pixPointer; 169 170 std::list<VarTree*> m_updatePtrs; //!< dereferenced pointers that need update 171 std::list<VarTree*> m_updateType; //!< structs whose type must be determined 172 std::list<VarTree*> m_updateStruct; //!< structs whose nested value needs update 173 174 ValueEdit* m_edit; 175 176 /** remove items that are in the subTree from the list */ 177 void unhookSubtree(VarTree* subTree); 178 static void unhookSubtree(std::list<VarTree*>& list, VarTree* subTree); 179 180 signals: 181 void removingItem(VarTree*); 182 void editValueCommitted(VarTree*, const QString&); 183 }; 184 185 #endif // EXPRWND_H 186