]> git.saurik.com Git - wxWidgets.git/blame - samples/regtest/regtest.cpp
Fix a crash in wxExecute() in wxMSW too.
[wxWidgets.git] / samples / regtest / regtest.cpp
CommitLineData
bbf1f0e5 1///////////////////////////////////////////////////////////////////////////////
23f681ec 2// Name: regtest.cpp
bbf1f0e5
KB
3// Purpose: wxRegKey class demo
4// Author: Vadim Zeitlin
23f681ec 5// Modified by:
bbf1f0e5
KB
6// Created: 03.04.98
7// RCS-ID: $Id$
8// Copyright: (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
526954c5 9// Licence: wxWindows licence
bbf1f0e5
KB
10///////////////////////////////////////////////////////////////////////////////
11
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19#include "wx/wxprec.h"
20
21#ifdef __BORLANDC__
721b8397 22# pragma hdrstop
bbf1f0e5
KB
23#endif
24
25#ifndef WX_PRECOMP
721b8397 26# include "wx/wx.h"
bbf1f0e5
KB
27#endif
28
bbf1f0e5 29#include "wx/treectrl.h"
721b8397
DS
30#include "wx/config.h"
31#include "wx/imaglist.h"
c41ea66a
VZ
32#include "wx/tokenzr.h"
33
bb5a9514 34#if wxUSE_CONFIG_NATIVE && defined( __WINDOWS__ )
721b8397
DS
35# define DO_REGTEST 1
36#else
37# define DO_REGTEST 0
38#endif
39
bbf1f0e5
KB
40// ----------------------------------------------------------------------------
41// application type
42// ----------------------------------------------------------------------------
43class RegApp : public wxApp
23f681ec 44{
bbf1f0e5 45public:
721b8397 46 bool OnInit();
bbf1f0e5
KB
47};
48
49// ----------------------------------------------------------------------------
50// image list with registry icons
51// ----------------------------------------------------------------------------
52class RegImageList : public wxImageList
53{
54public:
721b8397
DS
55 enum Icon
56 {
57 Root,
58 ClosedKey,
59 OpenedKey,
60 TextValue,
61 BinaryValue
62 };
63
64 RegImageList();
bbf1f0e5
KB
65};
66
721b8397
DS
67#if DO_REGTEST
68
bbf1f0e5
KB
69// ----------------------------------------------------------------------------
70// our control
71// ----------------------------------------------------------------------------
72class RegTreeCtrl : public wxTreeCtrl
73{
74public:
721b8397
DS
75 // ctor & dtor
76 RegTreeCtrl(wxWindow *parent, wxWindowID id);
77 virtual ~RegTreeCtrl();
bbf1f0e5 78
721b8397
DS
79 // notifications
80 void OnDeleteItem (wxTreeEvent& event);
81 void OnItemExpanding (wxTreeEvent& event);
82 void OnSelChanged (wxTreeEvent& event);
bbf1f0e5 83
721b8397
DS
84 void OnBeginEdit (wxTreeEvent& event);
85 void OnEndEdit (wxTreeEvent& event);
c41ea66a 86
721b8397
DS
87 void OnBeginDrag (wxTreeEvent& event);
88 void OnEndDrag (wxTreeEvent& event);
23f681ec 89
721b8397
DS
90 void OnRightClick (wxMouseEvent& event);
91 void OnChar (wxKeyEvent& event);
92 void OnIdle (wxIdleEvent& event);
bbf1f0e5 93
721b8397
DS
94 // forwarded notifications (by the frame)
95 void OnMenuTest();
bbf1f0e5 96
721b8397
DS
97 // operations
98 void GoTo(const wxString& location);
99 void DoRefresh();
100 void DeleteSelected();
101 void ShowProperties();
102 void CreateNewKey(const wxString& strName);
103 void CreateNewTextValue(const wxString& strName);
104 void CreateNewBinaryValue(const wxString& strName);
a5c46848 105 void SetRegistryView(wxRegKey::WOW64ViewMode viewMode);
bbf1f0e5 106
721b8397
DS
107 // information
108 bool IsKeySelected() const;
bbf1f0e5 109
bbf1f0e5 110private:
721b8397
DS
111 // structure describing a registry key/value
112 class TreeNode : public wxTreeItemData
113 {
114 WX_DEFINE_ARRAY_PTR(TreeNode *, TreeChildren);
115 public:
116 RegTreeCtrl *m_pTree; // must be !NULL
117 TreeNode *m_pParent; // NULL only for the root node
945d96f6 118 wxTreeItemId m_id; // the id of the tree control item
721b8397
DS
119 wxString m_strName; // name of the key/value
120 TreeChildren m_aChildren; // array of subkeys/values
121 bool m_bKey; // key or value?
122 wxRegKey *m_pKey; // only may be !NULL if m_bKey == true
a5c46848 123 wxRegKey::WOW64ViewMode m_viewMode; // How to view the registry.
23f681ec 124
721b8397 125 // trivial accessors
945d96f6
WS
126 wxTreeItemId Id() const { return m_id; }
127 bool IsRoot() const { return m_pParent == NULL; }
128 bool IsKey() const { return m_bKey; }
129 TreeNode *Parent() const { return m_pParent; }
23f681ec 130
721b8397
DS
131 // notifications
132 bool OnExpand();
133 void OnCollapse();
23f681ec 134
721b8397
DS
135 // operations
136 void Refresh();
137 bool DeleteChild(TreeNode *child);
138 void DestroyChildren();
139 const wxChar *FullName() const;
a5c46848 140 void SetRegistryView(wxRegKey::WOW64ViewMode viewMode);
23f681ec 141
721b8397
DS
142 // get the associated key: make sure the pointer is !NULL
143 wxRegKey& Key() { if ( !m_pKey ) OnExpand(); return *m_pKey; }
23f681ec 144
721b8397
DS
145 // dtor deletes all children
146 ~TreeNode();
147 };
bbf1f0e5 148
721b8397
DS
149 wxImageList *m_imageList;
150 wxMenu *m_pMenuPopup;
23f681ec 151
721b8397 152 TreeNode *m_pRoot;
23f681ec 153
721b8397
DS
154 TreeNode *m_draggedItem; // the item being dragged
155 bool m_copyOnDrop; // if false, then move
23f681ec 156
721b8397 157 bool m_restoreStatus; // after OnItemExpanding()
bbf1f0e5 158
721b8397 159 wxString m_nameOld; // the initial value of item being renamed
c41ea66a 160
a5c46848
VZ
161 wxRegKey::WOW64ViewMode m_viewMode; // Registry view to use for keys.
162
721b8397 163 TreeNode *GetNode(const wxTreeEvent& event)
2e3b8fa7 164 { return (TreeNode *)GetItemData(event.GetItem()); }
bbf1f0e5
KB
165
166public:
721b8397
DS
167 // create a new node and insert it to the tree
168 TreeNode *InsertNewTreeNode(TreeNode *pParent,
169 const wxString& strName,
170 int idImage = RegImageList::ClosedKey,
a5c46848
VZ
171 const wxString *pstrValue = NULL,
172 wxRegKey::WOW64ViewMode viewMode = wxRegKey::WOW64ViewMode_Default);
721b8397
DS
173
174 // add standard registry keys
175 void AddStdKeys();
23f681ec
VZ
176
177private:
721b8397 178 DECLARE_EVENT_TABLE()
bbf1f0e5
KB
179};
180
721b8397
DS
181#endif // #if DO_REGTEST
182
bbf1f0e5
KB
183// ----------------------------------------------------------------------------
184// the main window of our application
185// ----------------------------------------------------------------------------
186class RegFrame : public wxFrame
23f681ec 187{
bbf1f0e5 188public:
721b8397 189 // ctor & dtor
fbfb8bcc 190 RegFrame(wxFrame *parent, const wxChar *title, int x, int y, int w, int h);
721b8397 191 virtual ~RegFrame();
23f681ec 192
721b8397
DS
193 // callbacks
194 void OnQuit (wxCommandEvent& event);
195 void OnAbout(wxCommandEvent& event);
196 void OnTest (wxCommandEvent& event);
bbf1f0e5 197
721b8397 198 void OnGoTo (wxCommandEvent& event);
c41ea66a 199
721b8397
DS
200 void OnExpand (wxCommandEvent& event);
201 void OnCollapse(wxCommandEvent& event);
202 void OnToggle (wxCommandEvent& event);
203 void OnRefresh (wxCommandEvent& event);
bbf1f0e5 204
721b8397
DS
205 void OnDelete (wxCommandEvent& event);
206 void OnNewKey (wxCommandEvent& event);
207 void OnNewText (wxCommandEvent& event);
208 void OnNewBinary(wxCommandEvent& event);
bbf1f0e5 209
721b8397 210 void OnInfo (wxCommandEvent& event);
bbf1f0e5 211
a5c46848
VZ
212 void OnViewChange (wxCommandEvent& event);
213
721b8397 214 DECLARE_EVENT_TABLE()
bbf1f0e5
KB
215
216private:
721b8397
DS
217
218#if DO_REGTEST
219 RegTreeCtrl *m_treeCtrl;
220#endif
bbf1f0e5
KB
221};
222
223// ----------------------------------------------------------------------------
224// various ids
225// ----------------------------------------------------------------------------
226
227enum
228{
721b8397
DS
229 Menu_Quit = 100,
230 Menu_About,
231 Menu_Test,
232 Menu_GoTo,
233 Menu_Expand,
234 Menu_Collapse,
235 Menu_Toggle,
236 Menu_Refresh,
237 Menu_New,
238 Menu_NewKey,
239 Menu_NewText,
240 Menu_NewBinary,
241 Menu_Delete,
242 Menu_Info,
a5c46848
VZ
243 Menu_View,
244 Menu_ViewDefault,
245 Menu_View32,
246 Menu_View64,
721b8397 247
004f4002 248 Ctrl_RegTree = 200
bbf1f0e5
KB
249};
250
251// ----------------------------------------------------------------------------
252// event tables
253// ----------------------------------------------------------------------------
254
255BEGIN_EVENT_TABLE(RegFrame, wxFrame)
a5c46848
VZ
256 EVT_MENU(Menu_Test, RegFrame::OnTest)
257 EVT_MENU(Menu_About, RegFrame::OnAbout)
258 EVT_MENU(Menu_Quit, RegFrame::OnQuit)
259 EVT_MENU(Menu_GoTo, RegFrame::OnGoTo)
260 EVT_MENU(Menu_Expand, RegFrame::OnExpand)
261 EVT_MENU(Menu_Collapse, RegFrame::OnCollapse)
262 EVT_MENU(Menu_Toggle, RegFrame::OnToggle)
263 EVT_MENU(Menu_Refresh, RegFrame::OnRefresh)
264 EVT_MENU(Menu_Delete, RegFrame::OnDelete)
265 EVT_MENU(Menu_NewKey, RegFrame::OnNewKey)
266 EVT_MENU(Menu_NewText, RegFrame::OnNewText)
267 EVT_MENU(Menu_NewBinary, RegFrame::OnNewBinary)
268 EVT_MENU(Menu_Info, RegFrame::OnInfo)
269 EVT_MENU(Menu_ViewDefault, RegFrame::OnViewChange)
270 EVT_MENU(Menu_View32, RegFrame::OnViewChange)
271 EVT_MENU(Menu_View64, RegFrame::OnViewChange)
bbf1f0e5
KB
272END_EVENT_TABLE()
273
721b8397
DS
274#if DO_REGTEST
275
bbf1f0e5 276BEGIN_EVENT_TABLE(RegTreeCtrl, wxTreeCtrl)
676e9e35
VZ
277 EVT_TREE_DELETE_ITEM (Ctrl_RegTree, RegTreeCtrl::OnDeleteItem)
278 EVT_TREE_ITEM_EXPANDING (Ctrl_RegTree, RegTreeCtrl::OnItemExpanding)
279 EVT_TREE_ITEM_COLLAPSING(Ctrl_RegTree, RegTreeCtrl::OnItemExpanding)
280 EVT_TREE_SEL_CHANGED (Ctrl_RegTree, RegTreeCtrl::OnSelChanged)
c41ea66a 281
721b8397
DS
282 EVT_TREE_BEGIN_LABEL_EDIT(Ctrl_RegTree, RegTreeCtrl::OnBeginEdit)
283 EVT_TREE_END_LABEL_EDIT (Ctrl_RegTree, RegTreeCtrl::OnEndEdit)
c41ea66a 284
721b8397
DS
285 EVT_TREE_BEGIN_DRAG (Ctrl_RegTree, RegTreeCtrl::OnBeginDrag)
286 EVT_TREE_BEGIN_RDRAG (Ctrl_RegTree, RegTreeCtrl::OnBeginDrag)
287 EVT_TREE_END_DRAG (Ctrl_RegTree, RegTreeCtrl::OnEndDrag)
bbf1f0e5 288
721b8397
DS
289 EVT_CHAR (RegTreeCtrl::OnChar)
290 EVT_RIGHT_DOWN(RegTreeCtrl::OnRightClick)
291 EVT_IDLE (RegTreeCtrl::OnIdle)
bbf1f0e5
KB
292END_EVENT_TABLE()
293
721b8397
DS
294#endif
295
bbf1f0e5
KB
296// ============================================================================
297// implementation
298// ============================================================================
299
300// ----------------------------------------------------------------------------
301// global functions
302// ----------------------------------------------------------------------------
303
304// create the "registry operations" menu
305wxMenu *CreateRegistryMenu()
306{
721b8397 307 wxMenu *pMenuNew = new wxMenu;
9a83f860 308 pMenuNew->Append(Menu_NewKey, wxT("&Key"), wxT("Create a new key"));
721b8397 309 pMenuNew->AppendSeparator();
9a83f860
VZ
310 pMenuNew->Append(Menu_NewText, wxT("&Text value"), wxT("Create a new text value"));
311 pMenuNew->Append(Menu_NewBinary, wxT("&Binary value"), wxT("Create a new binary value"));
721b8397 312
a5c46848
VZ
313 wxMenu *pMenuView = new wxMenu;
314 pMenuView->AppendRadioItem(
315 Menu_ViewDefault,
316 wxT("&Default"),
317 wxT("Default registry view for the program environment."));
318 pMenuView->AppendRadioItem(
319 Menu_View32,
320 wxT("32-bit Registry"),
321 wxT("View 32-bit registry."));
322 pMenuView->AppendRadioItem(
323 Menu_View64,
324 wxT("64-bit Registry"),
325 wxT("View 64-bit registry."));
326
721b8397 327 wxMenu *pMenuReg = new wxMenu;
9a83f860
VZ
328 pMenuReg->Append(Menu_New, wxT("&New"), pMenuNew);
329 pMenuReg->Append(Menu_Delete, wxT("&Delete..."), wxT("Delete selected key/value"));
721b8397 330 pMenuReg->AppendSeparator();
9a83f860
VZ
331 pMenuReg->Append(Menu_GoTo, wxT("&Go to...\tCtrl-G"), wxT("Go to registry key"));
332 pMenuReg->Append(Menu_Expand, wxT("&Expand"), wxT("Expand current key"));
333 pMenuReg->Append(Menu_Collapse, wxT("&Collapse"), wxT("Collapse current key"));
334 pMenuReg->Append(Menu_Toggle, wxT("&Toggle"), wxT("Toggle current key"));
721b8397 335 pMenuReg->AppendSeparator();
9a83f860 336 pMenuReg->Append(Menu_Refresh, wxT("&Refresh"), wxT("Refresh the subtree"));
a5c46848 337 pMenuReg->Append(Menu_View, wxT("&View"), pMenuView);
721b8397 338 pMenuReg->AppendSeparator();
9a83f860 339 pMenuReg->Append(Menu_Info, wxT("&Properties"),wxT("Information about current selection"));
721b8397
DS
340
341 return pMenuReg;
bbf1f0e5
KB
342}
343
344// ----------------------------------------------------------------------------
345// application class
346// ----------------------------------------------------------------------------
347IMPLEMENT_APP(RegApp)
348
349// `Main program' equivalent, creating windows and returning main app frame
350bool RegApp::OnInit()
351{
45e6e6f8
VZ
352 if ( !wxApp::OnInit() )
353 return false;
354
721b8397 355 // create the main frame window and show it
9a83f860 356 RegFrame *frame = new RegFrame(NULL, wxT("wxRegTest"), 50, 50, 600, 350);
721b8397 357 frame->Show(true);
23f681ec 358
721b8397 359 return true;
bbf1f0e5
KB
360}
361
362// ----------------------------------------------------------------------------
363// RegFrame
364// ----------------------------------------------------------------------------
365
fbfb8bcc 366RegFrame::RegFrame(wxFrame *parent, const wxChar *title, int x, int y, int w, int h)
945d96f6 367 : wxFrame(parent, wxID_ANY, title, wxPoint(x, y), wxSize(w, h))
bbf1f0e5 368{
721b8397 369 // this reduces flicker effects
ea92bb67 370 SetBackgroundColour(*wxWHITE);
721b8397
DS
371
372 // set the icon
373 // ------------
9a83f860 374 SetIcon(wxIcon(wxT("app_icon")));
721b8397
DS
375
376 // create menu
377 // -----------
378 wxMenu *pMenuFile = new wxMenu;
9a83f860 379 pMenuFile->Append(Menu_Test, wxT("Te&st"), wxT("Test key creation"));
721b8397 380 pMenuFile->AppendSeparator();
2d143b66 381 pMenuFile->Append(Menu_About, wxT("&About"), wxT("Show an extraordinarly beautiful dialog"));
721b8397 382 pMenuFile->AppendSeparator();
9a83f860 383 pMenuFile->Append(Menu_Quit, wxT("E&xit"), wxT("Quit this program"));
721b8397
DS
384
385 wxMenuBar *pMenu = new wxMenuBar;
9a83f860
VZ
386 pMenu->Append(pMenuFile, wxT("&File"));
387 pMenu->Append(CreateRegistryMenu(), wxT("&Registry"));
721b8397
DS
388 SetMenuBar(pMenu);
389
390#if DO_REGTEST
391 // create child controls
392 // ---------------------
393 m_treeCtrl = new RegTreeCtrl(this, Ctrl_RegTree);
394#endif
395
8520f137 396#if wxUSE_STATUSBAR
721b8397
DS
397 // create the status line
398 // ----------------------
399 CreateStatusBar(2);
8520f137 400#endif // wxUSE_STATUSBAR
bbf1f0e5
KB
401}
402
23f681ec 403RegFrame::~RegFrame()
bbf1f0e5 404{
721b8397
DS
405#if DO_REGTEST
406 // this makes deletion of it *much* quicker
407 m_treeCtrl->Hide();
408#endif
bbf1f0e5
KB
409}
410
721b8397 411void RegFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
bbf1f0e5 412{
721b8397 413 Close(true);
bbf1f0e5
KB
414}
415
721b8397 416void RegFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
bbf1f0e5 417{
721b8397 418 wxMessageDialog dialog(this,
9a83f860
VZ
419 wxT("wxRegistry sample\n")
420 wxT("(c) 1998, 2000 Vadim Zeitlin"),
421 wxT("About wxRegTest"), wxOK);
bbf1f0e5 422
721b8397 423 dialog.ShowModal();
bbf1f0e5
KB
424}
425
c41ea66a 426void RegFrame::OnTest(wxCommandEvent& WXUNUSED(event))
bbf1f0e5 427{
721b8397
DS
428#if DO_REGTEST
429 m_treeCtrl->OnMenuTest();
430#endif
bbf1f0e5
KB
431}
432
c41ea66a
VZ
433void RegFrame::OnGoTo(wxCommandEvent& WXUNUSED(event))
434{
9a83f860 435 static wxString s_location = wxT("HKEY_CURRENT_USER\\Software\\wxWidgets");
c41ea66a 436
721b8397 437 wxString location = wxGetTextFromUser(
9a83f860
VZ
438 wxT("Enter the location to go to:"),
439 wxT("wxRegTest question"),
721b8397
DS
440 s_location,
441 this);
442
c41ea66a
VZ
443 if ( !location )
444 return;
445
446 s_location = location;
721b8397 447#if DO_REGTEST
c41ea66a 448 m_treeCtrl->GoTo(location);
721b8397 449#endif
c41ea66a
VZ
450}
451
452void RegFrame::OnExpand(wxCommandEvent& WXUNUSED(event))
bbf1f0e5 453{
721b8397
DS
454#if DO_REGTEST
455 m_treeCtrl->Expand(m_treeCtrl->GetSelection());
456#endif
bbf1f0e5
KB
457}
458
c41ea66a 459void RegFrame::OnCollapse(wxCommandEvent& WXUNUSED(event))
bbf1f0e5 460{
721b8397
DS
461#if DO_REGTEST
462 m_treeCtrl->Collapse(m_treeCtrl->GetSelection());
463#endif
bbf1f0e5
KB
464}
465
c41ea66a 466void RegFrame::OnToggle(wxCommandEvent& WXUNUSED(event))
bbf1f0e5 467{
721b8397
DS
468#if DO_REGTEST
469 m_treeCtrl->Toggle(m_treeCtrl->GetSelection());
470#endif
bbf1f0e5
KB
471}
472
c41ea66a 473void RegFrame::OnRefresh(wxCommandEvent& WXUNUSED(event))
5888ef1e 474{
721b8397
DS
475#if DO_REGTEST
476 m_treeCtrl->DoRefresh();
477#endif
5888ef1e
VZ
478}
479
c41ea66a 480void RegFrame::OnDelete(wxCommandEvent& WXUNUSED(event))
bbf1f0e5 481{
721b8397
DS
482#if DO_REGTEST
483 m_treeCtrl->DeleteSelected();
484#endif
bbf1f0e5
KB
485}
486
c41ea66a 487void RegFrame::OnNewKey(wxCommandEvent& WXUNUSED(event))
bbf1f0e5 488{
721b8397
DS
489#if DO_REGTEST
490 if ( m_treeCtrl->IsKeySelected() )
491 {
492 m_treeCtrl->CreateNewKey(
9a83f860 493 wxGetTextFromUser(wxT("Enter the name of the new key")));
721b8397
DS
494 }
495#endif
bbf1f0e5
KB
496}
497
c41ea66a 498void RegFrame::OnNewText(wxCommandEvent& WXUNUSED(event))
bbf1f0e5 499{
721b8397
DS
500#if DO_REGTEST
501 if ( m_treeCtrl->IsKeySelected() )
502 {
503 m_treeCtrl->CreateNewTextValue(
9a83f860 504 wxGetTextFromUser(wxT("Enter the name for the new text value")));
721b8397
DS
505 }
506#endif
bbf1f0e5
KB
507}
508
c41ea66a 509void RegFrame::OnNewBinary(wxCommandEvent& WXUNUSED(event))
bbf1f0e5 510{
721b8397
DS
511#if DO_REGTEST
512 if ( m_treeCtrl->IsKeySelected() )
513 {
514 m_treeCtrl->CreateNewBinaryValue(
9a83f860 515 wxGetTextFromUser(wxT("Enter the name for the new binary value")));
721b8397
DS
516 }
517#endif
bbf1f0e5
KB
518}
519
c41ea66a 520void RegFrame::OnInfo(wxCommandEvent& WXUNUSED(event))
23f681ec 521{
721b8397 522#if DO_REGTEST
23f681ec 523 m_treeCtrl->ShowProperties();
721b8397 524#endif
23f681ec
VZ
525}
526
a5c46848
VZ
527void RegFrame::OnViewChange(wxCommandEvent& event)
528{
529#if DO_REGTEST
530 wxRegKey::WOW64ViewMode view;
531 switch ( event.GetId() )
532 {
533 case Menu_ViewDefault:
534 view = wxRegKey::WOW64ViewMode_Default;
535 break;
536
537 case Menu_View32:
538 view = wxRegKey::WOW64ViewMode_32;
539 break;
540
541 case Menu_View64:
542 view = wxRegKey::WOW64ViewMode_64;
543 break;
544
545 default:
546 wxFAIL_MSG("Unexpected event source for view change.");
547 return;
548 }
549
550 m_treeCtrl->SetRegistryView(view);
551#endif
552}
553
bbf1f0e5
KB
554// ----------------------------------------------------------------------------
555// RegImageList
556// ----------------------------------------------------------------------------
721b8397 557RegImageList::RegImageList() : wxImageList(16, 16, true)
bbf1f0e5 558{
721b8397 559 // should be in sync with enum RegImageList::RegIcon
9a83f860
VZ
560 static const wxChar *aszIcons[] = { wxT("key1"),wxT("key2"),wxT("key3"),wxT("value1"),wxT("value2") };
561 wxString str = wxT("icon_");
721b8397
DS
562 for ( unsigned int n = 0; n < WXSIZEOF(aszIcons); n++ )
563 {
564 Add(wxIcon(str + aszIcons[n], wxBITMAP_TYPE_ICO_RESOURCE));
565 }
bbf1f0e5
KB
566}
567
721b8397
DS
568#if DO_REGTEST
569
bbf1f0e5
KB
570// ----------------------------------------------------------------------------
571// RegTreeCtrl
572// ----------------------------------------------------------------------------
573
574// create a new tree item and insert it into the tree
a5c46848
VZ
575RegTreeCtrl::TreeNode *RegTreeCtrl::InsertNewTreeNode(
576 TreeNode *pParent,
577 const wxString& strName,
578 int idImage,
579 const wxString *pstrValue,
580 wxRegKey::WOW64ViewMode viewMode)
bbf1f0e5 581{
721b8397
DS
582 // create new item & insert it
583 TreeNode *pNewNode = new TreeNode;
584 pNewNode->m_pTree = this;
585 pNewNode->m_pParent = pParent;
586 pNewNode->m_strName = strName;
587 pNewNode->m_bKey = pstrValue == NULL;
588 pNewNode->m_pKey = NULL;
a5c46848 589 pNewNode->m_viewMode = viewMode;
721b8397
DS
590 if (pParent)
591 {
592 pNewNode->m_id = AppendItem(pParent->Id(),
593 pNewNode->IsKey() ? strName : *pstrValue,
594 idImage);
595 }
596 else
597 {
598 pNewNode->m_id = AddRoot(strName);
599 }
600
601 wxASSERT_MSG( pNewNode->m_id, wxT("can't create tree control item!"));
602
603 // save the pointer in the item
604 SetItemData(pNewNode->m_id, pNewNode);
605
606 // add it to the list of parent's children
607 if ( pParent != NULL )
608 {
609 pParent->m_aChildren.Add(pNewNode);
610 }
611
612 if ( pNewNode->IsKey() )
613 {
614 SetItemHasChildren(pNewNode->Id());
615
616 if ( !pNewNode->IsRoot() )
617 {
618 // set the expanded icon as well
619 SetItemImage(pNewNode->Id(),
620 RegImageList::OpenedKey,
621 wxTreeItemIcon_Expanded);
622 }
23f681ec 623 }
bbf1f0e5 624
721b8397 625 return pNewNode;
bbf1f0e5
KB
626}
627
628RegTreeCtrl::RegTreeCtrl(wxWindow *parent, wxWindowID id)
721b8397
DS
629 : wxTreeCtrl(parent, id, wxDefaultPosition, wxDefaultSize,
630 wxTR_HAS_BUTTONS | wxTR_EDIT_LABELS | wxSUNKEN_BORDER)
bbf1f0e5 631{
721b8397
DS
632 // init members
633 m_draggedItem = NULL;
634 m_restoreStatus = false;
a5c46848 635 m_viewMode = wxRegKey::WOW64ViewMode_Default;
721b8397
DS
636
637 // create the image list
638 // ---------------------
639 m_imageList = new RegImageList;
640 SetImageList(m_imageList);
641
642 // create root keys
643 // ----------------
a5c46848
VZ
644 m_pRoot =
645 InsertNewTreeNode(
646 NULL,
647 wxT("Registry Root"),
648 RegImageList::Root,
649 NULL,
650 m_viewMode);
721b8397
DS
651
652 // create popup menu
653 // -----------------
654 m_pMenuPopup = CreateRegistryMenu();
bbf1f0e5
KB
655}
656
657RegTreeCtrl::~RegTreeCtrl()
658{
721b8397
DS
659 delete m_pMenuPopup;
660 // delete m_pRoot; -- this is done by the tree now
661 delete m_imageList;
bbf1f0e5
KB
662}
663
664void RegTreeCtrl::AddStdKeys()
665{
721b8397
DS
666 for ( unsigned int ui = 0; ui < wxRegKey::nStdKeys; ui++ )
667 {
a5c46848
VZ
668 InsertNewTreeNode(
669 m_pRoot,
670 wxRegKey::GetStdKeyName(ui),
671 RegImageList::ClosedKey,
672 NULL,
673 m_viewMode);
721b8397 674 }
bbf1f0e5
KB
675}
676
677// ----------------------------------------------------------------------------
678// notifications
679// ----------------------------------------------------------------------------
680
23f681ec
VZ
681void RegTreeCtrl::OnIdle(wxIdleEvent& WXUNUSED(event))
682{
721b8397
DS
683 if ( m_restoreStatus )
684 {
23f681ec 685 // restore it after OnItemExpanding()
a60b1f5d 686 wxLogStatus(wxT("Ok"));
23f681ec
VZ
687 wxSetCursor(*wxSTANDARD_CURSOR);
688
721b8397 689 m_restoreStatus = false;
23f681ec
VZ
690 }
691}
692
bbf1f0e5
KB
693void RegTreeCtrl::OnRightClick(wxMouseEvent& event)
694{
721b8397 695 int iFlags;
945d96f6 696 wxTreeItemId lId = HitTest(wxPoint(event.GetX(), event.GetY()), iFlags);
721b8397
DS
697 if ( iFlags & wxTREE_HITTEST_ONITEMLABEL )
698 {
699 // select the item first
700 SelectItem(lId);
701 }
702 //else: take the currently selected item if click not on item
703
704 PopupMenu(m_pMenuPopup, event.GetX(), event.GetY());
bbf1f0e5
KB
705}
706
707
721b8397 708void RegTreeCtrl::OnDeleteItem(wxTreeEvent& WXUNUSED(event))
bbf1f0e5
KB
709{
710}
711
712// test the key creation functions
713void RegTreeCtrl::OnMenuTest()
714{
945d96f6 715 wxTreeItemId lId = GetSelection();
721b8397
DS
716 TreeNode *pNode = (TreeNode *)GetItemData(lId);
717
718 wxCHECK_RET( pNode != NULL, wxT("tree item without data?") );
719
720 if ( pNode->IsRoot() )
721 {
722 wxLogError(wxT("Can't create a subkey under the root key."));
723 return;
724 }
725
726 if ( !pNode->IsKey() )
727 {
728 wxLogError(wxT("Can't create a subkey under a value!"));
729 return;
730 }
731
9a83f860 732 wxRegKey key1(pNode->Key(), wxT("key1"));
721b8397
DS
733 if ( key1.Create() )
734 {
9a83f860 735 wxRegKey key2a(key1, wxT("key2a")), key2b(key1, wxT("key2b"));
721b8397
DS
736 if ( key2a.Create() && key2b.Create() )
737 {
738 // put some values under the newly created keys
9a83f860
VZ
739 key1.SetValue(wxT("first_term"), wxT("10"));
740 key1.SetValue(wxT("second_term"), wxT("7"));
741 key2a = wxT("this is the unnamed value");
721b8397
DS
742 key2b.SetValue(wxT("sum"), 17);
743
744 // refresh tree
745 pNode->Refresh();
746 wxLogStatus(wxT("Test keys successfully added."));
747 return;
748 }
bbf1f0e5 749 }
23f681ec 750
721b8397 751 wxLogError(wxT("Creation of test keys failed."));
bbf1f0e5
KB
752}
753
754void RegTreeCtrl::OnChar(wxKeyEvent& event)
755{
721b8397
DS
756 switch ( event.GetKeyCode() )
757 {
758 case WXK_DELETE:
759 DeleteSelected();
760 return;
761
762 case WXK_RETURN:
763 if ( event.AltDown() )
764 {
765 ShowProperties();
766
767 return;
768 }
769 }
770
771 event.Skip();
bbf1f0e5
KB
772}
773
774void RegTreeCtrl::OnSelChanged(wxTreeEvent& event)
775{
8520f137 776#if wxUSE_STATUSBAR
721b8397
DS
777 wxFrame *pFrame = (wxFrame *) wxWindow::GetParent();
778 pFrame->SetStatusText(GetNode(event)->FullName(), 1);
8520f137
WS
779#else
780 wxUnusedVar(event);
781#endif // wxUSE_STATUSBAR
bbf1f0e5
KB
782}
783
784void RegTreeCtrl::OnItemExpanding(wxTreeEvent& event)
785{
721b8397 786 TreeNode *pNode = GetNode(event);
419c2241 787 bool bExpanding = event.GetEventType() == wxEVT_COMMAND_TREE_ITEM_EXPANDING;
721b8397
DS
788
789 // expansion might take some time
790 wxSetCursor(*wxHOURGLASS_CURSOR);
791 wxLogStatus(wxT("Working..."));
792 wxYield(); // to give the status line a chance to refresh itself
793 m_restoreStatus = true; // some time later...
794
795 if ( pNode->IsKey() )
796 {
797 if ( bExpanding )
798 {
799 // expanding: add subkeys/values
800 if ( !pNode->OnExpand() )
801 return;
802 }
803 else
804 {
805 // collapsing: clean up
806 pNode->OnCollapse();
807 }
bbf1f0e5 808 }
23f681ec
VZ
809}
810
c41ea66a
VZ
811void RegTreeCtrl::OnBeginEdit(wxTreeEvent& event)
812{
813 TreeNode *pNode = GetNode(event);
721b8397
DS
814 if ( pNode->IsRoot() || pNode->Parent()->IsRoot() )
815 {
9a83f860 816 wxLogStatus(wxT("This registry key can't be renamed."));
c41ea66a
VZ
817
818 event.Veto();
819 }
721b8397
DS
820 else
821 {
c41ea66a
VZ
822 m_nameOld = pNode->m_strName;
823 }
824}
825
826void RegTreeCtrl::OnEndEdit(wxTreeEvent& event)
827{
828 bool ok;
829
830 wxString name = event.GetLabel();
831
832 TreeNode *pNode = GetNode(event);
833 if ( pNode->IsKey() )
834 {
835 wxRegKey& key = pNode->Key();
836 ok = key.Rename(name);
837 }
838 else
839 {
840 pNode = pNode->Parent();
841 wxRegKey& key = pNode->Key();
842
843 ok = key.RenameValue(m_nameOld, name);
844 }
845
721b8397
DS
846 if ( !ok )
847 {
9a83f860 848 wxLogError(wxT("Failed to rename '%s' to '%s'."),
721b8397 849 m_nameOld.c_str(), name.c_str());
c41ea66a
VZ
850 }
851#if 0 // MSW tree ctrl doesn't like this at all, it hangs
721b8397
DS
852 else
853 {
c41ea66a
VZ
854 pNode->Refresh();
855 }
856#endif // 0
857}
858
23f681ec
VZ
859void RegTreeCtrl::OnBeginDrag(wxTreeEvent& event)
860{
861 m_copyOnDrop = event.GetEventType() == wxEVT_COMMAND_TREE_BEGIN_DRAG;
862
863 TreeNode *pNode = GetNode(event);
864 if ( pNode->IsRoot() || pNode->Parent()->IsRoot() )
865 {
a60b1f5d 866 wxLogStatus(wxT("This registry key can't be %s."),
721b8397 867 m_copyOnDrop ? wxT("copied") : wxT("moved"));
23f681ec
VZ
868 }
869 else
870 {
a60b1f5d 871 wxLogStatus(wxT("%s item %s..."),
721b8397
DS
872 m_copyOnDrop ? wxT("Copying") : wxT("Moving"),
873 pNode->FullName());
bbf1f0e5 874
23f681ec
VZ
875 m_draggedItem = pNode;
876
877 event.Allow();
878 }
879}
880
881void RegTreeCtrl::OnEndDrag(wxTreeEvent& event)
882{
a60b1f5d 883 wxCHECK_RET( m_draggedItem, wxT("end drag without begin drag?") );
23f681ec
VZ
884
885 // clear the pointer anyhow
886 TreeNode *src = m_draggedItem;
887 m_draggedItem = NULL;
888
889 // where are we going to drop it?
890 TreeNode *dst = GetNode(event);
721b8397
DS
891 if ( dst && !dst->IsKey() )
892 {
23f681ec
VZ
893 // we need a parent key
894 dst = dst->Parent();
895 }
721b8397
DS
896
897 if ( !dst || dst->IsRoot() )
898 {
a60b1f5d 899 wxLogError(wxT("Can't create a key here."));
23f681ec
VZ
900
901 return;
902 }
903
904 bool isKey = src->IsKey();
905 if ( (isKey && (src == dst)) ||
5888ef1e 906 (!isKey && (dst->Parent() == src)) ) {
a60b1f5d 907 wxLogStatus(wxT("Can't copy something on itself"));
23f681ec
VZ
908
909 return;
910 }
911
912 // remove the "Registry Root\\" from the full name
913 wxString nameSrc, nameDst;
914 nameSrc << wxString(src->FullName()).AfterFirst('\\');
915 nameDst << wxString(dst->FullName()).AfterFirst('\\') << '\\'
916 << wxString(src->FullName()).AfterLast('\\');
917
9a83f860
VZ
918 wxString verb = m_copyOnDrop ? wxT("copy") : wxT("move");
919 wxString what = isKey ? wxT("key") : wxT("value");
23f681ec
VZ
920
921 if ( wxMessageBox(wxString::Format
922 (
a60b1f5d 923 wxT("Do you really want to %s the %s %s to %s?"),
23f681ec
VZ
924 verb.c_str(),
925 what.c_str(),
926 nameSrc.c_str(),
927 nameDst.c_str()
928 ),
9a83f860 929 wxT("RegTest Confirm"),
23f681ec
VZ
930 wxICON_QUESTION | wxYES_NO | wxCANCEL, this) != wxYES ) {
931 return;
932 }
933
23f681ec 934 bool ok;
721b8397
DS
935 if ( isKey )
936 {
23f681ec 937 wxRegKey& key = src->Key();
5888ef1e 938 wxRegKey keyDst(dst->Key(), src->m_strName);
721b8397
DS
939 ok = keyDst.Create(false);
940 if ( !ok )
941 {
2b5f62a0 942 wxLogError(wxT("Key '%s' already exists"), keyDst.GetName().c_str());
5888ef1e 943 }
721b8397
DS
944 else
945 {
5888ef1e
VZ
946 ok = key.Copy(keyDst);
947 }
23f681ec 948
721b8397
DS
949 if ( ok && !m_copyOnDrop )
950 {
23f681ec
VZ
951 // delete the old key
952 ok = key.DeleteSelf();
721b8397
DS
953 if ( ok )
954 {
23f681ec
VZ
955 src->Parent()->Refresh();
956 }
957 }
958 }
721b8397
DS
959 else // value
960 {
23f681ec
VZ
961 wxRegKey& key = src->Parent()->Key();
962 ok = key.CopyValue(src->m_strName, dst->Key());
721b8397
DS
963 if ( ok && !m_copyOnDrop )
964 {
5888ef1e 965 // we moved it, so delete the old one
23f681ec 966 ok = key.DeleteValue(src->m_strName);
23f681ec 967 }
bbf1f0e5 968 }
bbf1f0e5 969
721b8397
DS
970 if ( !ok )
971 {
a60b1f5d
MB
972 wxLogError(wxT("Failed to %s registry %s."),
973 verb.c_str(), what.c_str());
23f681ec 974 }
721b8397
DS
975 else
976 {
c41ea66a
VZ
977 dst->Refresh();
978 }
bbf1f0e5
KB
979}
980
981// ----------------------------------------------------------------------------
982// TreeNode implementation
983// ----------------------------------------------------------------------------
984bool RegTreeCtrl::TreeNode::OnExpand()
985{
721b8397
DS
986 // we add children only once
987 if ( !m_aChildren.IsEmpty() )
988 {
989 // we've been already expanded
990 return true;
991 }
992
993 if ( IsRoot() )
994 {
995 // we're the root key
996 m_pTree->AddStdKeys();
997 return true;
998 }
999
1000 if ( Parent()->IsRoot() )
1001 {
1002 // we're a standard key
a5c46848 1003 m_pKey = new wxRegKey(m_strName, m_viewMode);
721b8397 1004 }
bbf1f0e5 1005 else
721b8397
DS
1006 {
1007 // we're a normal key
1008 m_pKey = new wxRegKey(*(Parent()->m_pKey), m_strName);
1009 }
1010
1011 if ( !m_pKey->Open() )
1012 {
1013 wxLogError(wxT("The key '%s' can't be opened."), FullName());
1014 return false;
1015 }
1016
1017 // if we're empty, we shouldn't be expandable at all
1018 bool isEmpty = true;
1019
1020 // enumeration variables
1021 long l;
1022 wxString str;
1023 bool bCont;
1024
1025 // enumerate all subkeys
1026 bCont = m_pKey->GetFirstKey(str, l);
1027 while ( bCont )
1028 {
a5c46848
VZ
1029 m_pTree->InsertNewTreeNode(
1030 this,
1031 str,
1032 RegImageList::ClosedKey,
1033 NULL,
1034 m_viewMode);
721b8397
DS
1035 bCont = m_pKey->GetNextKey(str, l);
1036
1037 // we have at least this key...
1038 isEmpty = false;
1039 }
1040
1041 // enumerate all values
1042 bCont = m_pKey->GetFirstValue(str, l);
1043 while ( bCont )
1044 {
1045 wxString strItem;
8afd90d5 1046 if (str.empty())
9a83f860 1047 strItem = wxT("<default>");
721b8397
DS
1048 else
1049 strItem = str;
9a83f860 1050 strItem += wxT(" = ");
721b8397
DS
1051
1052 // determine the appropriate icon
1053 RegImageList::Icon icon;
1054 switch ( m_pKey->GetValueType(str) )
bbf1f0e5 1055 {
721b8397
DS
1056 case wxRegKey::Type_String:
1057 case wxRegKey::Type_Expand_String:
1058 case wxRegKey::Type_Multi_String:
1059 {
1060 wxString strValue;
1061 icon = RegImageList::TextValue;
1062 m_pKey->QueryValue(str, strValue);
1063 strItem += strValue;
bbf1f0e5
KB
1064 }
1065 break;
1066
721b8397
DS
1067 case wxRegKey::Type_None:
1068 // @@ handle the error...
1069 icon = RegImageList::BinaryValue;
1070 break;
bbf1f0e5 1071
721b8397 1072 case wxRegKey::Type_Dword:
bbf1f0e5 1073 {
721b8397
DS
1074 long l;
1075 m_pKey->QueryValue(str, &l);
1076 strItem << l;
bbf1f0e5
KB
1077 }
1078
1079 // fall through
1080
721b8397
DS
1081 default:
1082 icon = RegImageList::BinaryValue;
1083 }
bbf1f0e5 1084
a5c46848 1085 m_pTree->InsertNewTreeNode(this, str, icon, &strItem, m_viewMode);
721b8397 1086 bCont = m_pKey->GetNextValue(str, l);
23f681ec 1087
721b8397
DS
1088 // we have at least this value...
1089 isEmpty = false;
1090 }
23f681ec 1091
721b8397
DS
1092 if ( isEmpty )
1093 {
1094 // this is for the case when our last child was just deleted
1095 wxTreeItemId theId(Id()); // Temp variable seems necessary for BC++
1096 m_pTree->Collapse(theId);
23f681ec 1097
721b8397
DS
1098 // we won't be expanded any more
1099 m_pTree->SetItemHasChildren(theId, false);
1100 }
bbf1f0e5 1101
721b8397 1102 return true;
bbf1f0e5
KB
1103}
1104
1105void RegTreeCtrl::TreeNode::OnCollapse()
1106{
721b8397 1107 DestroyChildren();
bbf1f0e5 1108
5276b0a5 1109 wxDELETE(m_pKey);
bbf1f0e5
KB
1110}
1111
23f681ec
VZ
1112void RegTreeCtrl::TreeNode::Refresh()
1113{
5888ef1e
VZ
1114 if ( !IsKey() )
1115 return;
1116
f6bcfd97
BP
1117 wxTreeItemId theId(Id()); // Temp variable seems necessary for BC++
1118 bool wasExpanded = m_pTree->IsExpanded(theId);
c41ea66a 1119 if ( wasExpanded )
f6bcfd97 1120 m_pTree->Collapse(theId);
c41ea66a
VZ
1121
1122 OnCollapse();
f6bcfd97 1123 m_pTree->SetItemHasChildren(theId);
721b8397
DS
1124 if ( wasExpanded )
1125 {
f6bcfd97 1126 m_pTree->Expand(theId);
5888ef1e
VZ
1127 OnExpand();
1128 }
23f681ec
VZ
1129}
1130
1131bool RegTreeCtrl::TreeNode::DeleteChild(TreeNode *child)
bbf1f0e5 1132{
23f681ec 1133 int index = m_aChildren.Index(child);
721b8397 1134 wxCHECK_MSG( index != wxNOT_FOUND, false,
a60b1f5d 1135 wxT("our child in tree should be in m_aChildren") );
23f681ec
VZ
1136
1137 m_aChildren.RemoveAt((size_t)index);
1138
1139 bool ok;
721b8397
DS
1140 if ( child->IsKey() )
1141 {
23f681ec
VZ
1142 // must close key before deleting it
1143 child->OnCollapse();
1144
1145 ok = Key().DeleteKey(child->m_strName);
1146 }
721b8397
DS
1147 else
1148 {
23f681ec
VZ
1149 ok = Key().DeleteValue(child->m_strName);
1150 }
1151
721b8397
DS
1152 if ( ok )
1153 {
f6bcfd97
BP
1154 wxTreeItemId theId(child->Id()); // Temp variable seems necessary for BC++
1155 m_pTree->Delete(theId);
23f681ec
VZ
1156
1157 Refresh();
1158 }
1159
1160 return ok;
bbf1f0e5
KB
1161}
1162
1163void RegTreeCtrl::TreeNode::DestroyChildren()
1164{
721b8397
DS
1165 // destroy all children
1166 size_t nCount = m_aChildren.GetCount();
1167 for ( size_t n = 0; n < nCount; n++ )
1168 {
945d96f6
WS
1169 wxTreeItemId lId = m_aChildren[n]->Id();
1170 m_pTree->Delete(lId);
721b8397
DS
1171 }
1172
1173 m_aChildren.Empty();
bbf1f0e5
KB
1174}
1175
1176RegTreeCtrl::TreeNode::~TreeNode()
1177{
721b8397 1178 delete m_pKey;
bbf1f0e5
KB
1179}
1180
a60b1f5d 1181const wxChar *RegTreeCtrl::TreeNode::FullName() const
bbf1f0e5 1182{
721b8397
DS
1183 static wxString s_strName;
1184
1185 if ( IsRoot() )
1186 {
1187 return wxT("Registry Root");
1188 }
1189 else
1190 {
1191 // our own registry key might not (yet) exist or we might be a value,
1192 // so just use the parent's and concatenate
1193 s_strName = Parent()->FullName();
1194 s_strName << wxT('\\') << m_strName;
1195
7e3ea54f 1196 return s_strName.t_str();
721b8397 1197 }
bbf1f0e5
KB
1198}
1199
a5c46848
VZ
1200void RegTreeCtrl::TreeNode::SetRegistryView(wxRegKey::WOW64ViewMode viewMode)
1201{
1202 m_viewMode = viewMode;
1203
1204 // Update children with new view.
1205 size_t nCount = m_aChildren.GetCount();
1206 for (size_t n = 0; n < nCount; n++)
1207 m_aChildren[n]->SetRegistryView(viewMode);
1208}
1209
bbf1f0e5
KB
1210// ----------------------------------------------------------------------------
1211// operations on RegTreeCtrl
1212// ----------------------------------------------------------------------------
1213
c41ea66a
VZ
1214void RegTreeCtrl::GoTo(const wxString& location)
1215{
9a83f860 1216 wxStringTokenizer tk(location, wxT("\\"));
c41ea66a
VZ
1217
1218 wxTreeItemId id = GetRootItem();
1219
721b8397
DS
1220 while ( tk.HasMoreTokens() )
1221 {
c41ea66a
VZ
1222 wxString subkey = tk.GetNextToken();
1223
1224 wxTreeItemId idCurrent = id;
1225 if ( !IsExpanded(idCurrent) )
1226 Expand(idCurrent);
1227
721b8397 1228 wxTreeItemIdValue dummy;
c41ea66a
VZ
1229 id = GetFirstChild(idCurrent, dummy);
1230
721b8397
DS
1231 if ( idCurrent == GetRootItem() )
1232 {
c41ea66a 1233 // special case: we understand both HKCU and HKEY_CURRENT_USER here
721b8397
DS
1234 for ( size_t key = 0; key < wxRegKey::nStdKeys; key++ )
1235 {
1236 if ( subkey == wxRegKey::GetStdKeyName(key)
1237 || subkey == wxRegKey::GetStdKeyShortName(key) )
1238 {
c41ea66a
VZ
1239 break;
1240 }
1241
1242 id = GetNextChild(idCurrent, dummy);
1243 }
1244 }
721b8397
DS
1245 else
1246 {
c41ea66a 1247 // enum all children
721b8397
DS
1248 while ( id.IsOk() )
1249 {
c41ea66a
VZ
1250 if ( subkey == ((TreeNode *)GetItemData(id))->m_strName )
1251 break;
1252
1253 id = GetNextChild(idCurrent, dummy);
1254 }
1255 }
1256
721b8397
DS
1257 if ( !id.IsOk() )
1258 {
9a83f860 1259 wxLogError(wxT("No such key '%s'."), location.c_str());
c41ea66a
VZ
1260
1261 return;
1262 }
1263 }
1264
1265 if ( id.IsOk() )
1266 SelectItem(id);
1267}
1268
bbf1f0e5
KB
1269void RegTreeCtrl::DeleteSelected()
1270{
945d96f6
WS
1271 wxTreeItemId lCurrent = GetSelection(),
1272 lParent = GetItemParent(lCurrent);
721b8397 1273
945d96f6 1274 if ( lParent == GetRootItem() )
721b8397
DS
1275 {
1276 wxLogError(wxT("Can't delete root key."));
1277 return;
1278 }
1279
1280 TreeNode *pCurrent = (TreeNode *)GetItemData(lCurrent),
945d96f6 1281 *pParent = (TreeNode *)GetItemData(lParent);
721b8397
DS
1282
1283 wxCHECK_RET(pCurrent && pParent, wxT("either node or parent without data?"));
1284
1285 if ( pParent->IsRoot() )
1286 {
1287 wxLogError(wxT("Can't delete standard key."));
1288 return;
1289 }
1290
9a83f860 1291 wxString what = pCurrent->IsKey() ? wxT("key") : wxT("value");
721b8397
DS
1292 if ( wxMessageBox(wxString::Format
1293 (
1294 wxT("Do you really want to delete this %s?"),
1295 what.c_str()
1296 ),
9a83f860 1297 wxT("Confirmation"),
721b8397
DS
1298 wxICON_QUESTION | wxYES_NO | wxCANCEL, this) != wxYES )
1299 {
1300 return;
1301 }
1302
1303 pParent->DeleteChild(pCurrent);
bbf1f0e5
KB
1304}
1305
1306void RegTreeCtrl::CreateNewKey(const wxString& strName)
1307{
945d96f6 1308 wxTreeItemId lCurrent = GetSelection();
721b8397 1309 TreeNode *pCurrent = (TreeNode *)GetItemData(lCurrent);
bbf1f0e5 1310
721b8397 1311 wxCHECK_RET( pCurrent != NULL, wxT("node without data?") );
23f681ec 1312
721b8397 1313 wxASSERT( pCurrent->IsKey() ); // check must have been done before
bbf1f0e5 1314
721b8397
DS
1315 if ( pCurrent->IsRoot() )
1316 {
1317 wxLogError(wxT("Can't create a new key under the root key."));
1318 return;
1319 }
bbf1f0e5 1320
721b8397
DS
1321 wxRegKey key(pCurrent->Key(), strName);
1322 if ( key.Create() )
1323 pCurrent->Refresh();
bbf1f0e5
KB
1324}
1325
1326void RegTreeCtrl::CreateNewTextValue(const wxString& strName)
1327{
945d96f6 1328 wxTreeItemId lCurrent = GetSelection();
721b8397 1329 TreeNode *pCurrent = (TreeNode *)GetItemData(lCurrent);
bbf1f0e5 1330
721b8397 1331 wxCHECK_RET( pCurrent != NULL, wxT("node without data?") );
23f681ec 1332
721b8397 1333 wxASSERT( pCurrent->IsKey() ); // check must have been done before
bbf1f0e5 1334
721b8397
DS
1335 if ( pCurrent->IsRoot() )
1336 {
1337 wxLogError(wxT("Can't create a new value under the root key."));
1338 return;
1339 }
bbf1f0e5 1340
721b8397
DS
1341 if ( pCurrent->Key().SetValue(strName, wxEmptyString) )
1342 pCurrent->Refresh();
bbf1f0e5
KB
1343}
1344
1345void RegTreeCtrl::CreateNewBinaryValue(const wxString& strName)
1346{
945d96f6 1347 wxTreeItemId lCurrent = GetSelection();
721b8397 1348 TreeNode *pCurrent = (TreeNode *)GetItemData(lCurrent);
bbf1f0e5 1349
721b8397 1350 wxCHECK_RET( pCurrent != NULL, wxT("node without data?") );
23f681ec 1351
721b8397 1352 wxASSERT( pCurrent->IsKey() ); // check must have been done before
bbf1f0e5 1353
721b8397
DS
1354 if ( pCurrent->IsRoot() )
1355 {
1356 wxLogError(wxT("Can't create a new value under the root key."));
1357 return;
1358 }
bbf1f0e5 1359
721b8397
DS
1360 if ( pCurrent->Key().SetValue(strName, 0) )
1361 pCurrent->Refresh();
bbf1f0e5
KB
1362}
1363
a5c46848
VZ
1364void RegTreeCtrl::SetRegistryView(wxRegKey::WOW64ViewMode viewMode)
1365{
1366 m_viewMode = viewMode;
1367 m_pRoot->SetRegistryView(viewMode);
1368 m_pRoot->Refresh();
1369}
1370
23f681ec
VZ
1371void RegTreeCtrl::ShowProperties()
1372{
945d96f6 1373 wxTreeItemId lCurrent = GetSelection();
23f681ec
VZ
1374 TreeNode *pCurrent = (TreeNode *)GetItemData(lCurrent);
1375
1376 if ( !pCurrent || pCurrent->IsRoot() )
1377 {
a60b1f5d 1378 wxLogStatus(wxT("No properties"));
23f681ec
VZ
1379
1380 return;
1381 }
1382
1383 if ( pCurrent->IsKey() )
1384 {
1385 const wxRegKey& key = pCurrent->Key();
1386 size_t nSubKeys, nValues;
1387 if ( !key.GetKeyInfo(&nSubKeys, NULL, &nValues, NULL) )
1388 {
a60b1f5d 1389 wxLogError(wxT("Couldn't get key info"));
23f681ec
VZ
1390 }
1391 else
1392 {
a60b1f5d 1393 wxLogMessage(wxT("Key '%s' has %u subkeys and %u values."),
23f681ec
VZ
1394 key.GetName().c_str(), nSubKeys, nValues);
1395 }
1396 }
1397 else // it's a value
1398 {
1399 TreeNode *parent = pCurrent->Parent();
a60b1f5d 1400 wxCHECK_RET( parent, wxT("reg value without key?") );
23f681ec
VZ
1401
1402 const wxRegKey& key = parent->Key();
a60b1f5d
MB
1403 const wxChar *value = pCurrent->m_strName.c_str();
1404 wxLogMessage(wxT("Value '%s' under the key '%s' is of type ")
721b8397
DS
1405 wxT("%d (%s)."),
1406 value,
1407 parent->m_strName.c_str(),
1408 key.GetValueType(value),
1409 key.IsNumericValue(value) ? wxT("numeric") : wxT("string"));
23f681ec
VZ
1410
1411 }
1412}
1413
bbf1f0e5
KB
1414bool RegTreeCtrl::IsKeySelected() const
1415{
945d96f6 1416 wxTreeItemId lCurrent = GetSelection();
721b8397 1417 TreeNode *pCurrent = (TreeNode *) GetItemData(lCurrent);
bbf1f0e5 1418
721b8397 1419 wxCHECK( pCurrent != NULL, false );
bbf1f0e5 1420
721b8397 1421 return pCurrent->IsKey();
23f681ec 1422}
5888ef1e 1423
721b8397 1424void RegTreeCtrl::DoRefresh()
5888ef1e 1425{
945d96f6 1426 wxTreeItemId lId = GetSelection();
5888ef1e
VZ
1427 if ( !lId )
1428 return;
1429
721b8397 1430 TreeNode *pNode = (TreeNode *) GetItemData(lId);
5888ef1e 1431
a60b1f5d 1432 wxCHECK_RET( pNode != NULL, wxT("tree item without data?") );
5888ef1e
VZ
1433
1434 pNode->Refresh();
1435}
1436
721b8397 1437#endif