File: localsview.cpp

package info (click to toggle)
codelite 12.0%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 95,112 kB
  • sloc: cpp: 424,040; ansic: 18,284; php: 9,569; lex: 4,186; yacc: 2,820; python: 2,294; sh: 312; makefile: 51; xml: 13
file content (216 lines) | stat: -rw-r--r-- 7,697 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
#include "localsview.h"
#include <lexer_configuration.h>
#include <editor_config.h>
#include <event_notifier.h>
#include <file_logger.h>
#include "XDebugManager.h"
#include "globals.h"
#include "editor_config.h"

LocalsView::LocalsView(wxWindow* parent)
    : LocalsViewBase(parent)
{
    Hide();
    //     LexerConf::Ptr_t lex =  EditorConfigST::Get()->GetLexer("php");
    //     if ( lex ) {
    //         m_dataview->SetFont( lex->GetFontForSyle(wxSTC_HPHP_DEFAULT) );
    //     }
    EventNotifier::Get()->Bind(wxEVT_XDEBUG_LOCALS_UPDATED, &LocalsView::OnLocalsUpdated, this);
    EventNotifier::Get()->Bind(wxEVT_XDEBUG_SESSION_ENDED, &LocalsView::OnXDebugSessionEnded, this);
    EventNotifier::Get()->Bind(wxEVT_XDEBUG_SESSION_STARTED, &LocalsView::OnXDebugSessionStarted, this);
    EventNotifier::Get()->Bind(wxEVT_XDEBUG_PROPERTY_GET, &LocalsView::OnProperytGet, this);
}

LocalsView::~LocalsView()
{
    EventNotifier::Get()->Unbind(wxEVT_XDEBUG_LOCALS_UPDATED, &LocalsView::OnLocalsUpdated, this);
    EventNotifier::Get()->Unbind(wxEVT_XDEBUG_SESSION_ENDED, &LocalsView::OnXDebugSessionEnded, this);
    EventNotifier::Get()->Unbind(wxEVT_XDEBUG_SESSION_STARTED, &LocalsView::OnXDebugSessionStarted, this);
    EventNotifier::Get()->Unbind(wxEVT_XDEBUG_PROPERTY_GET, &LocalsView::OnProperytGet, this);
}

void LocalsView::OnLocalCollapsed(wxDataViewEvent& event)
{
    /// We keep track on expanded and collapsed items by their fullname
    CHECK_ITEM_RET(event.GetItem());
    wxStringClientData* cd = dynamic_cast<wxStringClientData*>(m_dataviewModel->GetClientObject(event.GetItem()));
    CHECK_PTR_RET(cd);
    if(m_localsExpandedItemsFullname.count(cd->GetData())) {
        m_localsExpandedItemsFullname.erase(cd->GetData());
    }
}

void LocalsView::OnXDebugSessionEnded(XDebugEvent& e)
{
    e.Skip();
    CL_DEBUG("LocalsView::OnXDebugSessionEnded(): Debug sessions started - cleaning all locals view");
    // Clear the variables view
    m_dataviewModel->Clear();
    m_localsExpandedItemsFullname.clear();
    m_localsExpandedItems.Clear();
    m_waitingExpand.clear();
}

void LocalsView::OnLocalExpanded(wxDataViewEvent& event)
{
    /// We keep track on expanded and collapsed items by their fullname
    CHECK_ITEM_RET(event.GetItem());
    wxStringClientData* cd = dynamic_cast<wxStringClientData*>(m_dataviewModel->GetClientObject(event.GetItem()));
    CHECK_PTR_RET(cd);
    m_localsExpandedItemsFullname.insert(cd->GetData());
}

void LocalsView::OnLocalsUpdated(XDebugEvent& e)
{
    e.Skip();
    CL_DEBUG("Inside OnLocalsUpdated");

    m_dataviewModel->Clear();
    m_localsExpandedItems.Clear();

    const XVariable::List_t& vars = e.GetVariables();
    AppendVariablesToTree(wxDataViewItem(NULL), vars);

    // Expand the items that were expanded before the view refresh
    for(size_t i = 0; i < m_localsExpandedItems.GetCount(); ++i) {
        // Ensure it is visible
        m_dataview->EnsureVisible(m_localsExpandedItems.Item(i));
        // Ensure its expanded
        m_dataview->Expand(m_localsExpandedItems.Item(i));
    }
    m_localsExpandedItems.Clear();
}

void LocalsView::AppendVariablesToTree(const wxDataViewItem& parent, const XVariable::List_t& children)
{
    XVariable::List_t::const_iterator iter = children.begin();
    for(; iter != children.end(); ++iter) {
        const XVariable& var = *iter;
        wxVector<wxVariant> cols;
        cols.push_back(var.name);
        cols.push_back(var.type);
        cols.push_back(var.classname);
        cols.push_back(var.value);
        wxDataViewItem item = m_dataviewModel->AppendItem(parent, cols, new wxStringClientData(var.fullname));

        if(var.GetCreateFakeNode()) {
            // create dummy node in the tree view so we can expand it later
            cols.clear();
            cols.push_back("<dummy>");
            cols.push_back(wxString());
            cols.push_back(wxString());
            cols.push_back(wxString());
            m_dataviewModel->AppendItem(item, cols, new wxStringClientData(var.fullname));

        } else if(var.HasChildren()) {
            AppendVariablesToTree(item, var.children);
            if(m_localsExpandedItemsFullname.count(var.fullname)) {
                // this item should be expanded
                m_localsExpandedItems.Add(item);
            }
        }
    }
}

void LocalsView::OnXDebugSessionStarted(XDebugEvent& e)
{
    e.Skip();
    CL_DEBUG("LocalsView::OnXDebugSessionStarted(): Debug sessions started - cleaning all locals view");
    // Clear the variables view
    m_dataviewModel->Clear();
    m_localsExpandedItemsFullname.clear();
    m_localsExpandedItems.Clear();
    m_waitingExpand.clear();
}

void LocalsView::OnLocalExpanding(wxDataViewEvent& event)
{
    event.Skip();
    CHECK_ITEM_RET(event.GetItem());

    wxDataViewItem item = event.GetItem();
    wxDataViewItemArray children;
    if(m_dataviewModel->GetChildren(item, children) && children.GetCount() == 1) {
        wxDataViewItem child = children.Item(0);
        wxVariant v;
        m_dataviewModel->GetValue(v, child, 0);

        if(v.GetString() == "<dummy>") {
            // a dummy node has been found
            // Delete this node and request from XDebug to expand it
            m_dataviewModel->SetValue(wxString("Loading..."), child, 0);
            wxString propertyName = DoGetItemClientData(event.GetItem());
            XDebugManager::Get().SendGetProperty(propertyName);
            m_waitingExpand.insert(std::make_pair(propertyName, item));
        }
    }
}

wxString LocalsView::DoGetItemClientData(const wxDataViewItem& item) const
{
    wxStringClientData* scd = dynamic_cast<wxStringClientData*>(m_dataviewModel->GetClientObject(item));
    if(scd) {
        return scd->GetData();
    }
    return wxEmptyString;
}

void LocalsView::OnProperytGet(XDebugEvent& e)
{
    e.Skip();
    // An item was evaluated using property_get
    std::map<wxString, wxDataViewItem>::iterator iter = m_waitingExpand.find(e.GetEvaluted());
    if(iter == m_waitingExpand.end()) {
        return;
    }

    wxDataViewItem item = iter->second;
    m_waitingExpand.erase(iter);

    // Delete the fake node
    wxDataViewItemArray children;
    m_dataviewModel->GetChildren(item, children);
    if(!children.IsEmpty()) {
        m_dataviewModel->DeleteItems(item, children);
    }

    XVariable::List_t vars = e.GetVariables();
    if(vars.empty()) return;

    // Since we got here from property_get, XDebug will reply with the specific property (e.g. $myclass->secondClass)
    // and all its children. Howeverr, $myclass->secondClass already exist in the tree
    // so we are only interested with its children. so we use here vars.begin()->children (vars is always list of size
    // == 1)
    wxASSERT_MSG(vars.size() == 1, "property_get returned list of size != 1");
    XVariable::List_t childs;
    childs = vars.begin()->children;

    if(!childs.empty()) {
        AppendVariablesToTree(item, childs);
        m_dataview->Expand(item);
    }
}

void LocalsView::OnLocalsMenu(wxDataViewEvent& event)
{
    wxMenu menu;
    menu.Append(XRCID("php_locals_copy_value"), _("Copy Value"));

    menu.Bind(wxEVT_MENU, &LocalsView::OnCopyValue, this, XRCID("php_locals_copy_value"));
    m_dataview->PopupMenu(&menu);
}

void LocalsView::OnCopyValue(wxCommandEvent& event)
{
    wxVariant v;
    wxDataViewItemArray items;
    m_dataview->GetSelections(items);

    wxString textToCopy;
    for(size_t i = 0; i < items.size(); ++i) {
        m_dataviewModel->GetValue(v, items.Item(i), 3);
        textToCopy << v.GetString() << EditorConfigST::Get()->GetOptions()->GetEOLAsString();
    }

    ::CopyToClipboard(textToCopy);
}