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