IMPLEMENT_CLASS(wxRichTextCharacterStyleDefinition, wxRichTextStyleDefinition)
IMPLEMENT_CLASS(wxRichTextParagraphStyleDefinition, wxRichTextStyleDefinition)
IMPLEMENT_CLASS(wxRichTextListStyleDefinition, wxRichTextParagraphStyleDefinition)
+IMPLEMENT_CLASS(wxRichTextBoxStyleDefinition, wxRichTextStyleDefinition)
/*!
* A definition
m_baseStyle = def.m_baseStyle;
m_style = def.m_style;
m_description = def.m_description;
+ m_properties = def.m_properties;
}
bool wxRichTextStyleDefinition::Eq(const wxRichTextStyleDefinition& def) const
{
- return (m_name == def.m_name && m_baseStyle == def.m_baseStyle && m_style == def.m_style);
+ return (m_name == def.m_name && m_baseStyle == def.m_baseStyle && m_style == def.m_style && m_properties == def.m_properties);
}
/// 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;
+
+ bool isParaStyle = IsKindOf(wxCLASSINFO(wxRichTextParagraphStyleDefinition));
+ bool isCharStyle = IsKindOf(wxCLASSINFO(wxRichTextCharacterStyleDefinition));
+ bool isListStyle = IsKindOf(wxCLASSINFO(wxRichTextListStyleDefinition));
+ bool isBoxStyle = IsKindOf(wxCLASSINFO(wxRichTextBoxStyleDefinition));
+
+ // Collect the styles, detecting loops
+ wxArrayString styleNames;
+ wxList styles;
+ const wxRichTextStyleDefinition* def = this;
+ while (def)
{
- wxRichTextStyleDefinition* baseStyle = sheet->FindStyle(m_baseStyle);
- if (baseStyle)
+ styles.Insert((wxObject*) def);
+ styleNames.Add(def->GetName());
+
+ wxString baseStyleName = def->GetBaseStyle();
+ if (!baseStyleName.IsEmpty() && styleNames.Index(baseStyleName) == wxNOT_FOUND)
{
- wxTextAttr baseAttr = baseStyle->GetStyleMergedWithBase(sheet);
- baseAttr.Apply(m_style, NULL);
- return baseAttr;
+ 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 m_style;
+
+ return attr;
}
/*!
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
*/
}
/// 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)
return NULL;
}
-wxTextAttr* wxRichTextListStyleDefinition::GetLevelAttributes(int i)
+wxRichTextAttr* wxRichTextListStyleDefinition::GetLevelAttributes(int i)
{
wxASSERT( (i >= 0 && i < 10) );
if (i >= 0 && i < 10)
wxASSERT( (i >= 0 && i < 10) );
if (i >= 0 && i < 10)
{
- wxTextAttr attr;
+ wxRichTextAttr attr;
attr.SetBulletStyle(bulletStyle);
attr.SetLeftIndent(leftIndent, leftSubIndent);
/// 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();
/// 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);
/// 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();
return true;
if (RemoveListStyle(def, deleteStyle))
return true;
+ if (RemoveBoxStyle(def, deleteStyle))
+ return true;
return false;
}
for (wxList::compatibility_iterator node = list.GetFirst(); node; node = node->GetNext())
{
wxRichTextStyleDefinition* def = (wxRichTextStyleDefinition*) node->GetData();
- if (def->GetName().Lower() == name.Lower())
+ if (def->GetName() == name)
return def;
}
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
return AddStyle(m_listStyleDefinitions, def);
}
+/// Add a definition to the box style list
+bool wxRichTextStyleSheet::AddBoxStyle(wxRichTextBoxStyleDefinition* def)
+{
+ def->GetStyle().GetTextBoxAttr().SetBoxStyleName(def->GetName());
+ return AddStyle(m_boxStyleDefinitions, def);
+}
+
/// Add a definition to the appropriate style list
bool wxRichTextStyleSheet::AddStyle(wxRichTextStyleDefinition* def)
{
if (charDef)
return AddCharacterStyle(charDef);
+ wxRichTextBoxStyleDefinition* boxDef = wxDynamicCast(def, wxRichTextBoxStyleDefinition);
+ if (boxDef)
+ return AddBoxStyle(boxDef);
+
return false;
}
if (charDef)
return charDef;
+ wxRichTextBoxStyleDefinition* boxDef = FindBoxStyle(name, recurse);
+ if (boxDef)
+ return boxDef;
+
return NULL;
}
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());
+ m_properties = sheet.m_properties;
}
/// Equality
#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.
*/
if (i >= m_styleNames.GetCount() /* || i < 0 */ )
return NULL;
- return GetStyleSheet()->FindStyle(m_styleNames[i]);
+ 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
{
if (GetStyleSheet())
{
+ int oldSel = GetSelection();
+
SetSelection(wxNOT_FOUND);
m_styleNames.Clear();
if (GetStyleType() == wxRICHTEXT_STYLE_ALL || GetStyleType() == wxRICHTEXT_STYLE_PARAGRAPH)
{
for (i = 0; i < GetStyleSheet()->GetParagraphStyleCount(); i++)
- m_styleNames.Add(GetStyleSheet()->GetParagraphStyle(i)->GetName());
+ 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());
+ 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());
+ 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();
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();
}
}
+ else
+ {
+ m_styleNames.Clear();
+ SetSelection(wxNOT_FOUND);
+ SetItemCount(0);
+ Refresh();
+ }
}
// Get index for style name
int wxRichTextStyleListBox::GetIndexForStyle(const wxString& name) const
{
- return m_styleNames.Index(name);
+ 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
+ {
+ 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 m_styleNames.Index(s);
}
/// Set selection for string
{
int i = GetIndexForStyle(name);
if (i > -1)
+ {
SetSelection(i);
+ if (!IsVisible(i))
+ ScrollToRow(i);
+ }
return i;
}
bool isCentred = false;
- wxTextAttr attr(def->GetStyleMergedWithBase(GetStyleSheet()));
+ wxRichTextAttr attr(def->GetStyleMergedWithBase(GetStyleSheet()));
if (attr.HasAlignment() && attr.GetAlignment() == wxTEXT_ALIGNMENT_CENTRE)
isCentred = true;
str << wxT("<td nowrap>");
#ifdef __WXMSW__
- int size = 3;
+ int size = 2;
#else
- int size = 4;
+ int size = 3;
#endif
- int stdFontSize = 12;
- int thisFontSize = ((attr.GetFlags() & wxTEXT_ATTR_FONT_SIZE) != 0) ? attr.GetFontSize() : stdFontSize;
+ // 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.HasFontPointSize())
+ {
+ 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.HasFontPointSize())
+ {
+ 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.HasFontPointSize() ? attr.GetFontSize() : stdFontSize;
if (thisFontSize < stdFontSize)
- size ++;
- else if (thisFontSize > stdFontSize)
size --;
+ else if (thisFontSize > stdFontSize)
+ size ++;
str += wxT("<font");
if (!attr.GetFontFaceName().IsEmpty())
str << wxT(" face=\"") << attr.GetFontFaceName() << wxT("\"");
- if (attr.GetTextColour().Ok())
+ if (attr.GetTextColour().IsOk())
str << wxT(" color=\"#") << ColourToHexString(attr.GetTextColour()) << wxT("\"");
str << wxT(">");
{
wxVListBox::OnLeftDown(event);
- int item = HitTest(event.GetPosition());
+ int item = VirtualHitTest(event.GetPosition().y);
if (item != wxNOT_FOUND && GetApplyOnSelection())
ApplyStyle(item);
}
{
wxVListBox::OnLeftDown(event);
- int item = HitTest(event.GetPosition());
+ int item = VirtualHitTest(event.GetPosition().y);
if (item != wxNOT_FOUND && !GetApplyOnSelection())
ApplyStyle(item);
}
{
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())
{
- wxTextAttr attr;
-
- ctrl->GetStyle(adjustedCaretPos, attr);
wxRichTextApplyStyle(attr, ctrl->GetDefaultStyleEx());
if ((styleType == wxRICHTEXT_STYLE_ALL || styleType == wxRICHTEXT_STYLE_CHARACTER) &&
else if ((styleType == wxRICHTEXT_STYLE_ALL || styleType == wxRICHTEXT_STYLE_LIST) &&
!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());
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);
return;
wxRichTextStyleListBox::wxRichTextStyleType styleType = StyleIndexToType(event.GetSelection());
+ m_styleListBox->SetSelection(-1);
m_styleListBox->SetStyleType(styleType);
}
}
{
return 3;
}
+ else if (styleType == wxRichTextStyleListBox::wxRICHTEXT_STYLE_BOX)
+ {
+ return 4;
+ }
return 0;
}
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;
}
bool wxRichTextStyleComboPopup::Create( wxWindow* parent )
{
int borderStyle = GetDefaultBorder();
- if (borderStyle == wxBORDER_SUNKEN)
- borderStyle = wxBORDER_SIMPLE;
+ if (borderStyle == wxBORDER_SUNKEN || borderStyle == wxBORDER_NONE)
+ borderStyle = wxBORDER_THEME;
return wxRichTextStyleListBox::Create(parent, wxID_ANY,
wxPoint(0,0), wxDefaultSize,
{
// 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);
if ( !richtext )
return;
- if ( !IsPopupShown() && wxWindow::FindFocus() != this )
+ if ( !IsPopupShown() && IsShownOnScreen() && wxWindow::FindFocus() != this )
{
wxString styleName =
wxRichTextStyleListBox::GetStyleToShowInIdleTime(richtext, m_stylePopup->GetStyleType());