charstyle.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009 #include <QObject>
00010 #include "sctextstruct.h"
00011 #include "scfonts.h"
00012 #include "resourcecollection.h"
00013
00014 #include "styles/style.h"
00015 #include "charstyle.h"
00016 #include "desaxe/saxiohelper.h"
00017 #include "desaxe/simple_actions.h"
00018 #include "prefsmanager.h"
00019
00020 StyleFlag& StyleFlag::operator&= (const StyleFlag& right){
00021 int result = static_cast<int>(value) & static_cast<int>(right.value);
00022 value = static_cast<StyleFlagValue>(result);
00023 return *this;
00024 }
00025
00026 StyleFlag& StyleFlag::operator|= (const StyleFlag& right)
00027 {
00028 int result = static_cast<int>(value) | static_cast<int>(right.value);
00029 value = static_cast<StyleFlagValue>(result);
00030 return *this;
00031 }
00032
00033 StyleFlag StyleFlag::operator& (const StyleFlag& right)
00034 {
00035 int val = static_cast<int>(value) & static_cast<int>(right.value);
00036 StyleFlag result(static_cast<StyleFlagValue>(val));
00037 return result;
00038 }
00039
00040 StyleFlag StyleFlag::operator& (int right)
00041 {
00042 int val = static_cast<int>(value) & right;
00043 StyleFlag result(static_cast<StyleFlagValue>(val));
00044 return result;
00045 }
00046
00047 StyleFlag StyleFlag::operator| (const StyleFlag& right)
00048 {
00049 int val = static_cast<int>(value) | static_cast<int>(right.value);
00050 StyleFlag result(static_cast<StyleFlagValue>(val));
00051 return result;
00052 }
00053
00054 StyleFlag StyleFlag::operator^ (const StyleFlag& right)
00055 {
00056 int val = static_cast<int>(value) ^ static_cast<int>(right.value);
00057 StyleFlag result(static_cast<StyleFlagValue>(val));
00058 return result;
00059 }
00060
00061 StyleFlag StyleFlag::operator^ (int right)
00062 {
00063 int val = static_cast<int>(value) ^ right;
00064 StyleFlag result(static_cast<StyleFlagValue>(val));
00065 return result;
00066 }
00067
00068 StyleFlag StyleFlag::operator~ ()
00069 {
00070 int val = ~ static_cast<int>(value);
00071 StyleFlag result(static_cast<StyleFlagValue>(val));
00072 return result;
00073 }
00074
00075 bool StyleFlag::operator== (const StyleFlag& right) const
00076 {
00077 int result = static_cast<int>( (value ^ right.value) & ScStyle_UserStyles);
00078 return (result == 0);
00079 }
00080
00081 bool StyleFlag::operator== (const StyleFlagValue right) const
00082 {
00083 int result = static_cast<int>( (value ^ right) & ScStyle_UserStyles);
00084 return (result == 0);
00085 }
00086
00087 bool StyleFlag::operator== (int right) const
00088 {
00089 int result = static_cast<int>( (value ^ right) & ScStyle_UserStyles);
00090 return (result == 0);
00091 }
00092
00093 bool StyleFlag::operator!= (const StyleFlag& right) const
00094 {
00095 return !(*this==right);
00096 }
00097
00098 bool StyleFlag::operator!= (const StyleFlagValue right) const
00099 {
00100 return !(*this==right);
00101 }
00102
00103
00104
00105 void CharStyle::applyCharStyle(const CharStyle & other)
00106 {
00107 Style::applyStyle(other);
00108 #define ATTRDEF(attr_TYPE, attr_GETTER, attr_NAME, attr_DEFAULT) \
00109 if (! other.inh_##attr_NAME) \
00110 set##attr_NAME(other.m_##attr_NAME);
00111 #include "charstyle.attrdefs.cxx"
00112 #undef ATTRDEF
00113 updateFeatures();
00114 }
00115
00116
00117 void CharStyle::eraseCharStyle(const CharStyle & other)
00118 {
00119 other.validate();
00120 Style::eraseStyle(other);
00121 #define ATTRDEF(attr_TYPE, attr_GETTER, attr_NAME, attr_DEFAULT) \
00122 if (!inh_##attr_NAME && m_##attr_NAME == other.m_##attr_NAME) \
00123 reset##attr_NAME();
00124 #include "charstyle.attrdefs.cxx"
00125 #undef ATTRDEF
00126 updateFeatures();
00127 }
00128
00129 bool CharStyle::equiv(const Style & other) const
00130 {
00131 other.validate();
00132 const CharStyle * oth = dynamic_cast<const CharStyle*> ( & other );
00133 return oth &&
00134 parent() == oth->parent()
00135 #define ATTRDEF(attr_TYPE, attr_GETTER, attr_NAME, attr_DEFAULT) \
00136 && (inh_##attr_NAME == oth->inh_##attr_NAME) \
00137 && (inh_##attr_NAME || m_##attr_NAME == oth->m_##attr_NAME)
00138 #include "charstyle.attrdefs.cxx"
00139 #undef ATTRDEF
00140 ;
00141 }
00142
00143
00144 QString CharStyle::displayName() const
00145 {
00146 if ( hasName() || !hasParent() || ! m_context)
00147 return name();
00148
00149
00150 else
00151 return parentStyle()->displayName() + "+";
00152 }
00153
00154
00155
00156 QString CharStyle::asString() const
00157 {
00158 QString result;
00159 if ( !inh_Font )
00160 result += QObject::tr("font %1 ").arg(font().scName());
00161 if ( !inh_FontSize )
00162 result += QObject::tr("size %1 ").arg(fontSize());
00163 if ( !inh_Features )
00164 result += QObject::tr("+style ");
00165 if ( !inh_StrokeColor || !inh_StrokeShade || !inh_FillColor || !inh_FillShade )
00166 result += QObject::tr("+color ");
00167 if ( !inh_UnderlineWidth || !inh_UnderlineOffset )
00168 result += underlineWidth() > 0 ? QObject::tr("+underline ") : QObject::tr("-underline ");
00169 if ( !inh_StrikethruWidth || !inh_StrikethruOffset )
00170 result += strikethruWidth() > 0 ? QObject::tr("+strikeout ") : QObject::tr("-strikeout ");
00171 if ( !inh_ShadowXOffset || !inh_ShadowYOffset )
00172 result += shadowXOffset() != 0 || shadowYOffset() != 0 ? QObject::tr("+shadow ") : QObject::tr("-shadow ");
00173 if ( !inh_OutlineWidth )
00174 result += outlineWidth() > 0 ? QObject::tr("+outline ") : QObject::tr("-outline ");
00175 if ( !inh_Tracking )
00176 result += tracking() > 0 ? QObject::tr("+tracking %1 ").arg(tracking()) : QObject::tr("-tracking ");
00177 if ( !inh_BaselineOffset )
00178 result += QObject::tr("+baseline %1 ").arg(baselineOffset());
00179 if ( !inh_ScaleH || !inh_ScaleV )
00180 result += QObject::tr("+stretch ");
00181 if ( hasParent() )
00182 result += QObject::tr("parent= %1").arg(parent());
00183 return result.trimmed();
00184 }
00185
00186
00187 void CharStyle::update(const StyleContext* context)
00188 {
00189 Style::update(context);
00190 const CharStyle * oth = dynamic_cast<const CharStyle*> ( parentStyle() );
00191 if (oth) {
00192 #define ATTRDEF(attr_TYPE, attr_GETTER, attr_NAME, attr_DEFAULT) \
00193 if (inh_##attr_NAME) \
00194 m_##attr_NAME = oth->attr_GETTER();
00195 #include "charstyle.attrdefs.cxx"
00196 #undef ATTRDEF
00197 }
00198 updateFeatures();
00199 }
00200
00201
00202
00203 const QString CharStyle::INHERIT = "inherit";
00204 const QString CharStyle::BOLD = "bold";
00205 const QString CharStyle::ITALIC = "italic";
00206 const QString CharStyle::UNDERLINE = "underline";
00207 const QString CharStyle::UNDERLINEWORDS = "underlinewords";
00208 const QString CharStyle::STRIKETHROUGH = "strike";
00209 const QString CharStyle::SUPERSCRIPT = "superscript";
00210 const QString CharStyle::SUBSCRIPT = "subscript";
00211 const QString CharStyle::OUTLINE = "outline";
00212 const QString CharStyle::SHADOWED = "shadowed";
00213 const QString CharStyle::ALLCAPS = "allcaps";
00214 const QString CharStyle::SMALLCAPS = "smallcaps";
00215
00216 static const QString SHYPHEN = "shyphen";
00217
00218
00219 QStringList StyleFlag::featureList() const
00220 {
00221 QStringList result(CharStyle::INHERIT);
00222 if (*this & ScStyle_Underline)
00223 result << CharStyle::UNDERLINE;
00224 if (*this & ScStyle_UnderlineWords)
00225 result << CharStyle::UNDERLINEWORDS;
00226 if (*this & ScStyle_Strikethrough)
00227 result << CharStyle::STRIKETHROUGH;
00228 if (*this & ScStyle_Superscript)
00229 result << CharStyle::SUPERSCRIPT;
00230 if (*this & ScStyle_Subscript)
00231 result << CharStyle::SUBSCRIPT;
00232 if (*this & ScStyle_Outline)
00233 result << CharStyle::OUTLINE;
00234 if (*this & ScStyle_Shadowed)
00235 result << CharStyle::SHADOWED;
00236 if (*this & ScStyle_AllCaps)
00237 result << CharStyle::ALLCAPS;
00238 if (*this & ScStyle_SmallCaps)
00239 result << CharStyle::SMALLCAPS;
00240 if (*this & ScStyle_HyphenationPossible)
00241 result << SHYPHEN;
00242 return result;
00243 }
00244
00245
00246 void CharStyle::updateFeatures()
00247 {
00248 m_Effects &= ~ScStyle_UserStyles;
00249 runFeatures(m_Features, dynamic_cast<const CharStyle*>(parentStyle()));
00250
00251
00252
00253
00254
00255
00256 }
00257
00258
00259 void CharStyle::runFeatures(const QStringList& featureList, const CharStyle* parent)
00260 {
00261 QStringList::ConstIterator it;
00262 for (it = featureList.begin(); it != featureList.end(); ++it)
00263 {
00264 QString feature = it->trimmed();
00265 if (feature == INHERIT)
00266 {
00267 if (parent)
00268 runFeatures(parent->features(), dynamic_cast<const CharStyle*>(parent->parentStyle()));
00269 }
00270 else if (feature == BOLD)
00271 {
00272
00273 }
00274 else if (feature == ITALIC)
00275 {
00276
00277 }
00278 else if (feature == UNDERLINE)
00279 {
00280 m_Effects |= ScStyle_Underline;
00281 }
00282 else if (feature == UNDERLINEWORDS)
00283 {
00284 m_Effects |= ScStyle_UnderlineWords;
00285 }
00286 else if (feature == STRIKETHROUGH)
00287 {
00288 m_Effects |= ScStyle_Strikethrough;
00289 }
00290 else if (feature == SUPERSCRIPT)
00291 {
00292 m_Effects |= ScStyle_Superscript;
00293 }
00294 else if (feature == SUBSCRIPT)
00295 {
00296 m_Effects |= ScStyle_Subscript;
00297 }
00298 else if (feature == OUTLINE)
00299 {
00300 m_Effects |= ScStyle_Outline;
00301 }
00302 else if (feature == SHADOWED)
00303 {
00304 m_Effects |= ScStyle_Shadowed;
00305 }
00306 else if (feature == ALLCAPS)
00307 {
00308 m_Effects |= ScStyle_AllCaps;
00309 }
00310 else if (feature == SMALLCAPS)
00311 {
00312 m_Effects |= ScStyle_SmallCaps;
00313 }
00314 else if (feature == SHYPHEN)
00315 {
00316 m_Effects |= ScStyle_HyphenationPossible;
00317 }
00318 else if (feature.startsWith("-"))
00319 {
00320 QString no_feature = feature.mid(1);
00321 if (no_feature == BOLD)
00322 {
00323
00324 }
00325 else if (no_feature == ITALIC)
00326 {
00327
00328 }
00329 else if (no_feature == UNDERLINE)
00330 {
00331 m_Effects &= ~ScStyle_Underline;
00332 }
00333 else if (no_feature == UNDERLINEWORDS)
00334 {
00335 m_Effects &= ~ScStyle_UnderlineWords;
00336 }
00337 else if (no_feature == STRIKETHROUGH)
00338 {
00339 m_Effects &= ~ScStyle_Strikethrough;
00340 }
00341 else if (no_feature == SUPERSCRIPT)
00342 {
00343 m_Effects &= ~ScStyle_Superscript;
00344 }
00345 else if (no_feature == SUBSCRIPT)
00346 {
00347 m_Effects &= ~ScStyle_Subscript;
00348 }
00349 else if (no_feature == OUTLINE)
00350 {
00351 m_Effects &= ~ScStyle_Outline;
00352 }
00353 else if (no_feature == SHADOWED)
00354 {
00355 m_Effects &= ~ScStyle_Shadowed;
00356 }
00357 else if (no_feature == ALLCAPS)
00358 {
00359 m_Effects &= ~ScStyle_AllCaps;
00360 }
00361 else if (no_feature == SMALLCAPS)
00362 {
00363 m_Effects &= ~ScStyle_SmallCaps;
00364 }
00365 else {
00366 qDebug("CharStyle: unknown feature: %s", feature.toLocal8Bit().constData());
00367 }
00368 }
00369 else {
00370 qDebug("CharStyle: unknown feature: %s", feature.toLocal8Bit().constData());
00371 }
00372
00373 }
00374 }
00375
00376
00377
00378 void CharStyle::setStyle(const CharStyle& other)
00379 {
00380 other.validate();
00381 setParent(other.parent());
00382 m_contextversion = -1;
00383 #define ATTRDEF(attr_TYPE, attr_GETTER, attr_NAME, attr_DEFAULT) \
00384 inh_##attr_NAME = other.inh_##attr_NAME; \
00385 m_##attr_NAME = other.m_##attr_NAME;
00386 #include "charstyle.attrdefs.cxx"
00387 #undef ATTRDEF
00388 updateFeatures();
00389 }
00390
00391 void CharStyle::getNamedResources(ResourceCollection& lists) const
00392 {
00393 for (const Style* sty = parentStyle(); sty != NULL; sty = sty->parentStyle())
00394 lists.collectCharStyle(sty->name());
00395 lists.collectColor(fillColor());
00396 lists.collectColor(strokeColor());
00397 lists.collectFont(font().scName());
00398 }
00399
00400
00401 void CharStyle::replaceNamedResources(ResourceCollection& newNames)
00402 {
00403 QMap<QString,QString>::ConstIterator it;
00404
00405 if (!inh_FillColor && (it = newNames.colors().find(fillColor())) != newNames.colors().end())
00406 setFillColor(it.value());
00407
00408 if (!inh_StrokeColor && (it = newNames.colors().find(strokeColor())) != newNames.colors().end())
00409 setStrokeColor(it.value());
00410
00411 if (hasParent() && (it = newNames.charStyles().find(parent())) != newNames.charStyles().end())
00412 setParent(it.value());
00413
00414 if (!inh_Font && (it = newNames.fonts().find(font().scName())) != newNames.fonts().end())
00415 setFont(newNames.availableFonts->findFont(it.value(), NULL));
00416 updateFeatures();
00417 }
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458 Xml_string toXMLString(StyleFlag val)
00459 {
00460 return toXMLString(static_cast<unsigned int>(val & ScStyle_UserStyles));
00461 }
00462
00463
00464 void CharStyle::saxx(SaxHandler& handler, const Xml_string& elemtag) const
00465 {
00466 Xml_attr att;
00467 Style::saxxAttributes(att);
00468 #define ATTRDEF(attr_TYPE, attr_GETTER, attr_NAME, attr_DEFAULT) \
00469 if (!inh_##attr_NAME) \
00470 att.insert(# attr_NAME, toXMLString(m_##attr_NAME));
00471 #include "charstyle.attrdefs.cxx"
00472 #undef ATTRDEF
00473 if (!name().isEmpty())
00474 att["id"] = mkXMLName(elemtag + name());
00475 handler.begin(elemtag, att);
00476
00477
00478 handler.end(elemtag);
00479 }
00480
00481
00482
00483 template<>
00484 StyleFlag parse<StyleFlag>(const Xml_string& str)
00485 {
00486 return StyleFlag(parseInt(str));
00487 }
00488
00489 template<>
00490 ScFace parse<ScFace>(const Xml_string& str)
00491 {
00492
00493 return PrefsManager::instance()->appPrefs.AvailFonts[str];
00494 }
00495
00496
00497 using namespace desaxe;
00498
00499
00500 const Xml_string CharStyle::saxxDefaultElem("charstyle");
00501
00502 void CharStyle::desaxeRules(const Xml_string& prefixPattern, Digester& ruleset, Xml_string elemtag)
00503 {
00504 Xml_string stylePrefix(Digester::concat(prefixPattern, elemtag));
00505 ruleset.addRule(stylePrefix, Factory<CharStyle>());
00506 ruleset.addRule(stylePrefix, IdRef<CharStyle>());
00507 Style::desaxeRules<CharStyle>(prefixPattern, ruleset, elemtag);
00508 #define ATTRDEF(attr_TYPE, attr_GETTER, attr_NAME, attr_DEFAULT) \
00509 ruleset.addRule(stylePrefix, SetAttributeWithConversion<CharStyle, attr_TYPE> ( & CharStyle::set##attr_NAME, # attr_NAME, &parse<attr_TYPE> ));
00510 #include "charstyle.attrdefs.cxx"
00511 #undef ATTRDEF
00512 }