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