1 /*****************************************************************************
2 * cssedit.cpp - QStarDict, a StarDict clone written with using Qt *
3 * Copyright (C) 2008 Alexander Rodin *
5 * This program 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 * This program 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 along *
16 * with this program; if not, write to the Free Software Foundation, Inc., *
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
18 *****************************************************************************/
22 #include <QApplication>
23 #include <QColorDialog>
27 CSSEdit::CSSEdit(QWidget *parent)
31 //m_preview->setProperty("FingerScrollable", true);
33 connect(m_elementCombo, SIGNAL(currentIndexChanged(int)), SLOT(setCurrentElement(int)));
34 connect(m_fontCombo, SIGNAL(currentFontChanged(const QFont&)), SLOT(propertyChanged()));
35 connect(m_sizeSpin, SIGNAL(valueChanged(int)), SLOT(propertyChanged()));
36 connect(m_boldButton, SIGNAL(toggled(bool)), SLOT(propertyChanged()));
37 connect(m_italicButton, SIGNAL(toggled(bool)), SLOT(propertyChanged()));
38 connect(m_underlineButton, SIGNAL(toggled(bool)), SLOT(propertyChanged()));
39 connect(m_colorButton, SIGNAL(clicked()), SLOT(colorSelectClicked()));
40 connect(m_backgroundButton, SIGNAL(clicked()), SLOT(colorSelectClicked()));
43 void CSSEdit::setCSS(const QString &css)
48 QString currentProperty;
50 for (int i = 0; i < css.length(); ++i)
55 for (; i < css.length() && css[i] != '{'; ++i)
56 if (! css[i].isSpace())
58 if (i < css.length() && css[i] == '{')
66 currentProperty.clear();
67 for (; i < css.length() && css[i] != ':'; ++i)
68 if (! css[i].isSpace())
69 currentProperty += css[i];
74 for (++i; i < css.length() && css[i] != ';'; ++i)
80 while (i < css.length() && css[i] != ';')
85 currentValue += css[i];
87 else if (! css[i].isSpace())
89 if (css[i] == '\'' || css[i] == '\"')
90 quote = css[i].toAscii();
92 currentValue += css[i];
95 m_elements[element][currentProperty] = currentValue;
96 while (css[i + 1].isSpace())
98 if (css[i + 1] == '}')
106 updateElementCombo();
110 void CSSEdit::setElementsAliases(const QHash<QString, QString> &aliases)
112 m_elementsAliases = aliases;
113 updateElementCombo();
117 QString CSSEdit::css() const
120 for (QHash<QString, Element>::const_iterator i = m_elements.begin(); i != m_elements.end(); ++i)
122 result += i.key() + "\n{\n";
123 for (Element::const_iterator j = i->begin(); j != i->end(); ++j)
125 result += j.key() + ": ";
126 if (j->contains(' '))
127 result += "\"" + *j + "\";\n";
129 result += *j + ";\n";
136 void CSSEdit::setCurrentElement(int index)
138 if (! m_elements.contains(m_elementCombo->itemData(index).toString()))
140 m_currentElement = m_elementCombo->itemData(index).toString();
141 Element *element = &m_elements[m_currentElement];
142 Element parentElement = getParentElement(m_currentElement);
144 QColor color(element->contains("color") ? element->value("color") : parentElement["color"]);
145 m_colorButton->setText(color.name());
146 QPalette palette = m_colorButton->palette();
147 palette.setColor(QPalette::Normal, QPalette::ButtonText, color);
148 m_colorButton->setPalette(palette);
150 color = QColor(element->contains("background-color") ?
151 element->value("background-color") : parentElement["background-color"]);
152 m_backgroundButton->setText(color.name());
153 palette = m_backgroundButton->palette();
154 palette.setColor(QPalette::Normal, QPalette::ButtonText, color);
155 m_backgroundButton->setPalette(palette);
157 m_fontCombo->setCurrentFont(element->contains("font-family") ?
158 element->value("font-family") : parentElement["font-family"]);
160 QString value = element->contains("font-size") ?
161 element->value("font-size") : parentElement["font-size"];
162 if (! value.endsWith("pt"))
163 value = parentElement["font-size"];
164 m_sizeSpin->setValue(value.left(value.length() - 2).toInt());
166 value = element->contains("font-weight") ? element->value("font-weight") : parentElement["font-weight"];
167 m_boldButton->setChecked(value == "bold");
169 value = element->contains("font-style") ? element->value("font-style") : parentElement["font-style"];
170 m_italicButton->setChecked(value == "italic");
172 value = element->contains("text-decoration") ? element->value("text-decoration") : parentElement["text-decoration"];
173 m_underlineButton->setChecked(value == "underline");
178 void CSSEdit::propertyChanged()
182 if (! m_elements.contains(m_currentElement))
184 Element *element = &m_elements[m_currentElement];
185 Element parentElement = getParentElement(m_currentElement);
187 if (sender() == m_fontCombo)
189 QString font = m_fontCombo->currentText();
190 if (parentElement["font-family"] == font)
191 element->remove("font-family");
193 element->insert("font-family", font);
195 else if (sender() == m_sizeSpin)
197 QString size = QString::number(m_sizeSpin->value()) + "pt";
198 if (parentElement["font-size"] == size)
199 element->remove("font-size");
201 element->insert("font-size", size);
203 else if (sender() == m_boldButton)
205 QString weight = (m_boldButton->isChecked() ? "bold" : "normal");
206 if (parentElement["font-weight"] == weight)
207 element->remove("font-weight");
209 element->insert("font-weight", weight);
211 else if(sender() == m_italicButton)
213 QString style = (m_italicButton->isChecked() ? "italic" : "normal");
214 if (parentElement["font-style"] == style)
215 element->remove("font-style");
217 element->insert("font-style", style);
219 else if(sender() == m_underlineButton)
221 QString decoration = (m_underlineButton->isChecked() ? "underline" : "none");
222 if (parentElement["text-decoration"] == decoration)
223 element->remove("text-decoration");
225 element->insert("text-decoration", decoration);
231 void CSSEdit::colorSelectClicked()
233 QToolButton *colorButton;
234 QString propertyName;
235 if (sender() == m_colorButton)
237 colorButton = m_colorButton;
238 propertyName = "color";
240 else if (sender() == m_backgroundButton)
242 colorButton = m_backgroundButton;
243 propertyName = "background-color";
248 if (! m_elements.contains(m_currentElement))
250 Element *element = &m_elements[m_currentElement];
251 Element parentElement = getParentElement(m_currentElement);
252 QColor color = QColorDialog::getColor(QColor(colorButton->text()), this);
255 colorButton->setText(color.name());
256 QPalette palette = colorButton->palette();
257 palette.setColor(QPalette::Normal, QPalette::ButtonText, color);
258 colorButton->setPalette(palette);
259 if (parentElement[propertyName] == color.name())
260 element->remove(propertyName);
262 element->insert(propertyName, color.name());
267 void CSSEdit::updatePreview()
269 QString html = "<style>" + css() + "</style>";
271 for (QHash<QString, Element>::const_iterator i = m_elements.begin(); i != m_elements.end(); ++i)
274 if (m_elementsAliases.contains(i.key()))
275 alias = m_elementsAliases.value(i.key());
278 int pos = i.key().indexOf('.');
280 html += "<" + i.key() + ">" + alias + "</" + i.key() + "><br>";
283 QString parent = i.key().left(pos);
284 QString class_ = i.key().mid(pos + 1);
285 html += "<" + parent + " class=\'" + class_ + "\'>" + alias + "</" + parent + "><br>";
289 m_preview->setHtml(html);
292 void CSSEdit::updateElementCombo()
294 m_elementCombo->clear();
295 for (QHash<QString, Element>::const_iterator i = m_elements.begin(); i != m_elements.end(); ++i)
298 if (m_elementsAliases.contains(i.key()))
299 alias = m_elementsAliases.value(i.key());
302 m_elementCombo->addItem(alias, i.key());
304 if (m_elements.begin() != m_elements.end())
305 m_currentElement = m_elements.begin().key();
307 m_currentElement.clear();
310 CSSEdit::Element CSSEdit::getParentElement(const QString &elementName)
312 Element body = m_elements.value("body");
314 if (elementName == "body")
316 body["color"] = QApplication::palette().color(QPalette::Normal, QPalette::Text).name();
317 body["background-color"] = QApplication::palette().color(QPalette::Normal, QPalette::Base).name();
318 body["font-family"] = QApplication::font().family();
319 body["font-size"] = QString::number(QApplication::font().pointSize()) + "pt";
320 body["font-weight"] = (QApplication::font().weight() == QFont::Bold) ? "bold" : "normal";
321 body["font-style"] = (QApplication::font().style() == QFont::StyleItalic) ? "italic" : "normal";
322 body["text-decoration"] = QApplication::font().underline() ? "underline" : "none";
327 if (! body.contains("color"))
328 body["color"] = QApplication::palette().color(QPalette::Normal, QPalette::Text).name();
329 if (! body.contains("background-color"))
330 body["background-color"] = QApplication::palette().color(QPalette::Normal, QPalette::Base).name();
331 if (! body.contains("font-family"))
332 body["font-family"] = QApplication::font().family();
333 if (! body.contains("font-size"))
334 body["font-size"] = QString::number(QApplication::font().pointSize()) + "pt";
335 if (! body.contains("font-weight"))
336 body["font-weight"] = (QApplication::font().weight() == QFont::Bold) ? "bold" : "normal";
337 if (! body.contains("font-style"))
338 body["font-style"] = (QApplication::font().style() == QFont::StyleItalic) ? "italic" : "normal";
339 if (! body.contains("text-decoration"))
340 body["text-decoration"] = QApplication::font().underline() ? "underline" : "none";
344 int pos = elementName.indexOf('.');
347 parentName = elementName.left(pos);
348 if (m_elements.contains(parentName))
350 Element parent = m_elements[parentName];
351 for (Element::const_iterator i = body.begin(); i != body.end(); ++i)
352 if (! parent.contains(i.key()))
353 parent[i.key()] = *i;
363 // vim: tabstop=4 softtabstop=4 shiftwidth=4 expandtab cindent textwidth=120 formatoptions=tc