1 /* |
|
2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0"" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * |
|
16 */ |
|
17 |
|
18 #include "cpthemechanger.h" |
|
19 #include "cpthemechanger_p.h" |
|
20 #include "cpthemelistmodel.h" |
|
21 #include "cpthemeclient_p.h" |
|
22 #include "cpthemecommon_p.h" |
|
23 |
|
24 #include <QStringList> |
|
25 #include <QSettings> |
|
26 #include <QFileSystemWatcher> |
|
27 #include <QPixmap> |
|
28 #include <QFileInfoList> |
|
29 #include <QDir> |
|
30 |
|
31 #include <hbicon.h> |
|
32 #include <hbinstance.h> |
|
33 |
|
34 |
|
35 #if !defined(Q_OS_SYMBIAN) |
|
36 #include <stdio.h> |
|
37 static const char* KThemePathKey = "HB_THEMES_DIR"; |
|
38 #endif |
|
39 static const QString KDefaultTheme = "sfblacktheme"; |
|
40 static const QString KDefaultThemeIcon = ":/image/themePreview.nvg"; |
|
41 static const QString KPreviewThumbnailNVG = "/scalable/qtg_graf_theme_preview_thumbnail.nvg"; |
|
42 static const QString KPreviewThumbnailSVG = "/scalable/qtg_graf_theme_preview_thumbnail.svg"; |
|
43 |
|
44 static const QString KPreviewPrtNVG = "/scalable/qtg_graf_theme_preview_prt.nvg"; |
|
45 static const QString KPreviewLscNVG = "/scalable/qtg_graf_theme_preview_lsc.nvg"; |
|
46 static const QString KPreviewPrtSVG = "/scalable/qtg_graf_theme_preview_prt.svg"; |
|
47 static const QString KPreviewLscSVG = "/scalable/qtg_graf_theme_preview_lsc.svg"; |
|
48 |
|
49 static const QString KBackgroundPrtNVG = "/scalable/qtg_graf_screen_bg_prt.nvg"; |
|
50 static const QString KBackgroundLscNVG = "/scalable/qtg_graf_screen_bg_lsc.nvg"; |
|
51 static const QString KBackgroundPrtSVG = "/scalable/qtg_graf_screen_bg_prt.svg"; |
|
52 static const QString KBackgroundLscSVG = "/scalable/qtg_graf_screen_bg_lsc.svg"; |
|
53 |
|
54 static const QString KBackgroundPrtPNG = "/pixmap/qtg_graf_screen_bg_prt.png"; |
|
55 static const QString KBackgroundLscPNG = "/pixmap/qtg_graf_screen_bg_lsc.png"; |
|
56 |
|
57 |
|
58 |
|
59 CpThemeChangerPrivate::CpThemeChangerPrivate(CpThemeChanger* qq): |
|
60 q_ptr(qq), |
|
61 mThemeClient(CpThemeClient::global()), |
|
62 mFileWatcher(new QFileSystemWatcher(qq)), |
|
63 mModel(this, qq) |
|
64 |
|
65 { |
|
66 Q_Q(CpThemeChanger); |
|
67 |
|
68 // Figure out where our themes are. This is platform-dependent, |
|
69 // but not worth breaking out into platform-private implementations |
|
70 // at the moment. Ideally, this would be given to us by the theme server, |
|
71 #ifdef Q_OS_WIN |
|
72 static char* _path = NULL; |
|
73 static size_t _size = 0; |
|
74 _dupenv_s(&_path, &_size, KThemePathKey); |
|
75 mThemeRootPath = QString(_path); |
|
76 mThemeRootPathPostfix = QString(); |
|
77 free(_path); |
|
78 #elif defined(Q_OS_SYMBIAN) |
|
79 mThemeRootPath = "c:\\resource\\hb"; |
|
80 mThemeRootPathPostfix = "resource\\hb"; |
|
81 #elif defined(Q_OS_MACX) |
|
82 mThemeRootPath = QDir::homePath() + '/' + "Library" + QString("hb"); |
|
83 mThemeRootPathPostfix = QString(); |
|
84 #elif defined(Q_OS_UNIX) |
|
85 mThemeRootPath = QString(getenv(KThemePathKey)); |
|
86 mThemeRootPathPostfix = QString(); |
|
87 #else |
|
88 mThemeRootPath = "c:\\resource\\hb"; |
|
89 mThemeRootPathPostfix = QString(); |
|
90 #endif |
|
91 |
|
92 // Get our current state |
|
93 if (HbInstance::instance()) { |
|
94 HbTheme *hbTheme = HbInstance::instance()->theme(); |
|
95 if (hbTheme) { |
|
96 mCurrentTheme.name = hbTheme->name(); |
|
97 } |
|
98 } |
|
99 |
|
100 // Watch for changes to the theme directory in flash. |
|
101 // This may change once we start offering a model. |
|
102 #if defined(Q_OS_SYMBIAN) |
|
103 QFileInfoList driveInfoList = QDir::drives(); |
|
104 foreach (const QFileInfo &driveInfo, driveInfoList) { |
|
105 const QString drive = driveInfo.absolutePath(); |
|
106 mThemesPathList << drive + mThemeRootPathPostfix; |
|
107 } |
|
108 #else |
|
109 mThemesPathList << mThemeRootPath; |
|
110 #endif |
|
111 foreach (const QString &path, mThemesPathList) { |
|
112 QDir themeDir; |
|
113 themeDir.setPath( path ) ; |
|
114 QStringList list = themeDir.entryList(QDir::AllDirs|QDir::NoDotAndDotDot,QDir::Name); |
|
115 if(list.contains("themes", Qt::CaseSensitive )) { |
|
116 mFileWatcher->addPath(themeDir.path() + "/themes/"); |
|
117 } |
|
118 } |
|
119 |
|
120 q->connect(mFileWatcher, SIGNAL(directoryChanged(const QString&)), |
|
121 q, SLOT(_q_themeDirectoryChanged(const QString&))); |
|
122 |
|
123 updateThemeList(mCurrentTheme.name); |
|
124 |
|
125 // Connect to the theme server |
|
126 connectToServer(); |
|
127 } |
|
128 |
|
129 CpThemeChangerPrivate::~CpThemeChangerPrivate() |
|
130 { |
|
131 mThemeClient->releaseInstance(); |
|
132 mThemeClient = 0; |
|
133 } |
|
134 |
|
135 const CpThemeChanger::ThemeInfo& CpThemeChangerPrivate::currentTheme() const |
|
136 { |
|
137 return mCurrentTheme; |
|
138 } |
|
139 |
|
140 const QString& CpThemeChangerPrivate::currentThemeName() const |
|
141 { |
|
142 return mCurrentTheme.name.isEmpty() ? KDefaultTheme : mCurrentTheme.name; |
|
143 } |
|
144 |
|
145 int CpThemeChangerPrivate::indexOf(const CpThemeChanger::ThemeInfo& theme) const |
|
146 { |
|
147 return mThemeList.indexOf(theme); |
|
148 } |
|
149 |
|
150 void CpThemeChangerPrivate::updateThemeList(const QString& newThemeName) |
|
151 { |
|
152 if(!mThemeList.isEmpty()) { |
|
153 mThemeList.clear(); |
|
154 } |
|
155 |
|
156 mCurrentTheme.name = newThemeName.isEmpty() ? KDefaultTheme : newThemeName; |
|
157 |
|
158 foreach (const QString &path, mThemesPathList) { |
|
159 QDir themeDir; |
|
160 themeDir.setPath( path ) ; |
|
161 QStringList iconthemeslist; |
|
162 QStringList list = themeDir.entryList(QDir::AllDirs|QDir::NoDotAndDotDot,QDir::Name); |
|
163 CpThemeChanger::ThemeInfo nameIconPair; |
|
164 |
|
165 if(list.contains("themes", Qt::CaseSensitive )) { |
|
166 QDir root(themeDir.path()); |
|
167 themeDir.setPath(root.path() + "/themes/icons/") ; |
|
168 iconthemeslist = themeDir.entryList(QDir::AllDirs|QDir::NoDotAndDotDot,QDir::Name); |
|
169 foreach(QString themefolder, iconthemeslist) { |
|
170 QDir iconThemePath(root.path() + "/themes/icons/" + themefolder); |
|
171 if(iconThemePath.exists("index.theme") && |
|
172 (iconThemePath.exists("scalable") || iconThemePath.exists("pixmap") )) { |
|
173 QSettings iniSetting(iconThemePath.path() + "/index.theme", QSettings::IniFormat); |
|
174 iniSetting.beginGroup("Icon Theme"); |
|
175 QString hidden = iniSetting.value("Hidden").toString(); |
|
176 QString name = iniSetting.value("Name").toString(); |
|
177 QString iconPath = iniSetting.value("PreviewThumbnailPath").toString(); |
|
178 QString previewPathPrt = iniSetting.value("PreviewIconPath_prt").toString(); |
|
179 QString previewPathLsc = iniSetting.value("PreviewIconPath_lsc").toString(); |
|
180 if (name.isEmpty()) { |
|
181 continue; |
|
182 } |
|
183 |
|
184 QString fullPathToIcon(iconThemePath.path()); |
|
185 |
|
186 if(iconPath.isEmpty()|| !QFileInfo(fullPathToIcon + iconPath).exists()){ |
|
187 //Set thumbnail |
|
188 if(QFileInfo(fullPathToIcon + KPreviewThumbnailNVG).exists()){ |
|
189 nameIconPair.icon = HbIcon(fullPathToIcon + KPreviewThumbnailNVG); |
|
190 }else if(QFileInfo(fullPathToIcon + KPreviewThumbnailSVG).exists()){ |
|
191 nameIconPair.icon = HbIcon(fullPathToIcon + KPreviewThumbnailSVG); |
|
192 }else if(QFileInfo(fullPathToIcon + KBackgroundPrtNVG).exists()){ |
|
193 nameIconPair.icon = HbIcon(fullPathToIcon + KBackgroundPrtNVG); |
|
194 } else if(QFileInfo(fullPathToIcon + KBackgroundPrtSVG).exists()){ |
|
195 nameIconPair.icon = HbIcon(fullPathToIcon + KBackgroundPrtSVG); |
|
196 } else if(QFileInfo(fullPathToIcon + KBackgroundPrtPNG).exists()){ |
|
197 nameIconPair.icon = HbIcon(fullPathToIcon + KBackgroundPrtPNG); |
|
198 }else{ |
|
199 nameIconPair.icon = HbIcon(KDefaultThemeIcon); |
|
200 } |
|
201 |
|
202 } else { |
|
203 nameIconPair.icon = HbIcon(fullPathToIcon + iconPath); |
|
204 } |
|
205 |
|
206 //Portrait preview |
|
207 |
|
208 if(previewPathPrt.isEmpty() || !QFileInfo(fullPathToIcon + previewPathPrt).exists()) { |
|
209 |
|
210 if(QFileInfo(fullPathToIcon + KPreviewPrtNVG).exists()){ |
|
211 nameIconPair.portraitPreviewIcon = HbIcon(fullPathToIcon + KPreviewPrtNVG); |
|
212 }else if(QFileInfo(fullPathToIcon + KPreviewPrtSVG).exists()){ |
|
213 nameIconPair.portraitPreviewIcon = HbIcon(fullPathToIcon + KPreviewPrtSVG); |
|
214 }else if(QFileInfo(fullPathToIcon + KBackgroundPrtNVG).exists()){ |
|
215 nameIconPair.portraitPreviewIcon = HbIcon(fullPathToIcon + KBackgroundPrtNVG); |
|
216 } else if(QFileInfo(fullPathToIcon + KBackgroundPrtSVG).exists()){ |
|
217 nameIconPair.portraitPreviewIcon = HbIcon(fullPathToIcon + KBackgroundPrtSVG); |
|
218 } else if(QFileInfo(fullPathToIcon + KBackgroundPrtPNG).exists()){ |
|
219 nameIconPair.portraitPreviewIcon = HbIcon(fullPathToIcon + KBackgroundPrtPNG); |
|
220 } else{ |
|
221 nameIconPair.portraitPreviewIcon = HbIcon(KDefaultThemeIcon); |
|
222 } |
|
223 } |
|
224 else { |
|
225 nameIconPair.portraitPreviewIcon = HbIcon(fullPathToIcon + previewPathPrt); |
|
226 } |
|
227 |
|
228 //Landscape preview |
|
229 |
|
230 if(previewPathLsc.isEmpty() || !QFileInfo(fullPathToIcon + previewPathLsc).exists()) { |
|
231 if(QFileInfo(fullPathToIcon + KPreviewLscNVG).exists()){ |
|
232 nameIconPair.landscapePreviewIcon = HbIcon(fullPathToIcon + KPreviewLscNVG); |
|
233 }else if(QFileInfo(fullPathToIcon + KPreviewLscSVG).exists()){ |
|
234 nameIconPair.landscapePreviewIcon = HbIcon(fullPathToIcon + KPreviewLscSVG); |
|
235 }else if(QFileInfo(fullPathToIcon + KBackgroundLscNVG).exists()){ |
|
236 nameIconPair.landscapePreviewIcon = HbIcon(fullPathToIcon + KBackgroundLscNVG); |
|
237 } else if(QFileInfo(fullPathToIcon + KBackgroundLscSVG).exists()){ |
|
238 nameIconPair.landscapePreviewIcon = HbIcon(fullPathToIcon + KBackgroundLscSVG); |
|
239 } else if(QFileInfo(fullPathToIcon + KBackgroundLscPNG).exists()){ |
|
240 nameIconPair.landscapePreviewIcon = HbIcon(fullPathToIcon + KBackgroundLscPNG); |
|
241 } else{ |
|
242 nameIconPair.landscapePreviewIcon = HbIcon(KDefaultThemeIcon); |
|
243 } |
|
244 } |
|
245 else { |
|
246 nameIconPair.landscapePreviewIcon = HbIcon(fullPathToIcon + previewPathLsc); |
|
247 } |
|
248 |
|
249 nameIconPair.name = name; |
|
250 |
|
251 mThemeList.append(nameIconPair); |
|
252 |
|
253 if (name == mCurrentTheme.name) { |
|
254 mCurrentTheme = nameIconPair; |
|
255 } |
|
256 |
|
257 iniSetting.endGroup(); |
|
258 if((hidden == "true") ||( hidden == "")||(name != themefolder) ) { |
|
259 iconthemeslist.removeOne(themefolder); |
|
260 if(!mThemeList.isEmpty()) { |
|
261 mThemeList.removeLast(); |
|
262 } |
|
263 } |
|
264 } else { |
|
265 iconthemeslist.removeOne(themefolder); |
|
266 if(!mThemeList.isEmpty()) { |
|
267 mThemeList.removeLast(); |
|
268 } |
|
269 } |
|
270 } |
|
271 } |
|
272 } |
|
273 |
|
274 if (mCurrentTheme.name == KDefaultTheme) |
|
275 { |
|
276 // Include default |
|
277 CpThemeChanger::ThemeInfo def; |
|
278 def.name = KDefaultTheme; |
|
279 def.icon = HbIcon(KDefaultThemeIcon); |
|
280 mThemeList.append(def); |
|
281 |
|
282 mCurrentTheme = def; |
|
283 } |
|
284 |
|
285 } |
|
286 |
|
287 const QList<CpThemeChanger::ThemeInfo>& CpThemeChangerPrivate::themes() const |
|
288 { |
|
289 return mThemeList; |
|
290 } |
|
291 |
|
292 bool CpThemeChangerPrivate::connectToServer() |
|
293 { |
|
294 return mThemeClient->connectToServer(); |
|
295 } |
|
296 |
|
297 /** |
|
298 * Indicate if the client is connected to the server |
|
299 */ |
|
300 bool CpThemeChangerPrivate::isConnected() const |
|
301 { |
|
302 return mThemeClient->isConnected(); |
|
303 } |
|
304 |
|
305 /** |
|
306 * Change a theme |
|
307 */ |
|
308 bool CpThemeChangerPrivate::changeTheme(const QString& newTheme) |
|
309 { |
|
310 bool result = false; |
|
311 // Skip doing this if the request is for the current theme |
|
312 if (newTheme.isEmpty() || newTheme == mCurrentTheme.name) { |
|
313 return result; |
|
314 } |
|
315 |
|
316 // Make sure it's a valid theme name and set the current theme. |
|
317 bool exists = false; |
|
318 QList<CpThemeChanger::ThemeInfo>::const_iterator i; |
|
319 for (i = mThemeList.constBegin(); i != mThemeList.constEnd(); ++i) { |
|
320 if ( newTheme == i->name) { |
|
321 exists = true; |
|
322 break; |
|
323 } |
|
324 } |
|
325 |
|
326 if (exists) { |
|
327 result = mThemeClient->changeTheme(newTheme); |
|
328 if(result) { |
|
329 mCurrentTheme = *i; |
|
330 } |
|
331 } |
|
332 return result; |
|
333 } |
|
334 |
|
335 void CpThemeChangerPrivate::_q_themeDirectoryChanged(const QString&) |
|
336 { |
|
337 updateThemeList(); |
|
338 } |
|
339 |
|
340 |
|
341 |
|
342 // End of file |
|