]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/richtext/richtextstyles.cpp
deal with the situation when a (dynamic) event handler disconnects itself during...
[wxWidgets.git] / src / richtext / richtextstyles.cpp
... / ...
CommitLineData
1/////////////////////////////////////////////////////////////////////////////
2// Name: richtextstyles.cpp
3// Purpose: Style management for wxRichTextCtrl
4// Author: Julian Smart
5// Modified by:
6// Created: 2005-09-30
7// RCS-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
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/module.h"
31
32#include "wx/richtext/richtextctrl.h"
33
34IMPLEMENT_CLASS(wxRichTextStyleDefinition, wxObject)
35IMPLEMENT_CLASS(wxRichTextCharacterStyleDefinition, wxRichTextStyleDefinition)
36IMPLEMENT_CLASS(wxRichTextParagraphStyleDefinition, wxRichTextStyleDefinition)
37
38/*!
39 * The style manager
40 */
41
42IMPLEMENT_CLASS(wxRichTextStyleSheet, wxObject)
43
44/// Initialisation
45void wxRichTextStyleSheet::Init()
46{
47}
48
49/// Add a definition to one of the style lists
50bool wxRichTextStyleSheet::AddStyle(wxList& list, wxRichTextStyleDefinition* def)
51{
52 if (!list.Find(def))
53 list.Append(def);
54 return true;
55}
56
57/// Remove a style
58bool wxRichTextStyleSheet::RemoveStyle(wxList& list, wxRichTextStyleDefinition* def, bool deleteStyle)
59{
60 wxList::compatibility_iterator node = list.Find(def);
61 if (node)
62 {
63 wxRichTextStyleDefinition* def = (wxRichTextStyleDefinition*) node->GetData();
64 list.Erase(node);
65 if (deleteStyle)
66 delete def;
67 return true;
68 }
69 else
70 return false;
71}
72
73/// Find a definition by name
74wxRichTextStyleDefinition* wxRichTextStyleSheet::FindStyle(const wxList& list, const wxString& name) const
75{
76 for (wxList::compatibility_iterator node = list.GetFirst(); node; node = node->GetNext())
77 {
78 wxRichTextStyleDefinition* def = (wxRichTextStyleDefinition*) node->GetData();
79 if (def->GetName().Lower() == name.Lower())
80 return def;
81 }
82 return NULL;
83}
84
85/// Delete all styles
86void wxRichTextStyleSheet::DeleteStyles()
87{
88 WX_CLEAR_LIST(wxList, m_characterStyleDefinitions);
89 WX_CLEAR_LIST(wxList, m_paragraphStyleDefinitions);
90}
91
92#if wxUSE_HTML
93/*!
94 * wxRichTextStyleListBox class declaration
95 * A listbox to display styles.
96 */
97
98IMPLEMENT_CLASS(wxRichTextStyleListBox, wxHtmlListBox)
99
100BEGIN_EVENT_TABLE(wxRichTextStyleListBox, wxHtmlListBox)
101 EVT_LISTBOX(wxID_ANY, wxRichTextStyleListBox::OnSelect)
102 EVT_LEFT_DOWN(wxRichTextStyleListBox::OnLeftDown)
103END_EVENT_TABLE()
104
105wxRichTextStyleListBox::wxRichTextStyleListBox(wxWindow* parent, wxWindowID id, const wxPoint& pos,
106 const wxSize& size, long style): wxHtmlListBox(parent, id, pos, size, style)
107{
108 m_styleSheet = NULL;
109 m_richTextCtrl = NULL;
110}
111
112wxRichTextStyleListBox::~wxRichTextStyleListBox()
113{
114}
115
116/// Returns the HTML for this item
117wxString wxRichTextStyleListBox::OnGetItem(size_t n) const
118{
119 if (!GetStyleSheet())
120 return wxEmptyString;
121
122 // First paragraph styles, then character
123 if (n < GetStyleSheet()->GetParagraphStyleCount())
124 {
125 wxRichTextParagraphStyleDefinition* def = GetStyleSheet()->GetParagraphStyle(n);
126
127 wxString str = CreateHTML(def);
128 return str;
129 }
130
131 if ((n - GetStyleSheet()->GetParagraphStyleCount()) < GetStyleSheet()->GetCharacterStyleCount())
132 {
133 wxRichTextCharacterStyleDefinition* def = GetStyleSheet()->GetCharacterStyle(n - GetStyleSheet()->GetParagraphStyleCount());
134
135 wxString str = CreateHTML(def);
136 return str;
137 }
138 return wxEmptyString;
139}
140
141// Get style for index
142wxRichTextStyleDefinition* wxRichTextStyleListBox::GetStyle(size_t i) const
143{
144 if (!GetStyleSheet())
145 return NULL;
146
147 // First paragraph styles, then character
148 if (i < GetStyleSheet()->GetParagraphStyleCount())
149 return GetStyleSheet()->GetParagraphStyle(i);
150
151 if ((i - GetStyleSheet()->GetParagraphStyleCount()) < GetStyleSheet()->GetCharacterStyleCount())
152 return GetStyleSheet()->GetCharacterStyle(i - GetStyleSheet()->GetParagraphStyleCount());
153
154 return NULL;
155}
156
157/// Updates the list
158void wxRichTextStyleListBox::UpdateStyles()
159{
160 if (GetStyleSheet())
161 {
162 SetItemCount(GetStyleSheet()->GetParagraphStyleCount()+GetStyleSheet()->GetCharacterStyleCount());
163 Refresh();
164 }
165}
166
167// Convert a colour to a 6-digit hex string
168static wxString ColourToHexString(const wxColour& col)
169{
170 wxString hex;
171
172 hex += wxDecToHex(col.Red());
173 hex += wxDecToHex(col.Green());
174 hex += wxDecToHex(col.Blue());
175
176 return hex;
177}
178
179/// Creates a suitable HTML fragment for a definition
180wxString wxRichTextStyleListBox::CreateHTML(wxRichTextStyleDefinition* def) const
181{
182 wxString str(wxT("<table><tr>"));
183
184 if (def->GetStyle().GetLeftIndent() > 0)
185 {
186 wxClientDC dc((wxWindow*) this);
187
188 str << wxT("<td width=") << ConvertTenthsMMToPixels(dc, def->GetStyle().GetLeftIndent()) << wxT("></td>");
189 }
190
191 str << wxT("<td nowrap>");
192
193 int size = 5;
194
195 // Standard size is 12, say
196 size += 12 - def->GetStyle().GetFontSize();
197
198 str += wxT("<font");
199
200 str << wxT(" size=") << size;
201
202 if (!def->GetStyle().GetFontFaceName().IsEmpty())
203 str << wxT(" face=\"") << def->GetStyle().GetFontFaceName() << wxT("\"");
204
205 if (def->GetStyle().GetTextColour().Ok())
206 str << wxT(" color=\"#") << ColourToHexString(def->GetStyle().GetTextColour()) << wxT("\"");
207
208 str << wxT(">");
209
210 bool hasBold = false;
211 bool hasItalic = false;
212 bool hasUnderline = false;
213
214 if (def->GetStyle().GetFontWeight() == wxBOLD)
215 hasBold = true;
216 if (def->GetStyle().GetFontStyle() == wxITALIC)
217 hasItalic = true;
218 if (def->GetStyle().GetFontUnderlined())
219 hasUnderline = true;
220
221 if (hasBold)
222 str << wxT("<b>");
223 if (hasItalic)
224 str << wxT("<i>");
225 if (hasUnderline)
226 str << wxT("<u>");
227
228 str += def->GetName();
229
230 if (hasUnderline)
231 str << wxT("</u>");
232 if (hasItalic)
233 str << wxT("</i>");
234 if (hasBold)
235 str << wxT("</b>");
236
237 str << wxT("</font>");
238
239 str += wxT("</td></tr></table>");
240 return str;
241}
242
243// Convert units in tends of a millimetre to device units
244int wxRichTextStyleListBox::ConvertTenthsMMToPixels(wxDC& dc, int units) const
245{
246 int ppi = dc.GetPPI().x;
247
248 // There are ppi pixels in 254.1 "1/10 mm"
249
250 double pixels = ((double) units * (double)ppi) / 254.1;
251
252 return (int) pixels;
253}
254
255/// React to selection
256void wxRichTextStyleListBox::OnSelect(wxCommandEvent& WXUNUSED(event))
257{
258#if 0
259 wxRichTextStyleDefinition* def = GetStyle(event.GetSelection());
260 if (def)
261 {
262 wxMessageBox(def->GetName());
263 }
264#endif
265}
266
267void wxRichTextStyleListBox::OnLeftDown(wxMouseEvent& event)
268{
269 wxVListBox::OnLeftDown(event);
270
271 int item = HitTest(event.GetPosition());
272
273 if ( item != wxNOT_FOUND )
274 {
275 wxRichTextStyleDefinition* def = GetStyle(item);
276 if (def && GetRichTextCtrl())
277 {
278 wxRichTextRange range(m_richTextCtrl->GetInsertionPoint(), m_richTextCtrl->GetInsertionPoint());
279
280 // Flags are defined within each definition, so only certain
281 // attributes are applied.
282 wxRichTextAttr attr(def->GetStyle());
283
284 if (m_richTextCtrl->HasSelection())
285 m_richTextCtrl->SetStyle(m_richTextCtrl->GetSelectionRange(), attr);
286 else
287 m_richTextCtrl->SetDefaultStyle(attr);
288
289 m_richTextCtrl->SetFocus();
290 }
291 }
292}
293
294#if 0
295wxColour wxRichTextStyleListBox::GetSelectedTextColour(const wxColour& colFg) const
296{
297 return *wxBLACK;
298}
299
300wxColour wxRichTextStyleListBox::GetSelectedTextBgColour(const wxColour& colBg) const
301{
302 return *wxWHITE;
303}
304#endif
305
306#endif
307 // wxUSE_HTML
308
309#endif
310 // wxUSE_RICHTEXT
311