Fix crash if key bindings specified in profile cannot be found. Improve
[personal-kdebase.git] / apps / konqueror / settings / konqhtml / css / kcmcss.cpp
blobc18d55cd5c88ba214d1be2a58b66c4cdc3509bcb
2 // Own
3 #include "kcmcss.h"
5 // Qt
6 #include <QtGui/QCheckBox>
7 #include <QtGui/QComboBox>
8 #include <QtGui/QLayout>
9 #include <QtGui/QRadioButton>
10 #include <QtGui/QTextBrowser>
11 #include <QtGui/QBoxLayout>
13 // KDE
14 #include <kapplication.h>
15 #include <kcolorbutton.h>
16 #include <kconfig.h>
17 #include <kdialog.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>
27 // Local
28 #include "template.h"
30 #include "ui_cssconfig.h"
34 class CSSConfigWidget: public QWidget, public Ui::CSSConfigWidget
36 public:
37 CSSConfigWidget( QWidget *parent ) : QWidget( parent ) {
38 setupUi( this );
42 CSSConfig::CSSConfig(QWidget *parent, const QVariantList &)
43 : QWidget(parent)
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);
75 vbox->setMargin(0);
76 vbox->setSpacing(0);
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);
101 break;
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));
118 // Images
119 group = c->group("Images");
120 customDialog->hideImages->setChecked(group.readEntry("Hide", false));
121 customDialog->hideBackground->setChecked(group.readEntry("HideBackground", true));
123 delete c;
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());
161 c->sync();
162 delete c;
164 // generate CSS template
165 QString templ = KStandardDirs::locate("data", "kcmcss/template.css");
166 QString dest;
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);
187 c->sync();
188 delete c;
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);
207 break;
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)
225 QString px;
226 px.setNum(static_cast<int>(i * scale));
227 px += "px";
228 return px;
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));
250 else
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());
268 else
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()]));
283 // Images
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()]));
289 return dict;
293 void CSSConfig::slotCustomize()
295 customDialog->slotPreview();
296 customDialogBase->exec();
300 CSSCustomDialog::CSSCustomDialog( QWidget *parent )
301 : QWidget( parent )
302 , part(new KHTMLPart(this))
304 setupUi( 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()));
322 //QStringList fonts;
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");
334 QString dest;
335 if (templ.isEmpty()) return;
337 CSSTemplate css(templ);
339 part->begin();
340 part->setUserStyleSheet(css.expandToString(cssDict()));
341 part->write( i18n("<html>\n"
342 "\n"
343 "<h1>Heading 1</h1>\n"
344 "<h2>Heading 2</h2>\n"
345 "<h3>Heading 3</h3>\n"
346 "\n"
347 "<p>User defined stylesheets allow increased\n"
348 "accessibility for visually handicapped\n"
349 "people.</p>\n"
350 "\n"
351 "</html>\n")
353 part->end();
359 #include "kcmcss.moc"
361 // kate: space-indent on; indent-width 2; replace-tabs on;