Skip to content
Snippets Groups Projects
watchhandler.h 8.42 KiB
Newer Older
/**************************************************************************
con's avatar
con committed
**
** This file is part of Qt Creator
**
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
con's avatar
con committed
**
** Contact: Nokia Corporation (qt-info@nokia.com)
con's avatar
con committed
**
** Commercial Usage
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://www.qtsoftware.com/contact.
con's avatar
con committed
**
**************************************************************************/
hjk's avatar
hjk committed

con's avatar
con committed
#ifndef DEBUGGER_WATCHHANDLER_H
#define DEBUGGER_WATCHHANDLER_H

#include <QtCore/QPointer>
#include <QtCore/QObject>
#include <QtCore/QHash>
#include <QtCore/QSet>
#include <QtGui/QStandardItem>
#include <QtGui/QStandardItemModel>
#include <QtGui/QTreeView>
#include <QtScript/QScriptValue>

namespace Debugger {
namespace Internal {

hjk's avatar
hjk committed
class WatchItem;
class WatchHandler;
enum WatchType { LocalsWatch, WatchersWatch, TooltipsWatch };

con's avatar
con committed
class WatchData
{
public:
    WatchData();

    enum State
    {
        Complete = 0,
con's avatar
con committed
        ValueNeeded = 2,
        TypeNeeded = 4,
        ChildrenNeeded = 8,

        NeededMask = ValueNeeded
            | TypeNeeded
            | ChildrenNeeded
con's avatar
con committed

        InitialState = ValueNeeded
            | TypeNeeded
            | ChildrenNeeded
con's avatar
con committed
    };

    void setValue(const QString &);
con's avatar
con committed
    void setType(const QString &);
    void setValueToolTip(const QString &);
    void setError(const QString &);
    void setAddress(const QString &address);

    bool isSomethingNeeded() const { return state & NeededMask; }
    void setAllNeeded() { state = NeededMask; }
    void setAllUnneeded() { state = State(0); }

    bool isTypeNeeded() const { return state & TypeNeeded; }
    bool isTypeKnown() const { return !(state & TypeNeeded); }
    void setTypeNeeded() { state = State(state | TypeNeeded); }
    void setTypeUnneeded() { state = State(state & ~TypeNeeded); }

    bool isValueNeeded() const { return state & ValueNeeded; }
    bool isValueKnown() const { return !(state & ValueNeeded); }
    void setValueNeeded() { state = State(state | ValueNeeded); }
    void setValueUnneeded() { state = State(state & ~ValueNeeded); }

    bool isChildrenNeeded() const { return state & ChildrenNeeded; }
    bool isChildrenKnown() const { return !(state & ChildrenNeeded); }
    void setChildrenNeeded() { state = State(state | ChildrenNeeded); }
    void setChildrenUnneeded() { state = State(state & ~ChildrenNeeded); }

    bool isHasChildrenNeeded() const { return state & HasChildrenNeeded; }
    bool isHasChildrenKnown() const { return !(state & HasChildrenNeeded); }
    void setHasChildrenNeeded() { state = State(state | HasChildrenNeeded); }
    void setHasChildrenUnneeded() { state = State(state & ~HasChildrenNeeded); }
    void setHasChildren(bool c) { hasChildren = c; setHasChildrenUnneeded();
        if (!c) setChildrenUnneeded(); }
con's avatar
con committed

    WatchData pointerChildPlaceHolder() const;

con's avatar
con committed
    QString toString() const;
    QString toToolTip() const;
con's avatar
con committed
    bool isLocal() const { return iname.startsWith(QLatin1String("local.")); }
    bool isWatcher() const { return iname.startsWith(QLatin1String("watch.")); }
con's avatar
con committed
    bool isValid() const { return !iname.isEmpty(); }

public:
    QString iname;        // internal name sth like 'local.baz.public.a'
    QString exp;          // the expression
    QString name;         // displayed name
    QString value;        // displayed value
    QByteArray editvalue; // displayed value
    QString valuetooltip; // tooltip in value column
    QString type;         // displayed type
    QString variable;     // name of internal Gdb variable if created
    QString addr;         // displayed adress
    QString saddr;        // stored address (pointer in container)
con's avatar
con committed
    QString framekey;     // key for type cache
    QScriptValue scriptValue; // if needed...
hjk's avatar
hjk committed
    int generation;       // when updated?
con's avatar
con committed
    bool valuedisabled;   // value will be greyed out

private:

public:
    int source;  // Used by some debuggers (CDB) to tell where it originates from (dumper or symbol evaluation)
con's avatar
con committed
    int state;
    bool changed;
};

enum { INameRole = Qt::UserRole, ExpressionRole, ExpandedRole };
con's avatar
con committed

hjk's avatar
hjk committed
class WatchModel : public QAbstractItemModel
con's avatar
con committed
{
    Q_OBJECT

hjk's avatar
hjk committed
private:
    explicit WatchModel(WatchHandler *handler, WatchType type);
con's avatar
con committed

    QVariant data(const QModelIndex &index, int role) const;
    bool setData(const QModelIndex &index, const QVariant &value, int role);
con's avatar
con committed
    QModelIndex index(int, int, const QModelIndex &idx) const;
    QModelIndex parent(const QModelIndex &idx) const;
    int rowCount(const QModelIndex &idx) const;
    int columnCount(const QModelIndex &idx) const;
    bool hasChildren(const QModelIndex &idx) const;
    Qt::ItemFlags flags(const QModelIndex &idx) const;
    QVariant headerData(int section, Qt::Orientation orientation,
        int role = Qt::DisplayRole) const;
hjk's avatar
hjk committed
    bool canFetchMore(const QModelIndex &parent) const;
    void fetchMore(const QModelIndex &parent);

    friend class WatchHandler;
    WatchItem *watchItem(const QModelIndex &) const;
    QModelIndex watchIndex(const WatchItem *needle) const;
    QModelIndex watchIndexHelper(const WatchItem *needle,
        const WatchItem *parentItem, const QModelIndex &parentIndex) const;

    void insertData(const WatchData &data);
    WatchItem *findItem(const QString &iname, WatchItem *root) const;
    void reinitialize();
    void removeOutdated();
    void removeOutdatedHelper(WatchItem *item);
    WatchItem *dummyRoot() const;
    void removeItem(WatchItem *item);

private:
    WatchHandler *m_handler;
    WatchType m_type;
    WatchItem *m_root;
};

class WatchHandler : public QObject
{
    Q_OBJECT

public:
    WatchHandler();
    WatchModel *model(WatchType type) const;
    WatchModel *modelForIName(const QString &data) const;

con's avatar
con committed
//public slots:
    void cleanup();
    Q_SLOT void watchExpression(); // data in action->data().toString()
    Q_SLOT void watchExpression(const QString &exp);
    Q_SLOT void removeWatchExpression();
    Q_SLOT void removeWatchExpression(const QString &exp);
hjk's avatar
hjk committed
    void beginCycle(); // called at begin of updateLocals() cycle
    void updateWatchers(); // called after locals are fetched
    void endCycle(); // called after all results have been received
    void showEditValue(const WatchData &data);
con's avatar
con committed

hjk's avatar
hjk committed
    void insertData(const WatchData &data);
    WatchData *findItem(const QString &iname) const;
con's avatar
con committed

hjk's avatar
hjk committed
    void loadSessionData();
    void saveSessionData();
con's avatar
con committed

    bool isDisplayedIName(const QString &iname) const
        { return m_displayedINames.contains(iname); }
    bool isExpandedIName(const QString &iname) const
        { return m_expandedINames.contains(iname); }
    QSet<QString> expandedINames() const
        { return m_expandedINames; }
con's avatar
con committed

    static QString watcherEditPlaceHolder();

con's avatar
con committed
signals:
hjk's avatar
hjk committed
    void watchDataUpdateNeeded(const WatchData &data);
    void sessionValueRequested(const QString &name, QVariant *value);
    void setSessionValueRequested(const QString &name, const QVariant &value);

con's avatar
con committed
private:
hjk's avatar
hjk committed
    friend class WatchModel;
con's avatar
con committed

    void loadWatchers();
    void saveWatchers();

con's avatar
con committed
    bool m_expandPointers;
    bool m_inChange;

    typedef QMap<QString, QPointer<QWidget> > EditWindows;
    EditWindows m_editWindows;

hjk's avatar
hjk committed
    QHash<QString, int> m_watcherNames;
    QString watcherName(const QString &exp);
con's avatar
con committed

    void setDisplayedIName(const QString &iname, bool on);
    QSet<QString> m_expandedINames;  // those expanded in the treeview
    QSet<QString> m_displayedINames; // those with "external" viewers

hjk's avatar
hjk committed
    WatchModel *m_locals;
    WatchModel *m_watchers;
    WatchModel *m_tooltips;
con's avatar
con committed
};

} // namespace Internal
} // namespace Debugger

Q_DECLARE_METATYPE(Debugger::Internal::WatchData);

#endif // DEBUGGER_WATCHHANDLER_H