2 Copyright (c) 2006 Paolo Capriotti <p.capriotti@sns.it>
3 (c) 2006 Maurizio Monge <maurizio.monge@kdemail.net>
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.
14 #include <QStringList>
15 #include <QListWidgetItem>
16 #include <kstandarddirs.h>
18 #include "luaapi/loader.h"
19 #include "variants/variants.h"
21 #include "pref_theme.h"
23 class PrefTheme::ThemeInfo
{
29 QDateTime last_modified
;
31 ThemeInfo(const QString
& f
, const QString
& n
,
32 const QString
& d
, const QStringList
& v
, const QDateTime
& t
)
40 PrefTheme::ThemeInfoList
PrefTheme::to_theme_info_list(const QStringList
& files
, const Settings
& s
) {
41 std::map
<QString
, ThemeInfo
> cache
;
43 SettingArray themes
= s
.group("themes").array("theme");
44 foreach (Settings s_theme
, themes
) {
46 SettingArray s_variants
= s_theme
.group("variants").array("variant");
47 foreach (Settings s_var
, s_variants
) {
48 variants
.append(s_var
["name"].value
<QString
>());
50 QString f
= s_theme
["file-name"].value
<QString
>();
51 cache
.insert(std::make_pair(f
, ThemeInfo(f
,
52 s_theme
["name"].value
<QString
>(),
53 s_theme
["description"].value
<QString
>(),
55 QDateTime::fromString(s_theme
["last-modified"].value
<QString
>()))));
58 ThemeInfoList allluafiles
;
61 for(int i
=0;i
<files
.size();i
++) {
62 QDateTime lm
= QFileInfo(files
[i
]).lastModified();
63 std::map
<QString
, ThemeInfo
>::iterator it
= cache
.find(files
[i
]);
65 if(it
!= cache
.end() && it
->second
.last_modified
== lm
) {
66 if(!it
->second
.name
.isEmpty())
71 LuaApi::Loader
l(NULL
);
75 allluafiles
<< ThemeInfo(files
[i
], QString(), QString(), QStringList(), lm
);
76 std::cout
<< " --> Error loading " << files
[i
] << std::endl
77 << l
.errorString() << std::endl
;
81 QString name
= l
.getString("name");
83 allluafiles
<< ThemeInfo(files
[i
], QString(), QString(), QStringList(), lm
);
87 ThemeInfo
t(files
[i
], name
, l
.getString("description"), l
.getStringList("variants"), lm
);
94 SettingArray themes
= s
.group("themes").newArray("theme");
96 for (int i
= 0; i
< allluafiles
.size(); i
++) {
97 Settings s_theme
= themes
.append();
98 s_theme
["file-name"] = allluafiles
[i
].file_name
;
99 s_theme
["name"] = allluafiles
[i
].name
;
100 s_theme
["description"] = allluafiles
[i
].description
;
102 SettingArray variants
= s_theme
.group("variants").newArray("variant");
103 foreach (QString v
, allluafiles
[i
].variants
) {
104 Settings s_var
= variants
.append();
108 s_theme
["last-modified"] = allluafiles
[i
].last_modified
.toString();
115 OptList
PrefTheme::get_file_options(const QString
& f
) {
116 if(boost::shared_ptr
<OptList
> o
= m_new_theme_options
[f
])
119 LuaApi::Loader
l(NULL
);
122 boost::shared_ptr
<OptList
> o
= boost::shared_ptr
<OptList
>(new OptList(l
.getOptList("options")));
123 SettingMap
<QString
> s_lua
= settings
.group("lua-settings").map
<QString
>("entry", "file-name");
124 Settings entry
= s_lua
.insert(f
);
125 options_list_load_from_settings(*o
, entry
.group("options"));
127 m_new_theme_options
[f
] = o
;
131 PrefTheme::PrefTheme(QWidget
*parent
)
133 , m_pieces_opt_widget(NULL
)
134 , m_squares_opt_widget(NULL
) {
136 listPieces
->setSelectionMode(QAbstractItemView::SingleSelection
);
137 listSquares
->setSelectionMode(QAbstractItemView::SingleSelection
);
138 connect(listPieces
, SIGNAL(itemSelectionChanged()), this, SLOT(piecesThemeChanged()));
139 connect(listSquares
, SIGNAL(itemSelectionChanged()), this, SLOT(squaresThemeChanged()));
140 connect(checkPieces
, SIGNAL(toggled(bool)), this, SLOT(piecesThemeChecked(bool)));
141 connect(checkSquares
, SIGNAL(toggled(bool)), this, SLOT(squaresThemeChecked(bool)));
142 connect(comboVariant
, SIGNAL(currentIndexChanged(int)), this, SLOT(variantChanged()));
143 m_pieces_opt_layout
= new QHBoxLayout(widgetPieces
);
144 m_pieces_opt_layout
->setMargin(0);
145 m_squares_opt_layout
= new QHBoxLayout(widgetSquares
);
146 m_squares_opt_layout
->setMargin(0);
148 MasterSettings
s(".kboard_config_cache");
150 KStandardDirs
* dirs
= KGlobal::dirs();
151 m_pieces_themes
= to_theme_info_list(
152 dirs
->findAllResources("appdata", "themes/Pieces/*.lua", KStandardDirs::Recursive
),
154 m_squares_themes
= to_theme_info_list(
155 dirs
->findAllResources("appdata", "themes/Squares/*.lua", KStandardDirs::Recursive
),
158 const Variant::Variants
& all
= Variant::allVariants();
159 for(Variant::Variants::const_iterator it
= all
.begin(); it
!= all
.end(); ++it
)
160 comboVariant
->addItem(it
->first
, QVariant(it
->first
));
165 PrefTheme::~PrefTheme() {
169 void PrefTheme::apply() {
170 SettingMap
<QString
> variants
= settings
.group("variants").map
<QString
>("variant", "name");
172 for(std::map
<QString
, QString
>::iterator it
= m_new_piece_themes
.begin();
173 it
!= m_new_piece_themes
.end(); ++it
) {
174 Settings var
= variants
.insert(it
->first
);
175 var
["pieces-theme"] = it
->second
;
177 for(std::map
<QString
, bool>::iterator it
= m_new_use_def_pieces
.begin();
178 it
!= m_new_use_def_pieces
.end(); ++it
) {
179 Settings var
= variants
.insert(it
->first
);
180 var
["use-def-pieces"] = it
->second
;
182 for(std::map
<QString
, QString
>::iterator it
= m_new_square_themes
.begin();
183 it
!= m_new_square_themes
.end(); ++it
) {
184 Settings var
= variants
.insert(it
->first
);
185 var
["squares-theme"] = it
->second
;
187 for(std::map
<QString
, bool>::iterator it
= m_new_use_def_squares
.begin();
188 it
!= m_new_use_def_squares
.end(); ++it
) {
189 Settings var
= variants
.insert(it
->first
);
190 var
["use-def-squares"] = it
->second
;
193 for(std::map
<QString
, boost::shared_ptr
<OptList
> >::iterator it
= m_new_theme_options
.begin();
194 it
!= m_new_theme_options
.end(); ++it
) {
195 SettingMap
<QString
> s_lua
= settings
.group("lua-settings").map
<QString
>("entry", "file-name");
196 Settings entry
= s_lua
.insert(it
->first
);
197 options_list_save_to_settings(*it
->second
, entry
.group("options"));
201 void PrefTheme::update_list_view(QListWidget
* list
, const ThemeInfoList
& themes
,
202 QString variant
, QString settings
) {
206 QListWidgetItem
*prev_sel
= 0;
208 for(int i
=0;i
<themes
.size();i
++) {
209 bool ok1
= themes
[i
].variants
.contains(variant
, Qt::CaseInsensitive
);
210 bool ok2
= themes
[i
].variants
.contains(variant
+"[default]", Qt::CaseInsensitive
);
214 int ok
= themes
[i
].file_name
== settings
? 3 : ok2
? 2 : 1;
215 QListWidgetItem
*w
= new QListWidgetItem(themes
[i
].name
, list
);
217 w
->setData(Qt::UserRole
, i
);
220 list
->setItemSelected(prev_sel
, false);
221 list
->setItemSelected(w
, true);
228 void PrefTheme::variantChanged() {
229 QString c
= comboVariant
->itemData(comboVariant
->currentIndex()).toString();
230 VariantInfo
*vi
= Variant::variant(c
);
234 listPieces
->setEnabled(false);
235 labelPieces
->setText(QString());
236 labelPieces
->setEnabled(false);
237 checkSquares
->hide();
238 listSquares
->clear();
239 listSquares
->setEnabled(false);
240 labelSquares
->setText(QString());
241 labelSquares
->setEnabled(false);
245 QString vname
= vi
->name();
246 QString vproxy
= vi
->themeProxy();
247 SettingMap
<QString
> variants
= settings
.group("variants").map
<QString
>("variant", "name");
248 Settings var
= variants
.insert(vname
);
250 bool ck
= vname
!= vproxy
;
251 checkSquares
->setVisible(ck
);
252 checkPieces
->setVisible(ck
);
254 bool dp
= m_new_use_def_pieces
.count(vname
) ? m_new_use_def_pieces
[vname
]
255 : (var
["use-def-pieces"] | true).value();
256 bool ds
= m_new_use_def_squares
.count(vname
) ? m_new_use_def_squares
[vname
]
257 : (var
["use-def-squares"] | true).value();
258 checkPieces
->setText("Same as "+vproxy
);
259 checkPieces
->setChecked(dp
);
260 listPieces
->setEnabled(!dp
);
261 labelPieces
->setEnabled(!dp
);
262 checkSquares
->setText("Same as "+vproxy
);
263 checkSquares
->setChecked(ds
);
264 listSquares
->setEnabled(!ds
);
265 labelSquares
->setEnabled(!ds
);
268 listPieces
->setEnabled(true);
269 labelPieces
->setEnabled(true);
270 listSquares
->setEnabled(true);
271 labelSquares
->setEnabled(true);
274 QString pth
= m_new_piece_themes
.count(vname
) ? m_new_piece_themes
[vname
]
275 : (var
["pieces-theme"] | QString()).value();
276 QString sth
= m_new_square_themes
.count(vname
) ? m_new_square_themes
[vname
]
277 : (var
["squares-theme"] | QString()).value();
278 update_list_view(listPieces
, m_pieces_themes
, vproxy
, pth
);
279 update_list_view(listSquares
, m_squares_themes
, vproxy
, sth
);
282 void PrefTheme::piecesThemeChanged() {
283 QList
<QListWidgetItem
*> l
= listPieces
->selectedItems();
285 int i
= l
[0]->data(Qt::UserRole
).toInt();
286 if(i
>=0 && i
<m_pieces_themes
.size()) {
287 labelPieces
->setText(m_pieces_themes
[i
].description
);
289 QString c
= comboVariant
->itemData(comboVariant
->currentIndex()).toString();
290 VariantInfo
*vi
= Variant::variant(c
);
292 m_new_piece_themes
[vi
->name()] = m_pieces_themes
[i
].file_name
;
294 if(m_pieces_opt_widget
) {
295 delete m_pieces_opt_widget
;
296 m_pieces_opt_widget
= NULL
;
298 OptList ol
= get_file_options(m_pieces_themes
[i
].file_name
);
300 m_pieces_opt_widget
= new OptionWidget(ol
, widgetPieces
);
301 m_pieces_opt_layout
->addWidget(m_pieces_opt_widget
);
306 labelPieces
->setText(QString());
309 void PrefTheme::piecesThemeChecked(bool ck
) {
310 listPieces
->setEnabled(!ck
);
311 labelPieces
->setEnabled(!ck
);
313 QString c
= comboVariant
->itemData(comboVariant
->currentIndex()).toString();
314 VariantInfo
*vi
= Variant::variant(c
);
316 m_new_use_def_pieces
[vi
->name()] = ck
;
319 void PrefTheme::squaresThemeChanged() {
320 QList
<QListWidgetItem
*> l
= listSquares
->selectedItems();
322 int i
= l
[0]->data(Qt::UserRole
).toInt();
323 if(i
>=0 && i
<m_squares_themes
.size()) {
324 labelSquares
->setText(m_squares_themes
[i
].description
);
326 QString c
= comboVariant
->itemData(comboVariant
->currentIndex()).toString();
327 VariantInfo
*vi
= Variant::variant(c
);
329 m_new_square_themes
[vi
->name()] = m_squares_themes
[i
].file_name
;
331 if(m_squares_opt_widget
) {
332 delete m_squares_opt_widget
;
333 m_squares_opt_widget
= NULL
;
335 OptList ol
= get_file_options(m_squares_themes
[i
].file_name
);
337 m_squares_opt_widget
= new OptionWidget(ol
, widgetSquares
);
338 m_squares_opt_layout
->addWidget(m_squares_opt_widget
);
343 labelSquares
->setText(QString());
346 void PrefTheme::squaresThemeChecked(bool ck
) {
347 listSquares
->setEnabled(!ck
);
348 labelSquares
->setEnabled(!ck
);
350 QString c
= comboVariant
->itemData(comboVariant
->currentIndex()).toString();
351 VariantInfo
*vi
= Variant::variant(c
);
353 m_new_use_def_squares
[vi
->name()] = ck
;
356 QString
PrefTheme::getBestTheme(VariantInfo
* vi
, ThemeType type
) {
357 QString group
= type
== Pieces
? "pieces" :
358 type
== Squares
? "squares" : "figurines";
359 QString pattern
= type
== Pieces
? "themes/Pieces/*.lua" :
360 type
== Squares
? "themes/Squares/*.lua" : "themes/Figurines/*.lua";
361 QString tag
= group
+ "-theme";
362 QString deftag
= "use-def-" + group
;
363 QString v
= vi
->name();
364 SettingMap
<QString
> variants
= settings
.group("variants").map
<QString
>("variant", "name");
365 Settings var
= variants
.insert(v
);
366 if (v
!= vi
->themeProxy() &&
367 (var
[deftag
] | true) )
368 v
= vi
->themeProxy();
371 return var
[tag
].value
<QString
>();
373 MasterSettings
s(".kboard_config_cache.xml");
374 KStandardDirs
* dirs
= KGlobal::dirs();
375 ThemeInfoList themes
= to_theme_info_list(dirs
->findAllResources("appdata", pattern
, KStandardDirs::Recursive
), s
.group(group
));
379 for(int i
=0;i
<themes
.size();i
++) {
380 bool ok1
= themes
[i
].variants
.contains(v
, Qt::CaseInsensitive
);
381 bool ok2
= themes
[i
].variants
.contains(v
+"[default]", Qt::CaseInsensitive
);
385 int ok
= ok2
? 2 : 1;
387 retv
= themes
[i
].file_name
;
397 #include "pref_theme.moc"