]> git.saurik.com Git - wxWidgets.git/blob - utils/configtool/src/configtoolview.cpp
Added Find dialog
[wxWidgets.git] / utils / configtool / src / configtoolview.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: configtoolview.cpp
3 // Purpose: View class
4 // Author: Julian Smart
5 // Modified by:
6 // Created: 2003-06-04
7 // RCS-ID: $Id$
8 // Copyright: (c) Julian Smart
9 // Licence:
10 /////////////////////////////////////////////////////////////////////////////
11
12 #ifdef __GNUG__
13 #pragma implementation "configtoolview.h"
14 #endif
15
16 // Includes other headers for precompiled compilation
17 #include "wx/wx.h"
18
19 #ifdef __BORLANDC__
20 #pragma hdrstop
21 #endif
22
23 #include "wx/wfstream.h"
24
25 #include "configtoolview.h"
26 #include "configtooldoc.h"
27 #include "configtree.h"
28 #include "wxconfigtool.h"
29 #include "mainframe.h"
30 #include "propeditor.h"
31 #include "utils.h"
32 #include "custompropertydialog.h"
33
34 IMPLEMENT_DYNAMIC_CLASS(ctConfigToolView, wxView)
35
36 BEGIN_EVENT_TABLE(ctConfigToolView, wxView)
37 EVT_MENU(ctID_ADD_ITEM_CHECKBOX, ctConfigToolView::OnAddCheckBoxItem)
38 EVT_MENU(ctID_ADD_ITEM_RADIOBUTTON, ctConfigToolView::OnAddRadioButtonItem)
39 EVT_MENU(ctID_ADD_ITEM_GROUP, ctConfigToolView::OnAddGroupItem)
40 EVT_MENU(ctID_ADD_ITEM_CHECK_GROUP, ctConfigToolView::OnAddCheckGroupItem)
41 EVT_MENU(ctID_ADD_ITEM_RADIO_GROUP, ctConfigToolView::OnAddRadioGroupItem)
42 EVT_MENU(ctID_ADD_ITEM_STRING, ctConfigToolView::OnAddStringItem)
43 EVT_MENU(ctID_RENAME_ITEM, ctConfigToolView::OnRenameItem)
44 EVT_MENU(ctID_DELETE_ITEM, ctConfigToolView::OnDeleteItem)
45
46 EVT_MENU(wxID_COPY, ctConfigToolView::OnCopy)
47 EVT_MENU(wxID_CUT, ctConfigToolView::OnCut)
48 EVT_MENU(wxID_PASTE, ctConfigToolView::OnPaste)
49
50 EVT_UPDATE_UI(wxID_COPY, ctConfigToolView::OnUpdateCopy)
51 EVT_UPDATE_UI(wxID_CUT, ctConfigToolView::OnUpdateCut)
52 EVT_UPDATE_UI(wxID_PASTE, ctConfigToolView::OnUpdatePaste)
53
54 EVT_MENU(ctID_ITEM_HELP, ctConfigToolView::OnItemHelp)
55
56 EVT_UPDATE_UI(ctID_ADD_ITEM_CHECKBOX, ctConfigToolView::OnUpdateAddItem)
57 EVT_UPDATE_UI(ctID_ADD_ITEM_RADIOBUTTON, ctConfigToolView::OnUpdateAddItem)
58 EVT_UPDATE_UI(ctID_ADD_ITEM_GROUP, ctConfigToolView::OnUpdateAddItem)
59 EVT_UPDATE_UI(ctID_ADD_ITEM_CHECK_GROUP, ctConfigToolView::OnUpdateAddItem)
60 EVT_UPDATE_UI(ctID_ADD_ITEM_RADIO_GROUP, ctConfigToolView::OnUpdateAddItem)
61 EVT_UPDATE_UI(ctID_ADD_ITEM_STRING, ctConfigToolView::OnUpdateAddItem)
62 EVT_UPDATE_UI(ctID_RENAME_ITEM, ctConfigToolView::OnUpdateCut)
63 EVT_UPDATE_UI(ctID_DELETE_ITEM, ctConfigToolView::OnUpdateCut)
64 EVT_UPDATE_UI(ctID_ITEM_HELP, ctConfigToolView::OnUpdateItemHelp)
65
66 EVT_MENU(ctID_TREE_COPY, ctConfigToolView::OnContextCopy)
67 EVT_MENU(ctID_TREE_CUT, ctConfigToolView::OnContextCut)
68 EVT_MENU(ctID_TREE_PASTE_BEFORE, ctConfigToolView::OnContextPasteBefore)
69 EVT_MENU(ctID_TREE_PASTE_AFTER, ctConfigToolView::OnContextPasteAfter)
70 EVT_MENU(ctID_TREE_PASTE_AS_CHILD, ctConfigToolView::OnContextPasteAsChild)
71 EVT_UPDATE_UI(ctID_TREE_COPY, ctConfigToolView::OnUpdateContextCopy)
72 EVT_UPDATE_UI(ctID_TREE_CUT, ctConfigToolView::OnUpdateContextCut)
73 EVT_UPDATE_UI(ctID_TREE_PASTE_BEFORE, ctConfigToolView::OnUpdateContextPasteBefore)
74 EVT_UPDATE_UI(ctID_TREE_PASTE_AFTER, ctConfigToolView::OnUpdateContextPasteAfter)
75 EVT_UPDATE_UI(ctID_TREE_PASTE_AS_CHILD, ctConfigToolView::OnUpdateContextPasteAsChild)
76
77 EVT_MENU(ctID_ADD_CUSTOM_PROPERTY, ctConfigToolView::OnAddCustomProperty)
78 EVT_MENU(ctID_EDIT_CUSTOM_PROPERTY, ctConfigToolView::OnEditCustomProperty)
79 EVT_MENU(ctID_DELETE_CUSTOM_PROPERTY, ctConfigToolView::OnDeleteCustomProperty)
80 EVT_UPDATE_UI(ctID_ADD_CUSTOM_PROPERTY, ctConfigToolView::OnUpdateAddCustomProperty)
81 EVT_UPDATE_UI(ctID_EDIT_CUSTOM_PROPERTY, ctConfigToolView::OnUpdateEditCustomProperty)
82 EVT_UPDATE_UI(ctID_DELETE_CUSTOM_PROPERTY, ctConfigToolView::OnUpdateDeleteCustomProperty)
83
84 EVT_NOTEBOOK_PAGE_CHANGED(-1, ctConfigToolView::OnTabSelect)
85
86 EVT_MENU(ctID_SAVE_SETUP_FILE, ctConfigToolView::OnSaveSetupFile)
87 EVT_MENU(ctID_SAVE_CONFIGURE_COMMAND, ctConfigToolView::OnSaveConfigureCommand)
88 EVT_UPDATE_UI(ctID_SAVE_SETUP_FILE, ctConfigToolView::OnUpdateSaveSetupFile)
89 EVT_UPDATE_UI(ctID_SAVE_CONFIGURE_COMMAND, ctConfigToolView::OnUpdateSaveConfigureCommand)
90
91 EVT_MENU(wxID_FIND, ctConfigToolView::OnFind)
92 EVT_UPDATE_UI(wxID_FIND, ctConfigToolView::OnUpdateFind)
93
94 END_EVENT_TABLE()
95
96 ctConfigToolView::ctConfigToolView()
97 {
98 }
99
100 // What to do when a view is created. Creates actual
101 // windows for displaying the view.
102 bool ctConfigToolView::OnCreate(wxDocument *doc, long WXUNUSED(flags) )
103 {
104 wxGetApp().GetDocManager()->ActivateView(this, TRUE);
105 wxGetApp().GetMainFrame()->SetDocument((ctConfigToolDoc*) doc);
106 wxGetApp().GetMainFrame()->GetSetupPage()->SetDocument((ctConfigToolDoc*) doc) ;
107 wxGetApp().GetMainFrame()->GetConfigurePage()->SetDocument((ctConfigToolDoc*) doc) ;
108
109 return TRUE;
110 }
111
112 void ctConfigToolView::OnDraw(wxDC *dc)
113 {
114 }
115
116 void ctConfigToolView::OnUpdate(wxView *WXUNUSED(sender), wxObject *hintObj)
117 {
118 ctConfigToolDoc* doc = wxDynamicCast(GetDocument(), ctConfigToolDoc);
119 ctConfigTreeCtrl* treeCtrl = wxGetApp().GetMainFrame()->GetConfigTreeCtrl();
120 if (!treeCtrl)
121 return;
122
123 wxASSERT (doc != NULL);
124
125 ctConfigItem* selItem = NULL;
126
127 wxTreeItemId sel = treeCtrl->GetSelection();
128 if (sel.IsOk())
129 {
130 ctTreeItemData* data = (ctTreeItemData*) treeCtrl->GetItemData(sel);
131 if (data)
132 selItem = data->GetConfigItem() ;
133 }
134
135 ctConfigToolHint* hint = (ctConfigToolHint*) hintObj;
136 int hintOp = ctNoHint;
137 if (hint)
138 hintOp = hint->m_op;
139
140 switch (hintOp)
141 {
142 case ctInitialUpdate:
143 {
144 if (doc && doc->GetTopItem())
145 {
146 wxGetApp().GetMainFrame()->GetConfigTreeCtrl()->DeleteAllItems();
147 AddItems(wxGetApp().GetMainFrame()->GetConfigTreeCtrl(), doc->GetTopItem());
148 wxGetApp().GetMainFrame()->GetConfigTreeCtrl()->Expand(doc->GetTopItem()->GetTreeItemId());
149 }
150 }
151 break;
152 case ctSelChanged:
153 {
154 if (selItem)
155 {
156 wxGetApp().GetMainFrame()->GetPropertyEditor()->ShowItem(selItem);
157 }
158 }
159 break;
160 case ctAllSaved:
161 {
162 // TODO: update windows and frame title
163 }
164 break;
165 case ctFilenameChanged:
166 {
167 wxGetApp().GetMainFrame()->UpdateFrameTitle();
168 }
169 break;
170 case ctClear:
171 {
172 // TODO: update windows
173 treeCtrl->DeleteAllItems();
174 wxGetApp().GetMainFrame()->GetPropertyEditor()->ShowItem(NULL);
175 break;
176 }
177 case ctValueChanged:
178 {
179 // ctConfigItem& ti = *(ctConfigItem *)hint->m_item;
180 wxGetApp().GetMainFrame()->GetPropertyEditor()->ShowItem(selItem);
181 }
182 break;
183
184 default:
185 break;
186 }
187 }
188
189 // Clean up windows used for displaying the view.
190 bool ctConfigToolView::OnClose(bool deleteWindow)
191 {
192 if (!GetDocument()->Close())
193 return FALSE;
194
195 ctConfigToolHint hint(NULL, ctClear);
196 GetDocument()->UpdateAllViews (NULL, & hint);
197
198 wxGetApp().GetDocManager()->ActivateView(this, FALSE);
199
200 Activate(FALSE);
201
202 wxGetApp().GetMainFrame()->SetDocument(NULL);
203 wxGetApp().GetMainFrame()->GetSetupPage()->SetDocument(NULL) ;
204 wxGetApp().GetMainFrame()->GetConfigurePage()->SetDocument(NULL) ;
205
206 return TRUE;
207 }
208
209 void ctConfigToolView::OnChangeFilename()
210 {
211 if (wxGetApp().GetTopWindow() && GetDocument())
212 {
213 wxString docTitle(wxFileNameFromPath(GetDocument()->GetFilename()));
214 wxStripExtension(docTitle);
215 GetDocument()->SetTitle(docTitle);
216
217 wxString name(GetDocument()->GetFilename());
218 wxStripExtension(name);
219
220 wxString title;
221
222 wxString modifiedMarker;
223 if (GetDocument()->IsModified())
224 modifiedMarker = wxT("*");
225
226 title = docTitle + modifiedMarker + wxString(wxT(" - ")) + wxGetApp().GetSettings().GetAppName() ;
227
228 ((wxFrame*) wxGetApp().GetTopWindow())->SetTitle(title);
229 }
230 }
231
232 // General disabler
233 void ctConfigToolView::OnUpdateDisable(wxUpdateUIEvent& event)
234 {
235 event.Enable( FALSE );
236 }
237
238 void ctConfigToolView::OnUpdateAddItem(wxUpdateUIEvent& event)
239 {
240 event.Enable( TRUE );
241 }
242
243 /// Add item and its children to the tree
244 void ctConfigToolView::AddItems(ctConfigTreeCtrl* treeControl, ctConfigItem* item)
245 {
246 SyncItem(treeControl, item);
247
248 int count = item->GetChildCount();
249 int i;
250 for (i = 0; i < count; i++)
251 {
252 ctConfigItem* child = item->GetChild(i);
253 AddItems(treeControl, child);
254 }
255 }
256
257 /// Gets the tree item in sync with the item
258 void ctConfigToolView::SyncItem(ctConfigTreeCtrl* treeControl, ctConfigItem* item)
259 {
260 if (!item->GetTreeItemId().IsOk())
261 {
262 if (!item->GetParent())
263 {
264 item->SetTreeItem(treeControl->AddRoot(_(""), -1, -1, new ctTreeItemData(item)));
265 }
266 else
267 {
268 // Find the item to insert the new item after.
269 ctConfigItem* previousItem = item->FindPreviousSibling();
270 if (previousItem && previousItem->GetTreeItemId().IsOk())
271 {
272 item->SetTreeItem(treeControl->InsertItem(item->GetParent()->GetTreeItemId(),
273 previousItem->GetTreeItemId(),
274 item->GetName(), -1, -1, new ctTreeItemData(item)));
275 }
276 else if (!previousItem && item->GetParent()->GetChildCount() > 1
277 )
278 {
279 // Insert at the beginning
280 item->SetTreeItem(treeControl->InsertItem(item->GetParent()->GetTreeItemId(),
281 (size_t) 0, // Insert at first position
282 item->GetName(), -1, -1, new ctTreeItemData(item)));
283 }
284 else
285 {
286 item->SetTreeItem(treeControl->AppendItem(item->GetParent()->GetTreeItemId(),
287 item->GetName(), -1, -1, new ctTreeItemData(item)));
288 }
289 }
290 }
291
292 if (item->GetTreeItemId().IsOk())
293 {
294 treeControl->SetItemText(item->GetTreeItemId(), item->GetName());
295
296 int iconId = 0;
297
298 if (item->GetType() == ctTypeGroup)
299 {
300 iconId = treeControl->GetIconTable().GetIconId(wxT("Group"), 0, item->IsActive());
301 }
302 else if (item->GetType() == ctTypeCheckGroup)
303 {
304 iconId = treeControl->GetIconTable().GetIconId(wxT("CheckGroup"), item->IsEnabled() ? 0 : 1, item->IsActive());
305 }
306 else if (item->GetType() == ctTypeRadioGroup)
307 {
308 iconId = treeControl->GetIconTable().GetIconId(wxT("RadioGroup"), item->IsEnabled() ? 0 : 1, item->IsActive());
309 }
310 else if (item->GetType() == ctTypeBoolCheck)
311 {
312 iconId = treeControl->GetIconTable().GetIconId(wxT("Checkbox"), item->IsEnabled() ? 0 : 1, item->IsActive());
313 }
314 else if (item->GetType() == ctTypeBoolRadio)
315 {
316 iconId = treeControl->GetIconTable().GetIconId(wxT("Radiobutton"), item->IsEnabled() ? 0 : 1, item->IsActive());
317 }
318 treeControl->SetItemImage(item->GetTreeItemId(), iconId, wxTreeItemIcon_Normal);
319 treeControl->SetItemImage(item->GetTreeItemId(), iconId, wxTreeItemIcon_Selected);
320
321 if (treeControl->GetSelection() == item->GetTreeItemId())
322 {
323 if (wxGetApp().GetMainFrame()->GetPropertyEditor()->GetItem())
324 wxGetApp().GetMainFrame()->GetPropertyEditor()->UpdateTitle();
325 }
326 }
327 }
328
329 /// Clicked an icon
330 void ctConfigToolView::OnIconLeftDown(ctConfigTreeCtrl* treeControl, ctConfigItem* item)
331 {
332 if (!item->IsActive())
333 return;
334
335 if (item->GetType() == ctTypeCheckGroup ||
336 item->GetType() == ctTypeBoolCheck ||
337 item->GetType() == ctTypeBoolRadio ||
338 item->GetType() == ctTypeRadioGroup
339 )
340 {
341 // Don't toggle a radio button that's already
342 // enabled.
343 if ((item->GetType() == ctTypeBoolRadio || item->GetType() == ctTypeRadioGroup)
344 && item->IsEnabled())
345 return;
346
347 item->Enable(!item->IsEnabled());
348
349 GetDocument()->Modify(TRUE);
350 OnChangeFilename();
351
352 SyncItem(treeControl, item);
353
354 wxList considered;
355 item->PropagateChange(considered);
356 if ((item->GetType() == ctTypeBoolRadio || item->GetType() == ctTypeRadioGroup) && item->IsEnabled())
357 {
358 item->PropagateRadioButton(considered);
359 }
360 }
361 }
362
363 /// Returns the selected config item, if any.
364 ctConfigItem* ctConfigToolView::GetSelection()
365 {
366 wxTreeCtrl* treeCtrl = wxGetApp().GetMainFrame()->GetConfigTreeCtrl();
367 if (!treeCtrl)
368 return NULL;
369
370 wxTreeItemId sel = treeCtrl->GetSelection();
371 if (sel.IsOk())
372 {
373 ctTreeItemData* data = (ctTreeItemData*) treeCtrl->GetItemData(sel);
374 if (data)
375 return data->GetConfigItem() ;
376 }
377 return NULL;
378 }
379
380 /// Add a checkbox item
381 void ctConfigToolView::OnAddCheckBoxItem(wxCommandEvent& event)
382 {
383 AddItem(ctTypeBoolCheck, _("New checkbox item"));
384 }
385
386 /// Add a radiobutton item
387 void ctConfigToolView::OnAddRadioButtonItem(wxCommandEvent& event)
388 {
389 AddItem(ctTypeBoolRadio, _("New radio button item"));
390 }
391
392 /// Add a group item
393 void ctConfigToolView::OnAddGroupItem(wxCommandEvent& event)
394 {
395 AddItem(ctTypeGroup, _("New group item"));
396 }
397
398 /// Add a group option item
399 void ctConfigToolView::OnAddCheckGroupItem(wxCommandEvent& event)
400 {
401 AddItem(ctTypeCheckGroup, _("New check group item"));
402 }
403
404 /// Add a group option item
405 void ctConfigToolView::OnAddRadioGroupItem(wxCommandEvent& event)
406 {
407 AddItem(ctTypeRadioGroup, _("New radio group item"));
408 }
409
410 /// Add a string item
411 void ctConfigToolView::OnAddStringItem(wxCommandEvent& event)
412 {
413 AddItem(ctTypeString, _("New string item"));
414 }
415
416 /// Add an item
417 void ctConfigToolView::AddItem(ctConfigType type, const wxString& msg)
418 {
419 ctConfigItem* sel = GetSelection();
420 if (sel)
421 {
422 wxString name = wxGetTextFromUser(_("Please enter a name for the new item."),
423 msg, wxT(""));
424 if (!name.IsEmpty())
425 {
426 ctConfigItem* parent ;
427 ctConfigItem* insertBefore ;
428 if (sel->CanHaveChildren())
429 {
430 parent = sel;
431 insertBefore = NULL;
432 }
433 else
434 {
435 parent = sel->GetParent();
436 insertBefore = sel->FindNextSibling();
437 }
438
439 ctConfigItem* newItem = new ctConfigItem(NULL, type, name);
440 newItem->InitProperties();
441
442 newItem->GetDocument()->GetCommandProcessor()->Submit(
443 new ctConfigCommand(msg, ctCMD_NEW_ELEMENT, NULL, newItem,
444 parent, insertBefore));
445 }
446 }
447 }
448
449 /// Delete an item
450 void ctConfigToolView::OnDeleteItem(wxCommandEvent& event)
451 {
452 ctConfigItem* sel = GetSelection();
453 if (sel)
454 {
455 wxString name(sel->GetName());
456 wxString msg;
457 msg.Printf(_("Delete %s?"), (const wxChar*) name);
458 if (wxYES == wxMessageBox(msg, _("Delete item"), wxICON_QUESTION|wxYES_NO))
459 {
460 wxGetApp().GetMainFrame()->GetConfigTreeCtrl()->Delete(sel->GetTreeItemId());
461 }
462 }
463 }
464
465 /// Rename an item
466 void ctConfigToolView::OnRenameItem(wxCommandEvent& event)
467 {
468 ctConfigItem* sel = GetSelection();
469 if (sel)
470 {
471 wxString name = wxGetTextFromUser(_("Please enter a new name for the item."),
472 _("Rename item"), sel->GetName());
473 if (!name.IsEmpty())
474 {
475 sel->SetName(name);
476 SyncItem(wxGetApp().GetMainFrame()->GetConfigTreeCtrl(), sel);
477
478 ctConfigToolHint hint(NULL, ctSelChanged);
479 GetDocument()->UpdateAllViews (NULL, & hint);
480 }
481 }
482 }
483
484 /// Copy an item to the clipboard
485 void ctConfigToolView::OnCopy(wxCommandEvent& event)
486 {
487 ctConfigToolDoc* doc = (ctConfigToolDoc*) GetDocument();
488 ctConfigItem* sel = GetSelection();
489 if (sel)
490 {
491 doc->SetClipboardItem(sel->DeepClone());
492 }
493 }
494
495 /// Copy an item to the clipboard and cut the item
496 void ctConfigToolView::OnCut(wxCommandEvent& event)
497 {
498 ctConfigToolDoc* doc = (ctConfigToolDoc*) GetDocument();
499 ctConfigItem* sel = GetSelection();
500 if (sel)
501 {
502 {
503 ctConfigCommand* cmd = new ctConfigCommand(wxT("Cut Config Item"), ctCMD_CUT,
504 sel, (ctConfigItem*) NULL);
505 doc->GetCommandProcessor()->Submit(cmd);
506 }
507 }
508 }
509
510 /// Paste an item from the clipboard to the tree
511 void ctConfigToolView::OnPaste(wxCommandEvent& event)
512 {
513 ctConfigToolDoc* doc = (ctConfigToolDoc*) GetDocument();
514 ctConfigItem* sel = GetSelection();
515 if (sel && doc->GetClipboardItem())
516 {
517 ctConfigItem* parent ;
518 ctConfigItem* insertBefore ;
519 if (sel->CanHaveChildren())
520 {
521 parent = sel;
522 insertBefore = NULL;
523 }
524 else
525 {
526 parent = sel->GetParent();
527 insertBefore = sel->FindNextSibling();
528 }
529
530 ctConfigItem* newItem = doc->GetClipboardItem()->DeepClone();
531 ctConfigCommand* cmd = new ctConfigCommand(wxT("Paste Config Item"), ctCMD_PASTE,
532 NULL, newItem, parent, insertBefore);
533 doc->GetCommandProcessor()->Submit(cmd);
534 }
535 }
536
537 /// Update for copy command
538 void ctConfigToolView::OnUpdateCopy(wxUpdateUIEvent& event)
539 {
540 ctConfigToolDoc* doc = (ctConfigToolDoc*) GetDocument();
541 event.Enable( doc && GetSelection() && GetSelection()->GetParent() );
542 }
543
544 /// Update for cut
545 void ctConfigToolView::OnUpdateCut(wxUpdateUIEvent& event)
546 {
547 ctConfigToolDoc* doc = (ctConfigToolDoc*) GetDocument();
548 event.Enable( doc && GetSelection() && GetSelection()->GetParent() );
549 }
550
551 /// Update for paste
552 void ctConfigToolView::OnUpdatePaste(wxUpdateUIEvent& event)
553 {
554 ctConfigToolDoc* doc = (ctConfigToolDoc*) GetDocument();
555 event.Enable( doc && doc->GetClipboardItem() && GetSelection() );
556 }
557
558 /// Copy an item to the clipboard
559 void ctConfigToolView::OnContextCopy(wxCommandEvent& event)
560 {
561 ctConfigToolDoc* doc = (ctConfigToolDoc*) GetDocument();
562 ctConfigItem* sel = wxGetApp().GetMainFrame()->GetConfigTreeCtrl()->GetContextItem();
563 if (doc && sel)
564 {
565 doc->SetClipboardItem(sel->DeepClone());
566 }
567 }
568
569 /// Copy an item to the clipboard and cut the item
570 void ctConfigToolView::OnContextCut(wxCommandEvent& event)
571 {
572 ctConfigToolDoc* doc = (ctConfigToolDoc*) GetDocument();
573 ctConfigItem* sel = wxGetApp().GetMainFrame()->GetConfigTreeCtrl()->GetContextItem();
574 if (sel)
575 {
576 {
577 ctConfigCommand* cmd = new ctConfigCommand(wxT("Cut Config Item"), ctCMD_CUT,
578 sel, (ctConfigItem*) NULL);
579 doc->GetCommandProcessor()->Submit(cmd);
580 }
581 }
582 }
583
584 /// Paste an item from the clipboard to the tree
585 void ctConfigToolView::OnContextPasteBefore(wxCommandEvent& event)
586 {
587 ctConfigToolDoc* doc = (ctConfigToolDoc*) GetDocument();
588 ctConfigItem* sel = wxGetApp().GetMainFrame()->GetConfigTreeCtrl()->GetContextItem();
589 if (sel && doc->GetClipboardItem())
590 {
591 ctConfigItem* parent = sel->GetParent();
592 ctConfigItem* insertBefore = sel;
593
594 ctConfigItem* newItem = doc->GetClipboardItem()->DeepClone();
595 ctConfigCommand* cmd = new ctConfigCommand(wxT("Paste Config Item"), ctCMD_PASTE,
596 NULL, newItem, parent, insertBefore);
597 doc->GetCommandProcessor()->Submit(cmd);
598 }
599 }
600
601 /// Paste an item from the clipboard to the tree
602 void ctConfigToolView::OnContextPasteAfter(wxCommandEvent& event)
603 {
604 ctConfigToolDoc* doc = (ctConfigToolDoc*) GetDocument();
605 ctConfigItem* sel = wxGetApp().GetMainFrame()->GetConfigTreeCtrl()->GetContextItem();
606 if (sel && doc->GetClipboardItem())
607 {
608 ctConfigItem* parent = sel->GetParent();
609 ctConfigItem* insertBefore = sel->FindNextSibling();
610
611 ctConfigItem* newItem = doc->GetClipboardItem()->DeepClone();
612 ctConfigCommand* cmd = new ctConfigCommand(wxT("Paste Config Item"), ctCMD_PASTE,
613 NULL, newItem, parent, insertBefore);
614 doc->GetCommandProcessor()->Submit(cmd);
615 }
616 }
617
618 /// Paste an item from the clipboard to the tree
619 void ctConfigToolView::OnContextPasteAsChild(wxCommandEvent& event)
620 {
621 ctConfigToolDoc* doc = (ctConfigToolDoc*) GetDocument();
622 ctConfigItem* sel = wxGetApp().GetMainFrame()->GetConfigTreeCtrl()->GetContextItem();
623 if (sel && doc->GetClipboardItem())
624 {
625 if (sel->CanHaveChildren())
626 {
627 ctConfigItem* parent = sel;
628 ctConfigItem* insertBefore = NULL;
629
630 ctConfigItem* newItem = doc->GetClipboardItem()->DeepClone();
631 ctConfigCommand* cmd = new ctConfigCommand(wxT("Paste Config Item"), ctCMD_PASTE,
632 NULL, newItem, parent, insertBefore);
633 doc->GetCommandProcessor()->Submit(cmd);
634 }
635 }
636 }
637
638 /// Copy an item to the clipboard
639 void ctConfigToolView::OnUpdateContextCopy(wxUpdateUIEvent& event)
640 {
641 ctConfigToolDoc* doc = (ctConfigToolDoc*) GetDocument();
642 ctConfigItem* sel = wxGetApp().GetMainFrame()->GetConfigTreeCtrl()->GetContextItem();
643 event.Enable( doc && sel && sel->GetParent() );
644 }
645
646 /// Copy an item to the clipboard and cut the item
647 void ctConfigToolView::OnUpdateContextCut(wxUpdateUIEvent& event)
648 {
649 ctConfigToolDoc* doc = (ctConfigToolDoc*) GetDocument();
650 ctConfigItem* sel = wxGetApp().GetMainFrame()->GetConfigTreeCtrl()->GetContextItem();
651 event.Enable( doc && sel && sel->GetParent() );
652 }
653
654 /// Paste an item from the clipboard to the tree
655 void ctConfigToolView::OnUpdateContextPasteBefore(wxUpdateUIEvent& event)
656 {
657 ctConfigToolDoc* doc = (ctConfigToolDoc*) GetDocument();
658 ctConfigItem* sel = wxGetApp().GetMainFrame()->GetConfigTreeCtrl()->GetContextItem();
659 event.Enable( doc && sel && sel->GetParent() && doc->GetClipboardItem() );
660 }
661
662 /// Paste an item from the clipboard to the tree
663 void ctConfigToolView::OnUpdateContextPasteAfter(wxUpdateUIEvent& event)
664 {
665 ctConfigToolDoc* doc = (ctConfigToolDoc*) GetDocument();
666 ctConfigItem* sel = wxGetApp().GetMainFrame()->GetConfigTreeCtrl()->GetContextItem();
667 event.Enable( doc && sel && sel->GetParent() && doc->GetClipboardItem() );
668 }
669
670 /// Paste an item from the clipboard to the tree
671 void ctConfigToolView::OnUpdateContextPasteAsChild(wxUpdateUIEvent& event)
672 {
673 ctConfigToolDoc* doc = (ctConfigToolDoc*) GetDocument();
674 ctConfigItem* sel = wxGetApp().GetMainFrame()->GetConfigTreeCtrl()->GetContextItem();
675 event.Enable( doc && sel && sel->CanHaveChildren() && doc->GetClipboardItem() );
676 }
677
678 /// Item help
679 void ctConfigToolView::OnItemHelp(wxCommandEvent& event)
680 {
681 ctConfigToolDoc* doc = (ctConfigToolDoc*) GetDocument();
682 if ( doc && GetSelection() )
683 {
684 wxString helpTopic = GetSelection()->GetPropertyString(wxT("help-topic"));
685 if (!helpTopic.IsEmpty())
686 {
687 wxGetApp().GetReferenceHelpController().DisplaySection(helpTopic);
688 }
689 }
690 }
691
692 /// Item help update
693 void ctConfigToolView::OnUpdateItemHelp(wxUpdateUIEvent& event)
694 {
695 ctConfigToolDoc* doc = (ctConfigToolDoc*) GetDocument();
696 event.Enable( doc && GetSelection() );
697 }
698
699 /// Add a custom property
700 void ctConfigToolView::OnAddCustomProperty(wxCommandEvent& event)
701 {
702 ctConfigToolDoc* doc = (ctConfigToolDoc*) GetDocument();
703 ctConfigItem* sel = GetSelection();
704 ctPropertyEditor* editor = wxGetApp().GetMainFrame()->GetPropertyEditor();
705 if (doc && sel && editor)
706 {
707 ctCustomPropertyDialog dialog(wxGetApp().GetMainFrame(),
708 -1, _("Add a custom property"));
709 if (dialog.ShowModal() == wxID_OK)
710 {
711 wxString name = dialog.GetPropertyName();
712 wxString type = dialog.GetPropertyType();
713 wxString descr = dialog.GetPropertyDescription();
714 wxString editorType = dialog.GetEditorType();
715 wxArrayString choices = dialog.GetChoices();
716
717 if (sel->GetProperties().FindProperty(name))
718 {
719 wxMessageBox(_("Sorry, this name already exists."), _T("Add custom property"),
720 wxOK|wxICON_INFORMATION);
721 return;
722 }
723 ctProperty* property = new ctProperty;
724 if (type == wxT("bool"))
725 property->GetVariant() = wxVariant((bool) FALSE, name);
726 else if (type == wxT("double"))
727 property->GetVariant() = wxVariant((double) 0.0, name);
728 else if (type == wxT("long"))
729 property->GetVariant() = wxVariant((long) 0, name);
730 else
731 property->GetVariant() = wxVariant(wxT(""), name);
732 property->SetCustom(TRUE);
733 property->SetDescription(descr);
734 property->SetChoices(choices);
735 property->SetEditorType(editorType);
736
737 sel->GetProperties().AddProperty(property);
738 editor->ShowItem(sel);
739 OnChangeFilename();
740 }
741 }
742 }
743
744 /// Edit a custom property
745 void ctConfigToolView::OnEditCustomProperty(wxCommandEvent& event)
746 {
747 ctConfigToolDoc* doc = (ctConfigToolDoc*) GetDocument();
748 ctConfigItem* sel = GetSelection();
749 ctPropertyEditor* editor = wxGetApp().GetMainFrame()->GetPropertyEditor();
750 if (doc && sel && editor)
751 {
752 int row;
753 ctProperty* property = editor->FindSelectedProperty(row) ;
754 if (property && property->IsCustom())
755 {
756 wxString oldName = property->GetName();
757 wxString oldDescription = property->GetDescription();
758 wxString oldType = property->GetVariant().GetType();
759 wxString oldEditorType = property->GetEditorType();
760 wxArrayString oldChoices = property->GetChoices();
761
762 ctCustomPropertyDialog dialog(wxGetApp().GetMainFrame(),
763 -1, _("Edit custom property"));
764 dialog.SetPropertyName(oldName);
765 dialog.SetPropertyType(oldType);
766 dialog.SetPropertyDescription(oldDescription);
767 if (dialog.ShowModal() == wxID_OK)
768 {
769 wxString name = dialog.GetPropertyName();
770 wxString type = dialog.GetPropertyType();
771 wxString editorType = dialog.GetEditorType();
772 wxArrayString choices = dialog.GetChoices();
773 wxString descr = dialog.GetPropertyDescription();
774
775 if (name != oldName && sel->GetProperties().FindProperty(name))
776 {
777 wxMessageBox(_("Sorry, this name already exists."), _T("Add custom property"),
778 wxOK|wxICON_INFORMATION);
779 return;
780 }
781 if (type != oldType)
782 {
783 if (type == wxT("bool"))
784 property->GetVariant() = wxVariant((bool) FALSE, name);
785 else if (type == wxT("double"))
786 property->GetVariant() = wxVariant((double) 0.0, name);
787 else if (type == wxT("long"))
788 property->GetVariant() = wxVariant((long) 0, name);
789 else
790 property->GetVariant() = wxVariant(wxT(""), name);
791 }
792 if (name != oldName)
793 property->GetVariant().SetName(name);
794
795 if (choices != oldChoices)
796 property->SetChoices(choices);
797
798 if (editorType != oldEditorType)
799 property->SetEditorType(editorType);
800
801 if (name != oldName)
802 property->GetVariant().SetName(name);
803
804 property->SetCustom(TRUE);
805
806 if (descr != oldDescription)
807 property->SetDescription(descr);
808
809 editor->ShowItem(sel);
810 OnChangeFilename();
811 }
812 }
813 }
814 }
815
816 /// Delete a custom property
817 void ctConfigToolView::OnDeleteCustomProperty(wxCommandEvent& event)
818 {
819 ctConfigToolDoc* doc = (ctConfigToolDoc*) GetDocument();
820 ctConfigItem* sel = GetSelection();
821 ctPropertyEditor* editor = wxGetApp().GetMainFrame()->GetPropertyEditor();
822 if (doc && sel && editor)
823 {
824 int row;
825 ctProperty* property = editor->FindSelectedProperty(row) ;
826 if (property && property->IsCustom())
827 {
828 wxString name(property->GetName());
829 wxString msg;
830 msg.Printf(_("Delete custom property '%s'?"), (const wxChar*) name);
831 if (wxYES == wxMessageBox(msg, _("Delete property"), wxICON_EXCLAMATION|wxYES_NO))
832 {
833 sel->GetProperties().RemoveProperty(property);
834 editor->ShowItem(sel);
835 delete property;
836 OnChangeFilename();
837 }
838 }
839 }
840 }
841
842 /// Add a custom property: update event
843 void ctConfigToolView::OnUpdateAddCustomProperty(wxUpdateUIEvent& event)
844 {
845 ctConfigToolDoc* doc = (ctConfigToolDoc*) GetDocument();
846 event.Enable( doc && GetSelection() && GetSelection()->GetParent() );
847 }
848
849 /// Edit a custom property: update event
850 void ctConfigToolView::OnUpdateEditCustomProperty(wxUpdateUIEvent& event)
851 {
852 ctConfigToolDoc* doc = (ctConfigToolDoc*) GetDocument();
853 ctConfigItem* sel = GetSelection();
854 ctPropertyEditor* editor = wxGetApp().GetMainFrame()->GetPropertyEditor();
855 int row;
856 event.Enable( doc && sel && sel->GetParent() && editor &&
857 editor->FindSelectedProperty(row) &&
858 editor->FindSelectedProperty(row)->IsCustom() );
859 }
860
861 /// Delete a custom property: update event
862 void ctConfigToolView::OnUpdateDeleteCustomProperty(wxUpdateUIEvent& event)
863 {
864 ctConfigToolDoc* doc = (ctConfigToolDoc*) GetDocument();
865 ctConfigItem* sel = GetSelection();
866 ctPropertyEditor* editor = wxGetApp().GetMainFrame()->GetPropertyEditor();
867 int row;
868 event.Enable( doc && sel && sel->GetParent() && editor &&
869 editor->FindSelectedProperty(row) &&
870 editor->FindSelectedProperty(row)->IsCustom() );
871 }
872
873 /// Regenerate setup.h and configure command
874 void ctConfigToolView::RegenerateSetup()
875 {
876 ctConfigToolDoc* doc = (ctConfigToolDoc*) GetDocument();
877 ctOutputWindow* setupPage = wxGetApp().GetMainFrame()->GetSetupPage() ;
878 ctOutputWindow* configurePage = wxGetApp().GetMainFrame()->GetConfigurePage() ;
879
880 wxString setupStr = doc->GenerateSetup();
881 wxString configureStr = doc->GenerateConfigureCommand();
882
883 setupPage->SetText(setupStr);
884 configurePage->SetText(configureStr);
885 }
886
887 /// Regenerate if selected a tab
888 void ctConfigToolView::OnTabSelect(wxNotebookEvent& event)
889 {
890 if (wxGetApp().GetMainFrame()->GetMainNotebook() != event.GetEventObject())
891 {
892 event.Skip();
893 return;
894 }
895
896 if (event.GetSelection() > 0)
897 {
898 RegenerateSetup();
899 }
900 }
901
902 void ctConfigToolView::OnSaveSetupFile(wxCommandEvent& event)
903 {
904 ctConfigToolDoc* doc = (ctConfigToolDoc*) GetDocument();
905 wxString setupStr = doc->GenerateSetup();
906
907 wxString filename = _T("setup.h");
908 wxString path = doc->GetFrameworkDir(FALSE);
909 wxString wildcard = _T("Header files (*.h)|*.h|All files (*.*)|*.*");
910
911 wxFileDialog dialog(wxTheApp->GetTopWindow(),
912 _("Save Setup File As"),
913 path, filename ,
914 wildcard, wxSAVE|wxOVERWRITE_PROMPT);
915
916 if (dialog.ShowModal() == wxID_OK)
917 {
918 wxString fullPath = dialog.GetPath();
919
920 // TODO: save last saved path in settings.
921
922 wxFileOutputStream stream(fullPath);
923 if (!stream.Ok())
924 {
925 wxMessageBox(_("Sorry, could not save this file."), _("Save Setup File"), wxICON_EXCLAMATION|wxOK);
926 return;
927 }
928
929 stream << setupStr;
930 }
931 }
932
933 void ctConfigToolView::OnSaveConfigureCommand(wxCommandEvent& event)
934 {
935 ctConfigToolDoc* doc = (ctConfigToolDoc*) GetDocument();
936 wxString configureStr = doc->GenerateConfigureCommand();
937
938 wxString filename = _T("configurewx.sh");
939 wxString path = doc->GetFrameworkDir(FALSE);
940 wxString wildcard = _T("Shell script files (*.sh)|*.sh|All files (*.*)|*.*");
941
942 wxFileDialog dialog(wxTheApp->GetTopWindow(),
943 _("Save Configure Command File As"),
944 path, filename ,
945 wildcard, wxSAVE|wxOVERWRITE_PROMPT);
946
947 if (dialog.ShowModal() == wxID_OK)
948 {
949 wxString fullPath = dialog.GetPath();
950
951 // TODO: save last saved path in settings.
952
953 wxFileOutputStream stream(fullPath);
954 if (!stream.Ok())
955 {
956 wxMessageBox(_("Sorry, could not save this file."), _("Save Configure Command File"), wxICON_EXCLAMATION|wxOK);
957 return;
958 }
959
960 stream << configureStr;
961 }
962 }
963
964 void ctConfigToolView::OnUpdateSaveSetupFile(wxUpdateUIEvent& event)
965 {
966 event.Enable(TRUE);
967 }
968
969 void ctConfigToolView::OnUpdateSaveConfigureCommand(wxUpdateUIEvent& event)
970 {
971 event.Enable(TRUE);
972 }
973
974 /// Find text
975 void ctConfigToolView::OnFind(wxCommandEvent& event)
976 {
977 ctFindReplaceDialog* dialog = wxGetApp().GetMainFrame()->GetFindDialog();
978 if (dialog)
979 {
980 dialog->Raise();
981 }
982
983 if (!dialog)
984 {
985 int style = wxFR_NOUPDOWN;
986 wxString caption(wxT("Find text in settings"));
987 int flags = wxFR_DOWN;
988 if (wxGetApp().GetSettings().m_matchCase)
989 flags|=wxFR_MATCHCASE;
990 if (wxGetApp().GetSettings().m_matchWholeWord)
991 flags|=wxFR_WHOLEWORD;
992
993 ctFindReplaceDialog::sm_findData.SetFlags(flags);
994
995 dialog = new ctFindReplaceDialog(wxGetApp().GetMainFrame(), caption, style);
996 dialog->Show(TRUE);
997 }
998 }
999
1000 /// Update find text
1001 void ctConfigToolView::OnUpdateFind(wxUpdateUIEvent& event)
1002 {
1003 event.Enable(TRUE);
1004 }
1005
1006 //----------------------------------------------------------------------------
1007 // ctFindReplaceDialog
1008 //----------------------------------------------------------------------------
1009
1010 BEGIN_EVENT_TABLE(ctFindReplaceDialog, wxFindReplaceDialog)
1011 EVT_FIND(-1, ctFindReplaceDialog::OnFind)
1012 EVT_FIND_NEXT(-1, ctFindReplaceDialog::OnFind)
1013 EVT_FIND_CLOSE(-1, ctFindReplaceDialog::OnClose)
1014 END_EVENT_TABLE()
1015
1016 wxFindReplaceData ctFindReplaceDialog::sm_findData;
1017 wxString ctFindReplaceDialog::sm_currentItem = wxEmptyString;
1018
1019 ctFindReplaceDialog::ctFindReplaceDialog( wxWindow *parent, const wxString& title,
1020 long style):
1021 wxFindReplaceDialog( parent, & sm_findData, title, style )
1022 {
1023 sm_currentItem = wxEmptyString;
1024
1025 if (parent)
1026 ((ctMainFrame*) parent)->SetFindDialog(this);
1027 }
1028
1029 void ctFindReplaceDialog::OnFind(wxFindDialogEvent& event)
1030 {
1031 wxString textToFind = event.GetFindString();
1032 bool matchCase = ((event.GetFlags() & wxFR_MATCHCASE) != 0);
1033 bool wholeWord = ((event.GetFlags() & wxFR_WHOLEWORD) != 0);
1034
1035 wxGetApp().GetSettings().m_matchCase = matchCase;
1036 wxGetApp().GetSettings().m_matchWholeWord = wholeWord;
1037
1038 if (!DoFind(textToFind, matchCase, wholeWord))
1039 {
1040 wxMessageBox(wxT("No more matches."), wxT("Search"), wxOK|wxICON_INFORMATION, this);
1041 }
1042 }
1043
1044 bool ctFindReplaceDialog::DoFind(const wxString& textToFind, bool matchCase, bool wholeWord, bool wrap)
1045 {
1046 ctConfigToolDoc* doc = wxGetApp().GetMainFrame()->GetDocument();
1047 if (!doc)
1048 return FALSE;
1049 ctConfigToolView* view = (ctConfigToolView*) doc->GetFirstView();
1050
1051 ctConfigItem* currentItem = NULL;
1052 ctConfigItem* focusItem = view->GetSelection();
1053 if (!focusItem)
1054 {
1055 focusItem = doc->GetTopItem();
1056 if (!focusItem)
1057 return FALSE;
1058 }
1059
1060 if (!sm_currentItem.IsEmpty())
1061 {
1062 currentItem = doc->GetTopItem()->FindItem(sm_currentItem);
1063 }
1064
1065 // If we were at this item last time, skip the first one.
1066 bool skipFirstItem = (currentItem == focusItem);
1067 currentItem = FindNextItem(doc, currentItem, textToFind, matchCase, wholeWord, wrap,
1068 skipFirstItem);
1069
1070 if (currentItem)
1071 {
1072 sm_currentItem = currentItem->GetName();
1073 wxGetApp().GetMainFrame()->GetConfigTreeCtrl()->SelectItem(currentItem->GetTreeItemId());
1074 return TRUE;
1075 }
1076 else
1077 {
1078 sm_currentItem = wxEmptyString;
1079 }
1080
1081 return FALSE;
1082 }
1083
1084 ctConfigItem* ctFindReplaceDialog::FindNextItem(ctConfigToolDoc* doc,
1085 ctConfigItem* item,
1086 const wxString& text,
1087 bool matchCase,
1088 bool matchWordOnly,
1089 bool wrap,
1090 bool skipFirst)
1091 {
1092 ctConfigItem* firstInDoc = NULL;
1093
1094 wxString text2(text);
1095 if (!matchCase)
1096 text2.MakeLower();
1097
1098 ctConfigItem* found = NULL;
1099 ctConfigItem* next = item;
1100
1101 int i = 0;
1102 do
1103 {
1104 // If starting the search from beginning, we can now
1105 // set the value of 'item' in the 2nd iteration without immediately
1106 // dropping out of the while loop because card == next
1107 if (!item && (i > 0))
1108 item = firstInDoc;
1109
1110 // We might want to start from this item if skipFirst is false.
1111 if ((i == 0) && !skipFirst && next)
1112 {
1113 }
1114 else
1115 next = doc->FindNextItem(next, wrap);
1116
1117 // Save to be used in iteration 2
1118 if ((i == 0) && !item)
1119 firstInDoc = next;
1120
1121 if (next)
1122 {
1123 wxString str(next->GetName());
1124 wxString description(next->GetPropertyString(wxT("description")));
1125 wxString notes(next->GetPropertyString(wxT("notes")));
1126 if (!matchCase)
1127 {
1128 str.MakeLower();
1129 description.MakeLower();
1130 notes.MakeLower();
1131 }
1132 if (ctMatchString(str, text2, matchWordOnly) ||
1133 ctMatchString(description, text2, matchWordOnly) ||
1134 ctMatchString(notes, text2, matchWordOnly))
1135 {
1136 found = next;
1137 }
1138 }
1139 else
1140 break; // Didn't find an item at all
1141
1142 i ++;
1143 }
1144 while (!found && item != next);
1145
1146 if (item == found && !firstInDoc)
1147 return NULL;
1148 else
1149 return found;
1150 }
1151
1152 void ctFindReplaceDialog::OnClose(wxFindDialogEvent& event)
1153 {
1154 bool matchCase = ((event.GetFlags() & wxFR_MATCHCASE) != 0);
1155 bool wholeWord = ((event.GetFlags() & wxFR_WHOLEWORD) != 0);
1156 wxGetApp().GetSettings().m_matchCase = matchCase;
1157 wxGetApp().GetSettings().m_matchWholeWord = wholeWord;
1158
1159 this->Destroy();
1160 ((ctMainFrame*) GetParent())->SetFindDialog(NULL);
1161 }