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