X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/38f833b10c071603eb8d7739ab31b1c07c4576f1..d2e66707deb10dea6f92e3e4092f8a43ef942a5d:/src/richtext/richtextstyles.cpp diff --git a/src/richtext/richtextstyles.cpp b/src/richtext/richtextstyles.cpp index 86ac5b074d..c0cc55761f 100644 --- a/src/richtext/richtextstyles.cpp +++ b/src/richtext/richtextstyles.cpp @@ -35,6 +35,7 @@ IMPLEMENT_CLASS(wxRichTextStyleDefinition, wxObject) IMPLEMENT_CLASS(wxRichTextCharacterStyleDefinition, wxRichTextStyleDefinition) IMPLEMENT_CLASS(wxRichTextParagraphStyleDefinition, wxRichTextStyleDefinition) IMPLEMENT_CLASS(wxRichTextListStyleDefinition, wxRichTextParagraphStyleDefinition) +IMPLEMENT_CLASS(wxRichTextBoxStyleDefinition, wxRichTextStyleDefinition) /*! * A definition @@ -45,6 +46,7 @@ void wxRichTextStyleDefinition::Copy(const wxRichTextStyleDefinition& def) m_name = def.m_name; m_baseStyle = def.m_baseStyle; m_style = def.m_style; + m_description = def.m_description; } bool wxRichTextStyleDefinition::Eq(const wxRichTextStyleDefinition& def) const @@ -52,6 +54,56 @@ bool wxRichTextStyleDefinition::Eq(const wxRichTextStyleDefinition& def) const return (m_name == def.m_name && m_baseStyle == def.m_baseStyle && m_style == def.m_style); } +/// Gets the style combined with the base style +wxRichTextAttr wxRichTextStyleDefinition::GetStyleMergedWithBase(const wxRichTextStyleSheet* sheet) const +{ + if (m_baseStyle.IsEmpty()) + return m_style; + + bool isParaStyle = IsKindOf(CLASSINFO(wxRichTextParagraphStyleDefinition)); + bool isCharStyle = IsKindOf(CLASSINFO(wxRichTextCharacterStyleDefinition)); + bool isListStyle = IsKindOf(CLASSINFO(wxRichTextListStyleDefinition)); + bool isBoxStyle = IsKindOf(CLASSINFO(wxRichTextBoxStyleDefinition)); + + // Collect the styles, detecting loops + wxArrayString styleNames; + wxList styles; + const wxRichTextStyleDefinition* def = this; + while (def) + { + styles.Insert((wxObject*) def); + styleNames.Add(def->GetName()); + + wxString baseStyleName = def->GetBaseStyle(); + if (!baseStyleName.IsEmpty() && styleNames.Index(baseStyleName) == wxNOT_FOUND) + { + if (isParaStyle) + def = sheet->FindParagraphStyle(baseStyleName); + else if (isCharStyle) + def = sheet->FindCharacterStyle(baseStyleName); + else if (isListStyle) + def = sheet->FindListStyle(baseStyleName); + else if (isBoxStyle) + def = sheet->FindBoxStyle(baseStyleName); + else + def = sheet->FindStyle(baseStyleName); + } + else + def = NULL; + } + + wxRichTextAttr attr; + wxList::compatibility_iterator node = styles.GetFirst(); + while (node) + { + wxRichTextStyleDefinition* def = (wxRichTextStyleDefinition*) node->GetData(); + attr.Apply(def->GetStyle(), NULL); + node = node->GetNext(); + } + + return attr; +} + /*! * Paragraph style definition */ @@ -68,6 +120,20 @@ bool wxRichTextParagraphStyleDefinition::operator ==(const wxRichTextParagraphSt return (Eq(def) && m_nextStyle == def.m_nextStyle); } +/*! + * Box style definition + */ + +void wxRichTextBoxStyleDefinition::Copy(const wxRichTextBoxStyleDefinition& def) +{ + wxRichTextStyleDefinition::Copy(def); +} + +bool wxRichTextBoxStyleDefinition::operator ==(const wxRichTextBoxStyleDefinition& def) const +{ + return (Eq(def)); +} + /*! * List style definition */ @@ -75,7 +141,7 @@ bool wxRichTextParagraphStyleDefinition::operator ==(const wxRichTextParagraphSt void wxRichTextListStyleDefinition::Copy(const wxRichTextListStyleDefinition& def) { wxRichTextParagraphStyleDefinition::Copy(def); - + int i; for (i = 0; i < 10; i++) m_levelStyles[i] = def.m_levelStyles[i]; @@ -89,19 +155,19 @@ bool wxRichTextListStyleDefinition::operator ==(const wxRichTextListStyleDefinit for (i = 0; i < 10; i++) if (!(m_levelStyles[i] == def.m_levelStyles[i])) return false; - + return true; } /// Sets/gets the attributes for the given level -void wxRichTextListStyleDefinition::SetLevelAttributes(int i, const wxTextAttrEx& attr) +void wxRichTextListStyleDefinition::SetLevelAttributes(int i, const wxRichTextAttr& attr) { wxASSERT( (i >= 0 && i < 10) ); if (i >= 0 && i < 10) m_levelStyles[i] = attr; } -const wxTextAttrEx* wxRichTextListStyleDefinition::GetLevelAttributes(int i) const +const wxRichTextAttr* wxRichTextListStyleDefinition::GetLevelAttributes(int i) const { wxASSERT( (i >= 0 && i < 10) ); if (i >= 0 && i < 10) @@ -110,7 +176,7 @@ const wxTextAttrEx* wxRichTextListStyleDefinition::GetLevelAttributes(int i) con return NULL; } -wxTextAttrEx* wxRichTextListStyleDefinition::GetLevelAttributes(int i) +wxRichTextAttr* wxRichTextListStyleDefinition::GetLevelAttributes(int i) { wxASSERT( (i >= 0 && i < 10) ); if (i >= 0 && i < 10) @@ -125,16 +191,21 @@ void wxRichTextListStyleDefinition::SetAttributes(int i, int leftIndent, int lef wxASSERT( (i >= 0 && i < 10) ); if (i >= 0 && i < 10) { - wxTextAttrEx attr; - + wxRichTextAttr attr; + attr.SetBulletStyle(bulletStyle); attr.SetLeftIndent(leftIndent, leftSubIndent); if (!bulletSymbol.IsEmpty()) - attr.SetBulletSymbol(bulletSymbol[0]); - - m_levelStyles[i] = attr; - } + { + if (bulletStyle & wxTEXT_ATTR_BULLET_STYLE_SYMBOL) + attr.SetBulletText(bulletSymbol); + else + attr.SetBulletName(bulletSymbol); + } + + m_levelStyles[i] = attr; + } } /// Finds the level corresponding to the given indentation @@ -156,48 +227,54 @@ int wxRichTextListStyleDefinition::FindLevelForIndent(int indent) const /// Combine the list style with a paragraph style, using the given indent (from which /// an appropriate level is found) -wxTextAttrEx wxRichTextListStyleDefinition::CombineWithParagraphStyle(int indent, const wxTextAttrEx& paraStyle) +wxRichTextAttr wxRichTextListStyleDefinition::CombineWithParagraphStyle(int indent, const wxRichTextAttr& paraStyle, wxRichTextStyleSheet* styleSheet) { int listLevel = FindLevelForIndent(indent); - - wxTextAttrEx attr(*GetLevelAttributes(listLevel)); + + wxRichTextAttr attr(*GetLevelAttributes(listLevel)); int oldLeftIndent = attr.GetLeftIndent(); int oldLeftSubIndent = attr.GetLeftSubIndent(); - // First apply the overall paragraph style, if any - wxRichTextApplyStyle(attr, GetStyle()); + // First apply the overall paragraph style, if any + if (styleSheet) + attr.Apply(GetStyleMergedWithBase(styleSheet)); + else + attr.Apply(GetStyle()); // Then apply paragraph style, e.g. from paragraph style definition - wxRichTextApplyStyle(attr, paraStyle); - + attr.Apply(paraStyle); + // We override the indents according to the list definition attr.SetLeftIndent(oldLeftIndent, oldLeftSubIndent); - + return attr; } /// Combine the base and list style, using the given indent (from which /// an appropriate level is found) -wxTextAttrEx wxRichTextListStyleDefinition::GetCombinedStyle(int indent) +wxRichTextAttr wxRichTextListStyleDefinition::GetCombinedStyle(int indent, wxRichTextStyleSheet* styleSheet) { int listLevel = FindLevelForIndent(indent); - return GetCombinedStyleForLevel(listLevel); + return GetCombinedStyleForLevel(listLevel, styleSheet); } /// Combine the base and list style, using the given indent (from which /// an appropriate level is found) -wxTextAttrEx wxRichTextListStyleDefinition::GetCombinedStyleForLevel(int listLevel) +wxRichTextAttr wxRichTextListStyleDefinition::GetCombinedStyleForLevel(int listLevel, wxRichTextStyleSheet* styleSheet) { - wxTextAttrEx attr(*GetLevelAttributes(listLevel)); + wxRichTextAttr attr(*GetLevelAttributes(listLevel)); int oldLeftIndent = attr.GetLeftIndent(); int oldLeftSubIndent = attr.GetLeftSubIndent(); - // Apply the overall paragraph style, if any - wxRichTextApplyStyle(attr, GetStyle()); + // Apply the overall paragraph style, if any + if (styleSheet) + attr.Apply(GetStyleMergedWithBase(styleSheet)); + else + attr.Apply(GetStyle()); // We override the indents according to the list definition attr.SetLeftIndent(oldLeftIndent, oldLeftSubIndent); - + return attr; } @@ -221,10 +298,10 @@ wxRichTextStyleSheet::~wxRichTextStyleSheet() if (m_nextSheet) m_nextSheet->m_previousSheet = m_previousSheet; - + if (m_previousSheet) m_previousSheet->m_nextSheet = m_nextSheet; - + m_previousSheet = NULL; m_nextSheet = NULL; } @@ -260,6 +337,20 @@ bool wxRichTextStyleSheet::RemoveStyle(wxList& list, wxRichTextStyleDefinition* return false; } +/// Remove a style +bool wxRichTextStyleSheet::RemoveStyle(wxRichTextStyleDefinition* def, bool deleteStyle) +{ + if (RemoveParagraphStyle(def, deleteStyle)) + return true; + if (RemoveCharacterStyle(def, deleteStyle)) + return true; + if (RemoveListStyle(def, deleteStyle)) + return true; + if (RemoveBoxStyle(def, deleteStyle)) + return true; + return false; +} + /// Find a definition by name wxRichTextStyleDefinition* wxRichTextStyleSheet::FindStyle(const wxList& list, const wxString& name, bool recurse) const { @@ -269,7 +360,7 @@ wxRichTextStyleDefinition* wxRichTextStyleSheet::FindStyle(const wxList& list, c if (def->GetName().Lower() == name.Lower()) return def; } - + if (m_nextSheet && recurse) return m_nextSheet->FindStyle(list, name, recurse); @@ -282,6 +373,7 @@ void wxRichTextStyleSheet::DeleteStyles() WX_CLEAR_LIST(wxList, m_characterStyleDefinitions); WX_CLEAR_LIST(wxList, m_paragraphStyleDefinitions); WX_CLEAR_LIST(wxList, m_listStyleDefinitions); + WX_CLEAR_LIST(wxList, m_boxStyleDefinitions); } /// Insert into list of style sheets @@ -289,7 +381,7 @@ bool wxRichTextStyleSheet::InsertSheet(wxRichTextStyleSheet* before) { m_previousSheet = before->m_previousSheet; m_nextSheet = before; - + before->m_previousSheet = this; return true; } @@ -302,12 +394,12 @@ bool wxRichTextStyleSheet::AppendSheet(wxRichTextStyleSheet* after) { last = last->m_nextSheet; } - + if (last) { m_previousSheet = last; last->m_nextSheet = this; - + return true; } else @@ -321,7 +413,7 @@ void wxRichTextStyleSheet::Unlink() m_previousSheet->m_nextSheet = m_nextSheet; if (m_nextSheet) m_nextSheet->m_previousSheet = m_previousSheet; - + m_previousSheet = NULL; m_nextSheet = NULL; } @@ -347,6 +439,57 @@ bool wxRichTextStyleSheet::AddListStyle(wxRichTextListStyleDefinition* def) return AddStyle(m_listStyleDefinitions, def); } +/// Add a definition to the box style list +bool wxRichTextStyleSheet::AddBoxStyle(wxRichTextBoxStyleDefinition* def) +{ + def->GetStyle().SetParagraphStyleName(def->GetName()); + return AddStyle(m_boxStyleDefinitions, def); +} + +/// Add a definition to the appropriate style list +bool wxRichTextStyleSheet::AddStyle(wxRichTextStyleDefinition* def) +{ + wxRichTextListStyleDefinition* listDef = wxDynamicCast(def, wxRichTextListStyleDefinition); + if (listDef) + return AddListStyle(listDef); + + wxRichTextParagraphStyleDefinition* paraDef = wxDynamicCast(def, wxRichTextParagraphStyleDefinition); + if (paraDef) + return AddParagraphStyle(paraDef); + + wxRichTextCharacterStyleDefinition* charDef = wxDynamicCast(def, wxRichTextCharacterStyleDefinition); + if (charDef) + return AddCharacterStyle(charDef); + + wxRichTextBoxStyleDefinition* boxDef = wxDynamicCast(def, wxRichTextBoxStyleDefinition); + if (boxDef) + return AddBoxStyle(boxDef); + + return false; +} + +/// Find any definition by name +wxRichTextStyleDefinition* wxRichTextStyleSheet::FindStyle(const wxString& name, bool recurse) const +{ + wxRichTextListStyleDefinition* listDef = FindListStyle(name, recurse); + if (listDef) + return listDef; + + wxRichTextParagraphStyleDefinition* paraDef = FindParagraphStyle(name, recurse); + if (paraDef) + return paraDef; + + wxRichTextCharacterStyleDefinition* charDef = FindCharacterStyle(name, recurse); + if (charDef) + return charDef; + + wxRichTextBoxStyleDefinition* boxDef = FindBoxStyle(name, recurse); + if (boxDef) + return boxDef; + + return NULL; +} + /// Copy void wxRichTextStyleSheet::Copy(const wxRichTextStyleSheet& sheet) { @@ -371,6 +514,15 @@ void wxRichTextStyleSheet::Copy(const wxRichTextStyleSheet& sheet) wxRichTextListStyleDefinition* def = (wxRichTextListStyleDefinition*) node->GetData(); AddListStyle(new wxRichTextListStyleDefinition(*def)); } + + for (node = sheet.m_boxStyleDefinitions.GetFirst(); node; node = node->GetNext()) + { + wxRichTextBoxStyleDefinition* def = (wxRichTextBoxStyleDefinition*) node->GetData(); + AddBoxStyle(new wxRichTextBoxStyleDefinition(*def)); + } + + SetName(sheet.GetName()); + SetDescription(sheet.GetDescription()); } /// Equality @@ -382,6 +534,21 @@ bool wxRichTextStyleSheet::operator==(const wxRichTextStyleSheet& WXUNUSED(sheet #if wxUSE_HTML + +// Functions for dealing with clashing names for different kinds of style. +// Returns "P", "C", "L" or "B" (paragraph, character, list or box) for +// style name | type. +static wxString wxGetRichTextStyleType(const wxString& style) +{ + return style.AfterLast(wxT('|')); +} + +static wxString wxGetRichTextStyle(const wxString& style) +{ + return style.BeforeLast(wxT('|')); +} + + /*! * wxRichTextStyleListBox: a listbox to display styles. */ @@ -389,7 +556,6 @@ bool wxRichTextStyleSheet::operator==(const wxRichTextStyleSheet& WXUNUSED(sheet IMPLEMENT_CLASS(wxRichTextStyleListBox, wxHtmlListBox) BEGIN_EVENT_TABLE(wxRichTextStyleListBox, wxHtmlListBox) - EVT_LISTBOX(wxID_ANY, wxRichTextStyleListBox::OnSelect) EVT_LEFT_DOWN(wxRichTextStyleListBox::OnLeftDown) EVT_LEFT_DCLICK(wxRichTextStyleListBox::OnLeftDoubleClick) EVT_IDLE(wxRichTextStyleListBox::OnIdle) @@ -417,7 +583,7 @@ wxString wxRichTextStyleListBox::OnGetItem(size_t n) const { if (!GetStyleSheet()) return wxEmptyString; - + wxRichTextStyleDefinition* def = GetStyle(n); if (def) return CreateHTML(def); @@ -431,32 +597,21 @@ wxRichTextStyleDefinition* wxRichTextStyleListBox::GetStyle(size_t i) const if (!GetStyleSheet()) return NULL; - if (GetStyleType() == wxRICHTEXT_STYLE_ALL) - { - // First paragraph styles, then character, then list - if (i < GetStyleSheet()->GetParagraphStyleCount()) - return GetStyleSheet()->GetParagraphStyle(i); - - if ((i - GetStyleSheet()->GetParagraphStyleCount()) < GetStyleSheet()->GetCharacterStyleCount()) - return GetStyleSheet()->GetCharacterStyle(i - GetStyleSheet()->GetParagraphStyleCount()); - - if ((i - GetStyleSheet()->GetParagraphStyleCount() - GetStyleSheet()->GetCharacterStyleCount()) < GetStyleSheet()->GetListStyleCount()) - return GetStyleSheet()->GetListStyle(i - GetStyleSheet()->GetParagraphStyleCount() - GetStyleSheet()->GetCharacterStyleCount()); - } - else if ((GetStyleType() == wxRICHTEXT_STYLE_PARAGRAPH) && (i < GetStyleSheet()->GetParagraphStyleCount())) - { - return GetStyleSheet()->GetParagraphStyle(i); - } - else if ((GetStyleType() == wxRICHTEXT_STYLE_CHARACTER) && (i < GetStyleSheet()->GetCharacterStyleCount())) - { - return GetStyleSheet()->GetCharacterStyle(i); - } - else if ((GetStyleType() == wxRICHTEXT_STYLE_LIST) && (i < GetStyleSheet()->GetListStyleCount())) - { - return GetStyleSheet()->GetListStyle(i); - } + if (i >= m_styleNames.GetCount() /* || i < 0 */ ) + return NULL; - return NULL; + wxString styleType = wxGetRichTextStyleType(m_styleNames[i]); + wxString style = wxGetRichTextStyle(m_styleNames[i]); + if (styleType == wxT("P")) + return GetStyleSheet()->FindParagraphStyle(style); + else if (styleType == wxT("C")) + return GetStyleSheet()->FindCharacterStyle(style); + else if (styleType == wxT("L")) + return GetStyleSheet()->FindListStyle(style); + else if (styleType == wxT("B")) + return GetStyleSheet()->FindBoxStyle(style); + else + return GetStyleSheet()->FindStyle(style); } /// Updates the list @@ -464,34 +619,77 @@ void wxRichTextStyleListBox::UpdateStyles() { if (GetStyleSheet()) { - if (GetStyleType() == wxRICHTEXT_STYLE_ALL) - SetItemCount(GetStyleSheet()->GetParagraphStyleCount()+GetStyleSheet()->GetCharacterStyleCount()+GetStyleSheet()->GetListStyleCount()); - else if (GetStyleType() == wxRICHTEXT_STYLE_PARAGRAPH) - SetItemCount(GetStyleSheet()->GetParagraphStyleCount()); - else if (GetStyleType() == wxRICHTEXT_STYLE_CHARACTER) - SetItemCount(GetStyleSheet()->GetCharacterStyleCount()); - else if (GetStyleType() == wxRICHTEXT_STYLE_LIST) - SetItemCount(GetStyleSheet()->GetListStyleCount()); + int oldSel = GetSelection(); + + SetSelection(wxNOT_FOUND); + + m_styleNames.Clear(); + + size_t i; + if (GetStyleType() == wxRICHTEXT_STYLE_ALL || GetStyleType() == wxRICHTEXT_STYLE_PARAGRAPH) + { + for (i = 0; i < GetStyleSheet()->GetParagraphStyleCount(); i++) + m_styleNames.Add(GetStyleSheet()->GetParagraphStyle(i)->GetName() + wxT("|P")); + } + if (GetStyleType() == wxRICHTEXT_STYLE_ALL || GetStyleType() == wxRICHTEXT_STYLE_CHARACTER) + { + for (i = 0; i < GetStyleSheet()->GetCharacterStyleCount(); i++) + m_styleNames.Add(GetStyleSheet()->GetCharacterStyle(i)->GetName() + wxT("|C")); + } + if (GetStyleType() == wxRICHTEXT_STYLE_ALL || GetStyleType() == wxRICHTEXT_STYLE_LIST) + { + for (i = 0; i < GetStyleSheet()->GetListStyleCount(); i++) + m_styleNames.Add(GetStyleSheet()->GetListStyle(i)->GetName() + wxT("|L")); + } + if (GetStyleType() == wxRICHTEXT_STYLE_ALL || GetStyleType() == wxRICHTEXT_STYLE_BOX) + { + for (i = 0; i < GetStyleSheet()->GetBoxStyleCount(); i++) + m_styleNames.Add(GetStyleSheet()->GetBoxStyle(i)->GetName() + wxT("|B")); + } + + m_styleNames.Sort(); + SetItemCount(m_styleNames.GetCount()); + Refresh(); + + int newSel = -1; + if (oldSel >= 0 && oldSel < (int) GetItemCount()) + newSel = oldSel; + else if (GetItemCount() > 0) + newSel = 0; + + if (newSel >= 0) + { + SetSelection(newSel); + SendSelectedEvent(); + } } } // Get index for style name int wxRichTextStyleListBox::GetIndexForStyle(const wxString& name) const { - if (GetStyleSheet()) + wxString s(name); + if (GetStyleType() == wxRICHTEXT_STYLE_PARAGRAPH) + s += wxT("|P"); + else if (GetStyleType() == wxRICHTEXT_STYLE_CHARACTER) + s += wxT("|C"); + else if (GetStyleType() == wxRICHTEXT_STYLE_LIST) + s += wxT("|L"); + else if (GetStyleType() == wxRICHTEXT_STYLE_BOX) + s += wxT("|B"); + else { - int count = GetItemCount(); - - int i; - for (i = 0; i < (int) count; i++) - { - wxRichTextStyleDefinition* def = GetStyle(i); - if (def->GetName() == name) - return i; - } + if (m_styleNames.Index(s + wxT("|P")) != wxNOT_FOUND) + s += wxT("|P"); + else if (m_styleNames.Index(s + wxT("|C")) != wxNOT_FOUND) + s += wxT("|C"); + else if (m_styleNames.Index(s + wxT("|L")) != wxNOT_FOUND) + s += wxT("|L"); + else if (m_styleNames.Index(s + wxT("|B")) != wxNOT_FOUND) + s += wxT("|B"); } - return -1; + return m_styleNames.Index(s); } /// Set selection for string @@ -520,31 +718,111 @@ wxString wxRichTextStyleListBox::CreateHTML(wxRichTextStyleDefinition* def) cons { // TODO: indicate list format for list style types - wxString str(wxT("")); + wxString str; + + bool isCentred = false; + + wxRichTextAttr attr(def->GetStyleMergedWithBase(GetStyleSheet())); + + if (attr.HasAlignment() && attr.GetAlignment() == wxTEXT_ALIGNMENT_CENTRE) + isCentred = true; + + if (isCentred) + str << wxT("
"); + + + str << wxT("
"); - if (def->GetStyle().GetLeftIndent() > 0) + if (attr.GetLeftIndent() > 0) { wxClientDC dc((wxWindow*) this); - str << wxT(""); + str << wxT(""); } - str << wxT("
"); + if (isCentred) + str << wxT(""); + else + str << wxT(""); + +#ifdef __WXMSW__ + int size = 2; +#else + int size = 3; +#endif + + // Guess a standard font size + int stdFontSize = 0; + + // First see if we have a default/normal style to base the size on + wxString normalTranslated(_("normal")); + wxString defaultTranslated(_("default")); + size_t i; + for (i = 0; i < GetStyleSheet()->GetParagraphStyleCount(); i++) + { + wxRichTextStyleDefinition* d = GetStyleSheet()->GetParagraphStyle(i); + wxString name = d->GetName().Lower(); + if (name.Find(wxT("normal")) != wxNOT_FOUND || name.Find(normalTranslated) != wxNOT_FOUND || + name.Find(wxT("default")) != wxNOT_FOUND || name.Find(defaultTranslated) != wxNOT_FOUND) + { + wxRichTextAttr attr2(d->GetStyleMergedWithBase(GetStyleSheet())); + if (attr2.HasFontSize()) + { + stdFontSize = attr2.GetFontSize(); + break; + } + } + } + + if (stdFontSize == 0) + { + // Look at sizes up to 20 points, and see which is the most common + wxArrayInt sizes; + size_t maxSize = 20; + for (i = 0; i <= maxSize; i++) + sizes.Add(0); + for (i = 0; i < m_styleNames.GetCount(); i++) + { + wxRichTextStyleDefinition* d = GetStyle(i); + if (d) + { + wxRichTextAttr attr2(d->GetStyleMergedWithBase(GetStyleSheet())); + if (attr2.HasFontSize()) + { + if (attr2.GetFontSize() <= (int) maxSize) + sizes[attr2.GetFontSize()] ++; + } + } + } + int mostCommonSize = 0; + for (i = 0; i <= maxSize; i++) + { + if (sizes[i] > mostCommonSize) + mostCommonSize = i; + } + if (mostCommonSize > 0) + stdFontSize = mostCommonSize; + } + + if (stdFontSize == 0) + stdFontSize = 12; - int size = 4; + int thisFontSize = ((attr.GetFlags() & wxTEXT_ATTR_FONT_SIZE) != 0) ? attr.GetFontSize() : stdFontSize; - // Standard size is 12, say - size += (def->GetStyle().HasFont() ? def->GetStyle().GetFontSize() : 12) - 12; + if (thisFontSize < stdFontSize) + size --; + else if (thisFontSize > stdFontSize) + size ++; str += wxT("GetStyle().GetFontFaceName() << wxT("\""); + if (!attr.GetFontFaceName().IsEmpty()) + str << wxT(" face=\"") << attr.GetFontFaceName() << wxT("\""); - if (def->GetStyle().GetTextColour().Ok()) - str << wxT(" color=\"#") << ColourToHexString(def->GetStyle().GetTextColour()) << wxT("\""); + if (attr.GetTextColour().IsOk()) + str << wxT(" color=\"#") << ColourToHexString(attr.GetTextColour()) << wxT("\""); str << wxT(">"); @@ -552,11 +830,11 @@ wxString wxRichTextStyleListBox::CreateHTML(wxRichTextStyleDefinition* def) cons bool hasItalic = false; bool hasUnderline = false; - if (def->GetStyle().GetFontWeight() == wxBOLD) + if (attr.GetFontWeight() == wxBOLD) hasBold = true; - if (def->GetStyle().GetFontStyle() == wxITALIC) + if (attr.GetFontStyle() == wxITALIC) hasItalic = true; - if (def->GetStyle().GetFontUnderlined()) + if (attr.GetFontUnderlined()) hasUnderline = true; if (hasBold) @@ -575,9 +853,16 @@ wxString wxRichTextStyleListBox::CreateHTML(wxRichTextStyleDefinition* def) cons if (hasBold) str << wxT(""); + if (isCentred) + str << wxT(""); + str << wxT(""); - str += wxT("
"); + str << wxT(""); + + if (isCentred) + str << wxT(""); + return str; } @@ -593,23 +878,11 @@ int wxRichTextStyleListBox::ConvertTenthsMMToPixels(wxDC& dc, int units) const return (int) pixels; } -/// React to selection -void wxRichTextStyleListBox::OnSelect(wxCommandEvent& WXUNUSED(event)) -{ -#if 0 - wxRichTextStyleDefinition* def = GetStyle(event.GetSelection()); - if (def) - { - wxMessageBox(def->GetName()); - } -#endif -} - void wxRichTextStyleListBox::OnLeftDown(wxMouseEvent& event) { wxVListBox::OnLeftDown(event); - int item = HitTest(event.GetPosition()); + int item = VirtualHitTest(event.GetPosition().y); if (item != wxNOT_FOUND && GetApplyOnSelection()) ApplyStyle(item); } @@ -618,7 +891,7 @@ void wxRichTextStyleListBox::OnLeftDoubleClick(wxMouseEvent& event) { wxVListBox::OnLeftDown(event); - int item = HitTest(event.GetPosition()); + int item = VirtualHitTest(event.GetPosition().y); if (item != wxNOT_FOUND && !GetApplyOnSelection()) ApplyStyle(item); } @@ -628,47 +901,56 @@ wxString wxRichTextStyleListBox::GetStyleToShowInIdleTime(wxRichTextCtrl* ctrl, { int adjustedCaretPos = ctrl->GetAdjustedCaretPosition(ctrl->GetCaretPosition()); - wxRichTextParagraph* para = ctrl->GetBuffer().GetParagraphAtPosition(adjustedCaretPos); - wxRichTextObject* obj = ctrl->GetBuffer().GetLeafObjectAtPosition(adjustedCaretPos); - wxString styleName; + wxRichTextAttr attr; + ctrl->GetStyle(adjustedCaretPos, attr); + // Take into account current default style just chosen by user if (ctrl->IsDefaultStyleShowing()) { + wxRichTextApplyStyle(attr, ctrl->GetDefaultStyleEx()); + if ((styleType == wxRICHTEXT_STYLE_ALL || styleType == wxRICHTEXT_STYLE_CHARACTER) && - !ctrl->GetDefaultStyleEx().GetCharacterStyleName().IsEmpty()) - styleName = ctrl->GetDefaultStyleEx().GetCharacterStyleName(); + !attr.GetCharacterStyleName().IsEmpty()) + styleName = attr.GetCharacterStyleName(); else if ((styleType == wxRICHTEXT_STYLE_ALL || styleType == wxRICHTEXT_STYLE_PARAGRAPH) && - !ctrl->GetDefaultStyleEx().GetParagraphStyleName().IsEmpty()) - styleName = ctrl->GetDefaultStyleEx().GetParagraphStyleName(); + !attr.GetParagraphStyleName().IsEmpty()) + styleName = attr.GetParagraphStyleName(); else if ((styleType == wxRICHTEXT_STYLE_ALL || styleType == wxRICHTEXT_STYLE_LIST) && - !ctrl->GetDefaultStyleEx().GetListStyleName().IsEmpty()) - styleName = ctrl->GetDefaultStyleEx().GetListStyleName(); + !attr.GetListStyleName().IsEmpty()) + styleName = attr.GetListStyleName(); + // TODO: when we have a concept of focused object (text box), we'll + // use the paragraph style name of the focused object as the frame style name. +#if 0 + else if ((styleType == wxRICHTEXT_STYLE_ALL || styleType == wxRICHTEXT_STYLE_BOX) && + !attr.GetBoxStyleName().IsEmpty()) + styleName = attr.GetBoxStyleName(); +#endif } - else if (obj && (styleType == wxRICHTEXT_STYLE_ALL || styleType == wxRICHTEXT_STYLE_CHARACTER) && - !obj->GetAttributes().GetCharacterStyleName().IsEmpty()) + else if ((styleType == wxRICHTEXT_STYLE_ALL || styleType == wxRICHTEXT_STYLE_CHARACTER) && + !attr.GetCharacterStyleName().IsEmpty()) { - styleName = obj->GetAttributes().GetCharacterStyleName(); + styleName = attr.GetCharacterStyleName(); } - else if (para && (styleType == wxRICHTEXT_STYLE_ALL || styleType == wxRICHTEXT_STYLE_PARAGRAPH) && - !para->GetAttributes().GetParagraphStyleName().IsEmpty()) + else if ((styleType == wxRICHTEXT_STYLE_ALL || styleType == wxRICHTEXT_STYLE_PARAGRAPH) && + !attr.GetParagraphStyleName().IsEmpty()) { - styleName = para->GetAttributes().GetParagraphStyleName(); + styleName = attr.GetParagraphStyleName(); } - else if (para && (styleType == wxRICHTEXT_STYLE_ALL || styleType == wxRICHTEXT_STYLE_LIST) && - !para->GetAttributes().GetListStyleName().IsEmpty()) + else if ((styleType == wxRICHTEXT_STYLE_ALL || styleType == wxRICHTEXT_STYLE_LIST) && + !attr.GetListStyleName().IsEmpty()) { - styleName = para->GetAttributes().GetListStyleName(); + styleName = attr.GetListStyleName(); } - + return styleName; } /// Auto-select from style under caret in idle time void wxRichTextStyleListBox::OnIdle(wxIdleEvent& event) { - if (CanAutoSetSelection() && GetRichTextCtrl() && wxWindow::FindFocus() != this) + if (CanAutoSetSelection() && GetRichTextCtrl() && IsShownOnScreen() && wxWindow::FindFocus() != this) { wxString styleName = GetStyleToShowInIdleTime(GetRichTextCtrl(), GetStyleType()); @@ -723,38 +1005,65 @@ wxRichTextStyleListCtrl::wxRichTextStyleListCtrl(wxWindow* parent, wxWindowID id bool wxRichTextStyleListCtrl::Create(wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style) { + if ((style & wxBORDER_MASK) == wxBORDER_DEFAULT) + style |= wxBORDER_THEME; + wxControl::Create(parent, id, pos, size, style); - + SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); - - m_styleListBox = new wxRichTextStyleListBox(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSIMPLE_BORDER); - - wxArrayString choices; - choices.Add(_("All styles")); - choices.Add(_("Paragraph styles")); - choices.Add(_("Character styles")); - choices.Add(_("List styles")); - - m_styleChoice = new wxChoice(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, choices); - + if (size != wxDefaultSize) + SetInitialSize(size); + + bool showSelector = ((style & wxRICHTEXTSTYLELIST_HIDE_TYPE_SELECTOR) == 0); + + wxBorder listBoxStyle; + if (showSelector) + listBoxStyle = wxBORDER_THEME; + else + listBoxStyle = wxBORDER_NONE; + + m_styleListBox = new wxRichTextStyleListBox(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, listBoxStyle); + wxBoxSizer* boxSizer = new wxBoxSizer(wxVERTICAL); - boxSizer->Add(m_styleListBox, 1, wxALL|wxEXPAND, 5); - boxSizer->Add(m_styleChoice, 0, wxALL|wxEXPAND, 5); - - SetSizer(boxSizer); + + if (showSelector) + { + wxArrayString choices; + choices.Add(_("All styles")); + choices.Add(_("Paragraph styles")); + choices.Add(_("Character styles")); + choices.Add(_("List styles")); + choices.Add(_("Box styles")); + + m_styleChoice = new wxChoice(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, choices); + + boxSizer->Add(m_styleListBox, 1, wxALL|wxEXPAND, 5); + boxSizer->Add(m_styleChoice, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND, 5); + } + else + { + boxSizer->Add(m_styleListBox, 1, wxALL|wxEXPAND, 0); + } + + SetSizer(boxSizer); + Layout(); m_dontUpdate = true; - - int i = StyleTypeToIndex(m_styleListBox->GetStyleType()); - m_styleChoice->SetSelection(i); - + + if (m_styleChoice) + { + int i = StyleTypeToIndex(m_styleListBox->GetStyleType()); + m_styleChoice->SetSelection(i); + } + m_dontUpdate = false; - + return true; } wxRichTextStyleListCtrl::~wxRichTextStyleListCtrl() { + } /// React to style type choice @@ -766,8 +1075,9 @@ void wxRichTextStyleListCtrl::OnChooseType(wxCommandEvent& event) { if (m_dontUpdate) return; - + wxRichTextStyleListBox::wxRichTextStyleType styleType = StyleIndexToType(event.GetSelection()); + m_styleListBox->SetSelection(-1); m_styleListBox->SetStyleType(styleType); } } @@ -798,6 +1108,10 @@ int wxRichTextStyleListCtrl::StyleTypeToIndex(wxRichTextStyleListBox::wxRichText { return 3; } + else if (styleType == wxRichTextStyleListBox::wxRICHTEXT_STYLE_BOX) + { + return 4; + } return 0; } @@ -810,6 +1124,8 @@ wxRichTextStyleListBox::wxRichTextStyleType wxRichTextStyleListCtrl::StyleIndexT return wxRichTextStyleListBox::wxRICHTEXT_STYLE_CHARACTER; else if (i == 3) return wxRichTextStyleListBox::wxRICHTEXT_STYLE_LIST; + else if (i == 4) + return wxRichTextStyleListBox::wxRICHTEXT_STYLE_BOX; return wxRichTextStyleListBox::wxRICHTEXT_STYLE_ALL; } @@ -847,17 +1163,19 @@ wxRichTextCtrl* wxRichTextStyleListCtrl::GetRichTextCtrl() const /// Set/get the style type to display void wxRichTextStyleListCtrl::SetStyleType(wxRichTextStyleListBox::wxRichTextStyleType styleType) { - if (m_styleListBox) - m_styleListBox->SetStyleType(styleType); + if ( !m_styleListBox ) + return; + + m_styleListBox->SetStyleType(styleType); m_dontUpdate = true; if (m_styleChoice) - { + { int i = StyleTypeToIndex(m_styleListBox->GetStyleType()); m_styleChoice->SetSelection(i); } - + m_dontUpdate = false; } @@ -873,7 +1191,7 @@ wxRichTextStyleListBox::wxRichTextStyleType wxRichTextStyleListCtrl::GetStyleTyp void wxRichTextStyleListCtrl::UpdateStyles() { if (m_styleListBox) - m_styleListBox->UpdateStyles(); + m_styleListBox->UpdateStyles(); } #if wxUSE_COMBOCTRL @@ -888,6 +1206,17 @@ BEGIN_EVENT_TABLE(wxRichTextStyleComboPopup, wxRichTextStyleListBox) EVT_LEFT_DOWN(wxRichTextStyleComboPopup::OnMouseClick) END_EVENT_TABLE() +bool wxRichTextStyleComboPopup::Create( wxWindow* parent ) +{ + int borderStyle = GetDefaultBorder(); + if (borderStyle == wxBORDER_SUNKEN) + borderStyle = wxBORDER_SIMPLE; + + return wxRichTextStyleListBox::Create(parent, wxID_ANY, + wxPoint(0,0), wxDefaultSize, + borderStyle); +} + void wxRichTextStyleComboPopup::SetStringValue( const wxString& s ) { m_value = SetStyleSelection(s); @@ -914,7 +1243,7 @@ void wxRichTextStyleComboPopup::OnMouseMove(wxMouseEvent& event) { // Move selection to cursor if it is inside the popup - int itemHere = wxRichTextStyleListBox::HitTest(event.GetPosition()); + int itemHere = wxRichTextStyleListBox::VirtualHitTest(event.GetPosition().y); if ( itemHere >= 0 ) { wxRichTextStyleListBox::SetSelection(itemHere); @@ -978,10 +1307,20 @@ bool wxRichTextStyleComboCtrl::Create(wxWindow* parent, wxWindowID id, const wxP void wxRichTextStyleComboCtrl::OnIdle(wxIdleEvent& event) { - if (GetRichTextCtrl() && !IsPopupShown() && m_stylePopup && wxWindow::FindFocus() != this) + event.Skip(); + + if ( !m_stylePopup ) + return; + + wxRichTextCtrl * const richtext = GetRichTextCtrl(); + if ( !richtext ) + return; + + if ( !IsPopupShown() && IsShownOnScreen() && wxWindow::FindFocus() != this ) { - wxString styleName = wxRichTextStyleListBox::GetStyleToShowInIdleTime(GetRichTextCtrl(), m_stylePopup->GetStyleType()); - + wxString styleName = + wxRichTextStyleListBox::GetStyleToShowInIdleTime(richtext, m_stylePopup->GetStyleType()); + wxString currentValue = GetValue(); if (!styleName.IsEmpty()) { @@ -994,7 +1333,6 @@ void wxRichTextStyleComboCtrl::OnIdle(wxIdleEvent& event) else if (!currentValue.IsEmpty()) SetValue(wxEmptyString); } - event.Skip(); } #endif @@ -1005,4 +1343,3 @@ void wxRichTextStyleComboCtrl::OnIdle(wxIdleEvent& event) #endif // wxUSE_RICHTEXT -