X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/3570a1c6e596c358848c77c5b37d724097340ce8..5ad9ae3a29787f4cdf6dfc1c69d77fedfa2f4c73:/src/richtext/richtextstyles.cpp diff --git a/src/richtext/richtextstyles.cpp b/src/richtext/richtextstyles.cpp index 0ce957ad79..649a2a11c3 100644 --- a/src/richtext/richtextstyles.cpp +++ b/src/richtext/richtextstyles.cpp @@ -54,19 +54,37 @@ bool wxRichTextStyleDefinition::Eq(const wxRichTextStyleDefinition& def) const } /// Gets the style combined with the base style -wxTextAttr wxRichTextStyleDefinition::GetStyleMergedWithBase(const wxRichTextStyleSheet* sheet) const +wxRichTextAttr wxRichTextStyleDefinition::GetStyleMergedWithBase(const wxRichTextStyleSheet* sheet) const { - if (!m_baseStyle.IsEmpty()) + if (m_baseStyle.IsEmpty()) + return m_style; + + // Collect the styles, detecting loops + wxArrayString styleNames; + wxList styles; + const wxRichTextStyleDefinition* def = this; + while (def) { - wxRichTextStyleDefinition* baseStyle = sheet->FindStyle(m_baseStyle); - if (baseStyle) - { - wxTextAttr baseAttr = baseStyle->GetStyleMergedWithBase(sheet); - baseAttr.Apply(m_style, NULL); - return baseAttr; - } + styles.Insert((wxObject*) def); + styleNames.Add(def->GetName()); + + wxString baseStyleName = def->GetBaseStyle(); + if (!baseStyleName.IsEmpty() && styleNames.Index(baseStyleName) == wxNOT_FOUND) + 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 m_style; + + return attr; } /*! @@ -111,14 +129,14 @@ bool wxRichTextListStyleDefinition::operator ==(const wxRichTextListStyleDefinit } /// Sets/gets the attributes for the given level -void wxRichTextListStyleDefinition::SetLevelAttributes(int i, const wxTextAttr& attr) +void wxRichTextListStyleDefinition::SetLevelAttributes(int i, const wxRichTextAttr& attr) { wxASSERT( (i >= 0 && i < 10) ); if (i >= 0 && i < 10) m_levelStyles[i] = attr; } -const wxTextAttr* wxRichTextListStyleDefinition::GetLevelAttributes(int i) const +const wxRichTextAttr* wxRichTextListStyleDefinition::GetLevelAttributes(int i) const { wxASSERT( (i >= 0 && i < 10) ); if (i >= 0 && i < 10) @@ -127,7 +145,7 @@ const wxTextAttr* wxRichTextListStyleDefinition::GetLevelAttributes(int i) const return NULL; } -wxTextAttr* wxRichTextListStyleDefinition::GetLevelAttributes(int i) +wxRichTextAttr* wxRichTextListStyleDefinition::GetLevelAttributes(int i) { wxASSERT( (i >= 0 && i < 10) ); if (i >= 0 && i < 10) @@ -142,7 +160,7 @@ void wxRichTextListStyleDefinition::SetAttributes(int i, int leftIndent, int lef wxASSERT( (i >= 0 && i < 10) ); if (i >= 0 && i < 10) { - wxTextAttr attr; + wxRichTextAttr attr; attr.SetBulletStyle(bulletStyle); attr.SetLeftIndent(leftIndent, leftSubIndent); @@ -178,11 +196,11 @@ 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) -wxTextAttr wxRichTextListStyleDefinition::CombineWithParagraphStyle(int indent, const wxTextAttr& paraStyle, wxRichTextStyleSheet* styleSheet) +wxRichTextAttr wxRichTextListStyleDefinition::CombineWithParagraphStyle(int indent, const wxRichTextAttr& paraStyle, wxRichTextStyleSheet* styleSheet) { int listLevel = FindLevelForIndent(indent); - wxTextAttr attr(*GetLevelAttributes(listLevel)); + wxRichTextAttr attr(*GetLevelAttributes(listLevel)); int oldLeftIndent = attr.GetLeftIndent(); int oldLeftSubIndent = attr.GetLeftSubIndent(); @@ -203,7 +221,7 @@ wxTextAttr wxRichTextListStyleDefinition::CombineWithParagraphStyle(int indent, /// Combine the base and list style, using the given indent (from which /// an appropriate level is found) -wxTextAttr wxRichTextListStyleDefinition::GetCombinedStyle(int indent, wxRichTextStyleSheet* styleSheet) +wxRichTextAttr wxRichTextListStyleDefinition::GetCombinedStyle(int indent, wxRichTextStyleSheet* styleSheet) { int listLevel = FindLevelForIndent(indent); return GetCombinedStyleForLevel(listLevel, styleSheet); @@ -211,9 +229,9 @@ wxTextAttr wxRichTextListStyleDefinition::GetCombinedStyle(int indent, wxRichTex /// Combine the base and list style, using the given indent (from which /// an appropriate level is found) -wxTextAttr wxRichTextListStyleDefinition::GetCombinedStyleForLevel(int listLevel, wxRichTextStyleSheet* styleSheet) +wxRichTextAttr wxRichTextListStyleDefinition::GetCombinedStyleForLevel(int listLevel, wxRichTextStyleSheet* styleSheet) { - wxTextAttr attr(*GetLevelAttributes(listLevel)); + wxRichTextAttr attr(*GetLevelAttributes(listLevel)); int oldLeftIndent = attr.GetLeftIndent(); int oldLeftSubIndent = attr.GetLeftSubIndent(); @@ -520,6 +538,8 @@ void wxRichTextStyleListBox::UpdateStyles() { if (GetStyleSheet()) { + int oldSel = GetSelection(); + SetSelection(wxNOT_FOUND); m_styleNames.Clear(); @@ -546,9 +566,15 @@ void wxRichTextStyleListBox::UpdateStyles() Refresh(); - if (GetItemCount() > 0) + int newSel = -1; + if (oldSel >= 0 && oldSel < (int) GetItemCount()) + newSel = oldSel; + else if (GetItemCount() > 0) + newSel = 0; + + if (newSel >= 0) { - SetSelection(0); + SetSelection(newSel); SendSelectedEvent(); } } @@ -590,7 +616,7 @@ wxString wxRichTextStyleListBox::CreateHTML(wxRichTextStyleDefinition* def) cons bool isCentred = false; - wxTextAttr attr(def->GetStyleMergedWithBase(GetStyleSheet())); + wxRichTextAttr attr(def->GetStyleMergedWithBase(GetStyleSheet())); if (attr.HasAlignment() && attr.GetAlignment() == wxTEXT_ALIGNMENT_CENTRE) isCentred = true; @@ -614,18 +640,76 @@ wxString wxRichTextStyleListBox::CreateHTML(wxRichTextStyleDefinition* def) cons str << wxT(""); #ifdef __WXMSW__ - int size = 3; + int size = 2; #else - int size = 4; + int size = 3; #endif - int stdFontSize = 12; + // 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 < m_styleNames.GetCount(); i++) + { + wxString name = m_styleNames[i].Lower(); + if (name.Find(wxT("normal")) != wxNOT_FOUND || name.Find(normalTranslated) != wxNOT_FOUND || + name.Find(wxT("default")) != wxNOT_FOUND || name.Find(defaultTranslated) != wxNOT_FOUND) + { + wxRichTextStyleDefinition* d = GetStyleSheet()->FindStyle(m_styleNames[i]); + if (d) + { + 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 = GetStyleSheet()->FindStyle(m_styleNames[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 thisFontSize = ((attr.GetFlags() & wxTEXT_ATTR_FONT_SIZE) != 0) ? attr.GetFontSize() : stdFontSize; if (thisFontSize < stdFontSize) - size ++; - else if (thisFontSize > stdFontSize) size --; + else if (thisFontSize > stdFontSize) + size ++; str += wxT("GetStyle(adjustedCaretPos, attr); // Take into account current default style just chosen by user @@ -882,6 +966,7 @@ void wxRichTextStyleListCtrl::OnChooseType(wxCommandEvent& event) return; wxRichTextStyleListBox::wxRichTextStyleType styleType = StyleIndexToType(event.GetSelection()); + m_styleListBox->SetSelection(-1); m_styleListBox->SetStyleType(styleType); } } @@ -1041,7 +1126,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);