]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/richtext/richtextstyles.cpp
Replace node deletion with Erase
[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#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
35IMPLEMENT_CLASS(wxRichTextStyleDefinition, wxObject)
36IMPLEMENT_CLASS(wxRichTextCharacterStyleDefinition, wxRichTextStyleDefinition)
37IMPLEMENT_CLASS(wxRichTextParagraphStyleDefinition, wxRichTextStyleDefinition)
38
39/*!
40 * The style manager
41 */
42
43IMPLEMENT_CLASS(wxRichTextStyleSheet, wxObject)
44
45/// Initialisation
46void wxRichTextStyleSheet::Init()
47{
48}
49
50/// Add a definition to one of the style lists
51bool 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
59bool wxRichTextStyleSheet::RemoveStyle(wxList& list, wxRichTextStyleDefinition* def, bool deleteStyle)
60{
61 wxNode* node = list.Find(def);
62 if (node)
63 {
64 wxRichTextStyleDefinition* def = (wxRichTextStyleDefinition*) node->GetData();
65 delete node;
66 if (deleteStyle)
67 delete def;
68 return true;
69 }
70 else
71 return false;
72}
73
74/// Find a definition by name
75wxRichTextStyleDefinition* wxRichTextStyleSheet::FindStyle(const wxList& list, const wxString& name) const
76{
77 for (wxNode* 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
87void 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
99IMPLEMENT_CLASS(wxRichTextStyleListBox, wxHtmlListBox)
100
101BEGIN_EVENT_TABLE(wxRichTextStyleListBox, wxHtmlListBox)
102 EVT_LISTBOX(wxID_ANY, wxRichTextStyleListBox::OnSelect)
103 EVT_LEFT_DOWN(wxRichTextStyleListBox::OnLeftDown)
104END_EVENT_TABLE()
105
106wxRichTextStyleListBox::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
113wxRichTextStyleListBox::~wxRichTextStyleListBox()
114{
115}
116
117/// Returns the HTML for this item
118wxString 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
143wxRichTextStyleDefinition* 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
159void 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
169static 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
181wxString 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
245int 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
257void 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
268void 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
296wxColour wxRichTextStyleListBox::GetSelectedTextColour(const wxColour& colFg) const
297{
298 return *wxBLACK;
299}
300
301wxColour 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