6 #include <QtGui/QCheckBox>
7 #include <QtGui/QComboBox>
8 #include <QtGui/QLayout>
9 #include <QtGui/QRadioButton>
10 #include <QtGui/QTextBrowser>
11 #include <QtGui/QBoxLayout>
14 #include <kapplication.h>
15 #include <kcolorbutton.h>
18 #include <kfontdialog.h>
19 #include <kglobalsettings.h>
20 #include <kstandarddirs.h>
21 #include <kurlrequester.h>
22 #include <kpluginfactory.h>
23 #include <kpluginloader.h>
24 #include <khtml_part.h>
25 #include <khtmlview.h>
30 #include "ui_cssconfig.h"
34 class CSSConfigWidget
: public QWidget
, public Ui::CSSConfigWidget
37 CSSConfigWidget( QWidget
*parent
) : QWidget( parent
) {
42 CSSConfig::CSSConfig(QWidget
*parent
, const QVariantList
&)
44 , configWidget(new CSSConfigWidget(this))
45 , customDialogBase(new KDialog(this))
46 , customDialog(new CSSCustomDialog(customDialogBase
))
48 customDialogBase
->setObjectName( "customCSSDialog" );
49 customDialogBase
->setModal( true );
50 customDialogBase
->setButtons( KDialog::Close
);
51 customDialogBase
->setDefaultButton( KDialog::Close
);
53 customDialogBase
->setMainWidget(customDialog
);
55 // setQuickHelp( i18n("<h1>Konqueror Stylesheets</h1> This module allows you to apply your own color"
56 setWhatsThis( i18n("<h1>Konqueror Stylesheets</h1> This module allows you to apply your own color"
57 " and font settings to Konqueror by using"
58 " stylesheets (CSS). You can either specify"
59 " options or apply your own self-written"
60 " stylesheet by pointing to its location.<br />"
61 " Note that these settings will always have"
62 " precedence before all other settings made"
63 " by the site author. This can be useful to"
64 " visually impaired people or for web pages"
65 " that are unreadable due to bad design."));
67 connect(configWidget
->useDefault
, SIGNAL(clicked()), SIGNAL(changed()));
68 connect(configWidget
->useAccess
, SIGNAL(clicked()), SIGNAL(changed()));
69 connect(configWidget
->useUser
, SIGNAL(clicked()), SIGNAL(changed()));
70 connect(configWidget
->urlRequester
, SIGNAL(textChanged(const QString
&)),SIGNAL(changed()));
71 connect(configWidget
->customize
, SIGNAL(clicked()), SLOT(slotCustomize()));
72 connect(customDialog
, SIGNAL(changed()), SIGNAL(changed()));
74 QVBoxLayout
*vbox
= new QVBoxLayout(this);
77 vbox
->addWidget(configWidget
);
78 configWidget
->layout()->setMargin(0);
82 void CSSConfig::load()
84 KConfig
*c
= new KConfig("kcmcssrc", KConfig::NoGlobals
);
85 KConfigGroup group
= c
->group("Stylesheet");
86 QString u
= group
.readEntry("Use", "default");
87 configWidget
->useDefault
->setChecked(u
== "default");
88 configWidget
->useUser
->setChecked(u
== "user");
89 configWidget
->useAccess
->setChecked(u
== "access");
90 configWidget
->urlRequester
->setUrl(group
.readEntry("SheetName"));
92 group
= c
->group("Font");
93 customDialog
->basefontsize
->setEditText(QString::number(group
.readEntry("BaseSize", 12)));
94 customDialog
->dontScale
->setChecked(group
.readEntry("DontScale", false));
96 QString fname
= group
.readEntry("Family", "Arial");
97 for (int i
=0; i
< customDialog
->fontFamily
->count(); ++i
)
98 if (customDialog
->fontFamily
->itemText(i
) == fname
)
100 customDialog
->fontFamily
->setCurrentIndex(i
);
104 customDialog
->sameFamily
->setChecked(group
.readEntry("SameFamily", false));
106 group
= c
->group("Colors");
107 QString m
= group
.readEntry("Mode", "black-on-white");
108 customDialog
->blackOnWhite
->setChecked(m
== "black-on-white");
109 customDialog
->whiteOnBlack
->setChecked(m
== "white-on-black");
110 customDialog
->customColor
->setChecked(m
== "custom");
112 QColor
white (Qt::white
);
113 QColor
black (Qt::black
);
114 customDialog
->backgroundColorButton
->setColor(group
.readEntry("BackColor", white
));
115 customDialog
->foregroundColorButton
->setColor(group
.readEntry("ForeColor", black
));
116 customDialog
->sameColor
->setChecked(group
.readEntry("SameColor", false));
119 group
= c
->group("Images");
120 customDialog
->hideImages
->setChecked(group
.readEntry("Hide", false));
121 customDialog
->hideBackground
->setChecked(group
.readEntry("HideBackground", true));
127 void CSSConfig::save()
129 // write to config file
130 KConfig
*c
= new KConfig("kcmcssrc", KConfig::NoGlobals
);
131 KConfigGroup group
= c
->group("Stylesheet");
132 if (configWidget
->useDefault
->isChecked())
133 group
.writeEntry("Use", "default");
134 if (configWidget
->useUser
->isChecked())
135 group
.writeEntry("Use", "user");
136 if (configWidget
->useAccess
->isChecked())
137 group
.writeEntry("Use", "access");
138 group
.writeEntry("SheetName", configWidget
->urlRequester
->url().url());
140 group
= c
->group("Font");
141 group
.writeEntry("BaseSize", customDialog
->basefontsize
->currentText());
142 group
.writeEntry("DontScale", customDialog
->dontScale
->isChecked());
143 group
.writeEntry("SameFamily", customDialog
->sameFamily
->isChecked());
144 group
.writeEntry("Family", customDialog
->fontFamily
->currentText());
146 group
= c
->group("Colors");
147 if (customDialog
->blackOnWhite
->isChecked())
148 group
.writeEntry("Mode", "black-on-white");
149 if (customDialog
->whiteOnBlack
->isChecked())
150 group
.writeEntry("Mode", "white-on-black");
151 if (customDialog
->customColor
->isChecked())
152 group
.writeEntry("Mode", "custom");
153 group
.writeEntry("BackColor", customDialog
->backgroundColorButton
->color());
154 group
.writeEntry("ForeColor", customDialog
->foregroundColorButton
->color());
155 group
.writeEntry("SameColor", customDialog
->sameColor
->isChecked());
157 group
= c
->group("Images");
158 group
.writeEntry("Hide", customDialog
->hideImages
->isChecked());
159 group
.writeEntry("HideBackground", customDialog
->hideBackground
->isChecked());
164 // generate CSS template
165 QString templ
= KStandardDirs::locate("data", "kcmcss/template.css");
167 if (!templ
.isEmpty())
169 CSSTemplate
css(templ
);
171 dest
= KGlobal::mainComponent().dirs()->saveLocation("data", "kcmcss");
172 dest
+= "/override.css";
174 css
.expandToFile(dest
, customDialog
->cssDict());
177 // make konqueror use the right stylesheet
178 c
= new KConfig("konquerorrc", KConfig::NoGlobals
);
179 group
= c
->group("HTML Settings");
180 group
.writeEntry("UserStyleSheetEnabled", !configWidget
->useDefault
->isChecked());
182 if (configWidget
->useUser
->isChecked())
183 group
.writeEntry("UserStyleSheet", configWidget
->urlRequester
->url().url());
184 if (configWidget
->useAccess
->isChecked())
185 group
.writeEntry("UserStyleSheet", dest
);
192 void CSSConfig::defaults()
194 configWidget
->useDefault
->setChecked(true);
195 configWidget
->useUser
->setChecked(false);
196 configWidget
->useAccess
->setChecked(false);
197 configWidget
->urlRequester
->setUrl(KUrl());
199 customDialog
->basefontsize
->setEditText(QString::number(12));
200 customDialog
->dontScale
->setChecked(false);
202 QString fname
= "Arial";
203 for (int i
=0; i
< customDialog
->fontFamily
->count(); ++i
)
204 if (customDialog
->fontFamily
->itemText(i
) == fname
)
206 customDialog
->fontFamily
->setCurrentIndex(i
);
210 customDialog
->sameFamily
->setChecked(false);
211 customDialog
->blackOnWhite
->setChecked(true);
212 customDialog
->whiteOnBlack
->setChecked(false);
213 customDialog
->customColor
->setChecked(false);
214 customDialog
->backgroundColorButton
->setColor(Qt::white
);
215 customDialog
->foregroundColorButton
->setColor(Qt::black
);
216 customDialog
->sameColor
->setChecked(false);
218 customDialog
->hideImages
->setChecked(false);
219 customDialog
->hideBackground
->setChecked( true);
223 static QString
px(int i
, double scale
)
226 px
.setNum(static_cast<int>(i
* scale
));
232 QMap
<QString
,QString
> CSSCustomDialog::cssDict()
234 QMap
<QString
,QString
> dict
;
236 // Fontsizes ------------------------------------------------------
238 int bfs
= basefontsize
->currentText().toInt();
239 dict
.insert("fontsize-base", px(bfs
, 1.0));
241 if (dontScale
->isChecked())
243 dict
.insert("fontsize-small-1", px(bfs
, 1.0));
244 dict
.insert("fontsize-large-1", px(bfs
, 1.0));
245 dict
.insert("fontsize-large-2", px(bfs
, 1.0));
246 dict
.insert("fontsize-large-3", px(bfs
, 1.0));
247 dict
.insert("fontsize-large-4", px(bfs
, 1.0));
248 dict
.insert("fontsize-large-5", px(bfs
, 1.0));
252 // TODO: use something harmonic here
253 dict
.insert("fontsize-small-1", px(bfs
, 0.8));
254 dict
.insert("fontsize-large-1", px(bfs
, 1.2));
255 dict
.insert("fontsize-large-2", px(bfs
, 1.4));
256 dict
.insert("fontsize-large-3", px(bfs
, 1.5));
257 dict
.insert("fontsize-large-4", px(bfs
, 1.6));
258 dict
.insert("fontsize-large-5", px(bfs
, 1.8));
261 // Colors --------------------------------------------------------
263 if (customColor
->isChecked())
265 dict
.insert("background-color", backgroundColorButton
->color().name());
266 dict
.insert("foreground-color", foregroundColorButton
->color().name());
270 const char* blackOnWhiteFG
[2]={"White","Black"};
271 bool bw
=blackOnWhite
->isChecked();
272 dict
.insert("foreground-color", QLatin1String(blackOnWhiteFG
[bw
]));
273 dict
.insert("background-color", QLatin1String(blackOnWhiteFG
[!bw
]));
276 const char* notImportant
[2]={"","! important"};
277 dict
.insert("force-color", QLatin1String(notImportant
[sameColor
->isChecked()]));
279 // Fonts -------------------------------------------------------------
280 dict
.insert("font-family", fontFamily
->currentText());
281 dict
.insert("force-font", QLatin1String(notImportant
[sameFamily
->isChecked()]));
285 const char* bgNoneImportant
[2]={"","background-image : none ! important"};
286 dict
.insert("display-images", QLatin1String(bgNoneImportant
[hideImages
->isChecked()]));
287 dict
.insert("display-background", QLatin1String(bgNoneImportant
[hideBackground
->isChecked()]));
293 void CSSConfig::slotCustomize()
295 customDialog
->slotPreview();
296 customDialogBase
->exec();
300 CSSCustomDialog::CSSCustomDialog( QWidget
*parent
)
302 , part(new KHTMLPart(this))
305 connect(this,SIGNAL(changed()),SLOT(slotPreview()));
307 connect(basefontsize
, SIGNAL(highlighted(int)), SIGNAL(changed()));
308 connect(basefontsize
, SIGNAL(textChanged(const QString
&)),SIGNAL(changed()));
309 connect(dontScale
, SIGNAL(clicked()), SIGNAL(changed()));
310 connect(blackOnWhite
, SIGNAL(clicked()), SIGNAL(changed()));
311 connect(whiteOnBlack
, SIGNAL(clicked()), SIGNAL(changed()));
312 connect(customColor
, SIGNAL(clicked()), SIGNAL(changed()));
313 connect(foregroundColorButton
, SIGNAL(changed(const QColor
&)),SIGNAL(changed()));
314 connect(backgroundColorButton
, SIGNAL(changed(const QColor
&)),SIGNAL(changed()));
315 connect(fontFamily
, SIGNAL(highlighted(int)), SIGNAL(changed()));
316 connect(fontFamily
, SIGNAL(textChanged(const QString
&)),SIGNAL(changed()));
317 connect(sameFamily
, SIGNAL(clicked()), SIGNAL(changed()));
318 connect(sameColor
, SIGNAL(clicked()), SIGNAL(changed()));
319 connect(hideImages
, SIGNAL(clicked()), SIGNAL(changed()));
320 connect(hideBackground
, SIGNAL(clicked()), SIGNAL(changed()));
323 //KFontChooser::getFontList(fonts, 0);
324 //fontFamily->addItems(fonts);
326 part
->setAlwaysHonourDoctype(false);
327 QVBoxLayout
* l
= new QVBoxLayout(previewBox
);
328 l
->addWidget(part
->widget());
331 void CSSCustomDialog::slotPreview()
333 QString templ
= KStandardDirs::locate("data", "kcmcss/template.css");
335 if (templ
.isEmpty()) return;
337 CSSTemplate
css(templ
);
340 part
->setUserStyleSheet(css
.expandToString(cssDict()));
341 part
->write( i18n("<html>\n"
343 "<h1>Heading 1</h1>\n"
344 "<h2>Heading 2</h2>\n"
345 "<h3>Heading 3</h3>\n"
347 "<p>User defined stylesheets allow increased\n"
348 "accessibility for visually handicapped\n"
359 #include "kcmcss.moc"
361 // kate: space-indent on; indent-width 2; replace-tabs on;