00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "wx/wxprec.h"
00011
00012 #ifdef __BORLANDC__
00013 #pragma hdrstop
00014 #endif
00015
00016 #ifndef WX_PRECOMP
00017 #include "wx/wx.h"
00018 #endif
00019
00020 #include "wx/imaglist.h"
00021 #include "wx/artprov.h"
00022 #include "wx/listctrl.h"
00023 #include "wx/splitter.h"
00024 #include "wx/progdlg.h"
00025 #include "wx/clipbrd.h"
00026
00027 #include "wxluadebug/include/wxlstack.h"
00028 #include "wxlua/include/wxlua.h"
00029 #include "wxlua/include/wxlcallb.h"
00030 #include "wxluadebug/include/wxldebug.h"
00031
00032 #if defined(__WXGTK__) || defined(__WXMAC__) || defined(__WXMOTIF__)
00033 #include "art/wxlua.xpm"
00034 #endif
00035
00036
00037
00038 #if defined(__WXMSW__)
00039 #define WXLUA_STACK_MSWTREE
00040 #endif //defined(__WXMSW__)
00041
00042 #define DUMMY_TREEITEM wxT(" ")
00043
00044
00045
00046
00047
00048 class wxLuaStackListCtrl : public wxListCtrl
00049 {
00050 public:
00051 wxLuaStackListCtrl( wxLuaStackDialog* stkDialog,
00052 wxWindow *parent,
00053 wxWindowID winid = wxID_ANY,
00054 const wxPoint& pos = wxDefaultPosition,
00055 const wxSize& size = wxDefaultSize,
00056 long style = wxLC_REPORT,
00057 const wxValidator& validator = wxDefaultValidator,
00058 const wxString &name = wxT("wxLuaStackListCtrl"))
00059 : wxListCtrl(parent, winid, pos, size, style, validator, name)
00060 {
00061 m_stkDlg = stkDialog;
00062 }
00063
00064 virtual wxString OnGetItemText(long item, long column) const;
00065 virtual int OnGetItemImage(long item) const;
00066 virtual int OnGetItemColumnImage(long item, long column) const;
00067 virtual wxListItemAttr *OnGetItemAttr(long item) const;
00068
00069 wxListItemAttr m_itemAttr;
00070 wxLuaStackDialog* m_stkDlg;
00071 };
00072
00073
00074 wxString wxLuaStackListCtrl::OnGetItemText(long item, long column) const
00075 {
00076 return m_stkDlg->GetItemText(item, column);
00077 }
00078 int wxLuaStackListCtrl::OnGetItemImage(long item) const
00079 {
00080 return -1;
00081 }
00082 int wxLuaStackListCtrl::OnGetItemColumnImage(long item, long column) const
00083 {
00084 if ((column == wxLuaStackDialog::LIST_COL_KEY) ||
00085 (column == wxLuaStackDialog::LIST_COL_KEY_TYPE) ||
00086 (column == wxLuaStackDialog::LIST_COL_VALUE_TYPE))
00087 {
00088 wxLuaStackListData* stkListData = (wxLuaStackListData*)m_stkDlg->m_listData[item];
00089 wxCHECK_MSG(stkListData, -1, wxT("Invalid wxLuaStackListData item"));
00090 wxLuaDebugItem* debugItem = stkListData->GetDebugItem();
00091 wxCHECK_MSG(debugItem, -1, wxT("Invalid wxLuaDebugItem item"));
00092
00093 if (column == wxLuaStackDialog::LIST_COL_KEY)
00094 return m_stkDlg->GetItemImage(debugItem);
00095 else if (column == wxLuaStackDialog::LIST_COL_KEY_TYPE)
00096 {
00097 if (debugItem->GetFlagBit(WXLUA_DEBUGITEM_KEY_REF))
00098 {
00099 if (debugItem->GetFlagBit(WXLUA_DEBUGITEM_EXPANDED))
00100 return wxLuaStackDialog::IMG_TABLE_OPEN;
00101 else
00102 return wxLuaStackDialog::IMG_TABLE;
00103 }
00104 }
00105 else if (column == wxLuaStackDialog::LIST_COL_VALUE_TYPE)
00106 {
00107 if (debugItem->GetFlagBit(WXLUA_DEBUGITEM_VALUE_REF))
00108 {
00109 if (debugItem->GetFlagBit(WXLUA_DEBUGITEM_EXPANDED))
00110 return wxLuaStackDialog::IMG_TABLE_OPEN;
00111 else
00112 return wxLuaStackDialog::IMG_TABLE;
00113 }
00114 }
00115 }
00116
00117 return -1;
00118 }
00119 wxListItemAttr *wxLuaStackListCtrl::OnGetItemAttr(long item) const
00120 {
00121 wxLuaStackListData* stkListData = (wxLuaStackListData*)m_stkDlg->m_listData[item];
00122 wxCHECK_MSG(stkListData, NULL, wxT("Invalid wxLuaStackListData item"));
00123 wxLuaDebugItem* debugItem = stkListData->GetDebugItem();
00124 wxCHECK_MSG(debugItem, NULL, wxT("Invalid wxLuaDebugItem item"));
00125
00126 int img = m_stkDlg->GetItemImage(debugItem);
00127
00128 wxLuaStackListCtrl* stkCtrl = (wxLuaStackListCtrl*)this;
00129
00130 stkCtrl->m_itemAttr.SetTextColour(m_stkDlg->m_typeColours[img]);
00131
00132
00133
00134
00135 return &stkCtrl->m_itemAttr;
00136 }
00137
00138
00139
00140
00141 IMPLEMENT_ABSTRACT_CLASS(wxLuaStackDialog, wxDialog)
00142
00143 wxSize wxLuaStackDialog::m_defaultSize(500, 300);
00144
00145 BEGIN_EVENT_TABLE(wxLuaStackDialog, wxDialog)
00146 EVT_CHOICE( ID_WXLUA_STACK_CHOICE, wxLuaStackDialog::OnSelectStack)
00147
00148 EVT_BUTTON( ID_WXLUA_STACK_COLLAPSE_BUTTON, wxLuaStackDialog::OnExpandButton)
00149 EVT_BUTTON( ID_WXLUA_STACK_EXPAND_BUTTON, wxLuaStackDialog::OnExpandButton)
00150
00151 EVT_MENU( wxID_ANY, wxLuaStackDialog::OnMenu)
00152
00153 EVT_TEXT_ENTER( ID_WXLUA_STACK_FIND_COMBO, wxLuaStackDialog::OnFind)
00154 EVT_BUTTON( ID_WXLUA_STACK_FINDNEXT_BUTTON, wxLuaStackDialog::OnFind)
00155 EVT_BUTTON( ID_WXLUA_STACK_FINDPREV_BUTTON, wxLuaStackDialog::OnFind)
00156 EVT_BUTTON( ID_WXLUA_STACK_FINDMENU_BUTTON, wxLuaStackDialog::OnFind)
00157
00158 EVT_TREE_ITEM_COLLAPSED(ID_WXLUA_STACK_TREECTRL, wxLuaStackDialog::OnTreeItem)
00159 EVT_TREE_ITEM_EXPANDED( ID_WXLUA_STACK_TREECTRL, wxLuaStackDialog::OnTreeItem)
00160 EVT_TREE_SEL_CHANGED( ID_WXLUA_STACK_TREECTRL, wxLuaStackDialog::OnTreeItem)
00161
00162 EVT_LIST_ITEM_SELECTED( ID_WXLUA_STACK_LISTCTRL, wxLuaStackDialog::OnListItem)
00163 EVT_LIST_ITEM_ACTIVATED( ID_WXLUA_STACK_LISTCTRL, wxLuaStackDialog::OnListItem)
00164 EVT_LIST_ITEM_RIGHT_CLICK( ID_WXLUA_STACK_LISTCTRL, wxLuaStackDialog::OnListRightClick)
00165 END_EVENT_TABLE()
00166
00167 void wxLuaStackDialog::Init()
00168 {
00169 m_listCtrl = NULL;
00170 m_treeCtrl = NULL;
00171 m_listMenu = NULL;
00172 m_stackChoice = NULL;
00173 m_stack_sel = -1;
00174 m_findComboBox = NULL;
00175 m_findMenu = NULL;
00176
00177 m_imageList = NULL;
00178 m_img_font_size = 15;
00179
00180 m_show_dup_expand_msg = true;
00181 m_batch_count = 0;
00182 }
00183
00184 bool wxLuaStackDialog::Create(const wxLuaState& wxlState,
00185 wxWindow* parent, wxWindowID id,
00186 const wxString& title,
00187 const wxPoint& pos, const wxSize& size_)
00188 {
00189 m_wxlState = wxlState;
00190
00191 wxSize size(size_);
00192 if (size == wxDefaultSize) size = m_defaultSize;
00193
00194 if (!wxDialog::Create(parent, id, title, pos, size,
00195 wxDEFAULT_DIALOG_STYLE | wxDIALOG_MODAL | wxMAXIMIZE_BOX | wxRESIZE_BORDER))
00196 return false;
00197
00198 SetIcon(wxICON(LUA));
00199
00200
00201
00202 m_imageList = new wxImageList(16, 16, true);
00203
00204 wxBitmap bmp(wxArtProvider::GetIcon(wxART_NORMAL_FILE, wxART_TOOLBAR, wxSize(16,16)));
00205 m_imageList->Add(bmp);
00206 m_imageList->Add(bmp);
00207 m_imageList->Add(CreateBmpString(bmp, wxT("0")));
00208 m_imageList->Add(CreateBmpString(bmp, wxT("b")));
00209 m_imageList->Add(CreateBmpString(bmp, wxT("u")));
00210 m_imageList->Add(CreateBmpString(bmp, wxT("1")));
00211 m_imageList->Add(CreateBmpString(bmp, wxT("s")));
00212 m_imageList->Add(wxArtProvider::GetIcon(wxART_FOLDER, wxART_TOOLBAR, wxSize(16,16)));
00213 m_imageList->Add(CreateBmpString(bmp, wxT("f")));
00214 m_imageList->Add(CreateBmpString(bmp, wxT("u")));
00215 m_imageList->Add(CreateBmpString(bmp, wxT("t")));
00216 m_imageList->Add(CreateBmpString(bmp, wxT("1")));
00217 m_imageList->Add(CreateBmpString(bmp, wxT("c")));
00218 m_imageList->Add(wxArtProvider::GetIcon(wxART_NEW_DIR, wxART_TOOLBAR, wxSize(16,16)));
00219
00220
00221
00222 m_typeColours[IMG_NONE] = wxColour(wxT("DARK TURQUOISE"));
00223 m_typeColours[IMG_UNKNOWN] = wxColour(wxT("DARK TURQUOISE"));
00224 m_typeColours[IMG_NIL] = wxColour(wxT("BLACK"));
00225 m_typeColours[IMG_BOOLEAN] = wxColour(wxT("FIREBRICK"));
00226 m_typeColours[IMG_LIGHTUSERDATA]= wxColour(wxT("CORNFLOWER BLUE"));
00227 m_typeColours[IMG_NUMBER] = wxColour(wxT("DARK ORCHID"));
00228 m_typeColours[IMG_STRING] = wxColour(wxT("RED"));
00229 m_typeColours[IMG_TABLE] = wxColour(wxT("BLUE"));
00230 m_typeColours[IMG_LUAFUNCTION] = wxColour(wxT("MEDIUM FOREST GREEN"));
00231 m_typeColours[IMG_USERDATA] = wxColour(wxT("CORNFLOWER BLUE"));
00232 m_typeColours[IMG_THREAD] = wxColour(wxT("BLACK"));
00233 m_typeColours[IMG_INTEGER] = wxColour(wxT("DARK ORCHID"));
00234 m_typeColours[IMG_CFUNCTION] = wxColour(wxT("FOREST GREEN"));
00235 m_typeColours[IMG_TABLE_OPEN] = wxColour(wxT("BLUE"));
00236
00237
00238
00239 wxPanel* panel = new wxPanel(this, wxID_ANY);
00240
00241
00242
00243 wxStaticText* stackText = new wxStaticText( panel, wxID_ANY, wxT("Stack : "));
00244
00245 m_stackChoice = new wxChoice( panel, ID_WXLUA_STACK_CHOICE,
00246 wxDefaultPosition, wxDefaultSize,
00247 0, NULL, 0, wxDefaultValidator );
00248 m_stackChoice->SetToolTip(wxT("Select Lua stack frame to display."));
00249
00250 wxBitmapButton* expandButton = new wxBitmapButton(panel, ID_WXLUA_STACK_EXPAND_BUTTON,
00251 wxArtProvider::GetBitmap(wxART_ADD_BOOKMARK, wxART_BUTTON));
00252 expandButton->SetToolTip(wxT("Expand selected item's children (may take awhile)"));
00253
00254 wxBitmapButton* collapseButton = new wxBitmapButton(panel, ID_WXLUA_STACK_COLLAPSE_BUTTON,
00255 wxArtProvider::GetBitmap(wxART_DEL_BOOKMARK, wxART_BUTTON));
00256 collapseButton->SetToolTip(wxT("Collapse selected item's children (may take awhile)"));
00257
00258
00259
00260 wxStaticText* findText = new wxStaticText( panel, wxID_ANY, wxT("Find : "));
00261 m_findComboBox = new wxComboBox( panel, ID_WXLUA_STACK_FIND_COMBO,
00262 wxEmptyString,
00263 wxDefaultPosition, wxDefaultSize,
00264 0, NULL, wxCB_DROPDOWN | wxTE_PROCESS_ENTER);
00265 m_findComboBox->SetToolTip(wxT("Enter string to find"));
00266
00267 wxBitmapButton* findPrev = new wxBitmapButton( panel, ID_WXLUA_STACK_FINDPREV_BUTTON,
00268 wxArtProvider::GetBitmap(wxART_GO_BACK, wxART_BUTTON));
00269 wxBitmapButton* findNext = new wxBitmapButton( panel, ID_WXLUA_STACK_FINDNEXT_BUTTON,
00270 wxArtProvider::GetBitmap(wxART_GO_FORWARD, wxART_BUTTON));
00271 findPrev->SetToolTip(wxT("Find previous instance"));
00272 findNext->SetToolTip(wxT("Find next instance"));
00273
00274 wxBitmapButton* findMenuButton = new wxBitmapButton(panel, ID_WXLUA_STACK_FINDMENU_BUTTON,
00275 wxArtProvider::GetBitmap(wxART_HELP_SETTINGS, wxART_BUTTON));
00276 findMenuButton->SetToolTip(wxT("Select find options"));
00277
00278 m_findMenu = new wxMenu(wxT("Find Options"), 0);
00279 m_findMenu->Append(ID_WXLUA_STACK_FINDMENU_CASE, wxT("&Case sensitive"), wxT("Case sensitive searching"), wxITEM_CHECK);
00280 m_findMenu->Append(ID_WXLUA_STACK_FINDMENU_WHOLE_STRING, wxT("Match whole string"), wxT("Search for a string with an exact match"), wxITEM_CHECK);
00281 m_findMenu->AppendSeparator();
00282 m_findMenu->Append(ID_WXLUA_STACK_FINDMENU_ALL, wxT("Search &everywhere"), wxT("Search in all columns"), wxITEM_CHECK);
00283 m_findMenu->Append(ID_WXLUA_STACK_FINDMENU_NAME, wxT("Search &names"), wxT("Search in name column"), wxITEM_CHECK);
00284 m_findMenu->Append(ID_WXLUA_STACK_FINDMENU_LEVEL, wxT("Search &level"), wxT("Search in level column"), wxITEM_CHECK);
00285 m_findMenu->Append(ID_WXLUA_STACK_FINDMENU_KEYTYPE, wxT("Search &key type"), wxT("Search in key type column"), wxITEM_CHECK);
00286 m_findMenu->Append(ID_WXLUA_STACK_FINDMENU_VALUETYPE, wxT("Search v&alue type"), wxT("Search in value type column"), wxITEM_CHECK);
00287 m_findMenu->Append(ID_WXLUA_STACK_FINDMENU_VALUE, wxT("Search &values"), wxT("Search in value column"), wxITEM_CHECK);
00288
00289 m_findMenu->Check(ID_WXLUA_STACK_FINDMENU_NAME, true);
00290
00291
00292
00293 wxFlexGridSizer* topSizer = new wxFlexGridSizer(2, 1);
00294 topSizer->AddGrowableCol(1);
00295
00296 topSizer->Add(stackText, wxSizerFlags().Expand().Border().Align(wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL));
00297
00298 wxFlexGridSizer* stackSizer = new wxFlexGridSizer(3, 1);
00299 stackSizer->AddGrowableCol(0);
00300 stackSizer->Add(m_stackChoice, wxSizerFlags().Expand().Border());
00301 stackSizer->Add(collapseButton, wxSizerFlags().Border());
00302 stackSizer->Add(expandButton, wxSizerFlags().Border());
00303 topSizer->Add(stackSizer, wxSizerFlags().Expand());
00304
00305 topSizer->Add(findText, wxSizerFlags().Expand().Border().Align(wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL));
00306
00307 wxFlexGridSizer* findSizer = new wxFlexGridSizer(4, 1);
00308 findSizer->AddGrowableCol(0);
00309 findSizer->Add(m_findComboBox, wxSizerFlags().Expand().Border());
00310 findSizer->Add(findPrev, wxSizerFlags().Expand().Border());
00311 findSizer->Add(findNext, wxSizerFlags().Expand().Border());
00312
00313 findSizer->Add(findMenuButton, wxSizerFlags().Expand().Border());
00314
00315 topSizer->Add(findSizer, wxSizerFlags().Expand());
00316
00317
00318
00319 m_splitterWin = new wxSplitterWindow(panel, ID_WXLUA_STACK_SPLITTERWIN,
00320 wxDefaultPosition, wxDefaultSize,
00321 wxSP_3D);
00322 m_splitterWin->SetSashGravity(0.1);
00323 m_splitterWin->SetMinimumPaneSize(20);
00324
00325 m_treeCtrl = new wxTreeCtrl(m_splitterWin, ID_WXLUA_STACK_TREECTRL,
00326 wxDefaultPosition, wxDefaultSize,
00327 wxTR_HAS_BUTTONS|wxTR_SINGLE|wxTR_HIDE_ROOT|wxTR_LINES_AT_ROOT);
00328
00329 m_treeCtrl->SetImageList(m_imageList);
00330
00331 m_listCtrl = new wxLuaStackListCtrl(this, m_splitterWin, ID_WXLUA_STACK_LISTCTRL,
00332 wxDefaultPosition, wxDefaultSize,
00333 wxLC_REPORT|wxLC_SINGLE_SEL|wxLC_HRULES|wxLC_VRULES|wxLC_VIRTUAL );
00334
00335 m_listCtrl->SetImageList(m_imageList, wxIMAGE_LIST_SMALL);
00336 m_listCtrl->InsertColumn(LIST_COL_KEY, wxT("Name"), wxLIST_FORMAT_LEFT, -1);
00337 m_listCtrl->InsertColumn(LIST_COL_LEVEL, wxT("Level"), wxLIST_FORMAT_LEFT, -1);
00338 m_listCtrl->InsertColumn(LIST_COL_KEY_TYPE, wxT("Key Type"), wxLIST_FORMAT_LEFT, -1);
00339 m_listCtrl->InsertColumn(LIST_COL_VALUE_TYPE, wxT("Value Type"), wxLIST_FORMAT_LEFT, -1);
00340 m_listCtrl->InsertColumn(LIST_COL_VALUE, wxT("Value"), wxLIST_FORMAT_LEFT, -1);
00341
00342 int txt_width = 0, txt_height = 0;
00343
00344 m_listCtrl->GetTextExtent(wxString(wxT('W'), 25), &txt_width, &txt_height);
00345
00346
00347 m_listCtrl->SetColumnWidth(0, txt_width);
00348 m_listCtrl->SetColumnWidth(4, 4*txt_width);
00349 m_listCtrl->GetTextExtent(wxT("555:5555"), &txt_width, &txt_height);
00350 m_listCtrl->SetColumnWidth(1, txt_width);
00351 m_listCtrl->GetTextExtent(wxT("Light User DataX"), &txt_width, &txt_height);
00352 m_listCtrl->SetColumnWidth(2, txt_width);
00353 m_listCtrl->SetColumnWidth(3, txt_width);
00354
00355 m_listMenu = new wxMenu(wxEmptyString, 0);
00356 m_listMenu->Append(ID_WXLUA_STACK_LISTMENU_COPY0, wxT("Copy name"), wxT("Copy name to clipboard"), wxITEM_NORMAL);
00357 m_listMenu->Append(ID_WXLUA_STACK_LISTMENU_COPY1, wxT("Copy level"), wxT("Copy level to clipboard"), wxITEM_NORMAL);
00358 m_listMenu->Append(ID_WXLUA_STACK_LISTMENU_COPY2, wxT("Copy key type"), wxT("Copy key type to clipboard"), wxITEM_NORMAL);
00359 m_listMenu->Append(ID_WXLUA_STACK_LISTMENU_COPY3, wxT("Copy value type"), wxT("Copy value type to clipboard"), wxITEM_NORMAL);
00360 m_listMenu->Append(ID_WXLUA_STACK_LISTMENU_COPY4, wxT("Copy value"), wxT("Copy value to clipboard"), wxITEM_NORMAL);
00361
00362
00363
00364 m_splitterWin->SplitVertically(m_treeCtrl, m_listCtrl, 160);
00365
00366
00367 wxBoxSizer* rootSizer = new wxBoxSizer(wxVERTICAL);
00368 rootSizer->Add(topSizer, 0, wxEXPAND|wxBOTTOM, 5);
00369 rootSizer->Add(m_splitterWin, 1, wxEXPAND);
00370 rootSizer->SetMinSize(200, 150);
00371 panel->SetSizer(rootSizer);
00372 rootSizer->SetSizeHints(this);
00373
00374 SetSize(size);
00375
00376 EnumerateStack();
00377
00378 return true;
00379 }
00380
00381 wxLuaStackDialog::~wxLuaStackDialog()
00382 {
00383 if (!IsFullScreen() && !IsIconized() && !IsMaximized())
00384 m_defaultSize = GetSize();
00385
00386 RemoveAllLuaReferences();
00387 DeleteAllListItemData();
00388
00389 delete m_listMenu;
00390 delete m_findMenu;
00391
00392 if (m_listCtrl) m_listCtrl->SetImageList(NULL, wxIMAGE_LIST_SMALL);
00393 if (m_treeCtrl) m_treeCtrl->SetImageList(NULL);
00394 delete m_imageList;
00395 }
00396
00397 wxBitmap wxLuaStackDialog::CreateBmpString(const wxBitmap& bmp_, const wxString& s)
00398 {
00399 wxBitmap bmp(bmp_);
00400 int bmp_w = bmp.GetWidth();
00401 int bmp_h = bmp.GetHeight();
00402
00403 wxMemoryDC dc;
00404 dc.SelectObject(bmp);
00405
00406 wxFont font(m_img_font_size, wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL);
00407 wxCoord w = 0, h = 0;
00408
00409
00410 for ( ; m_img_font_size > 3; --m_img_font_size)
00411 {
00412 dc.GetTextExtent(s, &w, &h, NULL, NULL, &font);
00413
00414 if ((w < bmp_w) && (h < bmp_h))
00415 break;
00416
00417 font.SetPointSize(m_img_font_size);
00418 }
00419
00420 dc.SetFont(font);
00421 dc.DrawText(s, (bmp_w-w)/2, (bmp_h-h)/2);
00422 dc.SelectObject(wxNullBitmap);
00423
00424 return bmp;
00425 }
00426
00427 int wxLuaStackDialog::GetItemImage(const wxLuaDebugItem *dbgItem)
00428 {
00429 wxCHECK_MSG(dbgItem, IMG_UNKNOWN, wxT("Invalid wxLuaDebugItem"));
00430
00431 int img = IMG_NONE;
00432
00433
00434 if (dbgItem->GetFlagBit(WXLUA_DEBUGITEM_EXPANDED))
00435 img = IMG_TABLE_OPEN;
00436 else if (dbgItem->GetFlagBit(WXLUA_DEBUGITEM_LOCALS))
00437 img = IMG_TABLE;
00438 else
00439 {
00440 switch (dbgItem->GetValueType())
00441 {
00442 case WXLUA_TUNKNOWN : img = IMG_UNKNOWN; break;
00443 case WXLUA_TNONE : img = IMG_NONE; break;
00444 case WXLUA_TNIL : img = IMG_NIL; break;
00445 case WXLUA_TBOOLEAN : img = IMG_BOOLEAN; break;
00446 case WXLUA_TLIGHTUSERDATA : img = IMG_LIGHTUSERDATA; break;
00447 case WXLUA_TNUMBER : img = IMG_NUMBER; break;
00448 case WXLUA_TSTRING : img = IMG_STRING; break;
00449 case WXLUA_TTABLE : img = IMG_TABLE; break;
00450 case WXLUA_TFUNCTION : img = IMG_LUAFUNCTION; break;
00451 case WXLUA_TUSERDATA : img = IMG_USERDATA; break;
00452 case WXLUA_TTHREAD : img = IMG_THREAD; break;
00453 case WXLUA_TINTEGER : img = IMG_INTEGER; break;
00454 case WXLUA_TCFUNCTION : img = IMG_CFUNCTION; break;
00455 }
00456 }
00457
00458 return img;
00459 }
00460
00461 wxString wxLuaStackDialog::GetItemText(long item, long column, bool exact_value)
00462 {
00463 wxLuaStackListData* stkListData = (wxLuaStackListData*)m_listData[item];
00464 wxCHECK_MSG(stkListData, wxEmptyString, wxT("Invalid wxLuaStackListData item"));
00465 wxLuaDebugItem* debugItem = stkListData->GetDebugItem();
00466 wxCHECK_MSG(debugItem, wxEmptyString, wxT("Invalid wxLuaDebugItem item"));
00467
00468 switch (column)
00469 {
00470 case LIST_COL_KEY:
00471 {
00472 if (exact_value)
00473 return debugItem->GetKey();
00474
00475 if (stkListData->m_level > 0)
00476 {
00477
00478
00479
00480 return wxString(wxT(' '), stkListData->m_level*4) + debugItem->GetKey();
00481 }
00482 else
00483 return debugItem->GetKey();
00484 }
00485 case LIST_COL_LEVEL:
00486 return wxString::Format(wxT("%d:%d"), stkListData->m_level+1, stkListData->m_item_idx+1);
00487 case LIST_COL_KEY_TYPE:
00488 return debugItem->GetKeyTypeString();
00489 case LIST_COL_VALUE_TYPE:
00490 return debugItem->GetValueTypeString();
00491 case LIST_COL_VALUE:
00492 {
00493 if (exact_value)
00494 return debugItem->GetValue();
00495
00496 wxString value(debugItem->GetValue());
00497 if (value.Length() > 200) value = value.Mid(0, 200) + wxT("... <snip>");
00498 value.Replace(wxT("\n"), wxT("\\n"));
00499 value.Replace(wxT("\r"), wxT("\\r"));
00500 return value;
00501 }
00502 }
00503
00504 return wxEmptyString;
00505 }
00506
00507 void wxLuaStackDialog::EnumerateStack()
00508 {
00509 wxCHECK_RET(m_wxlState.Ok(), wxT("Invalid wxLuaState"));
00510 wxBusyCursor wait;
00511 wxLuaDebugData debugData(true);
00512 debugData.EnumerateStack(m_wxlState);
00513 FillStackCombobox(debugData);
00514 }
00515 void wxLuaStackDialog::EnumerateStackEntry(int nEntry)
00516 {
00517 wxCHECK_RET(m_wxlState.Ok(), wxT("Invalid wxLuaState"));
00518 wxBusyCursor wait;
00519 wxLuaDebugData debugData(true);
00520 debugData.EnumerateStackEntry(m_wxlState, nEntry, m_luaReferences);
00521 FillStackEntry(nEntry, debugData);
00522 }
00523 void wxLuaStackDialog::EnumerateTable(int nRef, int nEntry, long lc_item)
00524 {
00525 wxCHECK_RET(m_wxlState.Ok(), wxT("Invalid wxLuaState"));
00526 wxBusyCursor wait;
00527 wxLuaDebugData debugData(true);
00528 debugData.EnumerateTable(m_wxlState, nRef, nEntry, m_luaReferences);
00529 FillTableEntry(lc_item, debugData);
00530 }
00531 void wxLuaStackDialog::EnumerateGlobalData(long lc_item)
00532 {
00533 wxCHECK_RET(m_wxlState.Ok(), wxT("Invalid wxLuaState"));
00534 wxBusyCursor wait;
00535 wxLuaDebugData debugData(true);
00536 debugData.EnumerateTable(m_wxlState, -1, -1, m_luaReferences);
00537 FillTableEntry(lc_item, debugData);
00538 }
00539
00540 void wxLuaStackDialog::FillStackCombobox(const wxLuaDebugData& debugData)
00541 {
00542 wxCHECK_RET(debugData.Ok(), wxT("Invalid wxLuaDebugData in FillStackCombobox"));
00543
00544 m_stackChoice->Clear();
00545 m_stackEntries.Clear();
00546
00547 size_t n, count = debugData.GetCount();
00548 for (n = 0; n < count; ++n)
00549 {
00550 const wxLuaDebugItem *item = debugData.Item(n);
00551 m_stackEntries.Add(item->GetIndex());
00552 wxString name(item->GetKey());
00553 if (n == count - 1) name += wxT(" (Globals)");
00554 m_stackChoice->Append(name);
00555 }
00556
00557 if (count > 0)
00558 {
00559 m_stackChoice->SetSelection(0);
00560 SelectStack(0);
00561 }
00562 }
00563
00564 void wxLuaStackDialog::FillStackEntry(int WXUNUSED(nEntry), const wxLuaDebugData& debugData)
00565 {
00566 wxCHECK_RET(debugData.Ok(), wxT("Invalid wxLuaDebugData in FillStackEntry"));
00567
00568 RemoveAllLuaReferences();
00569 DeleteAllListItemData();
00570 m_expandedItems.clear();
00571 m_listCtrl->SetItemCount(0);
00572
00573 m_treeCtrl->DeleteAllItems();
00574 m_treeCtrl->AddRoot(wxT("wxLua Data"), -1, -1, NULL);
00575 m_treeCtrl->SetItemHasChildren(m_treeCtrl->GetRootItem());
00576
00577
00578 wxLuaDebugItem* localItem = new wxLuaDebugItem(_("Locals"), WXLUA_TNONE,
00579 wxString::Format(wxT("%d Items"), (int)debugData.GetCount()), WXLUA_TNONE,
00580 wxT(""), LUA_NOREF, 0, WXLUA_DEBUGITEM_EXPANDED|WXLUA_DEBUGITEM_LOCALS|WXLUA_DEBUGITEM_VALUE_REF);
00581 wxLuaDebugData localData(true);
00582 localData.Add(localItem);
00583 FillTableEntry(m_listCtrl->GetItemCount(), localData);
00584
00585 if (debugData.GetCount() > 0u)
00586 FillTableEntry(m_listCtrl->GetItemCount()-1, debugData);
00587
00588
00589 if (m_stack_sel == (int)m_stackEntries.GetCount() - 1)
00590 {
00591 EnumerateGlobalData(m_listCtrl->GetItemCount());
00592
00593
00594 if (m_wxlState.Ok())
00595 {
00596 wxLuaDebugData regData(true);
00597 regData.EnumerateTable(m_wxlState, LUA_REGISTRYINDEX, -1, m_luaReferences);
00598 FillTableEntry(m_listCtrl->GetItemCount(), regData);
00599 }
00600 }
00601 }
00602
00603 void wxLuaStackDialog::FillTableEntry(long lc_item_, const wxLuaDebugData& debugData)
00604 {
00605 wxCHECK_RET(debugData.Ok(), wxT("Invalid wxLuaDebugData in FillTableEntry"));
00606
00607 wxCHECK_RET(lc_item_ <= m_listCtrl->GetItemCount(), wxT("Attempting to add list item past end"));
00608
00609 if (debugData.GetCount() > 0)
00610 {
00611 wxTreeItemId treeId;
00612 wxString levelStr;
00613 int level = 0;
00614
00615
00616 if (lc_item_ < (long)m_listData.GetCount())
00617 {
00618
00619 wxLuaStackListData* stkListData = (wxLuaStackListData*)m_listData[lc_item_];
00620 wxCHECK_RET((stkListData != NULL), wxT("The wxLuaStackDialog does have stack data!"));
00621
00622 wxCHECK_RET(!stkListData->m_childrenDebugData.Ok() || (stkListData->m_childrenDebugData == debugData), wxT("Replacing the child data?"));
00623 if (!stkListData->m_childrenDebugData.Ok())
00624 stkListData->m_childrenDebugData = debugData;
00625
00626 treeId = stkListData->m_treeId;
00627 if (!treeId) treeId = m_treeCtrl->GetRootItem();
00628
00629 level = stkListData->m_level+1;
00630 }
00631 else
00632 {
00633 treeId = m_treeCtrl->GetRootItem();
00634 lc_item_--;
00635 }
00636
00637 m_treeCtrl->SetItemHasChildren(treeId);
00638
00639 BeginBatch();
00640
00641 bool removed_tree_dummy = false;
00642 size_t n, count = debugData.GetCount();
00643
00644 long lc_item = lc_item_;
00645 for (n = 0; n < count; ++n)
00646 {
00647 wxLuaStackListData* stkListData = new wxLuaStackListData(n, level, debugData);
00648 m_listData.Insert(stkListData, lc_item+n+1);
00649
00650 wxLuaDebugItem* debugItem = debugData.Item(n);
00651
00652 int img = GetItemImage(debugItem);
00653
00654 if ((debugItem->GetRef() != LUA_NOREF) ||
00655 debugItem->GetFlagBit(WXLUA_DEBUGITEM_LOCALS))
00656 {
00657 wxTreeItemId id = m_treeCtrl->AppendItem(treeId, debugItem->GetKey(), -1, -1, new wxLuaStackTreeData(stkListData));
00658 m_treeCtrl->SetItemHasChildren(id);
00659 stkListData->m_treeId = id;
00660
00661
00662
00663
00664 m_treeCtrl->AppendItem(id, DUMMY_TREEITEM);
00665
00666
00667 if (!removed_tree_dummy)
00668 {
00669 removed_tree_dummy = true;
00670
00671 wxTreeItemIdValue dummyCookie;
00672 wxTreeItemId dummyId = m_treeCtrl->GetFirstChild(treeId, dummyCookie);
00673 if (m_treeCtrl->GetItemText(dummyId) == DUMMY_TREEITEM)
00674 m_treeCtrl->Delete(dummyId);
00675 }
00676 }
00677 }
00678
00679 m_listCtrl->SetItemCount(m_listData.GetCount());
00680
00681 EndBatch();
00682
00683
00684
00685 #if !defined(WXLUA_STACK_MSWTREE)
00686
00687 if (treeId && !m_treeCtrl->IsExpanded(treeId) &&
00688 ((treeId != m_treeCtrl->GetRootItem()) || ((m_treeCtrl->GetWindowStyle() & wxTR_HIDE_ROOT) == 0)))
00689 m_treeCtrl->Expand(treeId);
00690 #endif //!defined(WXLUA_STACK_MSWTREE)
00691 }
00692 }
00693
00694 void wxLuaStackDialog::BeginBatch()
00695 {
00696 if (m_batch_count == 0)
00697 {
00698 m_listCtrl->Freeze();
00699 m_treeCtrl->Freeze();
00700 }
00701
00702 ++m_batch_count;
00703 }
00704
00705 void wxLuaStackDialog::EndBatch()
00706 {
00707 if (m_batch_count == 1)
00708 {
00709 m_listCtrl->Thaw();
00710 m_treeCtrl->Thaw();
00711 }
00712
00713 if (m_batch_count > 0)
00714 m_batch_count--;
00715 }
00716
00717 long wxLuaStackDialog::FindListItem(wxLuaStackListData* stkListData, bool get_parent) const
00718 {
00719 long n, count = m_listCtrl->GetItemCount();
00720 wxLuaStackListData* stkListData_n = NULL;
00721
00722 for (n = 0; n < count; ++n)
00723 {
00724 stkListData_n = (wxLuaStackListData*)m_listData[n];
00725
00726 if (!get_parent && (stkListData_n == stkListData))
00727 return n;
00728 else if (get_parent && (stkListData_n->m_childrenDebugData == stkListData->m_parentDebugData))
00729 return n;
00730 }
00731
00732 return wxNOT_FOUND;
00733 }
00734
00735 void wxLuaStackDialog::OnExpandButton(wxCommandEvent &event)
00736 {
00737 long start_item = m_listCtrl->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
00738
00739 if (start_item < 0) return;
00740
00741 if (event.GetId() == ID_WXLUA_STACK_EXPAND_BUTTON)
00742 ExpandItemChildren(start_item);
00743 else
00744 CollapseItem(start_item);
00745 }
00746
00747
00748 void wxLuaPrependComboBoxString(const wxString &str, int max_strings, wxComboBox *combo)
00749 {
00750 wxCHECK_RET(combo, wxT("Invalid combobox in wxLuaPrependComboBoxString"));
00751
00752 int pos = combo->FindString(str);
00753 if (pos == 0)
00754 return;
00755 if (pos != wxNOT_FOUND)
00756 combo->Delete(pos);
00757
00758 combo->Insert(str, 0);
00759 combo->SetSelection(0);
00760
00761 while ((max_strings > 0) && ((int)combo->GetCount() > max_strings))
00762 combo->Delete(combo->GetCount()-1);
00763 }
00764
00765 void wxLuaStackDialog::OnMenu(wxCommandEvent& event)
00766 {
00767 int id = event.GetId();
00768 bool checked = event.IsChecked();
00769
00770 if (id == ID_WXLUA_STACK_FINDMENU_ALL)
00771 {
00772 m_findMenu->Check(ID_WXLUA_STACK_FINDMENU_NAME, checked);
00773 m_findMenu->Check(ID_WXLUA_STACK_FINDMENU_LEVEL, checked);
00774 m_findMenu->Check(ID_WXLUA_STACK_FINDMENU_KEYTYPE, checked);
00775 m_findMenu->Check(ID_WXLUA_STACK_FINDMENU_VALUETYPE, checked);
00776 m_findMenu->Check(ID_WXLUA_STACK_FINDMENU_VALUE, checked);
00777 }
00778 else if ((id >= ID_WXLUA_STACK_FINDMENU_NAME) && (id <= ID_WXLUA_STACK_FINDMENU_VALUE))
00779 {
00780 bool all_checked = m_findMenu->IsChecked(ID_WXLUA_STACK_FINDMENU_NAME) &&
00781 m_findMenu->IsChecked(ID_WXLUA_STACK_FINDMENU_LEVEL) &&
00782 m_findMenu->IsChecked(ID_WXLUA_STACK_FINDMENU_KEYTYPE) &&
00783 m_findMenu->IsChecked(ID_WXLUA_STACK_FINDMENU_VALUETYPE) &&
00784 m_findMenu->IsChecked(ID_WXLUA_STACK_FINDMENU_VALUE);
00785
00786 if (m_findMenu->IsChecked(ID_WXLUA_STACK_FINDMENU_ALL) != checked)
00787 m_findMenu->Check(ID_WXLUA_STACK_FINDMENU_ALL, all_checked);
00788 }
00789 else if ((id >= ID_WXLUA_STACK_LISTMENU_COPY0) && (id <= ID_WXLUA_STACK_LISTMENU_COPY4))
00790 {
00791 long list_item = m_listCtrl->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
00792
00793 if (list_item >= 0)
00794 {
00795 wxString s(GetItemText(list_item, id - ID_WXLUA_STACK_LISTMENU_COPY0, true));
00796
00797 if (wxTheClipboard->Open())
00798 {
00799
00800
00801 wxTheClipboard->SetData( new wxTextDataObject(s) );
00802 wxTheClipboard->Close();
00803 }
00804 }
00805 }
00806 }
00807
00808 void wxLuaStackDialog::OnFind(wxCommandEvent &event)
00809 {
00810 if (event.GetId() == ID_WXLUA_STACK_FINDMENU_BUTTON)
00811 {
00812 wxWindow* button = ((wxWindow*)event.GetEventObject());
00813 wxSize s(button->GetSize());
00814 button->PopupMenu(m_findMenu, 0, s.GetHeight());
00815
00816 return;
00817 }
00818
00819
00820
00821 bool find_col[5] = {
00822 m_findMenu->IsChecked(ID_WXLUA_STACK_FINDMENU_NAME),
00823 m_findMenu->IsChecked(ID_WXLUA_STACK_FINDMENU_LEVEL),
00824 m_findMenu->IsChecked(ID_WXLUA_STACK_FINDMENU_KEYTYPE),
00825 m_findMenu->IsChecked(ID_WXLUA_STACK_FINDMENU_VALUETYPE),
00826 m_findMenu->IsChecked(ID_WXLUA_STACK_FINDMENU_VALUE),
00827 };
00828
00829
00830 if (!find_col[0] && !find_col[1] && !find_col[2] && !find_col[3] && !find_col[4])
00831 {
00832 wxMessageBox(wxT("Please select at least one column to search with the find options button"),
00833 wxT("wxLua Stack Find Error"),
00834 wxOK|wxICON_EXCLAMATION|wxCENTRE, this);
00835 return;
00836 }
00837
00838 wxString findStr = m_findComboBox->GetValue();
00839 if (findStr.IsEmpty())
00840 return;
00841
00842 wxBusyCursor busy;
00843 wxLuaPrependComboBoxString(findStr, 10, m_findComboBox);
00844
00845 bool match_case = m_findMenu->IsChecked(ID_WXLUA_STACK_FINDMENU_CASE);
00846 if (!match_case) findStr = findStr.Lower();
00847
00848 bool whole_string = m_findMenu->IsChecked(ID_WXLUA_STACK_FINDMENU_WHOLE_STRING);
00849
00850 long direction = (event.GetId() == ID_WXLUA_STACK_FINDPREV_BUTTON) ? -1 : 1;
00851
00852 long list_count = m_listCtrl->GetItemCount();
00853 long start_item = m_listCtrl->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
00854
00855 int wrap_count = 0;
00856
00857 bool found = false;
00858 wxString txt;
00859
00860 while ((wrap_count < 2) && !found)
00861 {
00862 long i = 0;
00863 found = false;
00864
00865 if (wrap_count == 0)
00866 {
00867 i = start_item + direction;
00868
00869
00870 if (start_item < 0)
00871 {
00872 i = (direction > 0) ? 0 : list_count - 1;
00873 ++wrap_count;
00874 }
00875 else if ((direction > 0) && (start_item == list_count - 1))
00876 {
00877 i = 0;
00878 ++wrap_count;
00879 }
00880 }
00881 else
00882 {
00883 i = (direction > 0) ? 0 : list_count - 1;
00884 }
00885
00886 for ( ; (i >= 0) && (i < list_count) && !found; i = i + direction)
00887 {
00888 for (int col = 0; (col < 5) && !found; ++col)
00889 {
00890 if (!find_col[col]) continue;
00891
00892 txt = GetItemText(i, col, true);
00893 if (!match_case) txt.MakeLower();
00894
00895 if ((whole_string && (txt == findStr)) ||
00896 (!whole_string && (txt.Find(findStr) != wxNOT_FOUND)))
00897 {
00898 m_listCtrl->SetItemState(i, wxLIST_STATE_FOCUSED, wxLIST_STATE_FOCUSED);
00899 m_listCtrl->SetItemState(i, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
00900 m_listCtrl->EnsureVisible(i);
00901 found = true;
00902 break;
00903 }
00904 }
00905 }
00906
00907 ++wrap_count;
00908 }
00909 }
00910
00911 void wxLuaStackDialog::OnSelectStack(wxCommandEvent &event)
00912 {
00913 if (event.GetSelection() >= 0)
00914 SelectStack(event.GetSelection());
00915 }
00916
00917 void wxLuaStackDialog::SelectStack(int stack_sel)
00918 {
00919 wxCHECK_RET((stack_sel >= 0) && (stack_sel < (int)m_stackEntries.GetCount()), wxT("Invalid stack index"));
00920 m_stack_sel = stack_sel;
00921 int n_entry = m_stackEntries[m_stack_sel];
00922 EnumerateStackEntry(n_entry);
00923 }
00924
00925 void wxLuaStackDialog::OnTreeItem(wxTreeEvent &event)
00926 {
00927 if (m_batch_count > 0) return;
00928
00929 wxTreeItemId id = event.GetItem();
00930 wxLuaStackTreeData* stkTreeData = (wxLuaStackTreeData*)m_treeCtrl->GetItemData(id);
00931 if (stkTreeData == NULL) return;
00932
00933 long list_item = FindListItem(stkTreeData->m_stkListData);
00934
00935 if (list_item < 0) return;
00936
00937 int evt_type = event.GetEventType();
00938
00939 if (evt_type == wxEVT_COMMAND_TREE_ITEM_EXPANDED)
00940 {
00941 wxBusyCursor busy;
00942 ExpandItem(list_item);
00943 m_listCtrl->RefreshItem(list_item);
00944 }
00945 else if (evt_type == wxEVT_COMMAND_TREE_ITEM_COLLAPSED)
00946 {
00947 wxBusyCursor busy;
00948 CollapseItem(list_item);
00949 m_listCtrl->RefreshItem(list_item);
00950 }
00951 else if (evt_type == wxEVT_COMMAND_TREE_SEL_CHANGED)
00952 {
00953 m_listCtrl->SetItemState(list_item, wxLIST_STATE_FOCUSED, wxLIST_STATE_FOCUSED);
00954 m_listCtrl->SetItemState(list_item, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
00955 m_listCtrl->EnsureVisible(list_item);
00956 }
00957 }
00958
00959 void wxLuaStackDialog::OnListItem(wxListEvent &event)
00960 {
00961 long list_item = event.GetIndex();
00962
00963 wxLuaStackListData* stkListData = (wxLuaStackListData*)m_listData[list_item];
00964 wxCHECK_RET(stkListData != NULL, wxT("Invalid wxLuaStack data"));
00965 wxLuaDebugItem* debugItem = stkListData->GetDebugItem();
00966 wxCHECK_RET(debugItem != NULL, wxT("Invalid debug item"));
00967
00968 if (event.GetEventType() == wxEVT_COMMAND_LIST_ITEM_SELECTED)
00969 {
00970 if (stkListData->m_treeId)
00971 {
00972 m_treeCtrl->SelectItem(stkListData->m_treeId, true);
00973 m_treeCtrl->EnsureVisible(stkListData->m_treeId);
00974 }
00975 }
00976 else if (event.GetEventType() == wxEVT_COMMAND_LIST_ITEM_ACTIVATED)
00977 {
00978 if (!debugItem->GetFlagBit(WXLUA_DEBUGITEM_EXPANDED))
00979 {
00980 if (ExpandItem(list_item))
00981 {
00982
00983 if (stkListData->m_treeId && !m_treeCtrl->IsExpanded(stkListData->m_treeId))
00984 m_treeCtrl->Expand(stkListData->m_treeId);
00985 }
00986 }
00987 else
00988 {
00989
00990 if (stkListData->m_treeId && m_treeCtrl->IsExpanded(stkListData->m_treeId))
00991 m_treeCtrl->Collapse(stkListData->m_treeId);
00992
00993 CollapseItem(list_item);
00994 }
00995
00996
00997 m_listCtrl->RefreshItem(list_item);
00998 }
00999 }
01000
01001 void wxLuaStackDialog::OnListRightClick(wxListEvent &event)
01002 {
01003 event.Skip();
01004
01005 if (event.GetIndex() >= 0)
01006 m_listCtrl->PopupMenu(m_listMenu);
01007 }
01008
01009 bool wxLuaStackDialog::ExpandItem(long lc_item)
01010 {
01011 wxCHECK_MSG((lc_item >= 0) && (lc_item < (long)m_listData.GetCount()), false,
01012 wxT("Invalid list item to expand"));
01013
01014 bool expanded = false;
01015
01016 wxLuaStackListData* stkListData = (wxLuaStackListData*)m_listData[lc_item];
01017 wxCHECK_MSG(stkListData != NULL, false, wxT("Invalid wxLuaStack data"));
01018 wxLuaDebugItem* debugItem = stkListData->GetDebugItem();
01019 wxCHECK_MSG(debugItem != NULL, false, wxT("Invalid debug item"));
01020
01021 int nRef = debugItem->GetRef();
01022
01023 if (!debugItem->GetFlagBit(WXLUA_DEBUGITEM_EXPANDED))
01024 {
01025
01026 if (stkListData->m_childrenDebugData.Ok())
01027 {
01028 debugItem->SetFlagBit(WXLUA_DEBUGITEM_EXPANDED, true);
01029
01030 long long_key = 0;
01031 if (debugItem->GetRefPtr(long_key))
01032 m_expandedItems[long_key] = (long)stkListData;
01033
01034 FillTableEntry(lc_item, stkListData->m_childrenDebugData);
01035 expanded = true;
01036 return true;
01037 }
01038
01039
01040 if (debugItem->GetRef() != LUA_NOREF)
01041 {
01042 long long_key = 0;
01043 wxCHECK_MSG(debugItem->GetRefPtr(long_key), false, wxT("Invalid table item"));
01044
01045 if (m_expandedItems[long_key])
01046 {
01047 if (m_show_dup_expand_msg)
01048 {
01049 wxMessageBox(wxT("Cannot expand linked tables,\nplease see the already expanded table."),
01050 wxT("wxLua Stack"), wxOK | wxCENTRE, this);
01051
01052 int n = m_listData.Index((void*)m_expandedItems[long_key]);
01053 wxCHECK_MSG(n != wxNOT_FOUND, false, wxT("Unable to find hash of expanded items."));
01054
01055 m_listCtrl->SetItemState(n, wxLIST_STATE_FOCUSED, wxLIST_STATE_FOCUSED);
01056 m_listCtrl->SetItemState(n, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
01057 m_listCtrl->EnsureVisible(n);
01058 }
01059
01060 return false;
01061 }
01062 }
01063
01064 if (nRef != LUA_NOREF)
01065 {
01066 debugItem->SetFlagBit(WXLUA_DEBUGITEM_EXPANDED, true);
01067
01068 long long_key = 0;
01069 wxCHECK_MSG(debugItem->GetRefPtr(long_key), false, wxT("Invalid table item"));
01070 m_expandedItems[long_key] = (long)stkListData;
01071
01072 int nIndex = debugItem->GetIndex() + 1;
01073 EnumerateTable(nRef, nIndex, lc_item);
01074 expanded = true;
01075 }
01076 }
01077
01078 return expanded;
01079 }
01080
01081 bool wxLuaStackDialog::ExpandItemChildren(long lc_item)
01082 {
01083 wxCHECK_MSG((lc_item >= 0) && (lc_item < (long)m_listData.GetCount()), false,
01084 wxT("Invalid list item to expand"));
01085
01086 bool expanded = false;
01087
01088 wxProgressDialog* dlg =
01089 new wxProgressDialog(wxT("wxLua Stack Expanding node"), wxEmptyString, 100, this,
01090 wxPD_AUTO_HIDE | wxPD_APP_MODAL | wxPD_CAN_ABORT);
01091
01092 BeginBatch();
01093
01094
01095
01096
01097
01098 wxLuaStackListData* stkListData = (wxLuaStackListData*)m_listData[lc_item];
01099
01100 int counter = 0;
01101 int n = lc_item, level = stkListData->m_level;
01102 while (n < (int)m_listData.GetCount())
01103 {
01104
01105 if (n > lc_item) m_show_dup_expand_msg = false;
01106
01107 wxLuaStackListData* stkListData_n = (wxLuaStackListData*)m_listData[n];
01108
01109 if ((n > lc_item) && (stkListData_n->m_level <= level)) break;
01110
01111 if (counter % 20 == 0)
01112 {
01113 if (!dlg->Pulse(wxString::Format(wxT("Expanding nodes : %d"), counter)))
01114 break;
01115 }
01116
01117 if (!stkListData_n->GetDebugItem()->GetFlagBit(WXLUA_DEBUGITEM_EXPANDED))
01118 expanded |= ExpandItem(n);
01119
01120 ++counter;
01121 ++n;
01122 }
01123
01124 dlg->Destroy();
01125
01126 EndBatch();
01127 m_show_dup_expand_msg = true;
01128
01129 return expanded;
01130 }
01131
01132 bool wxLuaStackDialog::CollapseItem(long lc_item)
01133 {
01134 wxCHECK_MSG((lc_item >= 0) && (lc_item < m_listCtrl->GetItemCount()), false,
01135 wxT("Invalid list item to expand"));
01136
01137 bool collapsed = false;
01138
01139 wxLuaStackListData* stkListData = (wxLuaStackListData*)m_listData[lc_item];
01140 wxCHECK_MSG(stkListData != NULL, false, wxT("Invalid wxLuaStack data"));
01141 wxLuaDebugItem* debugItem = stkListData->GetDebugItem();
01142 wxCHECK_MSG((debugItem != NULL), false, wxT("Invalid debug item"));
01143 wxLuaDebugData childData = stkListData->m_childrenDebugData;
01144
01145 BeginBatch();
01146
01147
01148 if (debugItem->GetFlagBit(WXLUA_DEBUGITEM_EXPANDED))
01149 {
01150 if (childData.Ok())
01151 {
01152 long n, count = m_listCtrl->GetItemCount();
01153
01154 for (n = lc_item+1; n < count; ++n)
01155 {
01156 wxLuaStackListData* stkListData_n = (wxLuaStackListData*)m_listData[n];
01157 wxCHECK_MSG(stkListData_n != NULL, false, wxT("Invalid wxLuaStack data"));
01158
01159 if (stkListData_n->m_parentDebugData == childData)
01160 {
01161 if (stkListData_n->m_childrenDebugData.Ok() &&
01162 stkListData_n->GetDebugItem()->GetFlagBit(WXLUA_DEBUGITEM_EXPANDED))
01163 {
01164 long long_key = 0;
01165 if (stkListData_n->GetDebugItem()->GetRefPtr(long_key))
01166 m_expandedItems.erase(long_key);
01167
01168 CollapseItem(n);
01169
01170 n--; count = m_listData.GetCount();
01171 continue;
01172 }
01173
01174 collapsed = true;
01175
01176 if (stkListData_n->m_treeId)
01177 m_treeCtrl->Delete(stkListData_n->m_treeId);
01178
01179 m_listData.RemoveAt(n);
01180
01181 if (stkListData_n != NULL)
01182 delete stkListData_n;
01183
01184 n--; count = m_listData.GetCount();
01185 }
01186 }
01187 }
01188
01189
01190
01191 m_treeCtrl->DeleteChildren(stkListData->m_treeId);
01192
01193 m_treeCtrl->AppendItem(stkListData->m_treeId, DUMMY_TREEITEM);
01194
01195 debugItem->SetFlagBit(WXLUA_DEBUGITEM_EXPANDED, false);
01196
01197 long long_key = 0;
01198 if (debugItem->GetRefPtr(long_key))
01199 m_expandedItems.erase(long_key);
01200 }
01201
01202 EndBatch();
01203
01204 m_listCtrl->SetItemCount(m_listData.GetCount());
01205
01206 return collapsed;
01207 }
01208
01209 void wxLuaStackDialog::DeleteAllListItemData()
01210 {
01211 m_expandedItems.clear();
01212
01213 int i, count = m_listData.GetCount();
01214
01215 for (i = 0; i < count; ++i)
01216 {
01217 wxLuaStackListData* stkListData = (wxLuaStackListData*)m_listData[i];
01218
01219 if (stkListData != NULL)
01220 delete stkListData;
01221 }
01222
01223 m_listData.Clear();
01224 }
01225
01226 void wxLuaStackDialog::RemoveAllLuaReferences()
01227 {
01228 if (!m_wxlState.Ok()) return;
01229
01230 int i;
01231
01232
01233
01234
01235
01236
01237
01238
01239
01240
01241
01242
01243
01244
01245
01246
01247
01248
01249
01250
01251
01252
01253
01254
01255
01256
01257
01258
01259 lua_State* L = m_wxlState.GetLuaState();
01260
01261
01262 for (i = (int)m_luaReferences.GetCount()-1; i >= 0; --i)
01263 {
01264 bool ok = wxluaR_unref(L, m_luaReferences[i], &wxlua_lreg_debug_refs_key);
01265 wxCHECK_RET(ok, wxT("Unable to remove a reference in Lua"));
01266
01267 }
01268
01269 m_luaReferences.Clear();
01270
01271
01272
01273
01274
01275
01276 lua_pushlightuserdata(L, &wxlua_lreg_debug_refs_key);
01277 lua_rawget(L, LUA_REGISTRYINDEX);
01278
01279 lua_pushnil(L);
01280 while (lua_next(L, -2) != 0)
01281 {
01282
01283 if (!lua_isnumber(L, -2))
01284 wxPrintf(wxT("wxLuaStackDialog::RemoveAllLuaReferences refs not empty key=%d value=%d\n"), lua_type(L, -2), lua_type(L, -1));
01285 else if ((lua_tonumber(L, -2) == 0) && (lua_tonumber(L, -1) != 1))
01286 wxPrintf(wxT("wxLuaStackDialog::RemoveAllLuaReferences refs not empty key=%lf value=%lg\n"), lua_tonumber(L, -2), lua_tonumber(L, -1));
01287
01288 lua_pop(L, 1);
01289 }
01290
01291 lua_pop(L, 1);
01292
01293
01294
01295
01296 wxlua_lreg_createtable(L, &wxlua_lreg_debug_refs_key);
01297 }