]> git.saurik.com Git - wxWidgets.git/blame - utils/wxprop/src/proplist.cpp
Added test for sprintf and vsnprintf to fix string.cpp for non-GNU systems.
[wxWidgets.git] / utils / wxprop / src / proplist.cpp
CommitLineData
457814b5
JS
1/////////////////////////////////////////////////////////////////////////////
2// Name: proplist.cpp
3// Purpose: Property list classes
4// Author: Julian Smart
5// Modified by:
6// Created: 04/01/98
7// RCS-ID: $Id$
8// Copyright: (c) Julian Smart
9// Licence: wxWindows license
10/////////////////////////////////////////////////////////////////////////////
11
12#ifdef __GNUG__
13#pragma implementation "proplist.h"
14#endif
15
16// For compilers that support precompilation, includes "wx/wx.h".
17#include "wx/wxprec.h"
18
19#ifdef __BORLANDC__
20#pragma hdrstop
21#endif
22
23#ifndef WX_PRECOMP
24#include "wx/wx.h"
25#endif
26
27#include <ctype.h>
28#include <stdlib.h>
29#include <math.h>
30#include <string.h>
31
48df9992 32#if wxUSE_IOSTREAMH
2049ba38 33#if defined(__WXMSW__) && !defined(__GNUWIN32__)
457814b5
JS
34#include <strstrea.h>
35#else
36#include <strstream.h>
37#endif
48df9992
UU
38#else
39#include <strstream>
40#endif
457814b5
JS
41
42#include "wx/window.h"
43#include "wx/utils.h"
44#include "wx/list.h"
45#include "wx/colordlg.h"
46#include "proplist.h"
47
48/*
49 * Property text edit control
50 */
51
52IMPLEMENT_CLASS(wxPropertyTextEdit, wxTextCtrl)
53
54wxPropertyTextEdit::wxPropertyTextEdit(wxPropertyListView *v, wxWindow *parent,
55 const wxWindowID id, const wxString& value,
56 const wxPoint& pos, const wxSize& size,
57 long style, const wxString& name):
58 wxTextCtrl(parent, id, value, pos, size, style, wxDefaultValidator, name)
59{
fd71308f 60 m_view = v;
457814b5
JS
61}
62
63void wxPropertyTextEdit::OnSetFocus(void)
64{
65}
66
67void wxPropertyTextEdit::OnKillFocus(void)
68{
69}
70
71/*
72 * Property list view
73 */
74
75IMPLEMENT_DYNAMIC_CLASS(wxPropertyListView, wxPropertyView)
76
77BEGIN_EVENT_TABLE(wxPropertyListView, wxPropertyView)
78 EVT_BUTTON(wxID_OK, wxPropertyListView::OnOk)
79 EVT_BUTTON(wxID_CANCEL, wxPropertyListView::OnCancel)
80 EVT_BUTTON(wxID_HELP, wxPropertyListView::OnHelp)
81 EVT_BUTTON(wxID_PROP_CROSS, wxPropertyListView::OnCross)
82 EVT_BUTTON(wxID_PROP_CHECK, wxPropertyListView::OnCheck)
83 EVT_BUTTON(wxID_PROP_EDIT, wxPropertyListView::OnEdit)
84 EVT_TEXT_ENTER(wxID_PROP_TEXT, wxPropertyListView::OnText)
85 EVT_LISTBOX(wxID_PROP_SELECT, wxPropertyListView::OnPropertySelect)
86 EVT_COMMAND(wxID_PROP_SELECT, wxEVT_COMMAND_LISTBOX_DOUBLECLICKED, wxPropertyListView::OnPropertyDoubleClick)
1573d8ed 87 EVT_LISTBOX(wxID_PROP_VALUE_SELECT, wxPropertyListView::OnValueListSelect)
457814b5
JS
88END_EVENT_TABLE()
89
fd71308f
JS
90bool wxPropertyListView::sm_dialogCancelled = FALSE;
91wxBitmap *wxPropertyListView::sm_tickBitmap = NULL;
92wxBitmap *wxPropertyListView::sm_crossBitmap = NULL;
457814b5
JS
93
94wxPropertyListView::wxPropertyListView(wxPanel *propPanel, long flags):wxPropertyView(flags)
95{
fd71308f
JS
96 m_propertyScrollingList = NULL;
97 m_valueList = NULL;
98 m_valueText = NULL;
99 m_editButton = NULL;
100 m_confirmButton = NULL;
101 m_cancelButton = NULL;
102 m_propertyWindow = propPanel;
103 m_managedWindow = NULL;
457814b5 104
fd71308f
JS
105 m_windowCloseButton = NULL;
106 m_windowCancelButton = NULL;
107 m_windowHelpButton = NULL;
457814b5 108
fd71308f 109 m_detailedEditing = FALSE;
457814b5
JS
110}
111
112wxPropertyListView::~wxPropertyListView(void)
113{
114/*
fd71308f
JS
115 if (m_tickBitmap)
116 delete m_tickBitmap;
117 if (m_crossBitmap)
118 delete m_crossBitmap;
457814b5
JS
119*/
120}
121
122void wxPropertyListView::ShowView(wxPropertySheet *ps, wxPanel *panel)
123{
fd71308f
JS
124 m_propertySheet = ps;
125
457814b5
JS
126 AssociatePanel(panel);
127 CreateControls();
128
129 UpdatePropertyList();
130 panel->Layout();
131}
132
133// Update this view of the viewed object, called e.g. by
134// the object itself.
135bool wxPropertyListView::OnUpdateView(void)
136{
137 return TRUE;
138}
139
140bool wxPropertyListView::UpdatePropertyList(bool clearEditArea)
141{
fd71308f 142 if (!m_propertyScrollingList || !m_propertySheet)
457814b5
JS
143 return FALSE;
144
fd71308f 145 m_propertyScrollingList->Clear();
457814b5
JS
146 if (clearEditArea)
147 {
fd71308f
JS
148 m_valueList->Clear();
149 m_valueText->SetValue("");
457814b5 150 }
fd71308f 151 wxNode *node = m_propertySheet->GetProperties().First();
457814b5
JS
152
153 // Should sort them... later...
154 while (node)
155 {
156 wxProperty *property = (wxProperty *)node->Data();
157 wxString stringValueRepr(property->GetValue().GetStringRepresentation());
158 wxString paddedString(MakeNameValueString(property->GetName(), stringValueRepr));
159
fd71308f 160 m_propertyScrollingList->Append(paddedString.GetData(), (char *)property);
457814b5
JS
161 node = node->Next();
162 }
163 return TRUE;
164}
165
166bool wxPropertyListView::UpdatePropertyDisplayInList(wxProperty *property)
167{
fd71308f 168 if (!m_propertyScrollingList || !m_propertySheet)
457814b5
JS
169 return FALSE;
170
fd71308f 171 int currentlySelected = m_propertyScrollingList->GetSelection();
2049ba38 172// #ifdef __WXMSW__
457814b5
JS
173 wxString stringValueRepr(property->GetValue().GetStringRepresentation());
174 wxString paddedString(MakeNameValueString(property->GetName(), stringValueRepr));
175 int sel = FindListIndexForProperty(property);
176
177 if (sel > -1)
178 {
179 // Don't update the listbox unnecessarily because it can cause
180 // ugly flashing.
181
fd71308f
JS
182 if (paddedString != m_propertyScrollingList->GetString(sel))
183 m_propertyScrollingList->SetString(sel, paddedString.GetData());
457814b5
JS
184 }
185//#else
186// UpdatePropertyList(FALSE);
187//#endif
188
b8c631bb
JS
189 // TODO: why is this necessary?
190#ifdef __WXMSW__
457814b5 191 if (currentlySelected > -1)
fd71308f 192 m_propertyScrollingList->SetSelection(currentlySelected);
b8c631bb 193#endif
457814b5
JS
194
195 return TRUE;
196}
197
198// Find the wxListBox index corresponding to this property
199int wxPropertyListView::FindListIndexForProperty(wxProperty *property)
200{
fd71308f 201 int n = m_propertyScrollingList->Number();
457814b5
JS
202 for (int i = 0; i < n; i++)
203 {
fd71308f 204 if (property == (wxProperty *)m_propertyScrollingList->wxListBox::GetClientData(i))
457814b5
JS
205 return i;
206 }
207 return -1;
208}
209
210wxString wxPropertyListView::MakeNameValueString(wxString name, wxString value)
211{
212 wxString theString(name);
213
214 int nameWidth = 25;
215 int padWith = nameWidth - theString.Length();
216 if (padWith < 0)
217 padWith = 0;
218
219 if (GetFlags() & wxPROP_SHOWVALUES)
220 {
221 // Want to pad with spaces
222 theString.Append(' ', padWith);
223 theString += value;
224 }
225
226 return theString;
227}
228
229// Select and show string representation in validator the given
230// property. NULL resets to show no property.
231bool wxPropertyListView::ShowProperty(wxProperty *property, bool select)
232{
fd71308f 233 if (m_currentProperty)
457814b5 234 {
fd71308f
JS
235 EndShowingProperty(m_currentProperty);
236 m_currentProperty = NULL;
457814b5
JS
237 }
238
fd71308f
JS
239 m_valueList->Clear();
240 m_valueText->SetValue("");
457814b5
JS
241
242 if (property)
243 {
fd71308f 244 m_currentProperty = property;
457814b5
JS
245 BeginShowingProperty(property);
246 }
247 if (select)
248 {
249 int sel = FindListIndexForProperty(property);
250 if (sel > -1)
fd71308f 251 m_propertyScrollingList->SetSelection(sel);
457814b5
JS
252 }
253 return TRUE;
254}
255
256// Find appropriate validator and load property into value controls
257bool wxPropertyListView::BeginShowingProperty(wxProperty *property)
258{
fd71308f
JS
259 m_currentValidator = FindPropertyValidator(property);
260 if (!m_currentValidator)
457814b5
JS
261 return FALSE;
262
fd71308f 263 if (!m_currentValidator->IsKindOf(CLASSINFO(wxPropertyListValidator)))
457814b5
JS
264 return FALSE;
265
fd71308f 266 wxPropertyListValidator *listValidator = (wxPropertyListValidator *)m_currentValidator;
457814b5 267
fd71308f 268 listValidator->OnPrepareControls(property, this, m_propertyWindow);
457814b5
JS
269 DisplayProperty(property);
270 return TRUE;
271}
272
273// Find appropriate validator and unload property from value controls
274bool wxPropertyListView::EndShowingProperty(wxProperty *property)
275{
fd71308f 276 if (!m_currentValidator)
457814b5
JS
277 return FALSE;
278
279 RetrieveProperty(property);
280
fd71308f 281 if (!m_currentValidator->IsKindOf(CLASSINFO(wxPropertyListValidator)))
457814b5
JS
282 return FALSE;
283
fd71308f 284 wxPropertyListValidator *listValidator = (wxPropertyListValidator *)m_currentValidator;
457814b5 285
fd71308f
JS
286 listValidator->OnClearControls(property, this, m_propertyWindow);
287 if (m_detailedEditing)
457814b5 288 {
fd71308f
JS
289 listValidator->OnClearDetailControls(property, this, m_propertyWindow);
290 m_detailedEditing = FALSE;
457814b5
JS
291 }
292 return TRUE;
293}
294
295void wxPropertyListView::BeginDetailedEditing(void)
296{
fd71308f 297 if (!m_currentValidator)
457814b5 298 return;
fd71308f 299 if (!m_currentProperty)
457814b5 300 return;
fd71308f 301 if (m_detailedEditing)
457814b5 302 return;
fd71308f 303 if (!m_currentValidator->IsKindOf(CLASSINFO(wxPropertyListValidator)))
457814b5 304 return;
fd71308f 305 if (!m_currentProperty->IsEnabled())
457814b5
JS
306 return;
307
fd71308f 308 wxPropertyListValidator *listValidator = (wxPropertyListValidator *)m_currentValidator;
457814b5 309
fd71308f
JS
310 if (listValidator->OnPrepareDetailControls(m_currentProperty, this, m_propertyWindow))
311 m_detailedEditing = TRUE;
457814b5
JS
312}
313
314void wxPropertyListView::EndDetailedEditing(void)
315{
fd71308f 316 if (!m_currentValidator)
457814b5 317 return;
fd71308f 318 if (!m_currentProperty)
457814b5
JS
319 return;
320
fd71308f 321 RetrieveProperty(m_currentProperty);
457814b5 322
fd71308f 323 if (!m_currentValidator->IsKindOf(CLASSINFO(wxPropertyListValidator)))
457814b5
JS
324 return;
325
fd71308f 326 wxPropertyListValidator *listValidator = (wxPropertyListValidator *)m_currentValidator;
457814b5 327
fd71308f 328 if (m_detailedEditing)
457814b5 329 {
fd71308f
JS
330 listValidator->OnClearDetailControls(m_currentProperty, this, m_propertyWindow);
331 m_detailedEditing = FALSE;
457814b5
JS
332 }
333}
334
335bool wxPropertyListView::DisplayProperty(wxProperty *property)
336{
fd71308f 337 if (!m_currentValidator)
457814b5
JS
338 return FALSE;
339
fd71308f
JS
340 if (((m_currentValidator->GetFlags() & wxPROP_ALLOW_TEXT_EDITING) == 0) || !property->IsEnabled())
341 m_valueText->SetEditable(FALSE);
457814b5 342 else
fd71308f 343 m_valueText->SetEditable(TRUE);
457814b5 344
fd71308f 345 if (!m_currentValidator->IsKindOf(CLASSINFO(wxPropertyListValidator)))
457814b5
JS
346 return FALSE;
347
fd71308f 348 wxPropertyListValidator *listValidator = (wxPropertyListValidator *)m_currentValidator;
457814b5 349
fd71308f 350 listValidator->OnDisplayValue(property, this, m_propertyWindow);
457814b5
JS
351 return TRUE;
352}
353
354bool wxPropertyListView::RetrieveProperty(wxProperty *property)
355{
fd71308f 356 if (!m_currentValidator)
457814b5
JS
357 return FALSE;
358 if (!property->IsEnabled())
359 return FALSE;
360
fd71308f 361 if (!m_currentValidator->IsKindOf(CLASSINFO(wxPropertyListValidator)))
457814b5
JS
362 return FALSE;
363
fd71308f 364 wxPropertyListValidator *listValidator = (wxPropertyListValidator *)m_currentValidator;
457814b5 365
fd71308f 366 if (listValidator->OnCheckValue(property, this, m_propertyWindow))
457814b5 367 {
fd71308f 368 if (listValidator->OnRetrieveValue(property, this, m_propertyWindow))
457814b5
JS
369 {
370 UpdatePropertyDisplayInList(property);
371 OnPropertyChanged(property);
372 }
373 }
374 else
375 {
376 // Revert to old value
fd71308f 377 listValidator->OnDisplayValue(property, this, m_propertyWindow);
457814b5
JS
378 }
379 return TRUE;
380}
381
382
8656024d 383bool wxPropertyListView::EditProperty(wxProperty *WXUNUSED(property))
457814b5
JS
384{
385 return TRUE;
386}
387
388// Called by the listbox callback
8656024d 389void wxPropertyListView::OnPropertySelect(wxCommandEvent& WXUNUSED(event))
457814b5 390{
fd71308f 391 int sel = m_propertyScrollingList->GetSelection();
457814b5
JS
392 if (sel > -1)
393 {
fd71308f
JS
394 wxProperty *newSel = (wxProperty *)m_propertyScrollingList->wxListBox::GetClientData(sel);
395 if (newSel && newSel != m_currentProperty)
457814b5
JS
396 {
397 ShowProperty(newSel, FALSE);
398 }
399 }
400}
401
402bool wxPropertyListView::CreateControls(void)
403{
fd71308f 404 wxPanel *panel = (wxPanel *)m_propertyWindow;
457814b5 405
bbcdf8bc 406 int largeButtonWidth = 60;
457814b5
JS
407 int largeButtonHeight = 25;
408
409 int smallButtonWidth = 25;
410 int smallButtonHeight = 20;
411
412 // XView must be allowed to choose its own sized buttons
413#ifdef __XVIEW__
414 largeButtonWidth = -1;
415 largeButtonHeight = -1;
416
417 smallButtonWidth = -1;
418 smallButtonHeight = -1;
419#endif
420
fd71308f 421 if (m_valueText)
457814b5
JS
422 return TRUE;
423
424 if (!panel)
425 return FALSE;
426
427 wxWindow *leftMostWindow = panel;
428 wxWindow *topMostWindow = panel;
429 wxWindow *rightMostWindow = panel;
430
431 wxSystemSettings settings;
432 wxFont guiFont = settings.GetSystemFont(wxSYS_DEFAULT_GUI_FONT);
433
bbcdf8bc 434#ifdef __WXMSW__
1573d8ed 435 wxFont *boringFont = wxTheFontList->FindOrCreateFont(guiFont.GetPointSize(), wxMODERN, wxNORMAL, wxNORMAL, FALSE, "Courier New");
bbcdf8bc 436#else
1573d8ed 437 wxFont *boringFont = wxTheFontList->FindOrCreateFont(guiFont.GetPointSize(), wxTELETYPE, wxNORMAL, wxNORMAL);
bbcdf8bc 438#endif
457814b5
JS
439
440 // May need to be changed in future to eliminate clashes with app.
441 panel->SetClientData((char *)this);
442
bbcdf8bc
JS
443 // These buttons are at the bottom of the window, but create them now
444 // so the constraints are evaluated in the correct order
fd71308f 445 if (m_buttonFlags & wxPROP_BUTTON_OK)
457814b5 446 {
fd71308f 447 m_windowCloseButton = new wxButton(panel, wxID_OK, "OK",
457814b5 448 wxPoint(-1, -1), wxSize(largeButtonWidth, largeButtonHeight));
fd71308f
JS
449 m_windowCloseButton->SetDefault();
450 m_windowCloseButton->SetFocus();
457814b5 451 }
fd71308f 452 else if (m_buttonFlags & wxPROP_BUTTON_CLOSE)
457814b5 453 {
fd71308f 454 m_windowCloseButton = new wxButton(panel, wxID_OK, "Close",
457814b5
JS
455 wxPoint(-1, -1), wxSize(largeButtonWidth, largeButtonHeight));
456 }
fd71308f 457 if (m_buttonFlags & wxPROP_BUTTON_CANCEL)
457814b5 458 {
fd71308f 459 m_windowCancelButton = new wxButton(panel, wxID_CANCEL, "Cancel",
457814b5
JS
460 wxPoint(-1, -1), wxSize(largeButtonWidth, largeButtonHeight));
461 }
fd71308f 462 if (m_buttonFlags & wxPROP_BUTTON_HELP)
457814b5 463 {
fd71308f 464 m_windowHelpButton = new wxButton(panel, wxID_HELP, "Help",
457814b5
JS
465 wxPoint(-1, -1), wxSize(largeButtonWidth, largeButtonHeight));
466 }
467
fd71308f 468 if (m_windowCloseButton)
457814b5
JS
469 {
470 wxLayoutConstraints *c1 = new wxLayoutConstraints;
bbcdf8bc 471
457814b5 472 c1->left.SameAs (panel, wxLeft, 2);
bbcdf8bc 473 c1->bottom.SameAs (panel, wxBottom, 2);
457814b5
JS
474 c1->width.AsIs();
475 c1->height.AsIs();
fd71308f
JS
476 m_windowCloseButton->SetConstraints(c1);
477 leftMostWindow = m_windowCloseButton;
457814b5 478 }
fd71308f 479 if (m_windowCancelButton)
457814b5
JS
480 {
481 wxLayoutConstraints *c2 = new wxLayoutConstraints;
bbcdf8bc
JS
482
483 c2->right.SameAs (panel, wxRight, 2);
484 c2->bottom.SameAs (panel, wxBottom, 2);
457814b5
JS
485 c2->width.AsIs();
486 c2->height.AsIs();
fd71308f
JS
487 m_windowCancelButton->SetConstraints(c2);
488 leftMostWindow = m_windowCancelButton;
457814b5 489 }
fd71308f 490 if (m_windowHelpButton)
457814b5
JS
491 {
492 wxLayoutConstraints *c2 = new wxLayoutConstraints;
493 if (leftMostWindow == panel)
494 c2->left.SameAs (panel, wxLeft, 2);
495 else
496 c2->left.RightOf (leftMostWindow, 2);
497
bbcdf8bc 498 c2->bottom.SameAs (panel, wxBottom, 2);
457814b5
JS
499 c2->width.AsIs();
500 c2->height.AsIs();
fd71308f
JS
501 m_windowHelpButton->SetConstraints(c2);
502 leftMostWindow = m_windowHelpButton;
457814b5
JS
503 }
504
fd71308f 505 if (m_buttonFlags & wxPROP_BUTTON_CHECK_CROSS)
457814b5
JS
506 {
507/*
508 if (!tickBitmap)
509 {
2049ba38 510#ifdef __WXMSW__
457814b5
JS
511 tickBitmap = new wxBitmap("tick_bmp", wxBITMAP_TYPE_RESOURCE);
512 crossBitmap = new wxBitmap("cross_bmp", wxBITMAP_TYPE_RESOURCE);
513 if (!tickBitmap || !crossBitmap || !tickBitmap->Ok() || !crossBitmap->Ok())
514 {
515 if (tickBitmap)
516 delete tickBitmap;
517 if (crossBitmap)
518 delete crossBitmap;
519 tickBitmap = NULL;
520 crossBitmap = NULL;
521 }
522#endif
523 }
524*/
525/*
526 if (tickBitmap && crossBitmap)
527 {
fd71308f 528 m_confirmButton = new wxBitmapButton(panel, wxID_PROP_CHECK, tickBitmap,
457814b5 529 wxPoint(-1, -1), wxSize(smallButtonWidth-5, smallButtonHeight-5));
fd71308f 530 m_cancelButton = new wxBitmapButton(panel, wxID_PROP_CROSS, crossBitmap,
457814b5
JS
531 wxPoint(-1, -1), wxSize(smallButtonWidth-5, smallButtonHeight-5));
532 }
533 else
534*/
535 {
fd71308f 536 m_confirmButton = new wxButton(panel, wxID_PROP_CHECK, ":-)",
457814b5 537 wxPoint(-1, -1), wxSize(smallButtonWidth, smallButtonHeight));
fd71308f 538 m_cancelButton = new wxButton(panel, wxID_PROP_CROSS, "X",
457814b5
JS
539 wxPoint(-1, -1), wxSize(smallButtonWidth, smallButtonHeight));
540 }
541
542 wxLayoutConstraints *c = new wxLayoutConstraints;
543 c->left.SameAs (panel, wxLeft, 2);
bbcdf8bc 544/*
457814b5 545 if (windowCloseButton)
fd71308f 546 c->top.Below (m_windowCloseButton, 2);
457814b5 547 else
bbcdf8bc 548*/
457814b5
JS
549 c->top.SameAs (panel, wxTop, 2);
550
551 c->width.AsIs();
552 c->height.AsIs();
553
fd71308f 554 m_cancelButton->SetConstraints(c);
457814b5
JS
555
556 c = new wxLayoutConstraints;
fd71308f
JS
557 c->left.RightOf (m_cancelButton, 2);
558 c->top.SameAs (m_cancelButton, wxTop, 0);
457814b5
JS
559 c->width.AsIs();
560 c->height.AsIs();
561
fd71308f 562 m_confirmButton->SetConstraints(c);
457814b5 563
fd71308f
JS
564 m_cancelButton->Enable(FALSE);
565 m_confirmButton->Enable(FALSE);
457814b5
JS
566 }
567
fd71308f 568 if (m_buttonFlags & wxPROP_PULLDOWN)
457814b5 569 {
fd71308f 570 m_editButton = new wxButton(panel, wxID_PROP_EDIT, "...",
457814b5 571 wxPoint(-1, -1), wxSize(smallButtonWidth, smallButtonHeight));
fd71308f 572 m_editButton->Enable(FALSE);
457814b5
JS
573 wxLayoutConstraints *c = new wxLayoutConstraints;
574
bbcdf8bc 575/*
fd71308f
JS
576 if (m_windowCloseButton)
577 c->top.Below (m_windowCloseButton, 2);
457814b5 578 else
bbcdf8bc 579*/
457814b5
JS
580 c->top.SameAs (panel, wxTop, 2);
581
582 c->right.SameAs (panel, wxRight, 2);
583 c->width.AsIs();
584 c->height.AsIs();
fd71308f 585 m_editButton->SetConstraints(c);
457814b5
JS
586 }
587
fd71308f
JS
588 m_valueText = new wxPropertyTextEdit(this, panel, wxID_PROP_TEXT, "", wxPoint(-1, -1), wxSize(-1, -1), wxPROCESS_ENTER);
589 m_valueText->Enable(FALSE);
457814b5
JS
590
591 wxLayoutConstraints *c = new wxLayoutConstraints;
592
fd71308f
JS
593 if (m_cancelButton)
594 c->left.RightOf (m_confirmButton, 2);
457814b5
JS
595 else
596 c->left.SameAs (panel, wxLeft, 2);
bbcdf8bc 597/*
fd71308f
JS
598 if (m_windowCloseButton)
599 c->top.Below (m_windowCloseButton, 2);
457814b5 600 else
bbcdf8bc 601*/
457814b5
JS
602 c->top.SameAs (panel, wxTop, 2);
603
fd71308f
JS
604 if (m_editButton)
605 c->right.LeftOf (m_editButton, 2);
457814b5
JS
606 else
607 c->right.SameAs (panel, wxRight, 2);
608 c->height.AsIs();
609
fd71308f 610 m_valueText->SetConstraints(c);
457814b5 611
fd71308f
JS
612 m_valueList = new wxListBox(panel, wxID_PROP_VALUE_SELECT, wxPoint(-1, -1), wxSize(-1, 60));
613 m_valueList->Show(FALSE);
457814b5
JS
614
615 c = new wxLayoutConstraints;
616
617 c->left.SameAs (panel, wxLeft, 2);
fd71308f 618 c->top.Below (m_valueText, 2);
457814b5
JS
619 c->right.SameAs (panel, wxRight, 2);
620 c->height.Absolute(60);
621
fd71308f 622 m_valueList->SetConstraints(c);
457814b5 623
fd71308f 624 m_propertyScrollingList = new wxListBox(panel, wxID_PROP_SELECT,
457814b5 625 wxPoint(-1, -1), wxSize(300, 300));
fd71308f 626 m_propertyScrollingList->SetFont(boringFont);
457814b5
JS
627
628 c = new wxLayoutConstraints;
629
630 c->left.SameAs (panel, wxLeft, 2);
631
fd71308f
JS
632 if (m_buttonFlags & wxPROP_DYNAMIC_VALUE_FIELD)
633 c->top.Below (m_valueText, 2);
457814b5 634 else
fd71308f 635 c->top.Below (m_valueList, 2);
457814b5
JS
636
637 c->right.SameAs (panel, wxRight, 2);
bbcdf8bc 638
fd71308f
JS
639 if (m_windowCloseButton)
640 c->bottom.Above (m_windowCloseButton, -2);
bbcdf8bc
JS
641 else
642 c->bottom.SameAs (panel, wxBottom, 2);
457814b5 643
fd71308f 644 m_propertyScrollingList->SetConstraints(c);
bbcdf8bc 645
457814b5
JS
646 // Note: if this is called now, it causes a GPF.
647 // Why?
648// panel->Layout();
649
650 return TRUE;
651}
652
653void wxPropertyListView::ShowTextControl(bool show)
654{
fd71308f
JS
655 if (m_valueText)
656 m_valueText->Show(show);
457814b5
JS
657}
658
659void wxPropertyListView::ShowListBoxControl(bool show)
660{
fd71308f 661 if (m_valueList)
457814b5 662 {
fd71308f
JS
663 m_valueList->Show(show);
664 if (m_buttonFlags & wxPROP_DYNAMIC_VALUE_FIELD)
457814b5 665 {
fd71308f 666 wxLayoutConstraints *constraints = m_propertyScrollingList->GetConstraints();
457814b5
JS
667 if (constraints)
668 {
669 if (show)
1573d8ed 670 {
fd71308f 671 constraints->top.Below(m_valueList, 2);
1573d8ed
JS
672 // Maintain back-pointer so when valueList is deleted,
673 // any reference to it from this window is removed.
fd71308f 674 m_valueList->AddConstraintReference(m_propertyScrollingList);
1573d8ed 675 }
457814b5 676 else
1573d8ed 677 {
fd71308f
JS
678 constraints->top.Below(m_valueText, 2);
679 m_valueText->AddConstraintReference(m_propertyScrollingList);
1573d8ed 680 }
fd71308f 681 m_propertyWindow->Layout();
457814b5
JS
682 }
683 }
684 }
685}
686
687void wxPropertyListView::EnableCheck(bool show)
688{
fd71308f
JS
689 if (m_confirmButton)
690 m_confirmButton->Enable(show);
457814b5
JS
691}
692
693void wxPropertyListView::EnableCross(bool show)
694{
fd71308f
JS
695 if (m_cancelButton)
696 m_cancelButton->Enable(show);
457814b5
JS
697}
698
699bool wxPropertyListView::OnClose(void)
700{
701 // Retrieve the value if any
702 wxCommandEvent event;
703 OnCheck(event);
704
705 delete this;
706 return TRUE;
707}
708
8656024d 709void wxPropertyListView::OnValueListSelect(wxCommandEvent& WXUNUSED(event))
457814b5 710{
fd71308f 711 if (m_currentProperty && m_currentValidator)
457814b5 712 {
fd71308f 713 if (!m_currentValidator->IsKindOf(CLASSINFO(wxPropertyListValidator)))
457814b5
JS
714 return;
715
fd71308f 716 wxPropertyListValidator *listValidator = (wxPropertyListValidator *)m_currentValidator;
457814b5 717
fd71308f 718 listValidator->OnValueListSelect(m_currentProperty, this, m_propertyWindow);
457814b5
JS
719 }
720}
721
722void wxPropertyListView::OnOk(wxCommandEvent& event)
723{
724 // Retrieve the value if any
725 OnCheck(event);
726
fd71308f 727 m_managedWindow->Close(TRUE);
457814b5
JS
728}
729
8656024d 730void wxPropertyListView::OnCancel(wxCommandEvent& WXUNUSED(event))
457814b5
JS
731{
732// SetReturnCode(wxID_CANCEL);
fd71308f
JS
733 m_managedWindow->Close(TRUE);
734 sm_dialogCancelled = TRUE;
457814b5
JS
735}
736
8656024d 737void wxPropertyListView::OnHelp(wxCommandEvent& WXUNUSED(event))
457814b5
JS
738{
739}
740
8656024d 741void wxPropertyListView::OnCheck(wxCommandEvent& WXUNUSED(event))
457814b5 742{
fd71308f 743 if (m_currentProperty)
457814b5 744 {
fd71308f 745 RetrieveProperty(m_currentProperty);
457814b5
JS
746 }
747}
748
8656024d 749void wxPropertyListView::OnCross(wxCommandEvent& WXUNUSED(event))
457814b5 750{
fd71308f 751 if (m_currentProperty && m_currentValidator)
457814b5 752 {
fd71308f 753 if (!m_currentValidator->IsKindOf(CLASSINFO(wxPropertyListValidator)))
457814b5
JS
754 return;
755
fd71308f 756 wxPropertyListValidator *listValidator = (wxPropertyListValidator *)m_currentValidator;
457814b5
JS
757
758 // Revert to old value
fd71308f 759 listValidator->OnDisplayValue(m_currentProperty, this, m_propertyWindow);
457814b5
JS
760 }
761}
762
8656024d 763void wxPropertyListView::OnPropertyDoubleClick(wxCommandEvent& WXUNUSED(event))
457814b5 764{
fd71308f 765 if (m_currentProperty && m_currentValidator)
457814b5 766 {
fd71308f 767 if (!m_currentValidator->IsKindOf(CLASSINFO(wxPropertyListValidator)))
457814b5
JS
768 return;
769
fd71308f 770 wxPropertyListValidator *listValidator = (wxPropertyListValidator *)m_currentValidator;
457814b5
JS
771
772 // Revert to old value
fd71308f 773 listValidator->OnDoubleClick(m_currentProperty, this, m_propertyWindow);
457814b5
JS
774 }
775}
776
8656024d 777void wxPropertyListView::OnEdit(wxCommandEvent& WXUNUSED(event))
457814b5 778{
fd71308f 779 if (m_currentProperty && m_currentValidator)
457814b5 780 {
fd71308f 781 if (!m_currentValidator->IsKindOf(CLASSINFO(wxPropertyListValidator)))
457814b5
JS
782 return;
783
fd71308f 784 wxPropertyListValidator *listValidator = (wxPropertyListValidator *)m_currentValidator;
457814b5 785
fd71308f 786 listValidator->OnEdit(m_currentProperty, this, m_propertyWindow);
457814b5
JS
787 }
788}
789
790void wxPropertyListView::OnText(wxCommandEvent& event)
791{
792 if (event.GetEventType() == wxEVT_COMMAND_TEXT_ENTER)
793 {
794 OnCheck(event);
795 }
796}
797
798/*
799 * Property dialog box
800 */
801
802IMPLEMENT_CLASS(wxPropertyListDialog, wxDialog)
803
804BEGIN_EVENT_TABLE(wxPropertyListDialog, wxDialog)
805 EVT_BUTTON(wxID_CANCEL, wxPropertyListDialog::OnCancel)
806END_EVENT_TABLE()
807
808wxPropertyListDialog::wxPropertyListDialog(wxPropertyListView *v, wxWindow *parent,
809 const wxString& title, const wxPoint& pos,
810 const wxSize& size, long style, const wxString& name):
811 wxDialog(parent, -1, title, pos, size, style, name)
812{
fd71308f
JS
813 m_view = v;
814 m_view->AssociatePanel( ((wxPanel*)this) );
815 m_view->SetManagedWindow(this);
457814b5
JS
816 SetAutoLayout(TRUE);
817}
818
819bool wxPropertyListDialog::OnClose(void)
820{
fd71308f 821 if (m_view)
457814b5
JS
822 {
823 SetReturnCode(wxID_CANCEL);
fd71308f
JS
824 m_view->OnClose();
825 m_view = NULL;
457814b5
JS
826 return TRUE;
827 }
828 else
829 return FALSE;
830}
831
8656024d 832void wxPropertyListDialog::OnCancel(wxCommandEvent& WXUNUSED(event))
457814b5
JS
833{
834 SetReturnCode(wxID_CANCEL);
835 this->Close();
836}
837
838void wxPropertyListDialog::OnDefaultAction(wxControl *item)
839{
840/*
fd71308f 841 if (item == m_view->GetPropertyScrollingList())
457814b5
JS
842 view->OnDoubleClick();
843*/
844}
845
846// Extend event processing to search the view's event table
847bool wxPropertyListDialog::ProcessEvent(wxEvent& event)
848{
fd71308f 849 if ( !m_view || ! m_view->ProcessEvent(event) )
457814b5
JS
850 return wxEvtHandler::ProcessEvent(event);
851 else
852 return TRUE;
853}
854
855/*
856 * Property panel
857 */
858
859IMPLEMENT_CLASS(wxPropertyListPanel, wxPanel)
860
bbcdf8bc
JS
861BEGIN_EVENT_TABLE(wxPropertyListPanel, wxPanel)
862 EVT_SIZE(wxPropertyListPanel::OnSize)
863END_EVENT_TABLE()
864
1573d8ed
JS
865wxPropertyListPanel::~wxPropertyListPanel()
866{
867}
868
457814b5
JS
869void wxPropertyListPanel::OnDefaultAction(wxControl *item)
870{
871/*
872 if (item == view->GetPropertyScrollingList())
873 view->OnDoubleClick();
874*/
875}
876
877// Extend event processing to search the view's event table
878bool wxPropertyListPanel::ProcessEvent(wxEvent& event)
879{
fd71308f 880 if ( !m_view || ! m_view->ProcessEvent(event) )
457814b5
JS
881 return wxEvtHandler::ProcessEvent(event);
882 else
883 return TRUE;
884}
885
8656024d 886void wxPropertyListPanel::OnSize(wxSizeEvent& WXUNUSED(event))
bbcdf8bc
JS
887{
888 Layout();
889}
890
457814b5
JS
891/*
892 * Property frame
893 */
894
895IMPLEMENT_CLASS(wxPropertyListFrame, wxFrame)
896
897bool wxPropertyListFrame::OnClose(void)
898{
fd71308f 899 if (m_view)
bbcdf8bc 900 {
fd71308f
JS
901 if (m_propertyPanel)
902 m_propertyPanel->SetView(NULL);
903 m_view->OnClose();
904 m_view = NULL;
bbcdf8bc
JS
905 return TRUE;
906 }
457814b5
JS
907 else
908 return FALSE;
909}
910
bbcdf8bc 911wxPropertyListPanel *wxPropertyListFrame::OnCreatePanel(wxFrame *parent, wxPropertyListView *v)
457814b5
JS
912{
913 return new wxPropertyListPanel(v, parent);
914}
915
916bool wxPropertyListFrame::Initialize(void)
917{
fd71308f
JS
918 m_propertyPanel = OnCreatePanel(this, m_view);
919 if (m_propertyPanel)
457814b5 920 {
fd71308f
JS
921 m_view->AssociatePanel(m_propertyPanel);
922 m_view->SetManagedWindow(this);
923 m_propertyPanel->SetAutoLayout(TRUE);
457814b5
JS
924 return TRUE;
925 }
926 else
927 return FALSE;
928}
929
930 /*
931 * Property list specific validator
932 */
933
934IMPLEMENT_ABSTRACT_CLASS(wxPropertyListValidator, wxPropertyValidator)
935
936bool wxPropertyListValidator::OnSelect(bool select, wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
937{
938// view->GetValueText()->Show(TRUE);
939 if (select)
940 OnDisplayValue(property, view, parentWindow);
941
942 return TRUE;
943}
944
945bool wxPropertyListValidator::OnValueListSelect(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
946{
947 wxString s(view->GetValueList()->GetStringSelection());
948 if (s != "")
949 {
950 view->GetValueText()->SetValue(s);
951 view->RetrieveProperty(property);
952 }
953 return TRUE;
954}
955
956bool wxPropertyListValidator::OnDisplayValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
957{
958// view->GetValueText()->Show(TRUE);
959 wxString str(property->GetValue().GetStringRepresentation());
960
b8c631bb 961 view->GetValueText()->SetValue(str);
457814b5
JS
962 return TRUE;
963}
964
965// Called when TICK is pressed or focus is lost or view wants to update
966// the property list.
967// Does the transferance from the property editing area to the property itself
968bool wxPropertyListValidator::OnRetrieveValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
969{
970 if (!view->GetValueText())
971 return FALSE;
972 return FALSE;
973}
974
975void wxPropertyListValidator::OnEdit(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
976{
977 if (view->GetDetailedEditing())
978 view->EndDetailedEditing();
979 else
980 view->BeginDetailedEditing();
981}
982
983bool wxPropertyListValidator::OnClearControls(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
984{
985 if (view->GetConfirmButton())
986 view->GetConfirmButton()->Enable(FALSE);
987 if (view->GetCancelButton())
988 view->GetCancelButton()->Enable(FALSE);
989 if (view->GetEditButton())
990 view->GetEditButton()->Enable(FALSE);
991 return TRUE;
992}
993
994/*
995 * Default validators
996 */
997
998IMPLEMENT_DYNAMIC_CLASS(wxRealListValidator, wxPropertyListValidator)
999
1000///
1001/// Real number validator
1002///
1003bool wxRealListValidator::OnCheckValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1004{
fd71308f 1005 if (m_realMin == 0.0 && m_realMax == 0.0)
457814b5
JS
1006 return TRUE;
1007
1008 if (!view->GetValueText())
1009 return FALSE;
1010 wxString value(view->GetValueText()->GetValue());
1011
1012 float val = 0.0;
1013 if (!StringToFloat(WXSTRINGCAST value, &val))
1014 {
1015 char buf[200];
1016 sprintf(buf, "Value %s is not a valid real number!", value.GetData());
1017 wxMessageBox(buf, "Property value error", wxOK | wxICON_EXCLAMATION, parentWindow);
1018 return FALSE;
1019 }
1020
fd71308f 1021 if (val < m_realMin || val > m_realMax)
457814b5
JS
1022 {
1023 char buf[200];
fd71308f 1024 sprintf(buf, "Value must be a real number between %.2f and %.2f!", m_realMin, m_realMax);
457814b5
JS
1025 wxMessageBox(buf, "Property value error", wxOK | wxICON_EXCLAMATION, parentWindow);
1026 return FALSE;
1027 }
1028 return TRUE;
1029}
1030
1031// Called when TICK is pressed or focus is lost or view wants to update
1032// the property list.
1033// Does the transferance from the property editing area to the property itself
1034bool wxRealListValidator::OnRetrieveValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1035{
1036 if (!view->GetValueText())
1037 return FALSE;
1038
1039 if (strlen(view->GetValueText()->GetValue()) == 0)
1040 return FALSE;
1041
1042 wxString value(view->GetValueText()->GetValue());
1043 float f = (float)atof(value.GetData());
1044 property->GetValue() = f;
1045 return TRUE;
1046}
1047
1048bool wxRealListValidator::OnPrepareControls(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1049{
1050 if (view->GetConfirmButton())
1051 view->GetConfirmButton()->Enable(TRUE);
1052 if (view->GetCancelButton())
1053 view->GetCancelButton()->Enable(TRUE);
1054 if (view->GetEditButton())
1055 view->GetEditButton()->Enable(FALSE);
1056 if (view->GetValueText())
1057 view->GetValueText()->Enable(TRUE);
1058 return TRUE;
1059}
1060
1061///
1062/// Integer validator
1063///
1064IMPLEMENT_DYNAMIC_CLASS(wxIntegerListValidator, wxPropertyListValidator)
1065
1066bool wxIntegerListValidator::OnCheckValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1067{
fd71308f 1068 if (m_integerMin == 0 && m_integerMax == 0)
457814b5
JS
1069 return TRUE;
1070
1071 if (!view->GetValueText())
1072 return FALSE;
1073 wxString value(view->GetValueText()->GetValue());
1074
1075 long val = 0;
1076 if (!StringToLong(WXSTRINGCAST value, &val))
1077 {
1078 char buf[200];
1079 sprintf(buf, "Value %s is not a valid integer!", value.GetData());
1080 wxMessageBox(buf, "Property value error", wxOK | wxICON_EXCLAMATION, parentWindow);
1081 return FALSE;
1082 }
fd71308f 1083 if (val < m_integerMin || val > m_integerMax)
457814b5
JS
1084 {
1085 char buf[200];
fd71308f 1086 sprintf(buf, "Value must be an integer between %ld and %ld!", m_integerMin, m_integerMax);
457814b5
JS
1087 wxMessageBox(buf, "Property value error", wxOK | wxICON_EXCLAMATION, parentWindow);
1088 return FALSE;
1089 }
1090 return TRUE;
1091}
1092
1093// Called when TICK is pressed or focus is lost or view wants to update
1094// the property list.
1095// Does the transferance from the property editing area to the property itself
1096bool wxIntegerListValidator::OnRetrieveValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1097{
1098 if (!view->GetValueText())
1099 return FALSE;
1100
1101 if (strlen(view->GetValueText()->GetValue()) == 0)
1102 return FALSE;
1103
1104 wxString value(view->GetValueText()->GetValue());
1105 long val = (long)atoi(value.GetData());
1106 property->GetValue() = (long)val;
1107 return TRUE;
1108}
1109
1110bool wxIntegerListValidator::OnPrepareControls(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1111{
1112 if (view->GetConfirmButton())
1113 view->GetConfirmButton()->Enable(TRUE);
1114 if (view->GetCancelButton())
1115 view->GetCancelButton()->Enable(TRUE);
1116 if (view->GetEditButton())
1117 view->GetEditButton()->Enable(FALSE);
1118 if (view->GetValueText())
1119 view->GetValueText()->Enable(TRUE);
1120 return TRUE;
1121}
1122
1123///
1124/// boolean validator
1125///
1126IMPLEMENT_DYNAMIC_CLASS(wxBoolListValidator, wxPropertyListValidator)
1127
1128bool wxBoolListValidator::OnCheckValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1129{
1130 if (!view->GetValueText())
1131 return FALSE;
1132 wxString value(view->GetValueText()->GetValue());
1133 if (value != "True" && value != "False")
1134 {
1135 wxMessageBox("Value must be True or False!", "Property value error", wxOK | wxICON_EXCLAMATION, parentWindow);
1136 return FALSE;
1137 }
1138 return TRUE;
1139}
1140
1141// Called when TICK is pressed or focus is lost or view wants to update
1142// the property list.
1143// Does the transferance from the property editing area to the property itself
1144bool wxBoolListValidator::OnRetrieveValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1145{
1146 if (!view->GetValueText())
1147 return FALSE;
1148
1149 if (strlen(view->GetValueText()->GetValue()) == 0)
1150 return FALSE;
1151
1152 wxString value(view->GetValueText()->GetValue());
1153 bool boolValue = FALSE;
1154 if (value == "True")
1155 boolValue = TRUE;
1156 else
1157 boolValue = FALSE;
1158 property->GetValue() = (bool)boolValue;
1159 return TRUE;
1160}
1161
1162bool wxBoolListValidator::OnDisplayValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1163{
1164 if (!view->GetValueText())
1165 return FALSE;
1166 wxString str(property->GetValue().GetStringRepresentation());
1167
b8c631bb
JS
1168 view->GetValueText()->SetValue(str);
1169
1170 if (view->GetValueList()->IsShown())
1171 {
1172 view->GetValueList()->SetStringSelection(str);
1173 }
457814b5
JS
1174 return TRUE;
1175}
1176
1177bool wxBoolListValidator::OnPrepareControls(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1178{
1179 if (view->GetConfirmButton())
1180 view->GetConfirmButton()->Enable(FALSE);
1181 if (view->GetCancelButton())
1182 view->GetCancelButton()->Enable(FALSE);
1183 if (view->GetEditButton())
1184 view->GetEditButton()->Enable(TRUE);
1185 if (view->GetValueText())
1186 view->GetValueText()->Enable(FALSE);
1187 return TRUE;
1188}
1189
1190bool wxBoolListValidator::OnPrepareDetailControls(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1191{
1192 if (view->GetValueList())
1193 {
1194 view->ShowListBoxControl(TRUE);
1195 view->GetValueList()->Enable(TRUE);
1196
1197 view->GetValueList()->Append("True");
1198 view->GetValueList()->Append("False");
1199 char *currentString = copystring(view->GetValueText()->GetValue());
1200 view->GetValueList()->SetStringSelection(currentString);
1201 delete[] currentString;
1202 }
1203 return TRUE;
1204}
1205
1206bool wxBoolListValidator::OnClearDetailControls(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1207{
1208 if (view->GetValueList())
1209 {
1210 view->GetValueList()->Clear();
1211 view->ShowListBoxControl(FALSE);
1212 view->GetValueList()->Enable(FALSE);
1213 }
1214 return TRUE;
1215}
1216
1217// Called when the property is double clicked. Extra functionality can be provided,
1218// cycling through possible values.
1219bool wxBoolListValidator::OnDoubleClick(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1220{
1221 if (!view->GetValueText())
1222 return FALSE;
1223 if (property->GetValue().BoolValue())
1224 property->GetValue() = (bool)FALSE;
1225 else
1226 property->GetValue() = (bool)TRUE;
1227 view->DisplayProperty(property);
1228 view->UpdatePropertyDisplayInList(property);
1229 view->OnPropertyChanged(property);
1230 return TRUE;
1231}
1232
1233///
1234/// String validator
1235///
1236IMPLEMENT_DYNAMIC_CLASS(wxStringListValidator, wxPropertyListValidator)
1237
1238wxStringListValidator::wxStringListValidator(wxStringList *list, long flags):
1239 wxPropertyListValidator(flags)
1240{
fd71308f 1241 m_strings = list;
457814b5 1242 // If no constraint, we just allow the string to be edited.
fd71308f
JS
1243 if (!m_strings && ((m_validatorFlags & wxPROP_ALLOW_TEXT_EDITING) == 0))
1244 m_validatorFlags |= wxPROP_ALLOW_TEXT_EDITING;
457814b5
JS
1245}
1246
1247bool wxStringListValidator::OnCheckValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1248{
fd71308f 1249 if (!m_strings)
457814b5
JS
1250 return TRUE;
1251
1252 if (!view->GetValueText())
1253 return FALSE;
1254 wxString value(view->GetValueText()->GetValue());
1255
fd71308f 1256 if (!m_strings->Member(value.GetData()))
457814b5
JS
1257 {
1258 wxString s("Value ");
1259 s += value.GetData();
1260 s += " is not valid.";
1261 wxMessageBox(s.GetData(), "Property value error", wxOK | wxICON_EXCLAMATION, parentWindow);
1262 return FALSE;
1263 }
1264 return TRUE;
1265}
1266
1267// Called when TICK is pressed or focus is lost or view wants to update
1268// the property list.
1269// Does the transferance from the property editing area to the property itself
1270bool wxStringListValidator::OnRetrieveValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1271{
1272 if (!view->GetValueText())
1273 return FALSE;
1274 wxString value(view->GetValueText()->GetValue());
1275 property->GetValue() = value ;
1276 return TRUE;
1277}
1278
1279// Called when TICK is pressed or focus is lost or view wants to update
1280// the property list.
1281// Does the transferance from the property editing area to the property itself
1282bool wxStringListValidator::OnDisplayValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1283{
1284 if (!view->GetValueText())
1285 return FALSE;
1286 wxString str(property->GetValue().GetStringRepresentation());
b8c631bb 1287 view->GetValueText()->SetValue(str);
fd71308f 1288 if (m_strings && view->GetValueList() && view->GetValueList()->IsShown() && view->GetValueList()->Number() > 0)
457814b5 1289 {
b8c631bb 1290 view->GetValueList()->SetStringSelection(str);
457814b5
JS
1291 }
1292 return TRUE;
1293}
1294
1295bool wxStringListValidator::OnPrepareControls(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1296{
1297 // Unconstrained
fd71308f 1298 if (!m_strings)
457814b5
JS
1299 {
1300 if (view->GetEditButton())
1301 view->GetEditButton()->Enable(FALSE);
1302 if (view->GetConfirmButton())
1303 view->GetConfirmButton()->Enable(TRUE);
1304 if (view->GetCancelButton())
1305 view->GetCancelButton()->Enable(TRUE);
1306 if (view->GetValueText())
1307 view->GetValueText()->Enable(TRUE);
1308 return TRUE;
1309 }
1310
1311 // Constrained
1312 if (view->GetValueText())
1313 view->GetValueText()->Enable(FALSE);
1314
1315 if (view->GetEditButton())
1316 view->GetEditButton()->Enable(TRUE);
1317
1318 if (view->GetConfirmButton())
1319 view->GetConfirmButton()->Enable(FALSE);
1320 if (view->GetCancelButton())
1321 view->GetCancelButton()->Enable(FALSE);
1322 return TRUE;
1323}
1324
1325bool wxStringListValidator::OnPrepareDetailControls(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1326{
1327 if (view->GetValueList())
1328 {
1329 view->ShowListBoxControl(TRUE);
1330 view->GetValueList()->Enable(TRUE);
fd71308f 1331 wxNode *node = m_strings->First();
457814b5
JS
1332 while (node)
1333 {
1334 char *s = (char *)node->Data();
1335 view->GetValueList()->Append(s);
1336 node = node->Next();
1337 }
1338 char *currentString = property->GetValue().StringValue();
1339 view->GetValueList()->SetStringSelection(currentString);
1340 }
1341 return TRUE;
1342}
1343
1344bool wxStringListValidator::OnClearDetailControls(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1345{
fd71308f 1346 if (!m_strings)
457814b5
JS
1347 {
1348 return TRUE;
1349 }
1350
1351 if (view->GetValueList())
1352 {
1353 view->GetValueList()->Clear();
1354 view->ShowListBoxControl(FALSE);
1355 view->GetValueList()->Enable(FALSE);
1356 }
1357 return TRUE;
1358}
1359
1360// Called when the property is double clicked. Extra functionality can be provided,
1361// cycling through possible values.
1362bool wxStringListValidator::OnDoubleClick(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1363{
1364 if (!view->GetValueText())
1365 return FALSE;
fd71308f 1366 if (!m_strings)
457814b5
JS
1367 return FALSE;
1368
fd71308f 1369 wxNode *node = m_strings->First();
457814b5
JS
1370 char *currentString = property->GetValue().StringValue();
1371 while (node)
1372 {
1373 char *s = (char *)node->Data();
1374 if (strcmp(s, currentString) == 0)
1375 {
1376 char *nextString = NULL;
1377 if (node->Next())
1378 nextString = (char *)node->Next()->Data();
1379 else
fd71308f 1380 nextString = (char *)m_strings->First()->Data();
457814b5
JS
1381 property->GetValue() = wxString(nextString);
1382 view->DisplayProperty(property);
1383 view->UpdatePropertyDisplayInList(property);
1384 view->OnPropertyChanged(property);
1385 return TRUE;
1386 }
1387 else node = node->Next();
1388 }
1389 return TRUE;
1390}
1391
1392///
1393/// Filename validator
1394///
1395IMPLEMENT_DYNAMIC_CLASS(wxFilenameListValidator, wxPropertyListValidator)
1396
1397wxFilenameListValidator::wxFilenameListValidator(wxString message , wxString wildcard, long flags):
fd71308f 1398 wxPropertyListValidator(flags), m_filenameWildCard(wildcard), m_filenameMessage(message)
457814b5
JS
1399{
1400}
1401
1402wxFilenameListValidator::~wxFilenameListValidator(void)
1403{
1404}
1405
1406bool wxFilenameListValidator::OnCheckValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1407{
1408 return TRUE;
1409}
1410
1411// Called when TICK is pressed or focus is lost or view wants to update
1412// the property list.
1413// Does the transferance from the property editing area to the property itself
1414bool wxFilenameListValidator::OnRetrieveValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1415{
1416 if (!view->GetValueText())
1417 return FALSE;
1418 wxString value(view->GetValueText()->GetValue());
1419 property->GetValue() = value ;
1420 return TRUE;
1421}
1422
1423// Called when TICK is pressed or focus is lost or view wants to update
1424// the property list.
1425// Does the transferance from the property editing area to the property itself
1426bool wxFilenameListValidator::OnDisplayValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1427{
1428 if (!view->GetValueText())
1429 return FALSE;
1430 wxString str(property->GetValue().GetStringRepresentation());
1431 view->GetValueText()->SetValue(str);
1432 return TRUE;
1433}
1434
1435// Called when the property is double clicked. Extra functionality can be provided,
1436// cycling through possible values.
1437bool wxFilenameListValidator::OnDoubleClick(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1438{
1439 if (!view->GetValueText())
1440 return FALSE;
1441 OnEdit(property, view, parentWindow);
1442 return TRUE;
1443}
1444
1445bool wxFilenameListValidator::OnPrepareControls(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1446{
1447 if (view->GetConfirmButton())
1448 view->GetConfirmButton()->Enable(TRUE);
1449 if (view->GetCancelButton())
1450 view->GetCancelButton()->Enable(TRUE);
1451 if (view->GetEditButton())
1452 view->GetEditButton()->Enable(TRUE);
1453 if (view->GetValueText())
1454 view->GetValueText()->Enable((GetFlags() & wxPROP_ALLOW_TEXT_EDITING) == wxPROP_ALLOW_TEXT_EDITING);
1455 return TRUE;
1456}
1457
1458void wxFilenameListValidator::OnEdit(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1459{
1460 if (!view->GetValueText())
1461 return;
1462
1463 char *s = wxFileSelector(
fd71308f 1464 m_filenameMessage.GetData(),
457814b5
JS
1465 wxPathOnly(property->GetValue().StringValue()),
1466 wxFileNameFromPath(property->GetValue().StringValue()),
1467 NULL,
fd71308f 1468 m_filenameWildCard.GetData(),
457814b5
JS
1469 0,
1470 parentWindow);
1471 if (s)
1472 {
1473 property->GetValue() = wxString(s);
1474 view->DisplayProperty(property);
1475 view->UpdatePropertyDisplayInList(property);
1476 view->OnPropertyChanged(property);
1477 }
1478}
1479
1480///
1481/// Colour validator
1482///
1483IMPLEMENT_DYNAMIC_CLASS(wxColourListValidator, wxPropertyListValidator)
1484
1485wxColourListValidator::wxColourListValidator(long flags):
1486 wxPropertyListValidator(flags)
1487{
1488}
1489
1490wxColourListValidator::~wxColourListValidator(void)
1491{
1492}
1493
1494bool wxColourListValidator::OnCheckValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1495{
1496 return TRUE;
1497}
1498
1499// Called when TICK is pressed or focus is lost or view wants to update
1500// the property list.
1501// Does the transferance from the property editing area to the property itself
1502bool wxColourListValidator::OnRetrieveValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1503{
1504 if (!view->GetValueText())
1505 return FALSE;
1506 wxString value(view->GetValueText()->GetValue());
1507
1508 property->GetValue() = value ;
1509 return TRUE;
1510}
1511
1512// Called when TICK is pressed or focus is lost or view wants to update
1513// the property list.
1514// Does the transferance from the property editing area to the property itself
1515bool wxColourListValidator::OnDisplayValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1516{
1517 if (!view->GetValueText())
1518 return FALSE;
1519 wxString str(property->GetValue().GetStringRepresentation());
1520 view->GetValueText()->SetValue(str);
1521 return TRUE;
1522}
1523
1524// Called when the property is double clicked. Extra functionality can be provided,
1525// cycling through possible values.
1526bool wxColourListValidator::OnDoubleClick(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1527{
1528 if (!view->GetValueText())
1529 return FALSE;
1530 OnEdit(property, view, parentWindow);
1531 return TRUE;
1532}
1533
1534bool wxColourListValidator::OnPrepareControls(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1535{
1536 if (view->GetConfirmButton())
1537 view->GetConfirmButton()->Enable(TRUE);
1538 if (view->GetCancelButton())
1539 view->GetCancelButton()->Enable(TRUE);
1540 if (view->GetEditButton())
1541 view->GetEditButton()->Enable(TRUE);
1542 if (view->GetValueText())
1543 view->GetValueText()->Enable((GetFlags() & wxPROP_ALLOW_TEXT_EDITING) == wxPROP_ALLOW_TEXT_EDITING);
1544 return TRUE;
1545}
1546
1547void wxColourListValidator::OnEdit(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1548{
1549 if (!view->GetValueText())
1550 return;
1551
1552 char *s = property->GetValue().StringValue();
1553 int r = 0;
1554 int g = 0;
1555 int b = 0;
1556 if (s)
1557 {
1558 r = wxHexToDec(s);
1559 g = wxHexToDec(s+2);
1560 b = wxHexToDec(s+4);
1561 }
1562
1563 wxColour col(r,g,b);
1564
1565 wxColourData data;
1566 data.SetChooseFull(TRUE);
1567 data.SetColour(col);
1568
1569 for (int i = 0; i < 16; i++)
1570 {
1571 wxColour colour(i*16, i*16, i*16);
1572 data.SetCustomColour(i, colour);
1573 }
1574
1575 wxColourDialog dialog(parentWindow, &data);
1576 if (dialog.ShowModal() != wxID_CANCEL)
1577 {
1578 wxColourData retData = dialog.GetColourData();
1579 col = retData.GetColour();
1580
1581 char buf[7];
1582 wxDecToHex(col.Red(), buf);
1583 wxDecToHex(col.Green(), buf+2);
1584 wxDecToHex(col.Blue(), buf+4);
1585
1586 property->GetValue() = wxString(buf);
1587 view->DisplayProperty(property);
1588 view->UpdatePropertyDisplayInList(property);
1589 view->OnPropertyChanged(property);
1590 }
1591}
1592
1593///
1594/// List of strings validator. For this we need more user interface than
1595/// we get with a property list; so create a new dialog for editing the list.
1596///
1597IMPLEMENT_DYNAMIC_CLASS(wxListOfStringsListValidator, wxPropertyListValidator)
1598
1599wxListOfStringsListValidator::wxListOfStringsListValidator(long flags):
1600 wxPropertyListValidator(flags)
1601{
1602}
1603
1604bool wxListOfStringsListValidator::OnCheckValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1605{
1606 // No constraints for an arbitrary, user-editable list of strings.
1607 return TRUE;
1608}
1609
1610// Called when TICK is pressed or focus is lost or view wants to update
1611// the property list.
1612// Does the transferance from the property editing area to the property itself.
1613// In this case, the user cannot directly edit the string list.
1614bool wxListOfStringsListValidator::OnRetrieveValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1615{
1616 return TRUE;
1617}
1618
1619bool wxListOfStringsListValidator::OnDisplayValue(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1620{
1621 if (!view->GetValueText())
1622 return FALSE;
1623 wxString str(property->GetValue().GetStringRepresentation());
b8c631bb 1624 view->GetValueText()->SetValue(str);
457814b5
JS
1625 return TRUE;
1626}
1627
1628bool wxListOfStringsListValidator::OnPrepareControls(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1629{
1630 if (view->GetEditButton())
1631 view->GetEditButton()->Enable(TRUE);
1632 if (view->GetValueText())
1633 view->GetValueText()->Enable(FALSE);
1634
1635 if (view->GetConfirmButton())
1636 view->GetConfirmButton()->Enable(FALSE);
1637 if (view->GetCancelButton())
1638 view->GetCancelButton()->Enable(FALSE);
1639 return TRUE;
1640}
1641
1642// Called when the property is double clicked. Extra functionality can be provided,
1643// cycling through possible values.
1644bool wxListOfStringsListValidator::OnDoubleClick(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1645{
1646 OnEdit(property, view, parentWindow);
1647 return TRUE;
1648}
1649
1650void wxListOfStringsListValidator::OnEdit(wxProperty *property, wxPropertyListView *view, wxWindow *parentWindow)
1651{
1652 // Convert property value to a list of strings for editing
1653 wxStringList *stringList = new wxStringList;
1654
1655 wxPropertyValue *expr = property->GetValue().GetFirst();
1656 while (expr)
1657 {
1658 char *s = expr->StringValue();
1659 if (s)
1660 stringList->Add(s);
1661 expr = expr->GetNext();
1662 }
1663
1664 wxString title("Editing ");
1665 title += property->GetName();
1666
1667 if (EditStringList(parentWindow, stringList, title.GetData()))
1668 {
1669 wxPropertyValue& oldValue = property->GetValue();
1670 oldValue.ClearList();
1671 wxNode *node = stringList->First();
1672 while (node)
1673 {
1674 char *s = (char *)node->Data();
1675 oldValue.Append(new wxPropertyValue(s));
1676
1677 node = node->Next();
1678 }
1679
1680 view->DisplayProperty(property);
1681 view->UpdatePropertyDisplayInList(property);
1682 view->OnPropertyChanged(property);
1683 }
1684 delete stringList;
1685}
1686
1687class wxPropertyStringListEditorDialog: public wxDialog
1688{
1689 public:
457814b5
JS
1690 wxPropertyStringListEditorDialog(wxWindow *parent, const wxString& title,
1691 const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize,
1692 long windowStyle = wxDEFAULT_DIALOG_STYLE, const wxString& name = "stringEditorDialogBox"):
1693 wxDialog(parent, -1, title, pos, size, windowStyle, name)
1694 {
fd71308f
JS
1695 m_stringList = NULL;
1696 m_stringText = NULL;
1697 m_listBox = NULL;
1698 sm_dialogCancelled = FALSE;
1699 m_currentSelection = -1;
457814b5
JS
1700 }
1701 ~wxPropertyStringListEditorDialog(void) {}
1702 bool OnClose(void);
1703 void SaveCurrentSelection(void);
1704 void ShowCurrentSelection(void);
1705
1706 void OnOK(wxCommandEvent& event);
1707 void OnCancel(wxCommandEvent& event);
1708 void OnAdd(wxCommandEvent& event);
1709 void OnDelete(wxCommandEvent& event);
1710 void OnStrings(wxCommandEvent& event);
1711 void OnText(wxCommandEvent& event);
1712
fd71308f
JS
1713public:
1714 wxStringList* m_stringList;
1715 wxListBox* m_listBox;
1716 wxTextCtrl* m_stringText;
1717 static bool sm_dialogCancelled;
1718 int m_currentSelection;
457814b5
JS
1719DECLARE_EVENT_TABLE()
1720};
1721
1722#define wxID_PROP_SL_ADD 3000
1723#define wxID_PROP_SL_DELETE 3001
1724#define wxID_PROP_SL_STRINGS 3002
1725#define wxID_PROP_SL_TEXT 3003
1726
1727BEGIN_EVENT_TABLE(wxPropertyStringListEditorDialog, wxDialog)
1728 EVT_BUTTON(wxID_OK, wxPropertyStringListEditorDialog::OnOK)
1729 EVT_BUTTON(wxID_CANCEL, wxPropertyStringListEditorDialog::OnCancel)
1730 EVT_BUTTON(wxID_PROP_SL_ADD, wxPropertyStringListEditorDialog::OnAdd)
1731 EVT_BUTTON(wxID_PROP_SL_DELETE, wxPropertyStringListEditorDialog::OnDelete)
1732 EVT_LISTBOX(wxID_PROP_SL_STRINGS, wxPropertyStringListEditorDialog::OnStrings)
83058c58 1733 EVT_TEXT_ENTER(wxID_PROP_SL_TEXT, wxPropertyStringListEditorDialog::OnText)
457814b5
JS
1734END_EVENT_TABLE()
1735
1736class wxPropertyStringListEditorText: public wxTextCtrl
1737{
1738 public:
1739 wxPropertyStringListEditorText(wxWindow *parent, wxWindowID id, const wxString& val,
1740 const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize,
1741 long windowStyle = 0, const wxString& name = "text"):
1742 wxTextCtrl(parent, id, val, pos, size, windowStyle, wxDefaultValidator, name)
1743 {
1744 }
1745 void OnKillFocus(void)
1746 {
1747 wxPropertyStringListEditorDialog *dialog = (wxPropertyStringListEditorDialog *)GetParent();
1748 dialog->SaveCurrentSelection();
1749 }
1750};
1751
fd71308f 1752bool wxPropertyStringListEditorDialog::sm_dialogCancelled = FALSE;
457814b5
JS
1753
1754// Edit the string list.
1755bool wxListOfStringsListValidator::EditStringList(wxWindow *parent, wxStringList *stringList, const char *title)
1756{
f97c9854
JS
1757 int largeButtonWidth = 60;
1758 int largeButtonHeight = 25;
1759
457814b5
JS
1760 wxBeginBusyCursor();
1761 wxPropertyStringListEditorDialog *dialog = new wxPropertyStringListEditorDialog(parent,
1762 title, wxPoint(10, 10), wxSize(400, 400), wxDEFAULT_DIALOG_STYLE|wxDIALOG_MODAL);
1763
fd71308f 1764 dialog->m_stringList = stringList;
457814b5 1765
fd71308f 1766 dialog->m_listBox = new wxListBox(dialog, wxID_PROP_SL_STRINGS,
f97c9854 1767 wxPoint(-1, -1), wxSize(-1, -1), 0, NULL, wxLB_SINGLE);
457814b5 1768
fd71308f 1769 dialog->m_stringText = new wxPropertyStringListEditorText(dialog,
457814b5
JS
1770 wxID_PROP_SL_TEXT, "", wxPoint(5, 240),
1771 wxSize(300, -1), wxPROCESS_ENTER);
fd71308f 1772 dialog->m_stringText->Enable(FALSE);
457814b5 1773
f97c9854
JS
1774 wxButton *addButton = new wxButton(dialog, wxID_PROP_SL_ADD, "Add", wxPoint(-1, -1), wxSize(largeButtonWidth, largeButtonHeight));
1775 wxButton *deleteButton = new wxButton(dialog, wxID_PROP_SL_DELETE, "Delete", wxPoint(-1, -1), wxSize(largeButtonWidth, largeButtonHeight));
1776 wxButton *cancelButton = new wxButton(dialog, wxID_CANCEL, "Cancel", wxPoint(-1, -1), wxSize(largeButtonWidth, largeButtonHeight));
1777 wxButton *okButton = new wxButton(dialog, wxID_OK, "OK", wxPoint(-1, -1), wxSize(largeButtonWidth, largeButtonHeight));
1778
1779 okButton->SetDefault();
1780
1781 wxLayoutConstraints *c = new wxLayoutConstraints;
1782
1783 c->top.SameAs (dialog, wxTop, 2);
1784 c->left.SameAs (dialog, wxLeft, 2);
1785 c->right.SameAs (dialog, wxRight, 2);
fd71308f
JS
1786 c->bottom.SameAs (dialog->m_stringText, wxTop, 2);
1787 dialog->m_listBox->SetConstraints(c);
f97c9854
JS
1788
1789 c = new wxLayoutConstraints;
1790 c->left.SameAs (dialog, wxLeft, 2);
1791 c->right.SameAs (dialog, wxRight, 2);
1792 c->bottom.SameAs (addButton, wxTop, 2);
1793 c->height.AsIs();
fd71308f 1794 dialog->m_stringText->SetConstraints(c);
f97c9854
JS
1795
1796 c = new wxLayoutConstraints;
1797 c->bottom.SameAs (dialog, wxBottom, 2);
1798 c->left.SameAs (dialog, wxLeft, 2);
1799 c->width.AsIs();
1800 c->height.AsIs();
1801 addButton->SetConstraints(c);
1802
1803 c = new wxLayoutConstraints;
1804 c->bottom.SameAs (dialog, wxBottom, 2);
1805 c->left.SameAs (addButton, wxRight, 2);
1806 c->width.AsIs();
1807 c->height.AsIs();
1808 deleteButton->SetConstraints(c);
1809
1810 c = new wxLayoutConstraints;
1811 c->bottom.SameAs (dialog, wxBottom, 2);
1812 c->right.SameAs (dialog, wxRight, 2);
1813 c->width.AsIs();
1814 c->height.AsIs();
1815 cancelButton->SetConstraints(c);
1816
1817 c = new wxLayoutConstraints;
1818 c->bottom.SameAs (dialog, wxBottom, 2);
1819 c->right.SameAs (cancelButton, wxLeft, 2);
1820 c->width.AsIs();
1821 c->height.AsIs();
1822 okButton->SetConstraints(c);
457814b5
JS
1823
1824 wxNode *node = stringList->First();
1825 while (node)
1826 {
1827 char *str = (char *)node->Data();
1828 // Save node as client data for each listbox item
fd71308f 1829 dialog->m_listBox->Append(str, (char *)node);
457814b5
JS
1830 node = node->Next();
1831 }
1832
1833 dialog->SetClientSize(310, 305);
f97c9854 1834 dialog->Layout();
457814b5
JS
1835
1836 dialog->Centre(wxBOTH);
1837 wxEndBusyCursor();
1838 if (dialog->ShowModal() == wxID_CANCEL)
1839 return FALSE;
1840 else
1841 return TRUE;
1842}
1843
1844/*
1845 * String list editor callbacks
1846 *
1847 */
1848
8656024d 1849void wxPropertyStringListEditorDialog::OnStrings(wxCommandEvent& WXUNUSED(event))
457814b5 1850{
fd71308f 1851 int sel = m_listBox->GetSelection();
457814b5
JS
1852 if (sel > -1)
1853 {
fd71308f 1854 m_currentSelection = sel;
457814b5
JS
1855
1856 ShowCurrentSelection();
1857 }
1858}
1859
8656024d 1860void wxPropertyStringListEditorDialog::OnDelete(wxCommandEvent& WXUNUSED(event))
457814b5 1861{
fd71308f 1862 int sel = m_listBox->GetSelection();
457814b5
JS
1863 if (sel == -1)
1864 return;
1865
fd71308f 1866 wxNode *node = (wxNode *)m_listBox->wxListBox::GetClientData(sel);
457814b5
JS
1867 if (!node)
1868 return;
1869
fd71308f 1870 m_listBox->Delete(sel);
457814b5
JS
1871 delete[] (char *)node->Data();
1872 delete node;
fd71308f
JS
1873 m_currentSelection = -1;
1874 m_stringText->SetValue("");
457814b5
JS
1875}
1876
8656024d 1877void wxPropertyStringListEditorDialog::OnAdd(wxCommandEvent& WXUNUSED(event))
457814b5
JS
1878{
1879 SaveCurrentSelection();
1880
1881 char *initialText = "";
fd71308f
JS
1882 wxNode *node = m_stringList->Add(initialText);
1883 m_listBox->Append(initialText, (char *)node);
1884 m_currentSelection = m_stringList->Number() - 1;
1885 m_listBox->SetSelection(m_currentSelection);
457814b5 1886 ShowCurrentSelection();
fd71308f 1887 m_stringText->SetFocus();
457814b5
JS
1888}
1889
8656024d 1890void wxPropertyStringListEditorDialog::OnOK(wxCommandEvent& WXUNUSED(event))
457814b5
JS
1891{
1892 SaveCurrentSelection();
1893 EndModal(wxID_OK);
1894 Close(TRUE);
1895}
1896
8656024d 1897void wxPropertyStringListEditorDialog::OnCancel(wxCommandEvent& WXUNUSED(event))
457814b5 1898{
fd71308f 1899 sm_dialogCancelled = TRUE;
457814b5
JS
1900 EndModal(wxID_CANCEL);
1901 Close(TRUE);
1902}
1903
1904void wxPropertyStringListEditorDialog::OnText(wxCommandEvent& event)
1905{
1906 if (event.GetEventType() == wxEVENT_TYPE_TEXT_ENTER_COMMAND)
1907 {
1908 SaveCurrentSelection();
1909 }
1910}
1911
1912bool wxPropertyStringListEditorDialog::OnClose(void)
1913{
1914 SaveCurrentSelection();
1915 return TRUE;
1916}
1917
1918void wxPropertyStringListEditorDialog::SaveCurrentSelection(void)
1919{
fd71308f 1920 if (m_currentSelection == -1)
457814b5
JS
1921 return;
1922
fd71308f 1923 wxNode *node = (wxNode *)m_listBox->wxListBox::GetClientData(m_currentSelection);
457814b5
JS
1924 if (!node)
1925 return;
1926
fd71308f 1927 wxString txt(m_stringText->GetValue());
457814b5
JS
1928 if (node->Data())
1929 delete[] (char *)node->Data();
1930 node->SetData((wxObject *)copystring(txt));
1931
fd71308f 1932 m_listBox->SetString(m_currentSelection, (char *)node->Data());
457814b5
JS
1933}
1934
1935void wxPropertyStringListEditorDialog::ShowCurrentSelection(void)
1936{
fd71308f 1937 if (m_currentSelection == -1)
457814b5 1938 {
fd71308f 1939 m_stringText->SetValue("");
457814b5
JS
1940 return;
1941 }
fd71308f 1942 wxNode *node = (wxNode *)m_listBox->wxListBox::GetClientData(m_currentSelection);
457814b5 1943 char *txt = (char *)node->Data();
fd71308f
JS
1944 m_stringText->SetValue(txt);
1945 m_stringText->Enable(TRUE);
457814b5 1946}