1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/richtext/richtextstyles.cpp
3 // Purpose: Style management for wxRichTextCtrl
4 // Author: Julian Smart
5 // Modified by:
6 // Created: 2005-09-30
7 // RCS-ID: $Id: richtextstyles.cpp 67222 2011-03-17 09:23:18Z JS $
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
19 #if wxUSE_RICHTEXT
20
21 #include "wx/richtext/richtextstyles.h"
22
23 #ifndef WX_PRECOMP
24 #include "wx/wx.h"
25 #endif
26
27 #include "wx/filename.h"
28 #include "wx/clipbrd.h"
29 #include "wx/wfstream.h"
30 #include "wx/settings.h"
31
32 #include "wx/richtext/richtextctrl.h"
33
IMPLEMENT_CLASS(wxRichTextStyleDefinition,wxObject)34 IMPLEMENT_CLASS(wxRichTextStyleDefinition, wxObject)
35 IMPLEMENT_CLASS(wxRichTextCharacterStyleDefinition, wxRichTextStyleDefinition)
36 IMPLEMENT_CLASS(wxRichTextParagraphStyleDefinition, wxRichTextStyleDefinition)
37 IMPLEMENT_CLASS(wxRichTextListStyleDefinition, wxRichTextParagraphStyleDefinition)
38
39 /*!
40 * A definition
41 */
42
43 void wxRichTextStyleDefinition::Copy(const wxRichTextStyleDefinition& def)
44 {
45 m_name = def.m_name;
46 m_baseStyle = def.m_baseStyle;
47 m_style = def.m_style;
48 m_description = def.m_description;
49 }
50
Eq(const wxRichTextStyleDefinition & def) const51 bool wxRichTextStyleDefinition::Eq(const wxRichTextStyleDefinition& def) const
52 {
53 return (m_name == def.m_name && m_baseStyle == def.m_baseStyle && m_style == def.m_style);
54 }
55
56 /// Gets the style combined with the base style
GetStyleMergedWithBase(const wxRichTextStyleSheet * sheet) const57 wxRichTextAttr wxRichTextStyleDefinition::GetStyleMergedWithBase(const wxRichTextStyleSheet* sheet) const
58 {
59 if (m_baseStyle.IsEmpty())
60 return m_style;
61
62 bool isParaStyle = IsKindOf(CLASSINFO(wxRichTextParagraphStyleDefinition));
63 bool isCharStyle = IsKindOf(CLASSINFO(wxRichTextCharacterStyleDefinition));
64 bool isListStyle = IsKindOf(CLASSINFO(wxRichTextListStyleDefinition));
65
66 // Collect the styles, detecting loops
67 wxArrayString styleNames;
68 wxList styles;
69 const wxRichTextStyleDefinition* def = this;
70 while (def)
71 {
72 styles.Insert((wxObject*) def);
73 styleNames.Add(def->GetName());
74
75 wxString baseStyleName = def->GetBaseStyle();
76 if (!baseStyleName.IsEmpty() && styleNames.Index(baseStyleName) == wxNOT_FOUND)
77 {
78 if (isParaStyle)
79 def = sheet->FindParagraphStyle(baseStyleName);
80 else if (isCharStyle)
81 def = sheet->FindCharacterStyle(baseStyleName);
82 else if (isListStyle)
83 def = sheet->FindListStyle(baseStyleName);
84 else
85 def = sheet->FindStyle(baseStyleName);
86 }
87 else
88 def = NULL;
89 }
90
91 wxRichTextAttr attr;
92 wxList::compatibility_iterator node = styles.GetFirst();
93 while (node)
94 {
95 wxRichTextStyleDefinition* def = (wxRichTextStyleDefinition*) node->GetData();
96 attr.Apply(def->GetStyle(), NULL);
97 node = node->GetNext();
98 }
99
100 return attr;
101 }
102
103 /*!
104 * Paragraph style definition
105 */
106
Copy(const wxRichTextParagraphStyleDefinition & def)107 void wxRichTextParagraphStyleDefinition::Copy(const wxRichTextParagraphStyleDefinition& def)
108 {
109 wxRichTextStyleDefinition::Copy(def);
110
111 m_nextStyle = def.m_nextStyle;
112 }
113
operator ==(const wxRichTextParagraphStyleDefinition & def) const114 bool wxRichTextParagraphStyleDefinition::operator ==(const wxRichTextParagraphStyleDefinition& def) const
115 {
116 return (Eq(def) && m_nextStyle == def.m_nextStyle);
117 }
118
119 /*!
120 * List style definition
121 */
122
Copy(const wxRichTextListStyleDefinition & def)123 void wxRichTextListStyleDefinition::Copy(const wxRichTextListStyleDefinition& def)
124 {
125 wxRichTextParagraphStyleDefinition::Copy(def);
126
127 int i;
128 for (i = 0; i < 10; i++)
129 m_levelStyles[i] = def.m_levelStyles[i];
130 }
131
operator ==(const wxRichTextListStyleDefinition & def) const132 bool wxRichTextListStyleDefinition::operator ==(const wxRichTextListStyleDefinition& def) const
133 {
134 if (!Eq(def))
135 return false;
136 int i;
137 for (i = 0; i < 10; i++)
138 if (!(m_levelStyles[i] == def.m_levelStyles[i]))
139 return false;
140
141 return true;
142 }
143
144 /// Sets/gets the attributes for the given level
SetLevelAttributes(int i,const wxRichTextAttr & attr)145 void wxRichTextListStyleDefinition::SetLevelAttributes(int i, const wxRichTextAttr& attr)
146 {
147 wxASSERT( (i >= 0 && i < 10) );
148 if (i >= 0 && i < 10)
149 m_levelStyles[i] = attr;
150 }
151
GetLevelAttributes(int i) const152 const wxRichTextAttr* wxRichTextListStyleDefinition::GetLevelAttributes(int i) const
153 {
154 wxASSERT( (i >= 0 && i < 10) );
155 if (i >= 0 && i < 10)
156 return & m_levelStyles[i];
157 else
158 return NULL;
159 }
160
GetLevelAttributes(int i)161 wxRichTextAttr* wxRichTextListStyleDefinition::GetLevelAttributes(int i)
162 {
163 wxASSERT( (i >= 0 && i < 10) );
164 if (i >= 0 && i < 10)
165 return & m_levelStyles[i];
166 else
167 return NULL;
168 }
169
170 /// Convenience function for setting the major attributes for a list level specification
SetAttributes(int i,int leftIndent,int leftSubIndent,int bulletStyle,const wxString & bulletSymbol)171 void wxRichTextListStyleDefinition::SetAttributes(int i, int leftIndent, int leftSubIndent, int bulletStyle, const wxString& bulletSymbol)
172 {
173 wxASSERT( (i >= 0 && i < 10) );
174 if (i >= 0 && i < 10)
175 {
176 wxRichTextAttr attr;
177
178 attr.SetBulletStyle(bulletStyle);
179 attr.SetLeftIndent(leftIndent, leftSubIndent);
180
181 if (!bulletSymbol.IsEmpty())
182 {
183 if (bulletStyle & wxTEXT_ATTR_BULLET_STYLE_SYMBOL)
184 attr.SetBulletText(bulletSymbol);
185 else
186 attr.SetBulletName(bulletSymbol);
187 }
188
189 m_levelStyles[i] = attr;
190 }
191 }
192
193 /// Finds the level corresponding to the given indentation
FindLevelForIndent(int indent) const194 int wxRichTextListStyleDefinition::FindLevelForIndent(int indent) const
195 {
196 int i;
197 for (i = 0; i < 10; i++)
198 {
199 if (indent < m_levelStyles[i].GetLeftIndent())
200 {
201 if (i > 0)
202 return i - 1;
203 else
204 return 0;
205 }
206 }
207 return 9;
208 }
209
210 /// Combine the list style with a paragraph style, using the given indent (from which
211 /// an appropriate level is found)
CombineWithParagraphStyle(int indent,const wxRichTextAttr & paraStyle,wxRichTextStyleSheet * styleSheet)212 wxRichTextAttr wxRichTextListStyleDefinition::CombineWithParagraphStyle(int indent, const wxRichTextAttr& paraStyle, wxRichTextStyleSheet* styleSheet)
213 {
214 int listLevel = FindLevelForIndent(indent);
215
216 wxRichTextAttr attr(*GetLevelAttributes(listLevel));
217 int oldLeftIndent = attr.GetLeftIndent();
218 int oldLeftSubIndent = attr.GetLeftSubIndent();
219
220 // First apply the overall paragraph style, if any
221 if (styleSheet)
222 attr.Apply(GetStyleMergedWithBase(styleSheet));
223 else
224 attr.Apply(GetStyle());
225
226 // Then apply paragraph style, e.g. from paragraph style definition
227 attr.Apply(paraStyle);
228
229 // We override the indents according to the list definition
230 attr.SetLeftIndent(oldLeftIndent, oldLeftSubIndent);
231
232 return attr;
233 }
234
235 /// Combine the base and list style, using the given indent (from which
236 /// an appropriate level is found)
GetCombinedStyle(int indent,wxRichTextStyleSheet * styleSheet)237 wxRichTextAttr wxRichTextListStyleDefinition::GetCombinedStyle(int indent, wxRichTextStyleSheet* styleSheet)
238 {
239 int listLevel = FindLevelForIndent(indent);
240 return GetCombinedStyleForLevel(listLevel, styleSheet);
241 }
242
243 /// Combine the base and list style, using the given indent (from which
244 /// an appropriate level is found)
GetCombinedStyleForLevel(int listLevel,wxRichTextStyleSheet * styleSheet)245 wxRichTextAttr wxRichTextListStyleDefinition::GetCombinedStyleForLevel(int listLevel, wxRichTextStyleSheet* styleSheet)
246 {
247 wxRichTextAttr attr(*GetLevelAttributes(listLevel));
248 int oldLeftIndent = attr.GetLeftIndent();
249 int oldLeftSubIndent = attr.GetLeftSubIndent();
250
251 // Apply the overall paragraph style, if any
252 if (styleSheet)
253 attr.Apply(GetStyleMergedWithBase(styleSheet));
254 else
255 attr.Apply(GetStyle());
256
257 // We override the indents according to the list definition
258 attr.SetLeftIndent(oldLeftIndent, oldLeftSubIndent);
259
260 return attr;
261 }
262
263 /// Is this a numbered list?
IsNumbered(int i) const264 bool wxRichTextListStyleDefinition::IsNumbered(int i) const
265 {
266 return (0 != (GetLevelAttributes(i)->GetFlags() &
267 (wxTEXT_ATTR_BULLET_STYLE_ARABIC|wxTEXT_ATTR_BULLET_STYLE_LETTERS_UPPER|wxTEXT_ATTR_BULLET_STYLE_LETTERS_LOWER|
268 wxTEXT_ATTR_BULLET_STYLE_ROMAN_UPPER|wxTEXT_ATTR_BULLET_STYLE_ROMAN_LOWER)));
269 }
270
271 /*!
272 * The style manager
273 */
274
IMPLEMENT_CLASS(wxRichTextStyleSheet,wxObject)275 IMPLEMENT_CLASS(wxRichTextStyleSheet, wxObject)
276
277 wxRichTextStyleSheet::~wxRichTextStyleSheet()
278 {
279 DeleteStyles();
280
281 if (m_nextSheet)
282 m_nextSheet->m_previousSheet = m_previousSheet;
283
284 if (m_previousSheet)
285 m_previousSheet->m_nextSheet = m_nextSheet;
286
287 m_previousSheet = NULL;
288 m_nextSheet = NULL;
289 }
290
291 /// Initialisation
Init()292 void wxRichTextStyleSheet::Init()
293 {
294 m_previousSheet = NULL;
295 m_nextSheet = NULL;
296 }
297
298 /// Add a definition to one of the style lists
AddStyle(wxList & list,wxRichTextStyleDefinition * def)299 bool wxRichTextStyleSheet::AddStyle(wxList& list, wxRichTextStyleDefinition* def)
300 {
301 if (!list.Find(def))
302 list.Append(def);
303 return true;
304 }
305
306 /// Remove a style
RemoveStyle(wxList & list,wxRichTextStyleDefinition * def,bool deleteStyle)307 bool wxRichTextStyleSheet::RemoveStyle(wxList& list, wxRichTextStyleDefinition* def, bool deleteStyle)
308 {
309 wxList::compatibility_iterator node = list.Find(def);
310 if (node)
311 {
312 wxRichTextStyleDefinition* def = (wxRichTextStyleDefinition*) node->GetData();
313 list.Erase(node);
314 if (deleteStyle)
315 delete def;
316 return true;
317 }
318 else
319 return false;
320 }
321
322 /// Remove a style
RemoveStyle(wxRichTextStyleDefinition * def,bool deleteStyle)323 bool wxRichTextStyleSheet::RemoveStyle(wxRichTextStyleDefinition* def, bool deleteStyle)
324 {
325 if (RemoveParagraphStyle(def, deleteStyle))
326 return true;
327 if (RemoveCharacterStyle(def, deleteStyle))
328 return true;
329 if (RemoveListStyle(def, deleteStyle))
330 return true;
331 return false;
332 }
333
334 /// Find a definition by name
FindStyle(const wxList & list,const wxString & name,bool recurse) const335 wxRichTextStyleDefinition* wxRichTextStyleSheet::FindStyle(const wxList& list, const wxString& name, bool recurse) const
336 {
337 for (wxList::compatibility_iterator node = list.GetFirst(); node; node = node->GetNext())
338 {
339 wxRichTextStyleDefinition* def = (wxRichTextStyleDefinition*) node->GetData();
340 if (def->GetName().Lower() == name.Lower())
341 return def;
342 }
343
344 if (m_nextSheet && recurse)
345 return m_nextSheet->FindStyle(list, name, recurse);
346
347 return NULL;
348 }
349
350 /// Delete all styles
DeleteStyles()351 void wxRichTextStyleSheet::DeleteStyles()
352 {
353 WX_CLEAR_LIST(wxList, m_characterStyleDefinitions);
354 WX_CLEAR_LIST(wxList, m_paragraphStyleDefinitions);
355 WX_CLEAR_LIST(wxList, m_listStyleDefinitions);
356 }
357
358 /// Insert into list of style sheets
InsertSheet(wxRichTextStyleSheet * before)359 bool wxRichTextStyleSheet::InsertSheet(wxRichTextStyleSheet* before)
360 {
361 m_previousSheet = before->m_previousSheet;
362 m_nextSheet = before;
363
364 before->m_previousSheet = this;
365 return true;
366 }
367
368 /// Append to list of style sheets
AppendSheet(wxRichTextStyleSheet * after)369 bool wxRichTextStyleSheet::AppendSheet(wxRichTextStyleSheet* after)
370 {
371 wxRichTextStyleSheet* last = after;
372 while (last && last->m_nextSheet)
373 {
374 last = last->m_nextSheet;
375 }
376
377 if (last)
378 {
379 m_previousSheet = last;
380 last->m_nextSheet = this;
381
382 return true;
383 }
384 else
385 return false;
386 }
387
388 /// Unlink from the list of style sheets
Unlink()389 void wxRichTextStyleSheet::Unlink()
390 {
391 if (m_previousSheet)
392 m_previousSheet->m_nextSheet = m_nextSheet;
393 if (m_nextSheet)
394 m_nextSheet->m_previousSheet = m_previousSheet;
395
396 m_previousSheet = NULL;
397 m_nextSheet = NULL;
398 }
399
400 /// Add a definition to the character style list
AddCharacterStyle(wxRichTextCharacterStyleDefinition * def)401 bool wxRichTextStyleSheet::AddCharacterStyle(wxRichTextCharacterStyleDefinition* def)
402 {
403 def->GetStyle().SetCharacterStyleName(def->GetName());
404 return AddStyle(m_characterStyleDefinitions, def);
405 }
406
407 /// Add a definition to the paragraph style list
AddParagraphStyle(wxRichTextParagraphStyleDefinition * def)408 bool wxRichTextStyleSheet::AddParagraphStyle(wxRichTextParagraphStyleDefinition* def)
409 {
410 def->GetStyle().SetParagraphStyleName(def->GetName());
411 return AddStyle(m_paragraphStyleDefinitions, def);
412 }
413
414 /// Add a definition to the list style list
AddListStyle(wxRichTextListStyleDefinition * def)415 bool wxRichTextStyleSheet::AddListStyle(wxRichTextListStyleDefinition* def)
416 {
417 def->GetStyle().SetListStyleName(def->GetName());
418 return AddStyle(m_listStyleDefinitions, def);
419 }
420
421 /// Add a definition to the appropriate style list
AddStyle(wxRichTextStyleDefinition * def)422 bool wxRichTextStyleSheet::AddStyle(wxRichTextStyleDefinition* def)
423 {
424 wxRichTextListStyleDefinition* listDef = wxDynamicCast(def, wxRichTextListStyleDefinition);
425 if (listDef)
426 return AddListStyle(listDef);
427
428 wxRichTextParagraphStyleDefinition* paraDef = wxDynamicCast(def, wxRichTextParagraphStyleDefinition);
429 if (paraDef)
430 return AddParagraphStyle(paraDef);
431
432 wxRichTextCharacterStyleDefinition* charDef = wxDynamicCast(def, wxRichTextCharacterStyleDefinition);
433 if (charDef)
434 return AddCharacterStyle(charDef);
435
436 return false;
437 }
438
439 /// Find any definition by name
FindStyle(const wxString & name,bool recurse) const440 wxRichTextStyleDefinition* wxRichTextStyleSheet::FindStyle(const wxString& name, bool recurse) const
441 {
442 wxRichTextListStyleDefinition* listDef = FindListStyle(name, recurse);
443 if (listDef)
444 return listDef;
445
446 wxRichTextParagraphStyleDefinition* paraDef = FindParagraphStyle(name, recurse);
447 if (paraDef)
448 return paraDef;
449
450 wxRichTextCharacterStyleDefinition* charDef = FindCharacterStyle(name, recurse);
451 if (charDef)
452 return charDef;
453
454 return NULL;
455 }
456
457 /// Copy
Copy(const wxRichTextStyleSheet & sheet)458 void wxRichTextStyleSheet::Copy(const wxRichTextStyleSheet& sheet)
459 {
460 DeleteStyles();
461
462 wxList::compatibility_iterator node;
463
464 for (node = sheet.m_characterStyleDefinitions.GetFirst(); node; node = node->GetNext())
465 {
466 wxRichTextCharacterStyleDefinition* def = (wxRichTextCharacterStyleDefinition*) node->GetData();
467 AddCharacterStyle(new wxRichTextCharacterStyleDefinition(*def));
468 }
469
470 for (node = sheet.m_paragraphStyleDefinitions.GetFirst(); node; node = node->GetNext())
471 {
472 wxRichTextParagraphStyleDefinition* def = (wxRichTextParagraphStyleDefinition*) node->GetData();
473 AddParagraphStyle(new wxRichTextParagraphStyleDefinition(*def));
474 }
475
476 for (node = sheet.m_listStyleDefinitions.GetFirst(); node; node = node->GetNext())
477 {
478 wxRichTextListStyleDefinition* def = (wxRichTextListStyleDefinition*) node->GetData();
479 AddListStyle(new wxRichTextListStyleDefinition(*def));
480 }
481
482 SetName(sheet.GetName());
483 SetDescription(sheet.GetDescription());
484 }
485
486 /// Equality
operator ==(const wxRichTextStyleSheet & WXUNUSED (sheet)) const487 bool wxRichTextStyleSheet::operator==(const wxRichTextStyleSheet& WXUNUSED(sheet)) const
488 {
489 // TODO
490 return false;
491 }
492
493
494 #if wxUSE_HTML
495
496 // Functions for dealing with clashing names for different kinds of style.
497 // Returns "P", "C", or "L" (paragraph, character, list) for
498 // style name | type.
wxGetRichTextStyleType(const wxString & style)499 static wxString wxGetRichTextStyleType(const wxString& style)
500 {
501 return style.AfterLast(wxT('|'));
502 }
503
wxGetRichTextStyle(const wxString & style)504 static wxString wxGetRichTextStyle(const wxString& style)
505 {
506 return style.BeforeLast(wxT('|'));
507 }
508
509 /*!
510 * wxRichTextStyleListBox: a listbox to display styles.
511 */
512
IMPLEMENT_CLASS(wxRichTextStyleListBox,wxHtmlListBox)513 IMPLEMENT_CLASS(wxRichTextStyleListBox, wxHtmlListBox)
514
515 BEGIN_EVENT_TABLE(wxRichTextStyleListBox, wxHtmlListBox)
516 EVT_LEFT_DOWN(wxRichTextStyleListBox::OnLeftDown)
517 EVT_LEFT_DCLICK(wxRichTextStyleListBox::OnLeftDoubleClick)
518 EVT_IDLE(wxRichTextStyleListBox::OnIdle)
519 END_EVENT_TABLE()
520
521 wxRichTextStyleListBox::wxRichTextStyleListBox(wxWindow* parent, wxWindowID id, const wxPoint& pos,
522 const wxSize& size, long style)
523 {
524 Init();
525 Create(parent, id, pos, size, style);
526 }
527
Create(wxWindow * parent,wxWindowID id,const wxPoint & pos,const wxSize & size,long style)528 bool wxRichTextStyleListBox::Create(wxWindow* parent, wxWindowID id, const wxPoint& pos,
529 const wxSize& size, long style)
530 {
531 return wxHtmlListBox::Create(parent, id, pos, size, style);
532 }
533
~wxRichTextStyleListBox()534 wxRichTextStyleListBox::~wxRichTextStyleListBox()
535 {
536 }
537
538 /// Returns the HTML for this item
OnGetItem(size_t n) const539 wxString wxRichTextStyleListBox::OnGetItem(size_t n) const
540 {
541 if (!GetStyleSheet())
542 return wxEmptyString;
543
544 wxRichTextStyleDefinition* def = GetStyle(n);
545 if (def)
546 return CreateHTML(def);
547
548 return wxEmptyString;
549 }
550
551 // Get style for index
GetStyle(size_t i) const552 wxRichTextStyleDefinition* wxRichTextStyleListBox::GetStyle(size_t i) const
553 {
554 if (!GetStyleSheet())
555 return NULL;
556
557 if (i >= m_styleNames.GetCount() /* || i < 0 */ )
558 return NULL;
559
560 wxString styleType = wxGetRichTextStyleType(m_styleNames[i]);
561 wxString style = wxGetRichTextStyle(m_styleNames[i]);
562 if (styleType == wxT("P"))
563 return GetStyleSheet()->FindParagraphStyle(style);
564 else if (styleType == wxT("C"))
565 return GetStyleSheet()->FindCharacterStyle(style);
566 else if (styleType == wxT("L"))
567 return GetStyleSheet()->FindListStyle(style);
568 else
569 return GetStyleSheet()->FindStyle(style);
570 }
571
572 /// Updates the list
UpdateStyles()573 void wxRichTextStyleListBox::UpdateStyles()
574 {
575 if (GetStyleSheet())
576 {
577 int oldSel = GetSelection();
578
579 SetSelection(wxNOT_FOUND);
580
581 m_styleNames.Clear();
582
583 size_t i;
584 if (GetStyleType() == wxRICHTEXT_STYLE_ALL || GetStyleType() == wxRICHTEXT_STYLE_PARAGRAPH)
585 {
586 for (i = 0; i < GetStyleSheet()->GetParagraphStyleCount(); i++)
587 m_styleNames.Add(GetStyleSheet()->GetParagraphStyle(i)->GetName() + wxT("|P"));
588 }
589 if (GetStyleType() == wxRICHTEXT_STYLE_ALL || GetStyleType() == wxRICHTEXT_STYLE_CHARACTER)
590 {
591 for (i = 0; i < GetStyleSheet()->GetCharacterStyleCount(); i++)
592 m_styleNames.Add(GetStyleSheet()->GetCharacterStyle(i)->GetName() + wxT("|C"));
593 }
594 if (GetStyleType() == wxRICHTEXT_STYLE_ALL || GetStyleType() == wxRICHTEXT_STYLE_LIST)
595 {
596 for (i = 0; i < GetStyleSheet()->GetListStyleCount(); i++)
597 m_styleNames.Add(GetStyleSheet()->GetListStyle(i)->GetName() + wxT("|L"));
598 }
599
600 m_styleNames.Sort();
601 SetItemCount(m_styleNames.GetCount());
602
603 Refresh();
604
605 int newSel = -1;
606 if (oldSel >= 0 && oldSel < (int) GetItemCount())
607 newSel = oldSel;
608 else if (GetItemCount() > 0)
609 newSel = 0;
610
611 if (newSel >= 0)
612 {
613 SetSelection(newSel);
614 SendSelectedEvent();
615 }
616 }
617 }
618
619 // Get index for style name
GetIndexForStyle(const wxString & name) const620 int wxRichTextStyleListBox::GetIndexForStyle(const wxString& name) const
621 {
622 wxString s(name);
623 if (GetStyleType() == wxRICHTEXT_STYLE_PARAGRAPH)
624 s += wxT("|P");
625 else if (GetStyleType() == wxRICHTEXT_STYLE_CHARACTER)
626 s += wxT("|C");
627 else if (GetStyleType() == wxRICHTEXT_STYLE_LIST)
628 s += wxT("|L");
629 else
630 {
631 if (m_styleNames.Index(s + wxT("|P")) != wxNOT_FOUND)
632 s += wxT("|P");
633 else if (m_styleNames.Index(s + wxT("|C")) != wxNOT_FOUND)
634 s += wxT("|C");
635 else if (m_styleNames.Index(s + wxT("|L")) != wxNOT_FOUND)
636 s += wxT("|L");
637 }
638 return m_styleNames.Index(s);
639 }
640
641 /// Set selection for string
SetStyleSelection(const wxString & name)642 int wxRichTextStyleListBox::SetStyleSelection(const wxString& name)
643 {
644 int i = GetIndexForStyle(name);
645 if (i > -1)
646 SetSelection(i);
647 return i;
648 }
649
650 // Convert a colour to a 6-digit hex string
ColourToHexString(const wxColour & col)651 static wxString ColourToHexString(const wxColour& col)
652 {
653 wxString hex;
654
655 hex += wxDecToHex(col.Red());
656 hex += wxDecToHex(col.Green());
657 hex += wxDecToHex(col.Blue());
658
659 return hex;
660 }
661
662 /// Creates a suitable HTML fragment for a definition
CreateHTML(wxRichTextStyleDefinition * def) const663 wxString wxRichTextStyleListBox::CreateHTML(wxRichTextStyleDefinition* def) const
664 {
665 // TODO: indicate list format for list style types
666
667 wxString str;
668
669 bool isCentred = false;
670
671 wxRichTextAttr attr(def->GetStyleMergedWithBase(GetStyleSheet()));
672
673 if (attr.HasAlignment() && attr.GetAlignment() == wxTEXT_ALIGNMENT_CENTRE)
674 isCentred = true;
675
676 if (isCentred)
677 str << wxT("<center>");
678
679
680 str << wxT("<table><tr>");
681
682 if (attr.GetLeftIndent() > 0)
683 {
684 wxClientDC dc((wxWindow*) this);
685
686 str << wxT("<td width=") << wxMin(50, (ConvertTenthsMMToPixels(dc, attr.GetLeftIndent())/2)) << wxT("></td>");
687 }
688
689 if (isCentred)
690 str << wxT("<td nowrap align=\"center\">");
691 else
692 str << wxT("<td nowrap>");
693
694 #ifdef __WXMSW__
695 int size = 2;
696 #else
697 int size = 3;
698 #endif
699
700 // Guess a standard font size
701 int stdFontSize = 0;
702
703 // First see if we have a default/normal style to base the size on
704 wxString normalTranslated(_("normal"));
705 wxString defaultTranslated(_("default"));
706 size_t i;
707 for (i = 0; i < GetStyleSheet()->GetParagraphStyleCount(); i++)
708 {
709 wxRichTextStyleDefinition* d = GetStyleSheet()->GetParagraphStyle(i);
710 wxString name = d->GetName().Lower();
711 if (name.Find(wxT("normal")) != wxNOT_FOUND || name.Find(normalTranslated) != wxNOT_FOUND ||
712 name.Find(wxT("default")) != wxNOT_FOUND || name.Find(defaultTranslated) != wxNOT_FOUND)
713 {
714 wxRichTextAttr attr2(d->GetStyleMergedWithBase(GetStyleSheet()));
715 if (attr2.HasFontSize())
716 {
717 stdFontSize = attr2.GetFontSize();
718 break;
719 }
720 }
721 }
722
723 if (stdFontSize == 0)
724 {
725 // Look at sizes up to 20 points, and see which is the most common
726 wxArrayInt sizes;
727 size_t maxSize = 20;
728 for (i = 0; i <= maxSize; i++)
729 sizes.Add(0);
730 for (i = 0; i < m_styleNames.GetCount(); i++)
731 {
732 wxRichTextStyleDefinition* d = GetStyle(i);
733 if (d)
734 {
735 wxRichTextAttr attr2(d->GetStyleMergedWithBase(GetStyleSheet()));
736 if (attr2.HasFontSize())
737 {
738 if (attr2.GetFontSize() <= (int) maxSize)
739 sizes[attr2.GetFontSize()] ++;
740 }
741 }
742 }
743 int mostCommonSize = 0;
744 for (i = 0; i <= maxSize; i++)
745 {
746 if (sizes[i] > mostCommonSize)
747 mostCommonSize = i;
748 }
749 if (mostCommonSize > 0)
750 stdFontSize = mostCommonSize;
751 }
752
753 if (stdFontSize == 0)
754 stdFontSize = 12;
755
756 int thisFontSize = ((attr.GetFlags() & wxTEXT_ATTR_FONT_SIZE) != 0) ? attr.GetFontSize() : stdFontSize;
757
758 if (thisFontSize < stdFontSize)
759 size --;
760 else if (thisFontSize > stdFontSize)
761 size ++;
762
763 str += wxT("<font");
764
765 str << wxT(" size=") << size;
766
767 if (!attr.GetFontFaceName().IsEmpty())
768 str << wxT(" face=\"") << attr.GetFontFaceName() << wxT("\"");
769
770 if (attr.GetTextColour().Ok())
771 str << wxT(" color=\"#") << ColourToHexString(attr.GetTextColour()) << wxT("\"");
772
773 str << wxT(">");
774
775 bool hasBold = false;
776 bool hasItalic = false;
777 bool hasUnderline = false;
778
779 if (attr.GetFontWeight() == wxBOLD)
780 hasBold = true;
781 if (attr.GetFontStyle() == wxITALIC)
782 hasItalic = true;
783 if (attr.GetFontUnderlined())
784 hasUnderline = true;
785
786 if (hasBold)
787 str << wxT("<b>");
788 if (hasItalic)
789 str << wxT("<i>");
790 if (hasUnderline)
791 str << wxT("<u>");
792
793 str += def->GetName();
794
795 if (hasUnderline)
796 str << wxT("</u>");
797 if (hasItalic)
798 str << wxT("</i>");
799 if (hasBold)
800 str << wxT("</b>");
801
802 if (isCentred)
803 str << wxT("</centre>");
804
805 str << wxT("</font>");
806
807 str << wxT("</td></tr></table>");
808
809 if (isCentred)
810 str << wxT("</center>");
811
812 return str;
813 }
814
815 // Convert units in tends of a millimetre to device units
ConvertTenthsMMToPixels(wxDC & dc,int units) const816 int wxRichTextStyleListBox::ConvertTenthsMMToPixels(wxDC& dc, int units) const
817 {
818 int ppi = dc.GetPPI().x;
819
820 // There are ppi pixels in 254.1 "1/10 mm"
821
822 double pixels = ((double) units * (double)ppi) / 254.1;
823
824 return (int) pixels;
825 }
826
OnLeftDown(wxMouseEvent & event)827 void wxRichTextStyleListBox::OnLeftDown(wxMouseEvent& event)
828 {
829 wxVListBox::OnLeftDown(event);
830
831 int item = HitTest(event.GetPosition());
832 if (item != wxNOT_FOUND && GetApplyOnSelection())
833 ApplyStyle(item);
834 }
835
OnLeftDoubleClick(wxMouseEvent & event)836 void wxRichTextStyleListBox::OnLeftDoubleClick(wxMouseEvent& event)
837 {
838 wxVListBox::OnLeftDown(event);
839
840 int item = HitTest(event.GetPosition());
841 if (item != wxNOT_FOUND && !GetApplyOnSelection())
842 ApplyStyle(item);
843 }
844
845 /// Helper for listbox and combo control
GetStyleToShowInIdleTime(wxRichTextCtrl * ctrl,wxRichTextStyleType styleType)846 wxString wxRichTextStyleListBox::GetStyleToShowInIdleTime(wxRichTextCtrl* ctrl, wxRichTextStyleType styleType)
847 {
848 int adjustedCaretPos = ctrl->GetAdjustedCaretPosition(ctrl->GetCaretPosition());
849
850 wxString styleName;
851
852 wxTextAttrEx attr;
853 ctrl->GetStyle(adjustedCaretPos, attr);
854
855 // Take into account current default style just chosen by user
856 if (ctrl->IsDefaultStyleShowing())
857 {
858 wxRichTextApplyStyle(attr, ctrl->GetDefaultStyleEx());
859
860 if ((styleType == wxRICHTEXT_STYLE_ALL || styleType == wxRICHTEXT_STYLE_CHARACTER) &&
861 !attr.GetCharacterStyleName().IsEmpty())
862 styleName = attr.GetCharacterStyleName();
863 else if ((styleType == wxRICHTEXT_STYLE_ALL || styleType == wxRICHTEXT_STYLE_PARAGRAPH) &&
864 !attr.GetParagraphStyleName().IsEmpty())
865 styleName = attr.GetParagraphStyleName();
866 else if ((styleType == wxRICHTEXT_STYLE_ALL || styleType == wxRICHTEXT_STYLE_LIST) &&
867 !attr.GetListStyleName().IsEmpty())
868 styleName = attr.GetListStyleName();
869 }
870 else if ((styleType == wxRICHTEXT_STYLE_ALL || styleType == wxRICHTEXT_STYLE_CHARACTER) &&
871 !attr.GetCharacterStyleName().IsEmpty())
872 {
873 styleName = attr.GetCharacterStyleName();
874 }
875 else if ((styleType == wxRICHTEXT_STYLE_ALL || styleType == wxRICHTEXT_STYLE_PARAGRAPH) &&
876 !attr.GetParagraphStyleName().IsEmpty())
877 {
878 styleName = attr.GetParagraphStyleName();
879 }
880 else if ((styleType == wxRICHTEXT_STYLE_ALL || styleType == wxRICHTEXT_STYLE_LIST) &&
881 !attr.GetListStyleName().IsEmpty())
882 {
883 styleName = attr.GetListStyleName();
884 }
885
886 return styleName;
887 }
888
889 /// Auto-select from style under caret in idle time
OnIdle(wxIdleEvent & event)890 void wxRichTextStyleListBox::OnIdle(wxIdleEvent& event)
891 {
892 if (CanAutoSetSelection() && GetRichTextCtrl() && IsShownOnScreen() && wxWindow::FindFocus() != this)
893 {
894 wxString styleName = GetStyleToShowInIdleTime(GetRichTextCtrl(), GetStyleType());
895
896 int sel = GetSelection();
897 if (!styleName.IsEmpty())
898 {
899 // Don't do the selection if it's already set
900 if (sel == GetIndexForStyle(styleName))
901 return;
902
903 SetStyleSelection(styleName);
904 }
905 else if (sel != -1)
906 SetSelection(-1);
907 }
908 event.Skip();
909 }
910
911 /// Do selection
ApplyStyle(int item)912 void wxRichTextStyleListBox::ApplyStyle(int item)
913 {
914 if ( item != wxNOT_FOUND )
915 {
916 wxRichTextStyleDefinition* def = GetStyle(item);
917 if (def && GetRichTextCtrl())
918 {
919 GetRichTextCtrl()->ApplyStyle(def);
920 GetRichTextCtrl()->SetFocus();
921 }
922 }
923 }
924
925 /*!
926 * wxRichTextStyleListCtrl class: manages a listbox and a choice control to
927 * switch shown style types
928 */
929
IMPLEMENT_CLASS(wxRichTextStyleListCtrl,wxControl)930 IMPLEMENT_CLASS(wxRichTextStyleListCtrl, wxControl)
931
932 BEGIN_EVENT_TABLE(wxRichTextStyleListCtrl, wxControl)
933 EVT_CHOICE(wxID_ANY, wxRichTextStyleListCtrl::OnChooseType)
934 EVT_SIZE(wxRichTextStyleListCtrl::OnSize)
935 END_EVENT_TABLE()
936
937 wxRichTextStyleListCtrl::wxRichTextStyleListCtrl(wxWindow* parent, wxWindowID id, const wxPoint& pos,
938 const wxSize& size, long style)
939 {
940 Init();
941 Create(parent, id, pos, size, style);
942 }
943
Create(wxWindow * parent,wxWindowID id,const wxPoint & pos,const wxSize & size,long style)944 bool wxRichTextStyleListCtrl::Create(wxWindow* parent, wxWindowID id, const wxPoint& pos,
945 const wxSize& size, long style)
946 {
947 if ((style & wxBORDER_MASK) == wxBORDER_DEFAULT)
948 #ifdef __WXMSW__
949 style |= GetThemedBorderStyle();
950 #else
951 style |= wxBORDER_SUNKEN;
952 #endif
953
954 wxControl::Create(parent, id, pos, size, style);
955
956 SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
957 if (size != wxDefaultSize)
958 SetInitialSize(size);
959
960 bool showSelector = ((style & wxRICHTEXTSTYLELIST_HIDE_TYPE_SELECTOR) == 0);
961
962 wxBorder listBoxStyle;
963 if (showSelector)
964 {
965 #ifdef __WXMSW__
966 listBoxStyle = GetThemedBorderStyle();
967 #else
968 listBoxStyle = wxBORDER_SUNKEN;
969 #endif
970 }
971 else
972 listBoxStyle = wxBORDER_NONE;
973
974 m_styleListBox = new wxRichTextStyleListBox(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, listBoxStyle);
975
976 wxBoxSizer* boxSizer = new wxBoxSizer(wxVERTICAL);
977
978 if (showSelector)
979 {
980 wxArrayString choices;
981 choices.Add(_("All styles"));
982 choices.Add(_("Paragraph styles"));
983 choices.Add(_("Character styles"));
984 choices.Add(_("List styles"));
985
986 m_styleChoice = new wxChoice(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, choices);
987
988 boxSizer->Add(m_styleListBox, 1, wxALL|wxEXPAND, 5);
989 boxSizer->Add(m_styleChoice, 0, wxALL|wxEXPAND, 5);
990 }
991 else
992 {
993 boxSizer->Add(m_styleListBox, 1, wxALL|wxEXPAND, 0);
994 }
995
996 SetSizer(boxSizer);
997 Layout();
998
999 m_dontUpdate = true;
1000
1001 if (m_styleChoice)
1002 {
1003 int i = StyleTypeToIndex(m_styleListBox->GetStyleType());
1004 m_styleChoice->SetSelection(i);
1005 }
1006
1007 m_dontUpdate = false;
1008
1009 return true;
1010 }
1011
~wxRichTextStyleListCtrl()1012 wxRichTextStyleListCtrl::~wxRichTextStyleListCtrl()
1013 {
1014
1015 }
1016
1017 /// React to style type choice
OnChooseType(wxCommandEvent & event)1018 void wxRichTextStyleListCtrl::OnChooseType(wxCommandEvent& event)
1019 {
1020 if (event.GetEventObject() != m_styleChoice)
1021 event.Skip();
1022 else
1023 {
1024 if (m_dontUpdate)
1025 return;
1026
1027 wxRichTextStyleListBox::wxRichTextStyleType styleType = StyleIndexToType(event.GetSelection());
1028 m_styleListBox->SetSelection(-1);
1029 m_styleListBox->SetStyleType(styleType);
1030 }
1031 }
1032
1033 /// Lay out the controls
OnSize(wxSizeEvent & WXUNUSED (event))1034 void wxRichTextStyleListCtrl::OnSize(wxSizeEvent& WXUNUSED(event))
1035 {
1036 if (GetAutoLayout())
1037 Layout();
1038 }
1039
1040 /// Get the choice index for style type
StyleTypeToIndex(wxRichTextStyleListBox::wxRichTextStyleType styleType)1041 int wxRichTextStyleListCtrl::StyleTypeToIndex(wxRichTextStyleListBox::wxRichTextStyleType styleType)
1042 {
1043 if (styleType == wxRichTextStyleListBox::wxRICHTEXT_STYLE_ALL)
1044 {
1045 return 0;
1046 }
1047 else if (styleType == wxRichTextStyleListBox::wxRICHTEXT_STYLE_PARAGRAPH)
1048 {
1049 return 1;
1050 }
1051 else if (styleType == wxRichTextStyleListBox::wxRICHTEXT_STYLE_CHARACTER)
1052 {
1053 return 2;
1054 }
1055 else if (styleType == wxRichTextStyleListBox::wxRICHTEXT_STYLE_LIST)
1056 {
1057 return 3;
1058 }
1059 return 0;
1060 }
1061
1062 /// Get the style type for choice index
StyleIndexToType(int i)1063 wxRichTextStyleListBox::wxRichTextStyleType wxRichTextStyleListCtrl::StyleIndexToType(int i)
1064 {
1065 if (i == 1)
1066 return wxRichTextStyleListBox::wxRICHTEXT_STYLE_PARAGRAPH;
1067 else if (i == 2)
1068 return wxRichTextStyleListBox::wxRICHTEXT_STYLE_CHARACTER;
1069 else if (i == 3)
1070 return wxRichTextStyleListBox::wxRICHTEXT_STYLE_LIST;
1071
1072 return wxRichTextStyleListBox::wxRICHTEXT_STYLE_ALL;
1073 }
1074
1075 /// Associates the control with a style manager
SetStyleSheet(wxRichTextStyleSheet * styleSheet)1076 void wxRichTextStyleListCtrl::SetStyleSheet(wxRichTextStyleSheet* styleSheet)
1077 {
1078 if (m_styleListBox)
1079 m_styleListBox->SetStyleSheet(styleSheet);
1080 }
1081
GetStyleSheet() const1082 wxRichTextStyleSheet* wxRichTextStyleListCtrl::GetStyleSheet() const
1083 {
1084 if (m_styleListBox)
1085 return m_styleListBox->GetStyleSheet();
1086 else
1087 return NULL;
1088 }
1089
1090 /// Associates the control with a wxRichTextCtrl
SetRichTextCtrl(wxRichTextCtrl * ctrl)1091 void wxRichTextStyleListCtrl::SetRichTextCtrl(wxRichTextCtrl* ctrl)
1092 {
1093 if (m_styleListBox)
1094 m_styleListBox->SetRichTextCtrl(ctrl);
1095 }
1096
GetRichTextCtrl() const1097 wxRichTextCtrl* wxRichTextStyleListCtrl::GetRichTextCtrl() const
1098 {
1099 if (m_styleListBox)
1100 return m_styleListBox->GetRichTextCtrl();
1101 else
1102 return NULL;
1103 }
1104
1105 /// Set/get the style type to display
SetStyleType(wxRichTextStyleListBox::wxRichTextStyleType styleType)1106 void wxRichTextStyleListCtrl::SetStyleType(wxRichTextStyleListBox::wxRichTextStyleType styleType)
1107 {
1108 if (m_styleListBox)
1109 m_styleListBox->SetStyleType(styleType);
1110
1111 m_dontUpdate = true;
1112
1113 if (m_styleChoice)
1114 {
1115 int i = StyleTypeToIndex(m_styleListBox->GetStyleType());
1116 m_styleChoice->SetSelection(i);
1117 }
1118
1119 m_dontUpdate = false;
1120 }
1121
GetStyleType() const1122 wxRichTextStyleListBox::wxRichTextStyleType wxRichTextStyleListCtrl::GetStyleType() const
1123 {
1124 if (m_styleListBox)
1125 return m_styleListBox->GetStyleType();
1126 else
1127 return wxRichTextStyleListBox::wxRICHTEXT_STYLE_ALL;
1128 }
1129
1130 /// Updates the style list box
UpdateStyles()1131 void wxRichTextStyleListCtrl::UpdateStyles()
1132 {
1133 if (m_styleListBox)
1134 m_styleListBox->UpdateStyles();
1135 }
1136
1137 #if wxUSE_COMBOCTRL
1138
1139 /*!
1140 * Style drop-down for a wxComboCtrl
1141 */
1142
1143
BEGIN_EVENT_TABLE(wxRichTextStyleComboPopup,wxRichTextStyleListBox)1144 BEGIN_EVENT_TABLE(wxRichTextStyleComboPopup, wxRichTextStyleListBox)
1145 EVT_MOTION(wxRichTextStyleComboPopup::OnMouseMove)
1146 EVT_LEFT_DOWN(wxRichTextStyleComboPopup::OnMouseClick)
1147 END_EVENT_TABLE()
1148
1149 void wxRichTextStyleComboPopup::SetStringValue( const wxString& s )
1150 {
1151 m_value = SetStyleSelection(s);
1152 }
1153
GetStringValue() const1154 wxString wxRichTextStyleComboPopup::GetStringValue() const
1155 {
1156 int sel = m_value;
1157 if (sel > -1)
1158 {
1159 wxRichTextStyleDefinition* def = GetStyle(sel);
1160 if (def)
1161 return def->GetName();
1162 }
1163 return wxEmptyString;
1164 }
1165
1166 //
1167 // Popup event handlers
1168 //
1169
1170 // Mouse hot-tracking
OnMouseMove(wxMouseEvent & event)1171 void wxRichTextStyleComboPopup::OnMouseMove(wxMouseEvent& event)
1172 {
1173 // Move selection to cursor if it is inside the popup
1174
1175 int itemHere = wxRichTextStyleListBox::HitTest(event.GetPosition());
1176 if ( itemHere >= 0 )
1177 {
1178 wxRichTextStyleListBox::SetSelection(itemHere);
1179 m_itemHere = itemHere;
1180 }
1181 event.Skip();
1182 }
1183
1184 // On mouse left, set the value and close the popup
OnMouseClick(wxMouseEvent & WXUNUSED (event))1185 void wxRichTextStyleComboPopup::OnMouseClick(wxMouseEvent& WXUNUSED(event))
1186 {
1187 if (m_itemHere >= 0)
1188 m_value = m_itemHere;
1189
1190 // Ordering is important, so we don't dismiss this popup accidentally
1191 // by setting the focus elsewhere e.g. in ApplyStyle
1192 Dismiss();
1193
1194 if (m_itemHere >= 0)
1195 wxRichTextStyleListBox::ApplyStyle(m_itemHere);
1196 }
1197
1198 /*!
1199 * wxRichTextStyleComboCtrl
1200 * A combo for applying styles.
1201 */
1202
IMPLEMENT_CLASS(wxRichTextStyleComboCtrl,wxComboCtrl)1203 IMPLEMENT_CLASS(wxRichTextStyleComboCtrl, wxComboCtrl)
1204
1205 BEGIN_EVENT_TABLE(wxRichTextStyleComboCtrl, wxComboCtrl)
1206 EVT_IDLE(wxRichTextStyleComboCtrl::OnIdle)
1207 END_EVENT_TABLE()
1208
1209 bool wxRichTextStyleComboCtrl::Create(wxWindow* parent, wxWindowID id, const wxPoint& pos,
1210 const wxSize& size, long style)
1211 {
1212 if (!wxComboCtrl::Create(parent, id, wxEmptyString, pos, size, style))
1213 return false;
1214
1215 SetPopupMaxHeight(400);
1216
1217 m_stylePopup = new wxRichTextStyleComboPopup;
1218
1219 SetPopupControl(m_stylePopup);
1220
1221 return true;
1222 }
1223
1224 /// Auto-select from style under caret in idle time
1225
1226 // TODO: must be able to show italic, bold, combinations
1227 // in style box. Do we have a concept of automatic, temporary
1228 // styles that are added whenever we wish to show a style
1229 // that doesn't exist already? E.g. "Bold, Italic, Underline".
1230 // Word seems to generate these things on the fly.
1231 // If there's a named style already, it uses e.g. Heading1 + Bold, Italic
1232 // If you unembolden text in a style that has bold, it uses the
1233 // term "Not bold".
1234 // TODO: order styles alphabetically. This means indexes can change,
1235 // so need a different way to specify selections, i.e. by name.
1236
OnIdle(wxIdleEvent & event)1237 void wxRichTextStyleComboCtrl::OnIdle(wxIdleEvent& event)
1238 {
1239 if (GetRichTextCtrl() && !IsPopupShown() && m_stylePopup && IsShownOnScreen() && wxWindow::FindFocus() != this)
1240 {
1241 wxString styleName = wxRichTextStyleListBox::GetStyleToShowInIdleTime(GetRichTextCtrl(), m_stylePopup->GetStyleType());
1242
1243 wxString currentValue = GetValue();
1244 if (!styleName.IsEmpty())
1245 {
1246 // Don't do the selection if it's already set
1247 if (currentValue == styleName)
1248 return;
1249
1250 SetValue(styleName);
1251 }
1252 else if (!currentValue.IsEmpty())
1253 SetValue(wxEmptyString);
1254 }
1255 event.Skip();
1256 }
1257
1258 #endif
1259 // wxUSE_COMBOCTRL
1260
1261 #endif
1262 // wxUSE_HTML
1263
1264 #endif
1265 // wxUSE_RICHTEXT
1266