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