]> git.saurik.com Git - wxWidgets.git/blob - utils/configtool/src/propeditor.cpp
Fix docs for Bind
[wxWidgets.git] / utils / configtool / src / propeditor.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: propeditor.cpp
3 // Purpose: wxWindows Configuration Tool property editor
4 // Author: Julian Smart
5 // Modified by:
6 // Created: 2003-06-03
7 // RCS-ID: $Id$
8 // Copyright: (c) Julian Smart
9 // Licence:
10 /////////////////////////////////////////////////////////////////////////////
11
12 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
13 #pragma implementation "propeditor.h"
14 #endif
15
16 #include <wx/wx.h>
17
18 #ifdef __BORLANDC__
19 #pragma hdrstop
20 #endif
21
22 #include "wx/html/htmlwin.h"
23 #include "wx/grid.h"
24 #include "wx/filedlg.h"
25 #include "wx/tokenzr.h"
26 #include "wx/valgen.h"
27
28 #include "propeditor.h"
29 #include "symbols.h"
30 #include "utils.h"
31 #include "configtooldoc.h"
32 #include "configitemselector.h"
33 #include "bitmaps/ellipsis.xpm"
34
35
36 /*!
37 * A container window for the property editor.
38 * and attribute editor.
39 */
40
41 IMPLEMENT_CLASS(ctPropertyEditor, wxPanel)
42
43 BEGIN_EVENT_TABLE(ctPropertyEditor, wxPanel)
44 EVT_BUTTON(ctID_ATTRIBUTE_EDITOR_EDIT_DETAILS, ctPropertyEditor::OnEditDetails)
45 EVT_GRID_SELECT_CELL(ctPropertyEditor::OnSelectCell)
46 EVT_GRID_CELL_CHANGE(ctPropertyEditor::OnChangeCell)
47 EVT_GRID_CELL_LEFT_DCLICK(ctPropertyEditor::OnDClickCell)
48 EVT_UPDATE_UI(ctID_ATTRIBUTE_EDITOR_EDIT_DETAILS, ctPropertyEditor::OnUpdateEditDetails)
49 END_EVENT_TABLE()
50
51 ctPropertyEditor::ctPropertyEditor(wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style):
52 wxPanel(parent, id, pos, size, style)
53 {
54 m_splitterWindow = NULL;
55 m_attributeEditorGrid = NULL;
56 m_propertyDescriptionWindow = NULL;
57 m_elementTitleTextCtrl = NULL;
58
59 CreateControls(this);
60 }
61
62 ctPropertyEditor::~ctPropertyEditor()
63 {
64 }
65
66 void ctPropertyEditor::CreateControls(wxWindow* parent)
67 {
68 m_elementTitleTextCtrl = new wxTextCtrl(this, -1, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_READONLY);
69 wxBitmap detailsIcon(ellipsis_xpm);
70
71 wxBoxSizer *item0 = new wxBoxSizer( wxVERTICAL );
72
73 wxBoxSizer *item1 = new wxBoxSizer( wxHORIZONTAL );
74
75 wxTextCtrl *item2 = m_elementTitleTextCtrl;
76 item1->Add( item2, 1, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
77
78 wxButton *item3a = new wxButton( parent, ctID_ATTRIBUTE_EDITOR_EDIT_DETAILS, wxT("Edit..."), wxDefaultPosition, wxSize(-1, -1));
79 item1->Add( item3a, 0, wxALIGN_CENTRE|wxRIGHT|wxTOP|wxBOTTOM, 5 );
80
81 item0->Add( item1, 0, wxGROW|wxALIGN_CENTER_VERTICAL, 5 );
82
83 // TODO: find sash pos from last time
84 int sashPos = 100;
85
86 m_splitterWindow = new wxSplitterWindow(parent, ctID_PROPERTY_EDITOR_SPLITTER, wxDefaultPosition, wxSize(500, 400), wxSP_3DSASH|wxSP_FULLSASH/*|wxCLIP_CHILDREN*/ |wxBORDER_NONE|wxNO_FULL_REPAINT_ON_RESIZE);
87 m_splitterWindow->SetMinimumPaneSize(10);
88
89 m_propertyDescriptionWindow = new wxHtmlWindow(m_splitterWindow, ctID_ATTRIBUTE_EDITOR_DESCRIPTION, wxDefaultPosition, wxSize(200, 60), wxSUNKEN_BORDER);
90 m_propertyDescriptionWindow->SetBackgroundColour(ctDESCRIPTION_BACKGROUND_COLOUR);
91 m_propertyDescriptionWindow->SetBorders(4);
92 m_attributeEditorGrid = new ctPropertyEditorGrid(m_splitterWindow, ctID_ATTRIBUTE_EDITOR_GRID , wxPoint(0, 0), wxSize(200, 100), wxBORDER_SUNKEN | wxWANTS_CHARS);
93
94 m_splitterWindow->SplitHorizontally(m_propertyDescriptionWindow, m_attributeEditorGrid, sashPos);
95
96 // TODO: show or hide description window
97 // if (some-setting)
98 // ShowDescriptionWindow(FALSE);
99
100 item0->Add( m_splitterWindow, 1, wxGROW|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxBOTTOM, 5 );
101
102 this->SetAutoLayout( TRUE );
103 this->SetSizer( item0 );
104
105 /// Add help text
106 m_elementTitleTextCtrl->SetHelpText(_("The title of the property being edited."));
107 FindWindow(ctID_ATTRIBUTE_EDITOR_EDIT_DETAILS)->SetHelpText(_("Click to use an appropriate editor for the selected property (if any)."));
108 FindWindow(ctID_ATTRIBUTE_EDITOR_GRID)->SetHelpText(_("Shows the properties of the selected item."));
109 FindWindow(ctID_ATTRIBUTE_EDITOR_DESCRIPTION)->SetHelpText(_("Shows a description of the selected property, or a summary of the whole item."));
110
111 /// Set up the grid to display properties
112 m_attributeEditorGrid->RegisterDataType(ctGRID_VALUE_STRING,
113 new wxGridCellStringRenderer,
114 new ctGridCellTextEditor);
115
116 m_attributeEditorGrid->CreateGrid( 0, 2, wxGrid::wxGridSelectRows );
117 m_attributeEditorGrid->SetRowLabelSize(0);
118 m_attributeEditorGrid->SetColLabelSize(0 /* 18 */);
119
120 wxArrayString columns;
121 columns.Add(_T("Name"));
122 columns.Add(_T("Value"));
123
124 m_attributeEditorGrid->SetColSize(0, 140);
125 m_attributeEditorGrid->SetColSize(1, 80);
126
127 m_attributeEditorGrid->SetColumnsToDisplay(columns);
128 m_attributeEditorGrid->DisplayLabels();
129
130 m_attributeEditorGrid->SetStretchableColumn(1);
131
132 m_attributeEditorGrid->SetDefaultCellBackgroundColour(ctCELL_BACKGROUND_COLOUR);
133
134 UpdateDescription();
135 }
136
137 /// Show/hide the description control
138 void ctPropertyEditor::ShowDescriptionWindow(bool show)
139 {
140 if (!show)
141 {
142 if (m_splitterWindow->IsSplit())
143 m_splitterWindow->Unsplit(m_propertyDescriptionWindow);
144 }
145 else
146 {
147 // TODO
148 int pos = 100;
149 m_propertyDescriptionWindow->Show(TRUE);
150 if (!m_splitterWindow->IsSplit())
151 {
152 m_splitterWindow->SplitHorizontally(m_propertyDescriptionWindow, m_attributeEditorGrid, pos);
153 }
154 }
155 }
156
157 /// Clear grid editor
158 void ctPropertyEditor::ClearEditor()
159 {
160 m_attributeEditorGrid->ClearAttributes();
161 m_propertyDescriptionWindow->SetPage(WrapDescription(wxEmptyString));
162 m_elementTitleTextCtrl->SetValue(_T(""));
163 }
164
165 /// Handles detailed editing event.
166 void ctPropertyEditor::OnEditDetails(wxCommandEvent& WXUNUSED(event))
167 {
168 wxWindow* parentFrame = this;
169 while (parentFrame && !parentFrame->IsKindOf(CLASSINFO(wxFrame)))
170 parentFrame = parentFrame->GetParent();
171
172 EditDetails(parentFrame);
173 }
174
175 /// Handles detailed editing update event.
176 void ctPropertyEditor::OnUpdateEditDetails(wxUpdateUIEvent& event)
177 {
178 event.Enable(CanEditDetails());
179 }
180
181 /// Can we edit the details of the selected property?
182 bool ctPropertyEditor::CanEditDetails()
183 {
184 if (!m_item)
185 return FALSE;
186
187 int row;
188 ctProperty* prop = FindSelectedProperty(row);
189 if (!prop || prop->GetEditorType().IsEmpty())
190 return FALSE;
191 return TRUE;
192 }
193
194 /// Shows the item
195 void ctPropertyEditor::ShowItem(ctConfigItem* item)
196 {
197 if (m_attributeEditorGrid->IsCellEditControlEnabled())
198 m_attributeEditorGrid->SaveEditControlValue();
199
200 ClearEditor();
201 if (item)
202 {
203 m_item = item;
204
205 UpdateTitle();
206
207 m_attributeEditorGrid->AppendRows(m_item->GetProperties().GetCount());
208
209 wxNode* node = m_item->GetProperties().GetList().GetFirst();
210 int i = 0;
211 while (node)
212 {
213 ctProperty* prop = (ctProperty*) node->GetData();
214 DisplayProperty(i, prop);
215
216 i ++;
217 node = node->GetNext();
218 }
219 // Make sure scrollbars are up-to-date, etc.
220 wxSizeEvent event(m_attributeEditorGrid->GetSize(), m_attributeEditorGrid->GetId());
221 m_attributeEditorGrid->GetEventHandler()->ProcessEvent(event);
222
223 DisplayDefaultProperty();
224 }
225 else
226 {
227 m_item = NULL;
228 }
229 }
230
231 /// Determine background colour for this property.
232 void ctPropertyEditor::DeterminePropertyColour(ctProperty* prop, wxColour& colour)
233 {
234 if (prop->IsCustom())
235 colour = ctCUSTOM_CELL_BACKGROUND_COLOUR;
236 else
237 colour = ctCELL_BACKGROUND_COLOUR;
238 }
239
240 /// Update the title at the top of the property editor
241 void ctPropertyEditor::UpdateTitle()
242 {
243 if (m_item)
244 {
245 wxString name(m_item->GetTitle());
246 m_elementTitleTextCtrl->SetValue(name);
247 }
248 }
249
250 /// Updates the item display, assuming it was already displayed.
251 void ctPropertyEditor::UpdateItem()
252 {
253 if (m_attributeEditorGrid->IsCellEditControlEnabled())
254 m_attributeEditorGrid->SaveEditControlValue();
255 if (m_item)
256 {
257 UpdateTitle();
258
259 wxNode* node = m_item->GetProperties().GetList().GetFirst();
260 int i = 0;
261 while (node)
262 {
263 ctProperty* prop = (ctProperty*) node->GetData();
264 DisplayProperty(i, prop, TRUE);
265
266 i ++;
267 node = node->GetNext();
268 }
269 // Make sure scrollbars are up-to-date, etc.
270 wxSizeEvent event(m_attributeEditorGrid->GetSize(), this->GetId());
271 m_attributeEditorGrid->GetEventHandler()->ProcessEvent(event);
272 }
273 }
274
275 /// Display attribute at given row
276 bool ctPropertyEditor::DisplayProperty(int row, ctProperty* prop, bool valueOnly)
277 {
278 wxColour backgroundColour;
279
280 DeterminePropertyColour(prop, backgroundColour);
281
282 if (!valueOnly)
283 {
284 m_attributeEditorGrid->SetCellBackgroundColour(row, 0, backgroundColour);
285 m_attributeEditorGrid->SetCellBackgroundColour(row, 1, backgroundColour);
286
287 m_attributeEditorGrid->SetCellValue(row, 0, prop->GetName());
288
289 m_attributeEditorGrid->SetReadOnly(row, 0);
290 // Set the alignment
291 m_attributeEditorGrid->SetCellAlignment(row, 1, wxALIGN_LEFT, wxALIGN_CENTER);
292 }
293
294 if (!m_item->CanEditProperty(prop->GetName()))
295 {
296 m_attributeEditorGrid->SetReadOnly(row, 1);
297
298 wxColour col(wxSystemSettings::GetColour(wxSYS_COLOUR_GRAYTEXT));
299 m_attributeEditorGrid->SetCellTextColour(row, 1, col);
300 }
301 else
302 {
303 m_attributeEditorGrid->SetReadOnly(row, 1, FALSE);
304 m_attributeEditorGrid->SetCellTextColour(row, 1, * wxBLACK);
305 }
306
307 // Set the value
308 m_attributeEditorGrid->SetCellValue(row, 1, ctConvertToSingleText(prop->GetValue()));
309
310 if (valueOnly)
311 return TRUE;
312
313 // Set the value type
314 if (prop->GetEditorType() == _T("choice"))
315 {
316 #if 0
317 wxString* strArr = prop->GetChoices().GetStringArray();
318
319 m_attributeEditorGrid->SetCellEditor(row, 1,
320 new wxGridCellChoiceEditor(prop->GetChoices().GetCount(), strArr));
321
322 delete[] strArr;
323 #endif
324 m_attributeEditorGrid->SetCellEditor(row, 1,
325 new wxGridCellChoiceEditor(prop->GetChoices()));
326 }
327 else if (prop->GetEditorType() == _T("integer") || prop->GetVariant().GetType() == _T("long"))
328 {
329 m_attributeEditorGrid->SetCellEditor(row, 1,
330 new wxGridCellNumberEditor);
331 }
332 else if (prop->GetEditorType() == _T("float") || prop->GetVariant().GetType() == _T("double"))
333 {
334 m_attributeEditorGrid->SetCellEditor(row, 1,
335 new wxGridCellFloatEditor);
336 }
337 else if (prop->GetEditorType() == _T("bool") || prop->GetVariant().GetType() == _T("bool"))
338 {
339 m_attributeEditorGrid->SetCellValue(row, 1, prop->GetVariant().GetBool() ? _T("1") : _T("0"));
340 m_attributeEditorGrid->SetCellEditor(row, 1,
341 new wxGridCellBoolEditor);
342 m_attributeEditorGrid->SetCellRenderer(row, 1, new wxGridCellBoolRenderer);
343 }
344 else
345 {
346 m_attributeEditorGrid->SetCellEditor(row, 1,
347 new ctGridCellTextEditor);
348 }
349
350 return TRUE;
351 }
352
353 /// Display attribute value
354 bool ctPropertyEditor::DisplayProperty(ctProperty* prop)
355 {
356 if (!m_item)
357 return FALSE;
358
359 int index = m_item->GetProperties().GetList().IndexOf(prop);
360 return DisplayProperty(index, prop, TRUE);
361 }
362
363 /// Display the default property
364 bool ctPropertyEditor::DisplayDefaultProperty()
365 {
366 if (!m_item)
367 return FALSE;
368
369 wxString str = m_item->GetDefaultProperty();
370
371 ctProperty* prop = m_item->GetProperties().FindProperty(str);
372 if (prop)
373 {
374 int index = m_item->GetProperties().GetList().IndexOf(prop);
375 this->m_attributeEditorGrid->SelectRow(index);
376 this->m_attributeEditorGrid->SetGridCursor(index, 1);
377 }
378 return TRUE;
379 }
380
381 /// Edit the default property
382 bool ctPropertyEditor::EditDefaultProperty(ctConfigItem* item)
383 {
384 wxString defaultPropertyName = item->GetDefaultProperty();
385 if (!defaultPropertyName.IsEmpty())
386 {
387 ctProperty* prop = item->GetProperties().FindProperty(defaultPropertyName);
388 if (prop)
389 {
390 int index = item->GetProperties().GetList().IndexOf(prop);
391 if (index >= 0)
392 {
393 this->m_attributeEditorGrid->SelectRow(index);
394 this->m_attributeEditorGrid->SetGridCursor(index, 1);
395 EditDetails(wxTheApp->GetTopWindow());
396 return TRUE;
397 }
398 }
399
400 }
401 return FALSE;
402 }
403
404 /// Find the selected property
405 ctProperty* ctPropertyEditor::FindSelectedProperty(int& row)
406 {
407 if (!m_item)
408 return NULL;
409
410 int selRow = m_attributeEditorGrid->GetCursorRow();
411 if (selRow > -1)
412 {
413 row = selRow;
414
415 if (selRow < (int) m_item->GetProperties().GetCount())
416 {
417 ctProperty* prop = m_item->GetProperties().GetNth(selRow);
418 return prop;
419 }
420 }
421 return NULL;
422 }
423
424 /// Find the property
425 ctProperty* ctPropertyEditor::FindProperty(int row)
426 {
427 if (!m_item)
428 return NULL;
429
430 if (row > -1)
431 {
432 if (row < (int) m_item->GetProperties().GetCount())
433 {
434 ctProperty* prop = m_item->GetProperties().GetNth(row);
435 return prop;
436 }
437 }
438 return NULL;
439 }
440
441 /// Edit the details of this cell appropriately.
442 bool ctPropertyEditor::EditDetails(wxWindow* WXUNUSED(parent))
443 {
444 if (CanEditDetails())
445 {
446 int row;
447 ctProperty* prop = FindSelectedProperty(row);
448 if (!prop)
449 return FALSE;
450
451 wxString type(prop->GetEditorType());
452 wxString value = m_attributeEditorGrid->GetCellValue(row, 1);
453
454 if (type == _T("multiline"))
455 {
456 value = ctConvertToMultilineText(value);
457 wxString msg;
458 msg.Printf(wxT("Edit %s:"), (const wxChar*) prop->GetName());
459 ctMultiLineTextEditor dialog(wxTheApp->GetTopWindow(),
460 -1, wxT("Edit Text Property"), msg, value);
461 if (dialog.ShowModal() == wxID_OK)
462 {
463 value = ctConvertToSingleText(dialog.GetText());
464 m_attributeEditorGrid->SetCellValue(row, 1, value);
465 ApplyCellValueToProperty(row, 1);
466 return TRUE;
467 }
468 else
469 return FALSE;
470 }
471 else if (type == _T("filename"))
472 {
473 wxString fullPath = value;
474 wxString defaultDir ;
475 wxString defaultFilename = wxFileNameFromPath(fullPath);
476
477 defaultDir = wxPathOnly(value);
478
479 wxString msg = wxT("Choose a filename");
480 wxFileDialog dialog(wxTheApp->GetTopWindow(),
481 msg, defaultDir, defaultFilename, wxT("*.*"));
482 if (dialog.ShowModal() == wxID_OK)
483 {
484 fullPath = dialog.GetPath();
485 value = fullPath;
486
487 m_attributeEditorGrid->SetCellValue(row, 1, value);
488 ApplyCellValueToProperty(row, 1);
489 return TRUE;
490 }
491 else
492 return FALSE;
493 }
494 else if (type == _T("configitems"))
495 {
496 wxArrayString items;
497 ctConfigItem::StringToArray(value, items);
498
499 ctConfigItemsSelector dialog(wxTheApp->GetTopWindow(),
500 -1, wxT("Select Configuration Items"));
501 dialog.SetConfigList(items);
502 if (dialog.ShowModal() == wxID_OK)
503 {
504 wxString newValue;
505 items = dialog.GetConfigList();
506 ctConfigItem::ArrayToString(items, newValue);
507
508 m_attributeEditorGrid->SetCellValue(row, 1, newValue);
509 ApplyCellValueToProperty(row, 1);
510 return TRUE;
511 }
512 else
513 return FALSE;
514 }
515 }
516
517 return FALSE;
518 }
519
520 /// Intercept selection event.
521 void ctPropertyEditor::OnSelectCell(wxGridEvent& event)
522 {
523 int row = event.GetRow();
524
525 UpdateDescription(row);
526
527 event.Skip();
528 }
529
530 /// Update the description
531 void ctPropertyEditor::UpdateDescription(int row)
532 {
533 if (row == -1)
534 {
535 row = m_attributeEditorGrid->GetCursorRow();
536 }
537 if (row == -1)
538 {
539 wxString str = WrapDescription(wxEmptyString);
540 m_propertyDescriptionWindow->SetPage(str);
541 }
542 else
543 {
544 ctProperty* prop = FindProperty(row);
545 if (prop)
546 {
547 wxString str = WrapDescription(m_item->GetDescription(prop));
548 m_propertyDescriptionWindow->SetPage(str);
549 }
550 }
551 }
552
553 /// Wraps a description string in HTML
554 wxString ctPropertyEditor::WrapDescription(const wxString& s)
555 {
556 /// Convert a colour to a 6-digit hex string
557 wxColour col = ctDESCRIPTION_BACKGROUND_COLOUR;
558 wxString colStr = apColourToHexString(col);
559 colStr = wxT("#") + colStr;
560
561 wxString str;
562 str << _T("<HTML><BODY BGCOLOR=\"") << colStr << wxT("\"><FONT SIZE=-1>") ;
563 str << s;
564 str << _T("</FONT></BODY></HTML>");
565
566 return str;
567 }
568
569 /// Intercept cell data change event.
570 void ctPropertyEditor::OnChangeCell(wxGridEvent& event)
571 {
572 int row = event.GetRow();
573 int col = event.GetCol();
574
575 ApplyCellValueToProperty(row, col);
576 }
577
578 /// Double-click to show specialised editor.
579 void ctPropertyEditor::OnDClickCell(wxGridEvent& WXUNUSED(event))
580 {
581 wxWindow* parentFrame = this;
582 while (parentFrame && !parentFrame->IsKindOf(CLASSINFO(wxFrame)))
583 parentFrame = parentFrame->GetParent();
584
585 EditDetails(parentFrame);
586 }
587
588 /// Apply the cell value to the property, and notify the
589 /// item object.
590 void ctPropertyEditor::ApplyCellValueToProperty(int row, int col)
591 {
592 static bool s_Applying = FALSE;
593
594 if (s_Applying)
595 return;
596
597 s_Applying = TRUE;
598 if (col == 1 && m_item)
599 {
600 ctProperty* prop = m_item->GetProperties().GetNth(row);
601
602 wxString value = m_attributeEditorGrid->GetCellValue(row, col);
603 if (prop->GetEditorType() == wxT("multiline"))
604 value = ctConvertToMultilineText(value);
605
606 wxVariant variant = prop->GetVariant();
607
608 if (prop->GetVariant().GetType() == _T("bool"))
609 {
610 if (value == _T("1"))
611 variant = (bool) TRUE;
612 else
613 variant = (bool) FALSE;
614 }
615 else if (prop->GetVariant().GetType() == _T("long"))
616 {
617 long l;
618 value.ToLong(& l);
619 variant = l;
620 }
621 else if (prop->GetVariant().GetType() == _T("double"))
622 {
623 double d;
624 value.ToDouble(& d);
625 variant = d;
626 }
627 else
628 {
629 variant = value;
630 }
631
632 ApplyPropertyValue(m_item, prop, variant);
633
634 if (prop->GetName() == _T("description"))
635 UpdateDescription(row);
636 }
637 s_Applying = FALSE;
638 }
639
640 /// Apply the cell value to the property, and notify the
641 /// item object.
642 void ctPropertyEditor::ApplyPropertyValue(ctConfigItem* item, ctProperty* property, const wxVariant& variant)
643 {
644 static bool s_Applying = FALSE;
645
646 if (s_Applying)
647 return;
648
649 s_Applying = TRUE;
650
651 // Save the old values
652 ctProperties* oldProperties = new ctProperties(item->GetProperties());
653
654 wxVariant oldValue = property->GetVariant();
655
656 // Apply the new value
657 property->GetVariant() = variant;
658 item->ApplyProperty(property, oldValue);
659 item->Modify();
660
661 UpdateItem();
662
663 wxString menuLabel(_T("Change ") + property->GetName());
664
665 // This won't do anything first time Do is applied,
666 // since we've already done the action for this property.
667 // But when we Undo or Redo, the changed properties will be applied.
668 item->GetDocument()->GetCommandProcessor()->Submit(
669 new ctConfigCommand(menuLabel, ctCMD_APPLY_PROPERTY,
670 item, oldProperties, TRUE));
671
672 s_Applying = FALSE;
673 }
674
675 /*!
676 * Attribute editor grid
677 */
678
679 IMPLEMENT_CLASS(ctPropertyEditorGrid, wxGrid)
680
681 BEGIN_EVENT_TABLE(ctPropertyEditorGrid, wxGrid)
682 EVT_SIZE(ctPropertyEditorGrid::OnSize)
683 END_EVENT_TABLE()
684
685 ctPropertyEditorGrid::ctPropertyEditorGrid(wxWindow* parent, wxWindowID id,
686 const wxPoint& pos,
687 const wxSize& sz, long style):
688 wxGrid(parent, id, pos, sz, style)
689
690 {
691 m_stretchableColumn = -1;
692 }
693
694 void ctPropertyEditorGrid::OnSize(wxSizeEvent& event)
695 {
696 if (m_stretchableColumn != -1)
697 {
698 // This window's client size = the internal window's
699 // client size if it has no borders
700 wxSize sz = GetClientSize();
701
702 int totalSize = 0;
703 int i;
704 for (i = 0; i < GetNumberCols(); i ++)
705 {
706 if (i != m_stretchableColumn)
707 {
708 totalSize += GetColSize(i);
709 }
710 }
711
712 // Allow for grid lines
713 totalSize += 1;
714
715 int stretchSize = wxMax(5, sz.x - totalSize);
716 SetColSize(m_stretchableColumn, stretchSize);
717 }
718
719 event.Skip();
720 }
721
722 /// Use m_columnsToDisplay to set the label strings
723 void ctPropertyEditorGrid::DisplayLabels()
724 {
725 size_t i;
726 for (i = 0; i < m_columnsToDisplay.GetCount(); i++)
727 {
728 SetColLabelValue(i, m_columnsToDisplay[i]);
729 }
730 }
731
732 /// Clear attributes
733 bool ctPropertyEditorGrid::ClearAttributes()
734 {
735 if (GetNumberRows() > 0)
736 DeleteRows(0, GetNumberRows());
737 return TRUE;
738 }
739
740 /*!
741 * Use a single-line text control.
742 */
743
744 void ctGridCellTextEditor::Create(wxWindow* parent, wxWindowID id,
745 wxEvtHandler* evtHandler)
746 {
747 m_control = new wxTextCtrl(parent, id, wxEmptyString,
748 wxDefaultPosition, wxDefaultSize
749 );
750
751 wxGridCellEditor::Create(parent, id, evtHandler);
752 }
753
754
755 /// Translate the value to one which can be edited in a single-line
756 /// text control
757 wxString ctConvertToSingleText(const wxString& value)
758 {
759 wxString value1(value);
760 value1.Replace(wxT("\n"), wxT("\\n"));
761 value1.Replace(wxT("\t"), wxT("\\t"));
762 return value1;
763 }
764
765 /// Translate back to 'real' characters, i.e. newlines are real
766 /// newlines.
767 wxString ctConvertToMultilineText(const wxString& value)
768 {
769 wxString value1(value);
770 value1.Replace(wxT("\\n"), wxT("\n"));
771 value1.Replace(wxT("\\t"), wxT("\t"));
772 return value1;
773 }
774
775 //----------------------------------------------------------------------------
776 // ctMultiLineTextEditor
777 //----------------------------------------------------------------------------
778
779 BEGIN_EVENT_TABLE(ctMultiLineTextEditor, wxDialog)
780 END_EVENT_TABLE()
781
782 ctMultiLineTextEditor::ctMultiLineTextEditor( wxWindow *parent, wxWindowID id, const wxString &title,
783 const wxString& msg,
784 const wxString& value,
785 const wxPoint& pos,
786 const wxSize& size,
787 long style):
788 wxDialog(parent, id, title, pos, size, style)
789 {
790 m_text = value;
791 AddControls(this, msg);
792 Centre();
793 }
794
795 bool ctMultiLineTextEditor::AddControls(wxWindow* parent, const wxString& msg)
796 {
797 wxBoxSizer *item0 = new wxBoxSizer( wxVERTICAL );
798
799 wxBoxSizer *item1 = new wxBoxSizer( wxVERTICAL );
800
801 wxStaticText *item2 = new wxStaticText( parent, wxID_STATIC, msg, wxDefaultPosition, wxDefaultSize, 0 );
802 item1->Add( item2, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT, 5 );
803
804 wxTextCtrl *item3 = new wxTextCtrl( parent, -1, wxT(""), wxDefaultPosition, wxSize(330,180), wxTE_MULTILINE|wxTE_RICH );
805 item1->Add( item3, 1, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
806
807 wxBoxSizer *item4 = new wxBoxSizer( wxHORIZONTAL );
808
809 item4->Add( 5, 5, 1, wxALIGN_CENTRE|wxALL, 5 );
810
811 wxButton *item5 = new wxButton( parent, wxID_OK, _("&OK"), wxDefaultPosition, wxDefaultSize, 0 );
812 item5->SetDefault();
813 item4->Add( item5, 0, wxALIGN_CENTRE|wxALL, 5 );
814
815 wxButton *item6 = new wxButton( parent, wxID_CANCEL, _("&Cancel"), wxDefaultPosition, wxDefaultSize, 0 );
816 item4->Add( item6, 0, wxALIGN_CENTRE|wxALL, 5 );
817
818 item1->Add( item4, 0, wxGROW|wxALIGN_CENTER_VERTICAL, 5 );
819
820 item0->Add( item1, 1, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
821
822 item3->SetValue(m_text);
823 item3->SetValidator(wxGenericValidator(& m_text));
824
825
826 item3->SetFocus();
827 ((wxButton*) FindWindow(wxID_OK))->SetDefault();
828
829 parent->SetAutoLayout( TRUE );
830 parent->SetSizer(item0);
831 item0->Fit(parent);
832
833 return TRUE;
834 }
835
836 /*
837 * Special-purpose splitter window for changing sash look and
838 * also saving sash width
839 */
840
841 BEGIN_EVENT_TABLE(ctSplitterWindow, wxSplitterWindow)
842 EVT_SPLITTER_SASH_POS_CHANGED(-1, ctSplitterWindow::OnChangeSash)
843 END_EVENT_TABLE()
844
845 ctSplitterWindow::ctSplitterWindow(wxWindow* parent, wxWindowID id,
846 const wxPoint& pos, const wxSize& size, long style):
847 wxSplitterWindow(parent, id, pos, size, style)
848 {
849 m_updateSettings = FALSE;
850 m_position = 0;
851 }
852
853 void ctSplitterWindow::OnChangeSash(wxSplitterEvent& event)
854 {
855 if (!m_updateSettings)
856 return;
857
858 m_position = event.GetSashPosition();
859 }