]> git.saurik.com Git - wxWidgets.git/blame - src/richtext/richtextformatdlg.cpp
Remove copied class definitions from missing.h. Disable custom scheme handling under...
[wxWidgets.git] / src / richtext / richtextformatdlg.cpp
CommitLineData
97ff49b3
JS
1/////////////////////////////////////////////////////////////////////////////
2// Name: src/richtext/richtextformatdlg.cpp
3// Purpose: Formatting dialog for wxRichTextCtrl
4// Author: Julian Smart
5// Modified by:
6// Created: 2006-10-01
7// RCS-ID: $Id$
8// Copyright: (c) Julian Smart
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
12// For compilers that support precompilation, includes "wx.h".
13#include "wx/wxprec.h"
14
15#ifdef __BORLANDC__
16 #pragma hdrstop
17#endif
18
62b51bfb 19#if wxUSE_RICHTEXT
97ff49b3 20
528e5cf8
PC
21#include "wx/richtext/richtextformatdlg.h"
22
97ff49b3
JS
23#ifndef WX_PRECOMP
24 #include "wx/listbox.h"
25 #include "wx/combobox.h"
26 #include "wx/textctrl.h"
27 #include "wx/sizer.h"
28 #include "wx/stattext.h"
29 #include "wx/statline.h"
30 #include "wx/radiobut.h"
31 #include "wx/icon.h"
32 #include "wx/bitmap.h"
33 #include "wx/dcclient.h"
34 #include "wx/frame.h"
97ff49b3
JS
35 #include "wx/checkbox.h"
36 #include "wx/button.h"
37#endif // WX_PRECOMP
38
97ff49b3
JS
39#include "wx/bookctrl.h"
40#include "wx/colordlg.h"
97ff49b3
JS
41#include "wx/settings.h"
42#include "wx/module.h"
62b51bfb 43#include "wx/imaglist.h"
97ff49b3 44
97ff49b3
JS
45#include "wx/richtext/richtextctrl.h"
46#include "wx/richtext/richtextstyles.h"
47
ee5c8f01
SC
48#ifdef __WXMAC__
49#include "../../src/richtext/richtextfontpage.cpp"
50#include "../../src/richtext/richtextindentspage.cpp"
51#include "../../src/richtext/richtexttabspage.cpp"
52#include "../../src/richtext/richtextbulletspage.cpp"
53#include "../../src/richtext/richtextstylepage.cpp"
dadd4f55 54#include "../../src/richtext/richtextliststylepage.cpp"
603f702b
JS
55#include "../../src/richtext/richtextsizepage.cpp"
56#include "../../src/richtext/richtextmarginspage.cpp"
57#include "../../src/richtext/richtextborderspage.cpp"
58#include "../../src/richtext/richtextbackgroundpage.cpp"
ee5c8f01 59#else
97ff49b3
JS
60#include "richtextfontpage.cpp"
61#include "richtextindentspage.cpp"
62#include "richtexttabspage.cpp"
63#include "richtextbulletspage.cpp"
603f702b
JS
64#include "richtextmarginspage.cpp"
65#include "richtextsizepage.cpp"
66#include "richtextborderspage.cpp"
67#include "richtextbackgroundpage.cpp"
1f71a770
JS
68// Digital Mars can't cope with this much code
69#ifndef __DMC__
70 #include "richtextliststylepage.cpp"
71#endif
97ff49b3 72#include "richtextstylepage.cpp"
ee5c8f01 73#endif
97ff49b3 74
61c006ec 75#if 0 // def __WXMAC__
c730fa07 76#define wxRICHTEXT_USE_TOOLBOOK 1
97ff49b3 77#else
c730fa07 78#define wxRICHTEXT_USE_TOOLBOOK 0
97ff49b3
JS
79#endif
80
dadd4f55
JS
81bool wxRichTextFormattingDialog::sm_showToolTips = false;
82
97ff49b3
JS
83IMPLEMENT_CLASS(wxRichTextFormattingDialog, wxPropertySheetDialog)
84
85BEGIN_EVENT_TABLE(wxRichTextFormattingDialog, wxPropertySheetDialog)
2b741a39 86 EVT_BOOKCTRL_PAGE_CHANGED(wxID_ANY, wxRichTextFormattingDialog::OnTabChanged)
603f702b
JS
87 EVT_BUTTON(wxID_HELP, wxRichTextFormattingDialog::OnHelp)
88 EVT_UPDATE_UI(wxID_HELP, wxRichTextFormattingDialog::OnUpdateHelp)
97ff49b3
JS
89END_EVENT_TABLE()
90
603f702b
JS
91IMPLEMENT_HELP_PROVISION(wxRichTextFormattingDialog)
92
97ff49b3
JS
93wxRichTextFormattingDialogFactory* wxRichTextFormattingDialog::ms_FormattingDialogFactory = NULL;
94
95void wxRichTextFormattingDialog::Init()
96{
97ff49b3
JS
97 m_styleDefinition = NULL;
98 m_styleSheet = NULL;
603f702b 99 m_object = NULL;
97ff49b3
JS
100}
101
102wxRichTextFormattingDialog::~wxRichTextFormattingDialog()
103{
97ff49b3
JS
104 delete m_styleDefinition;
105}
106
107bool wxRichTextFormattingDialog::Create(long flags, wxWindow* parent, const wxString& title, wxWindowID id,
108 const wxPoint& pos, const wxSize& sz, long style)
109{
110 SetExtraStyle(wxDIALOG_EX_CONTEXTHELP|wxWS_EX_VALIDATE_RECURSIVELY);
111
112 int resizeBorder = wxRESIZE_BORDER;
113
114 GetFormattingDialogFactory()->SetSheetStyle(this);
115
116 wxPropertySheetDialog::Create(parent, id, title, pos, sz,
528e5cf8 117 style | (int)wxPlatform::IfNot(wxOS_WINDOWS_CE, resizeBorder)
97ff49b3
JS
118 );
119
120 GetFormattingDialogFactory()->CreateButtons(this);
121 GetFormattingDialogFactory()->CreatePages(flags, this);
122
123 LayoutDialog();
124
125 return true;
126}
127
128/// Get attributes from the given range
129bool wxRichTextFormattingDialog::GetStyle(wxRichTextCtrl* ctrl, const wxRichTextRange& range)
130{
603f702b 131 if (ctrl->GetFocusObject()->GetStyleForRange(range.ToInternal(), m_attributes))
97ff49b3
JS
132 return UpdateDisplay();
133 else
134 return false;
135}
136
137/// Apply attributes to the given range, only applying if necessary (wxRICHTEXT_SETSTYLE_OPTIMIZE)
138bool wxRichTextFormattingDialog::ApplyStyle(wxRichTextCtrl* ctrl, const wxRichTextRange& range, int flags)
139{
140 return ctrl->SetStyleEx(range, m_attributes, flags);
141}
142
603f702b
JS
143// Apply attributes to the object being edited, if any
144bool wxRichTextFormattingDialog::ApplyStyle(wxRichTextCtrl* WXUNUSED(ctrl), int flags)
145{
146 if (GetObject())
147 {
148 wxRichTextParagraphLayoutBox* parentContainer = GetObject()->GetParentContainer();
149 if (parentContainer)
150 parentContainer->SetStyle(GetObject(), m_attributes, flags);
151 return true;
152 }
153 else
154 return false;
155}
156
97ff49b3 157/// Set the attributes and optionally update the display
24777478 158bool wxRichTextFormattingDialog::SetStyle(const wxRichTextAttr& style, bool update)
97ff49b3
JS
159{
160 m_attributes = style;
161 if (update)
162 UpdateDisplay();
163 return true;
164}
165
166/// Set the style definition and optionally update the display
167bool wxRichTextFormattingDialog::SetStyleDefinition(const wxRichTextStyleDefinition& styleDef, wxRichTextStyleSheet* sheet, bool update)
168{
169 m_styleSheet = sheet;
170
171 if (m_styleDefinition)
172 delete m_styleDefinition;
173 m_styleDefinition = styleDef.Clone();
174
175 return SetStyle(m_styleDefinition->GetStyle(), update);
176}
177
178/// Transfers the data and from to the window
179bool wxRichTextFormattingDialog::TransferDataToWindow()
180{
181 if (m_styleDefinition)
182 m_attributes = m_styleDefinition->GetStyle();
183
184 if (!wxPropertySheetDialog::TransferDataToWindow())
185 return false;
186
187 return true;
188}
189
190bool wxRichTextFormattingDialog::TransferDataFromWindow()
191{
192 if (!wxPropertySheetDialog::TransferDataFromWindow())
193 return false;
194
195 if (m_styleDefinition)
196 m_styleDefinition->GetStyle() = m_attributes;
197
198 return true;
199}
200
201/// Update the display
202bool wxRichTextFormattingDialog::UpdateDisplay()
203{
204 return TransferDataToWindow();
205}
206
207/// Apply the styles when a different tab is selected, so the previews are
208/// up to date
2b741a39 209void wxRichTextFormattingDialog::OnTabChanged(wxBookCtrlEvent& event)
97ff49b3
JS
210{
211 if (GetBookCtrl() != event.GetEventObject())
212 {
213 event.Skip();
214 return;
215 }
216
217 int oldPageId = event.GetOldSelection();
218 if (oldPageId != -1)
219 {
220 wxWindow* page = GetBookCtrl()->GetPage(oldPageId);
221 if (page)
222 page->TransferDataFromWindow();
223 }
224
225 int pageId = event.GetSelection();
226 if (pageId != -1)
227 {
228 wxWindow* page = GetBookCtrl()->GetPage(pageId);
229 if (page)
230 page->TransferDataToWindow();
231 }
232}
233
1807a1f3
JS
234/// Respond to help command
235void wxRichTextFormattingDialog::OnHelp(wxCommandEvent& event)
236{
237 int selPage = GetBookCtrl()->GetSelection();
238 if (selPage != wxNOT_FOUND)
239 {
603f702b
JS
240 int pageId = -1;
241 if (selPage < (int) m_pageIds.GetCount())
242 pageId = m_pageIds[selPage];
1807a1f3
JS
243 if (!GetFormattingDialogFactory()->ShowHelp(pageId, this))
244 event.Skip();
245 }
246}
247
603f702b
JS
248void wxRichTextFormattingDialog::OnUpdateHelp(wxUpdateUIEvent& event)
249{
250 event.Enable(true);
251}
252
97ff49b3
JS
253void wxRichTextFormattingDialog::SetFormattingDialogFactory(wxRichTextFormattingDialogFactory* factory)
254{
255 if (ms_FormattingDialogFactory)
256 delete ms_FormattingDialogFactory;
257 ms_FormattingDialogFactory = factory;
258}
259
603f702b
JS
260// Find a page by class
261wxWindow* wxRichTextFormattingDialog::FindPage(wxClassInfo* info) const
262{
263 size_t i;
264 for (i = 0; i < GetBookCtrl()->GetPageCount(); i++)
265 {
266 wxWindow* w = GetBookCtrl()->GetPage(i);
267 if (w && w->GetClassInfo() == info)
268 return w;
269 }
270 return NULL;
271}
272
273
97ff49b3
JS
274/*!
275 * Factory for formatting dialog
276 */
277
278/// Create all pages, under the dialog's book control, also calling AddPage
279bool wxRichTextFormattingDialogFactory::CreatePages(long pages, wxRichTextFormattingDialog* dialog)
280{
281 if (dialog->GetImageList())
282 dialog->GetBookCtrl()->SetImageList(dialog->GetImageList());
283
284 int availablePageCount = GetPageIdCount();
285 int i;
61c006ec 286 bool selected = false;
97ff49b3
JS
287 for (i = 0; i < availablePageCount; i ++)
288 {
289 int pageId = GetPageId(i);
290 if (pageId != -1 && (pages & pageId))
291 {
292 wxString title;
293 wxPanel* panel = CreatePage(pageId, title, dialog);
294 wxASSERT( panel != NULL );
295 if (panel)
296 {
297 int imageIndex = GetPageImage(pageId);
61c006ec
JS
298 dialog->GetBookCtrl()->AddPage(panel, title, !selected, imageIndex);
299 selected = true;
41a85215 300
1807a1f3 301 dialog->AddPageId(pageId);
97ff49b3
JS
302 }
303 }
304 }
2b741a39 305
97ff49b3
JS
306 return true;
307}
308
309/// Create a page, given a page identifier
310wxPanel* wxRichTextFormattingDialogFactory::CreatePage(int page, wxString& title, wxRichTextFormattingDialog* dialog)
311{
312 if (page == wxRICHTEXT_FORMAT_STYLE_EDITOR)
313 {
314 wxRichTextStylePage* page = new wxRichTextStylePage(dialog->GetBookCtrl(), wxID_ANY);
315 title = _("Style");
316 return page;
317 }
318 else if (page == wxRICHTEXT_FORMAT_FONT)
319 {
320 wxRichTextFontPage* page = new wxRichTextFontPage(dialog->GetBookCtrl(), wxID_ANY);
321 title = _("Font");
322 return page;
323 }
324 else if (page == wxRICHTEXT_FORMAT_INDENTS_SPACING)
325 {
326 wxRichTextIndentsSpacingPage* page = new wxRichTextIndentsSpacingPage(dialog->GetBookCtrl(), wxID_ANY);
327 title = _("Indents && Spacing");
328 return page;
329 }
330 else if (page == wxRICHTEXT_FORMAT_TABS)
331 {
332 wxRichTextTabsPage* page = new wxRichTextTabsPage(dialog->GetBookCtrl(), wxID_ANY);
333 title = _("Tabs");
334 return page;
335 }
336 else if (page == wxRICHTEXT_FORMAT_BULLETS)
337 {
338 wxRichTextBulletsPage* page = new wxRichTextBulletsPage(dialog->GetBookCtrl(), wxID_ANY);
339 title = _("Bullets");
340 return page;
341 }
1f71a770 342#ifndef __DMC__
dadd4f55
JS
343 else if (page == wxRICHTEXT_FORMAT_LIST_STYLE)
344 {
345 wxRichTextListStylePage* page = new wxRichTextListStylePage(dialog->GetBookCtrl(), wxID_ANY);
346 title = _("List Style");
347 return page;
348 }
1f71a770 349#endif
603f702b
JS
350 else if (page == wxRICHTEXT_FORMAT_SIZE)
351 {
352 wxRichTextSizePage* page = new wxRichTextSizePage(dialog->GetBookCtrl(), wxID_ANY);
353 title = _("Size");
354 return page;
355 }
356 else if (page == wxRICHTEXT_FORMAT_MARGINS)
357 {
358 wxRichTextMarginsPage* page = new wxRichTextMarginsPage(dialog->GetBookCtrl(), wxID_ANY);
359 title = _("Margins");
360 return page;
361 }
362 else if (page == wxRICHTEXT_FORMAT_BORDERS)
363 {
364 wxRichTextBordersPage* page = new wxRichTextBordersPage(dialog->GetBookCtrl(), wxID_ANY);
365 title = _("Borders");
366 return page;
367 }
368 else if (page == wxRICHTEXT_FORMAT_BACKGROUND)
369 {
370 wxRichTextBackgroundPage* page = new wxRichTextBackgroundPage(dialog->GetBookCtrl(), wxID_ANY);
371 title = _("Background");
372 return page;
373 }
97ff49b3
JS
374 else
375 return NULL;
376}
377
378/// Enumerate all available page identifiers
379int wxRichTextFormattingDialogFactory::GetPageId(int i) const
380{
381 int pages[] = {
382 wxRICHTEXT_FORMAT_STYLE_EDITOR,
383 wxRICHTEXT_FORMAT_FONT,
384 wxRICHTEXT_FORMAT_INDENTS_SPACING,
385 wxRICHTEXT_FORMAT_BULLETS,
dadd4f55 386 wxRICHTEXT_FORMAT_TABS,
603f702b
JS
387 wxRICHTEXT_FORMAT_LIST_STYLE,
388 wxRICHTEXT_FORMAT_SIZE,
389 wxRICHTEXT_FORMAT_MARGINS,
390 wxRICHTEXT_FORMAT_BORDERS,
391 wxRICHTEXT_FORMAT_BACKGROUND
392 };
393
394 if (i < 0 || i >= GetPageIdCount())
97ff49b3
JS
395 return -1;
396
397 return pages[i];
398}
399
400/// Get the number of available page identifiers
401int wxRichTextFormattingDialogFactory::GetPageIdCount() const
402{
1f71a770 403#ifdef __DMC__
603f702b 404 return 9;
1f71a770 405#else
603f702b 406 return 10;
1f71a770 407#endif
97ff49b3
JS
408}
409
410/// Set the sheet style, called at the start of wxRichTextFormattingDialog::Create
411bool wxRichTextFormattingDialogFactory::SetSheetStyle(wxRichTextFormattingDialog* dialog)
412{
d0cf4953
VZ
413#if wxRICHTEXT_USE_TOOLBOOK
414 int sheetStyle = wxPROPSHEET_SHRINKTOFIT;
97ff49b3 415#ifdef __WXMAC__
d0cf4953 416 sheetStyle |= wxPROPSHEET_BUTTONTOOLBOOK;
97ff49b3 417#else
d0cf4953 418 sheetStyle |= wxPROPSHEET_TOOLBOOK;
97ff49b3
JS
419#endif
420
d0cf4953
VZ
421 dialog->SetSheetStyle(sheetStyle);
422 dialog->SetSheetInnerBorder(0);
423 dialog->SetSheetOuterBorder(0);
c730fa07 424#else
44cc96a8 425 wxUnusedVar(dialog);
d0cf4953 426#endif // wxRICHTEXT_USE_TOOLBOOK
97ff49b3
JS
427
428 return true;
429}
430
431/// Create the main dialog buttons
432bool wxRichTextFormattingDialogFactory::CreateButtons(wxRichTextFormattingDialog* dialog)
433{
97ff49b3
JS
434 int flags = wxOK|wxCANCEL;
435#ifndef __WXWINCE__
dadd4f55
JS
436 if (dialog->GetWindowStyleFlag() & wxRICHTEXT_FORMAT_HELP_BUTTON)
437 flags |= wxHELP;
97ff49b3
JS
438#endif
439
d0cf4953
VZ
440 // If using a toolbook, also follow Mac style and don't create buttons
441#if !wxRICHTEXT_USE_TOOLBOOK
442 dialog->CreateButtons(flags);
443#endif
97ff49b3
JS
444
445 return true;
446}
447
603f702b
JS
448// Invoke help for the dialog
449bool wxRichTextFormattingDialogFactory::ShowHelp(int WXUNUSED(page), wxRichTextFormattingDialog* dialog)
450{
451 wxRichTextDialogPage* window = NULL;
452 int sel = dialog->GetBookCtrl()->GetSelection();
453 if (sel != -1)
454 window = wxDynamicCast(dialog->GetBookCtrl()->GetPage(sel), wxRichTextDialogPage);
455 if (window && window->GetHelpId() != -1)
456 {
457 if (window->GetUICustomization())
458 return window->GetUICustomization()->ShowHelp(dialog, window->GetHelpId());
459 else if (dialog->GetUICustomization())
460 return dialog->GetUICustomization()->ShowHelp(dialog, window->GetHelpId());
461 else
462 return false;
463 }
464 else if (dialog->GetHelpId() != -1 && dialog->GetUICustomization())
465 return dialog->ShowHelp(dialog);
466 else
467 return false;
468}
469
97ff49b3
JS
470/*
471 * Module to initialise and clean up handlers
472 */
473
474class wxRichTextFormattingDialogModule: public wxModule
475{
476DECLARE_DYNAMIC_CLASS(wxRichTextFormattingDialogModule)
477public:
478 wxRichTextFormattingDialogModule() {}
47b378bd
VS
479 bool OnInit() { wxRichTextFormattingDialog::SetFormattingDialogFactory(new wxRichTextFormattingDialogFactory); return true; }
480 void OnExit() { wxRichTextFormattingDialog::SetFormattingDialogFactory(NULL); }
97ff49b3
JS
481};
482
483IMPLEMENT_DYNAMIC_CLASS(wxRichTextFormattingDialogModule, wxModule)
484
485/*
486 * Font preview control
487 */
488
489BEGIN_EVENT_TABLE(wxRichTextFontPreviewCtrl, wxWindow)
490 EVT_PAINT(wxRichTextFontPreviewCtrl::OnPaint)
491END_EVENT_TABLE()
492
2fce6547
JS
493wxRichTextFontPreviewCtrl::wxRichTextFontPreviewCtrl(wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxSize& sz, long style)
494{
495 if ((style & wxBORDER_MASK) == wxBORDER_DEFAULT)
496 style |= wxBORDER_THEME;
497
498 wxWindow::Create(parent, id, pos, sz, style);
499
500 SetBackgroundColour(*wxWHITE);
501 m_textEffects = 0;
502}
503
97ff49b3
JS
504void wxRichTextFontPreviewCtrl::OnPaint(wxPaintEvent& WXUNUSED(event))
505{
506 wxPaintDC dc(this);
507
508 wxSize size = GetSize();
509 wxFont font = GetFont();
510
30bf7630
JS
511 if ((GetTextEffects() & wxTEXT_ATTR_EFFECT_SUPERSCRIPT) || (GetTextEffects() & wxTEXT_ATTR_EFFECT_SUBSCRIPT))
512 {
513 double size = static_cast<double>(font.GetPointSize()) / wxSCRIPT_MUL_FACTOR;
514 font.SetPointSize( static_cast<int>(size) );
515 }
516
a1b806b9 517 if ( font.IsOk() )
97ff49b3
JS
518 {
519 dc.SetFont(font);
520 // Calculate vertical and horizontal centre
0bc58f95 521 wxCoord w = 0, h = 0;
97ff49b3
JS
522
523 wxString text(_("ABCDEFGabcdefg12345"));
42688aea
JS
524 if (GetTextEffects() & wxTEXT_ATTR_EFFECT_CAPITALS)
525 text.MakeUpper();
97ff49b3
JS
526
527 dc.GetTextExtent( text, &w, &h);
528 int cx = wxMax(2, (size.x/2) - (w/2));
529 int cy = wxMax(2, (size.y/2) - (h/2));
530
30bf7630
JS
531 if ( GetTextEffects() & wxTEXT_ATTR_EFFECT_SUPERSCRIPT )
532 cy -= h/2;
533 if ( GetTextEffects() & wxTEXT_ATTR_EFFECT_SUBSCRIPT )
534 cy += h/2;
535
97ff49b3
JS
536 dc.SetTextForeground(GetForegroundColour());
537 dc.SetClippingRegion(2, 2, size.x-4, size.y-4);
538 dc.DrawText(text, cx, cy);
c730fa07 539
42688aea
JS
540 if (GetTextEffects() & wxTEXT_ATTR_EFFECT_STRIKETHROUGH)
541 {
542 dc.SetPen(wxPen(GetForegroundColour(), 1));
543 dc.DrawLine(cx, (int) (cy + h/2 + 0.5), cx + w, (int) (cy + h/2 + 0.5));
544 }
c730fa07 545
97ff49b3
JS
546 dc.DestroyClippingRegion();
547 }
548}
549
550// Helper for pages to get the top-level dialog
551wxRichTextFormattingDialog* wxRichTextFormattingDialog::GetDialog(wxWindow* win)
552{
553 wxWindow* p = win->GetParent();
554 while (p && !p->IsKindOf(CLASSINFO(wxRichTextFormattingDialog)))
555 p = p->GetParent();
556 wxRichTextFormattingDialog* dialog = wxDynamicCast(p, wxRichTextFormattingDialog);
557 return dialog;
558}
559
97ff49b3 560// Helper for pages to get the attributes
24777478 561wxRichTextAttr* wxRichTextFormattingDialog::GetDialogAttributes(wxWindow* win)
97ff49b3
JS
562{
563 wxRichTextFormattingDialog* dialog = GetDialog(win);
564 if (dialog)
565 return & dialog->GetAttributes();
566 else
567 return NULL;
568}
569
603f702b
JS
570#if 0
571// Helper for pages to get the attributes to reset
572wxRichTextAttr* wxRichTextFormattingDialog::GetDialogResetAttributes(wxWindow* win)
573{
574 wxRichTextFormattingDialog* dialog = GetDialog(win);
575 if (dialog)
576 return & dialog->GetResetAttributes();
577 else
578 return NULL;
579}
580#endif
581
97ff49b3
JS
582// Helper for pages to get the style
583wxRichTextStyleDefinition* wxRichTextFormattingDialog::GetDialogStyleDefinition(wxWindow* win)
584{
585 wxRichTextFormattingDialog* dialog = GetDialog(win);
586 if (dialog)
587 return dialog->GetStyleDefinition();
588 else
589 return NULL;
590}
591
603f702b
JS
592void wxRichTextFormattingDialog::SetDimensionValue(wxTextAttrDimension& dim, wxTextCtrl* valueCtrl, wxComboBox* unitsCtrl, wxCheckBox* checkBox)
593{
594 int unitsIdx = 0;
706465df 595
603f702b
JS
596 if (!dim.IsValid())
597 {
598 checkBox->SetValue(false);
599 valueCtrl->SetValue(wxT("0"));
600 unitsCtrl->SetSelection(0);
601#if 0
602 dim.SetValue(0);
603 dim.SetUnits(wxTEXT_ATTR_UNITS_PIXELS);
604#endif
605 }
606 else
607 {
608 checkBox->SetValue(true);
609 if (dim.GetUnits() == wxTEXT_ATTR_UNITS_TENTHS_MM)
610 {
611 unitsIdx = 1;
706465df 612 float value = float(dim.GetValue()) / 100.0;
603f702b
JS
613 valueCtrl->SetValue(wxString::Format(wxT("%.2f"), value));
614 }
706465df
JS
615 else if (dim.GetUnits() == wxTEXT_ATTR_UNITS_PERCENTAGE)
616 {
617 unitsIdx = 2;
618 valueCtrl->SetValue(wxString::Format(wxT("%d"), (int) dim.GetValue()));
619 }
603f702b
JS
620 else
621 {
622 unitsIdx = 0;
623 valueCtrl->SetValue(wxString::Format(wxT("%d"), (int) dim.GetValue()));
624 }
625
626 unitsCtrl->SetSelection(unitsIdx);
627 }
628}
629
630void wxRichTextFormattingDialog::GetDimensionValue(wxTextAttrDimension& dim, wxTextCtrl* valueCtrl, wxComboBox* unitsCtrl, wxCheckBox* checkBox)
631{
632 if (!checkBox->GetValue())
633 {
634 dim.Reset();
635 }
636 else
637 {
638 if (unitsCtrl->GetSelection() == 1)
639 dim.SetUnits(wxTEXT_ATTR_UNITS_TENTHS_MM);
706465df
JS
640 else if (unitsCtrl->GetSelection() == 2)
641 dim.SetUnits(wxTEXT_ATTR_UNITS_PERCENTAGE);
603f702b
JS
642 else
643 dim.SetUnits(wxTEXT_ATTR_UNITS_PIXELS);
644
645 int value = 0;
646 if (ConvertFromString(valueCtrl->GetValue(), value, dim.GetUnits()))
647 dim.SetValue(value);
648 }
649}
650
651bool wxRichTextFormattingDialog::ConvertFromString(const wxString& string, int& ret, int scale)
652{
653 const wxChar* chars = string.GetData();
654 int remain = 2;
655 bool dot = false;
656 ret = 0;
657
658 for (unsigned int i = 0; i < string.Len() && remain; i++)
659 {
660 if (!(chars[i] >= wxT('0') && chars[i] <= wxT('9')) && !(scale == wxTEXT_ATTR_UNITS_TENTHS_MM && chars[i] == wxT('.')))
661 return false;
662
663 if (chars[i] == wxT('.'))
664 {
665 dot = true;
666 continue;
667 }
668
669 if (dot)
670 remain--;
671
672 ret = ret * 10 + chars[i] - wxT('0');
673 }
674
675 while (remain-- > 0 && scale == wxTEXT_ATTR_UNITS_TENTHS_MM)
676 ret *= 10;
677
678 return true;
679}
680
97ff49b3
JS
681/*
682 * A control for displaying a small preview of a colour or bitmap
683 */
684
685BEGIN_EVENT_TABLE(wxRichTextColourSwatchCtrl, wxControl)
686 EVT_MOUSE_EVENTS(wxRichTextColourSwatchCtrl::OnMouseEvent)
687END_EVENT_TABLE()
688
689IMPLEMENT_CLASS(wxRichTextColourSwatchCtrl, wxControl)
690
2fce6547 691wxRichTextColourSwatchCtrl::wxRichTextColourSwatchCtrl(wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style)
97ff49b3 692{
2fce6547
JS
693 if ((style & wxBORDER_MASK) == wxBORDER_DEFAULT)
694 style |= wxBORDER_THEME;
695
696 wxControl::Create(parent, id, pos, size, style);
697
97ff49b3 698 SetColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
97ff49b3
JS
699}
700
701wxRichTextColourSwatchCtrl::~wxRichTextColourSwatchCtrl()
702{
703}
704
705void wxRichTextColourSwatchCtrl::OnMouseEvent(wxMouseEvent& event)
706{
707 if (event.LeftDown())
708 {
709 wxWindow* parent = GetParent();
710 while (parent != NULL && !parent->IsKindOf(CLASSINFO(wxDialog)) && !parent->IsKindOf(CLASSINFO(wxFrame)))
711 parent = parent->GetParent();
712
713 wxColourData data;
714 data.SetChooseFull(true);
715 data.SetColour(m_colour);
2b741a39 716#if wxUSE_COLOURDLG
97ff49b3
JS
717 wxColourDialog *dialog = new wxColourDialog(parent, &data);
718 // Crashes on wxMac (no m_peer)
719#ifndef __WXMAC__
2fce6547 720 dialog->SetTitle(_("Colour"));
97ff49b3
JS
721#endif
722 if (dialog->ShowModal() == wxID_OK)
723 {
724 wxColourData retData = dialog->GetColourData();
725 m_colour = retData.GetColour();
726 SetBackgroundColour(m_colour);
727 }
728 dialog->Destroy();
2b741a39 729#endif // wxUSE_COLOURDLG
97ff49b3
JS
730 Refresh();
731
732 wxCommandEvent event(wxEVT_COMMAND_BUTTON_CLICKED, GetId());
733 GetEventHandler()->ProcessEvent(event);
734 }
735}
736
737#if wxUSE_HTML
738
739/*!
740 * wxRichTextFontListBox class declaration
741 * A listbox to display styles.
742 */
743
744IMPLEMENT_CLASS(wxRichTextFontListBox, wxHtmlListBox)
745
746BEGIN_EVENT_TABLE(wxRichTextFontListBox, wxHtmlListBox)
747END_EVENT_TABLE()
748
749wxRichTextFontListBox::wxRichTextFontListBox(wxWindow* parent, wxWindowID id, const wxPoint& pos,
750 const wxSize& size, long style)
751{
752 Init();
753 Create(parent, id, pos, size, style);
754}
755
756bool wxRichTextFontListBox::Create(wxWindow* parent, wxWindowID id, const wxPoint& pos,
757 const wxSize& size, long style)
758{
2fce6547
JS
759 if ((style & wxBORDER_MASK) == wxBORDER_DEFAULT)
760 style |= wxBORDER_THEME;
761
97ff49b3
JS
762 return wxHtmlListBox::Create(parent, id, pos, size, style);
763}
764
765wxRichTextFontListBox::~wxRichTextFontListBox()
766{
767}
768
769/// Returns the HTML for this item
770wxString wxRichTextFontListBox::OnGetItem(size_t n) const
771{
772 if (m_faceNames.GetCount() == 0)
773 return wxEmptyString;
774
775 wxString str = CreateHTML(m_faceNames[n]);
776 return str;
777}
778
779/// Get font name for index
780wxString wxRichTextFontListBox::GetFaceName(size_t i) const
781{
782 return m_faceNames[i];
783}
784
785/// Set selection for string, returning the index.
786int wxRichTextFontListBox::SetFaceNameSelection(const wxString& name)
787{
788 int i = m_faceNames.Index(name);
789 SetSelection(i);
790
791 return i;
792}
793
794/// Updates the font list
795void wxRichTextFontListBox::UpdateFonts()
796{
dadd4f55 797 wxArrayString facenames = wxRichTextCtrl::GetAvailableFontNames();
97ff49b3
JS
798 m_faceNames = facenames;
799 m_faceNames.Sort();
800
801 SetItemCount(m_faceNames.GetCount());
802 Refresh();
803}
804
805#if 0
806// Convert a colour to a 6-digit hex string
807static wxString ColourToHexString(const wxColour& col)
808{
809 wxString hex;
810
811 hex += wxDecToHex(col.Red());
812 hex += wxDecToHex(col.Green());
813 hex += wxDecToHex(col.Blue());
814
815 return hex;
816}
817#endif
818
819/// Creates a suitable HTML fragment for a definition
820wxString wxRichTextFontListBox::CreateHTML(const wxString& facename) const
821{
822 wxString str = wxT("<font");
823
824 str << wxT(" size=\"+2\"");;
825
826 if (!facename.IsEmpty() && facename != _("(none)"))
827 str << wxT(" face=\"") << facename << wxT("\"");
828/*
a1b806b9 829 if (def->GetStyle().GetTextColour().IsOk())
97ff49b3
JS
830 str << wxT(" color=\"#") << ColourToHexString(def->GetStyle().GetTextColour()) << wxT("\"");
831*/
832
833 str << wxT(">");
834
835 bool hasBold = false;
836
837 if (hasBold)
838 str << wxT("<b>");
839
840 str += facename;
841
842 if (hasBold)
843 str << wxT("</b>");
844
845 str << wxT("</font>");
846
847 return str;
848}
849
850#endif
851 // wxUSE_HTML
852
853
854#endif
855 // wxUSE_RICHTEXT