1 /***************************************************************************
2 * This file is part of KWorship. *
3 * Copyright 2008 James Hogan <james@albanarts.com> *
5 * KWorship is free software: you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation, either version 2 of the License, or *
8 * (at your option) any later version. *
10 * KWorship is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
15 * You should have received a copy of the GNU General Public License *
16 * along with KWorship. If not, write to the Free Software Foundation, *
17 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
18 ***************************************************************************/
21 * @file KwCssStyleSheet.cpp
22 * @brief Cascading style sheet.
23 * @author James Hogan <james@albanarts.com>
26 #include "KwCssStyleSheet.h"
27 #include "KwCssStyleRule.h"
32 * Constructors + destructors
35 /// Default constructor.
36 KwCssStyleSheet::KwCssStyleSheet()
43 * This copies all except the actual styles in each rule which are aliased.
45 KwCssStyleSheet::KwCssStyleSheet(const KwCssStyleSheet
& copy
)
49 assert(0&&"unimplemented");
53 KwCssStyleSheet::~KwCssStyleSheet()
62 void KwCssStyleSheet::clear()
68 void KwCssStyleSheet::addRule(const KwCssStyleRule
& rule
)
70 m_rules
.push_back(rule
);
73 /// Import another stylesheet.
74 void KwCssStyleSheet::importStyleSheet(const KwCssStyleSheet
* styleSheet
)
76 m_rules
+= styleSheet
->m_rules
;
79 /// Import from CSS-like format into the sheet.
80 void KwCssStyleSheet::import(const KwCssSchema
* schema
, const QString
& sheet
)
84 // Strip out comments and newlines
85 static QRegExp
reComment("\\/\\*([^*]|\\*[^/])*\\*\\/|\n");
86 css
.replace(reComment
, " ");
89 static QRegExp
reRuleStart("^\\s*(\\S[^{]*)?\\s*\\{\\s*");
92 while (-1 != (rulesPos
= reRuleStart
.indexIn(css
, lastRulesPos
, QRegExp::CaretAtOffset
)))
94 lastRulesPos
= rulesPos
+ reRuleStart
.matchedLength();
97 // Read the key criteria
98 static QRegExp
reCriteriaKey("^(\\w*)(#(\\w+))?\\s*");
99 KwCssStyleRule::KeyList keys
;
100 QString head
= reRuleStart
.cap(1);
103 while (-1 != (headPos
= reCriteriaKey
.indexIn(head
, lastHeadPos
, QRegExp::CaretAtOffset
)) && reCriteriaKey
.matchedLength() > 0)
105 lastHeadPos
= headPos
+ reCriteriaKey
.matchedLength();
106 QString keyTypeName
= reCriteriaKey
.cap(1);
107 QString keyName
= reCriteriaKey
.cap(2);
109 if (!keyTypeName
.isEmpty())
111 keyType
= KwCssScopeKey::registerScopeType(keyTypeName
);
113 keys
+= KwCssScopeKey(keyType
, keyName
);
115 rule
.setCriteriaKeys(keys
);
117 // Read the class criteria
118 static QRegExp
reCriteriaClass("^\\.(\\w+)\\s*");
119 KwCssStyleRule::StringSet classes
;
120 while (-1 != (headPos
= reCriteriaClass
.indexIn(head
, lastHeadPos
, QRegExp::CaretAtOffset
)))
122 lastHeadPos
= headPos
+ reCriteriaClass
.matchedLength();
123 classes
+= reCriteriaClass
.cap(1);
125 rule
.setCriteriaClasses(classes
);
127 // Read the class includes
128 static QRegExp
reIncludeStart("^:\\s*");
129 if (-1 != (headPos
= reIncludeStart
.indexIn(head
, lastHeadPos
, QRegExp::CaretAtOffset
)))
131 lastHeadPos
= headPos
+ reIncludeStart
.matchedLength();
132 KwCssStyleRule::StringSet classes
;
133 while (-1 != (headPos
= reCriteriaClass
.indexIn(head
, lastHeadPos
, QRegExp::CaretAtOffset
)))
135 lastHeadPos
= headPos
+ reCriteriaClass
.matchedLength();
136 classes
+= reCriteriaClass
.cap(1);
138 rule
.setIncludedStyles(classes
);
141 // Should be no more head left
142 static QRegExp
reWhitespace("^\\s*$");
143 if (-1 == reWhitespace
.indexIn(head
, lastHeadPos
, QRegExp::CaretAtOffset
))
145 Q_ASSERT(0&& "Expected '{' near something else");
149 lastRulesPos
= rule
.getStyles()->import(schema
, css
, lastRulesPos
);
152 static QRegExp
reRuleEnd("^\\}\\s*");
153 if (-1 != (rulesPos
= reRuleEnd
.indexIn(css
, lastRulesPos
, QRegExp::CaretAtOffset
)))
155 lastRulesPos
= rulesPos
+ reRuleEnd
.matchedLength();
159 // Expected end of rule but got something else
160 Q_ASSERT(0&& "Expected '}' near something else");
171 KwCssStyleSheet::RuleList
& KwCssStyleSheet::getRules()
176 /// Get the constant rules.
177 const KwCssStyleSheet::RuleList
& KwCssStyleSheet::getRules() const
182 /// Convert to CSS-like format.
183 QString
KwCssStyleSheet::toString() const
185 /// @todo Take into account of shared styles in rules!
186 QString result
= "/* Doesn't take shared styles into account */\n";
187 foreach (const KwCssStyleRule
& rule
, m_rules
)
189 result
+= rule
.toString();