28 |
28 |
29 */ |
29 */ |
30 |
30 |
31 #include <QString> |
31 #include <QString> |
32 #include <QModelIndex> |
32 #include <QModelIndex> |
33 #include <QStandardItemModel> |
|
34 #include <QStandardItem> |
|
35 #include <QTranslator> |
33 #include <QTranslator> |
36 #include <QSortFilterProxyModel> |
34 #include <QSortFilterProxyModel> |
37 #include <QDebug> |
|
38 #include <QThread> |
35 #include <QThread> |
|
36 #include <QTimer> |
|
37 #include <QDesktopServices> |
|
38 #include <QUrl> |
39 |
39 |
40 #include <hbmainwindow.h> |
40 #include <hbmainwindow.h> |
41 #include <hbinstance.h> |
41 #include <hbinstance.h> |
42 #include "cpthemechanger.h" |
42 #include "cpthemechanger.h" |
43 |
43 |
44 #include "cpthemecontrol.h" |
44 #include "cpthemecontrol.h" |
45 #include "cpthemelistview.h" |
45 #include "cpthemelistview.h" |
46 #include "cpthemepreview.h" |
46 #include "cpthemepreview.h" |
47 |
47 #include "cpthemeinfo.h" |
48 static const QString KPlaceholderPreview = ":/image/themePreview.svg"; |
48 #include "cpthemelistmodel.h" |
|
49 |
|
50 #include <hbdialog.h> |
|
51 #include <hblabel.h> |
|
52 |
49 |
53 |
50 /*! |
54 /*! |
51 Helper function to fetch the main window. |
55 Helper function to fetch the main window. |
52 */ |
56 */ |
53 |
57 |
65 */ |
69 */ |
66 CpThemeControl::CpThemeControl(): mThemeListView(0), |
70 CpThemeControl::CpThemeControl(): mThemeListView(0), |
67 mThemePreview(0), |
71 mThemePreview(0), |
68 mThemeChanger(0), |
72 mThemeChanger(0), |
69 mListModel(0), |
73 mListModel(0), |
70 mSortModel(0), |
74 mThemeChangeFinished(false), |
71 mIdleTimer(0) |
75 mWaitDialog(0) |
72 { |
76 { |
73 mThemeChanger = new CpThemeChanger(); |
77 mThemeChanger = new CpThemeChanger(); |
74 |
|
75 |
78 |
76 QTranslator *translator = new QTranslator(this); |
79 QTranslator *translator = new QTranslator(this); |
77 QString lang = QLocale::system().name(); |
80 QString lang = QLocale::system().name(); |
78 QString path = "Z:/resource/qt/translations/"; |
81 QString path = "Z:/resource/qt/translations/"; |
79 translator->load("control_panel_" + lang, path); |
82 translator->load("control_panel_" + lang, path); |
80 qApp->installTranslator(translator); |
83 qApp->installTranslator(translator); |
81 |
84 |
82 mIdleTimer = new QTimer(this); |
85 connect(mThemeChanger,SIGNAL(themeChangeFinished()), this, SLOT(themeChangeFinished())); |
83 connect(mIdleTimer, SIGNAL(timeout()), this, SLOT(themeChangeTimeout())); |
|
84 connect(hbInstance->theme(),SIGNAL(changeFinished()), this, SLOT(themeChangeFinished())); |
|
85 |
86 |
86 } |
87 } |
87 |
|
88 |
88 |
89 |
89 |
90 /*! |
90 /*! |
91 destorys the list view, preview and theme changer objects. |
91 destorys the list view, preview and theme changer objects. |
92 */ |
92 */ |
109 void CpThemeControl::createThemeList() |
112 void CpThemeControl::createThemeList() |
110 { |
113 { |
111 |
114 |
112 mThemeListView = new CpThemeListView(); |
115 mThemeListView = new CpThemeListView(); |
113 |
116 |
114 mListModel = &mThemeChanger->model(); |
117 if(!mListModel) { |
115 |
118 mListModel = new CpThemeListModel(this); |
116 mSortModel = new QSortFilterProxyModel(this); |
119 } |
117 mSortModel->setDynamicSortFilter(true); |
120 |
118 mSortModel->setSortCaseSensitivity(Qt::CaseInsensitive); |
|
119 mSortModel->sort(0); |
|
120 mSortModel->setSourceModel(mListModel); |
|
121 |
|
122 // Set the model for theme list. |
121 // Set the model for theme list. |
123 mThemeListView->setModel(mSortModel); |
122 mThemeListView->setModel(mListModel); |
124 mThemeListView->themeList()->setSelectionMode(HbAbstractItemView::SingleSelection); |
123 mThemeListView->themeList()->setSelectionMode(HbAbstractItemView::SingleSelection); |
125 |
124 |
126 setActiveThemeIndex(); |
125 setActiveThemeIndex(); |
127 |
126 |
128 |
127 |
140 the view. |
139 the view. |
141 */ |
140 */ |
142 CpBaseSettingView* CpThemeControl::themeListView() |
141 CpBaseSettingView* CpThemeControl::themeListView() |
143 { |
142 { |
144 //If the view was removed before by control panel app, create it again. |
143 //If the view was removed before by control panel app, create it again. |
145 if(!mThemeListView) |
144 if(!mThemeListView) { |
146 createThemeList(); |
145 createThemeList(); |
|
146 } |
147 |
147 |
148 return mThemeListView; |
148 return mThemeListView; |
149 } |
149 } |
150 |
150 |
151 /*! |
151 /*! |
152 returns the name of the current theme. |
152 returns the name of the current theme. |
153 */ |
153 */ |
154 QString CpThemeControl::currentThemeName() const |
154 QString CpThemeControl::currentThemeName() const |
155 { |
155 { |
156 return mThemeChanger->currentTheme().name; |
156 QString name = ""; |
|
157 if(mThemeChanger->currentTheme()) { |
|
158 name = mThemeChanger->currentTheme()->name(); |
|
159 } |
|
160 return name; |
157 } |
161 } |
158 |
162 |
159 /*! |
163 /*! |
160 returns the repersenatative icon of the current theme. |
164 returns the repersenatative icon of the current theme. |
161 */ |
165 */ |
162 HbIcon CpThemeControl::currentThemeIcon() const |
166 HbIcon CpThemeControl::currentThemeIcon() const |
163 { |
167 { |
164 return mThemeChanger->currentTheme().icon; |
168 HbIcon icon; |
|
169 if(mThemeChanger->currentTheme()) { |
|
170 icon = mThemeChanger->currentTheme()->icon(); |
|
171 } |
|
172 return icon; |
165 } |
173 } |
166 |
174 |
167 /*! |
175 /*! |
168 Slot called when a list item of the theme list is selected. |
176 Slot called when a list item of the theme list is selected. |
169 */ |
177 */ |
170 void CpThemeControl::newThemeSelected(const QModelIndex& index) |
178 void CpThemeControl::newThemeSelected(const QModelIndex& index) |
171 { |
179 { |
172 if(!index.isValid()) { |
180 if(!index.isValid()) { |
173 return; |
181 return; |
174 } |
182 } |
175 |
183 |
176 |
184 CpThemeInfo themeInfo; |
177 CpThemeChanger::ThemeInfo themeInfo; |
|
178 QVariant data; |
185 QVariant data; |
179 |
186 |
180 //reset the current index to active theme, so that the selection remains on current |
187 //reset the current index to active theme, so that the selection remains on current |
181 //theme even though another list item is selected. |
188 //theme even though another list item is selected. |
182 setActiveThemeIndex(); |
189 setActiveThemeIndex(); |
183 |
190 |
|
191 // Figure out whether this is a URI and appropriately delegate |
|
192 data = index.data(CpThemeListModel::ItemTypeRole); |
|
193 if(data.isValid() && data.canConvert<CpThemeInfo::ThemeListItemType>()) { |
|
194 |
|
195 CpThemeInfo::ThemeListItemType type = data.value<CpThemeInfo::ThemeListItemType>(); |
|
196 |
|
197 switch (type) { |
|
198 case CpThemeInfo::ThemeListItemType_URL: |
|
199 //get the URL |
|
200 data = index.data(CpThemeListModel::ItemDataRole); |
|
201 if(data.isValid()) { |
|
202 QString url = data.toString(); |
|
203 // Launch the URL in the browser and |
|
204 // continue to Preview if not successful |
|
205 if (QDesktopServices::openUrl(QUrl(url, QUrl::TolerantMode))) { |
|
206 return; |
|
207 } |
|
208 } |
|
209 break; |
|
210 |
|
211 case CpThemeInfo::ThemeListItemType_APP: |
|
212 break; |
|
213 |
|
214 default: |
|
215 // do nothing |
|
216 qt_noop(); |
|
217 } |
|
218 } |
|
219 |
184 //get the theme name. |
220 //get the theme name. |
185 data = index.data(Qt::DisplayRole); |
221 data = index.data(Qt::DisplayRole); |
186 if(data.isValid()) { |
222 if(data.isValid()) { |
187 themeInfo.name = data.toString(); |
223 themeInfo.setName(data.toString()); |
188 } |
224 } |
|
225 |
189 //get theme icon. |
226 //get theme icon. |
190 data = index.data(Qt::DecorationRole); |
227 data = index.data(Qt::DecorationRole); |
191 if(data.isValid()) { |
228 if(data.isValid()) { |
192 themeInfo.icon = data.value<HbIcon>(); |
229 themeInfo.setIcon(data.value<HbIcon>()); |
193 } |
230 } |
194 |
231 |
195 data = index.data(CpThemeChanger::PortraitPreviewRole); |
232 data = index.data(CpThemeListModel::PortraitPreviewRole); |
196 if(data.isValid()) { |
233 if(data.isValid()) { |
197 themeInfo.portraitPreviewIcon = data.value<HbIcon>(); |
234 themeInfo.setPortraitPreviewIcon(data.value<HbIcon>()); |
198 } |
235 } |
199 |
236 |
200 data = index.data(CpThemeChanger::LandscapePreviewRole); |
237 data = index.data(CpThemeListModel::LandscapePreviewRole); |
201 if(data.isValid()) { |
238 if(data.isValid()) { |
202 themeInfo.landscapePreviewIcon = data.value<HbIcon>(); |
239 themeInfo.setLandscapePreviewIcon(data.value<HbIcon>()); |
203 } |
240 } |
204 |
241 |
205 |
242 //Set up the theme preview and set it to |
206 //Set up the theme preview and set it to |
|
207 //the current view of main window. |
243 //the current view of main window. |
208 HbMainWindow* mWindow = ::mainWindow(); |
244 HbMainWindow* mWindow = ::mainWindow(); |
209 |
245 |
210 if(!mThemePreview){ |
246 if(!mThemePreview){ |
211 mThemePreview = new CpThemePreview(themeInfo); |
247 mThemePreview = new CpThemePreview(themeInfo); |
217 connect(mThemePreview, SIGNAL(applyTheme(const QString&)), |
253 connect(mThemePreview, SIGNAL(applyTheme(const QString&)), |
218 this, SLOT(themeApplied(const QString&))); |
254 this, SLOT(themeApplied(const QString&))); |
219 } else { |
255 } else { |
220 mThemePreview->setThemeInfo(themeInfo); |
256 mThemePreview->setThemeInfo(themeInfo); |
221 } |
257 } |
222 //TODO: use qtTrId(text_id). |
258 mThemePreview->setTitle(hbTrId("txt_cp_title_control_panel")); |
223 mThemePreview->setTitle(tr("Control Panel")); |
259 |
224 |
|
225 mWindow->setCurrentView(mThemePreview); |
260 mWindow->setCurrentView(mThemePreview); |
226 |
261 |
227 } |
262 } |
228 |
263 |
229 /*! |
264 /*! |
230 Slot called when a Select key is pressed in theme preview view. |
265 Slot called when a Select key is pressed in theme preview view. |
231 */ |
266 */ |
232 void CpThemeControl::themeApplied(const QString& theme) |
267 void CpThemeControl::themeApplied(const QString& theme) |
233 { |
268 { |
234 bool success = false; |
269 QThread::currentThread()->setPriority(QThread::HighPriority); |
235 |
270 |
236 success = mThemeChanger->connectToServer(); |
271 if(mThemeChanger->changeTheme(theme)) { |
237 |
272 |
238 if (success) { |
273 //Start a timer. If theme change takes more than 1 seconds, |
239 QThread::currentThread()->setPriority(QThread::HighPriority); |
274 //we will show a dialog (mWaitDialog) until theme change |
240 mThemeChanger->changeTheme(theme); |
275 //is done (themeChangeFinished is called). |
241 emit themeUpdated(mThemeChanger->currentTheme().name, mThemeChanger->currentTheme().icon); |
276 QTimer::singleShot(1000, this, SLOT(themeWaitTimeout())); |
242 } |
277 |
243 |
278 mThemeChangeFinished = false; |
244 //Go back to control panel view. Close theme preview. |
279 } else { |
245 previewClosed(); |
280 //theme change failed, go back to control panel. |
246 //ask the themelistview to close. Control Panel will |
281 previewClosed(); |
247 //take care of removing it from window. |
282 triggerThemeListClose(); |
248 triggerThemeListClose(); |
283 } |
249 |
284 |
250 } |
285 } |
|
286 |
251 /*! |
287 /*! |
252 Slot called when the theme preview view is closed. |
288 Slot called when the theme preview view is closed. |
253 */ |
289 */ |
254 void CpThemeControl::previewClosed() |
290 void CpThemeControl::previewClosed() |
255 { |
291 { |
287 mThemeListView->closeView(); |
323 mThemeListView->closeView(); |
288 } |
324 } |
289 |
325 |
290 void CpThemeControl::themeChangeTimeout() |
326 void CpThemeControl::themeChangeTimeout() |
291 { |
327 { |
292 //qDebug() << "ThemeChangeTimeout " ; |
328 //Theme change is finished and idle timer has timed out, |
293 mIdleTimer->stop(); |
329 //so revert back the application priority to normal |
294 QThread::currentThread()->setPriority(QThread::NormalPriority); |
330 //and go back to control panel view. |
295 |
331 if(mWaitDialog && mWaitDialog->isVisible()) { |
|
332 mWaitDialog->hide(); |
|
333 } |
|
334 |
|
335 previewClosed(); |
|
336 //ask the themelistview to close. Control Panel will |
|
337 //take care of removing it from window. |
|
338 triggerThemeListClose(); |
|
339 |
|
340 QThread::currentThread()->setPriority(QThread::NormalPriority); |
|
341 } |
|
342 |
|
343 void CpThemeControl::themeWaitTimeout() |
|
344 { |
|
345 //If after this timeOut, theme change is still in progress, |
|
346 //show a processing dialog. |
|
347 if(!mThemeChangeFinished) |
|
348 { |
|
349 if(!mWaitDialog) { |
|
350 mWaitDialog = new HbDialog(); |
|
351 mWaitDialog->setDismissPolicy(HbPopup::NoDismiss); |
|
352 mWaitDialog->setModal(false); |
|
353 mWaitDialog->setTimeout(HbPopup::NoTimeout); |
|
354 //TODO: need localized text for Hb Dialog |
|
355 // Create and set HbLabel as content widget. |
|
356 HbLabel *label = new HbLabel("Processing ..."); |
|
357 label->setAlignment(Qt::AlignCenter); |
|
358 mWaitDialog->setContentWidget(label); |
|
359 } |
|
360 // as we do not need any signals, calling show() instead of open() |
|
361 mWaitDialog->show(); |
|
362 } |
296 } |
363 } |
297 |
364 |
298 void CpThemeControl::themeChangeFinished() |
365 void CpThemeControl::themeChangeFinished() |
299 { |
366 { |
300 //qDebug() << "ThemeChangeFinished " ; |
367 //Theme change is done. Start an idle timer to let the UI |
301 mIdleTimer->start(0); |
368 //finish remaining tasks. |
|
369 QTimer::singleShot(0, this, SLOT(themeChangeTimeout())); |
|
370 mThemeChangeFinished = true; |
|
371 |
|
372 if(mThemeChanger->currentTheme()) { |
|
373 emit themeUpdated(mThemeChanger->currentTheme()->name(), mThemeChanger->currentTheme()->icon()); |
|
374 } |
|
375 |
302 } |
376 } |
303 |
377 |
304 /*! |
378 /*! |
305 * Private function that sets the current index of theme list view to indicate |
379 * Private function that sets the current index of theme list view to indicate |
306 * the active theme. |
380 * the active theme. |
307 */ |
381 */ |
308 void CpThemeControl::setActiveThemeIndex() |
382 void CpThemeControl::setActiveThemeIndex() |
309 { |
383 { |
310 //Get the index of current theme. |
384 //Get the index of current theme. |
311 QModelIndex sourceIndex = mListModel->index(mThemeChanger->indexOf(mThemeChanger->currentTheme()),0); |
385 CpThemeListModel* themeListModel = dynamic_cast<CpThemeListModel*>(mListModel); |
312 //Map it to the sort model index. |
386 const CpThemeInfo* currentTheme = mThemeChanger->currentTheme(); |
313 QModelIndex sortedIndex = mSortModel->mapFromSource(sourceIndex); |
387 if(themeListModel && currentTheme) { |
314 //set current index. |
388 QModelIndex sourceIndex = mListModel->index(themeListModel->indexOf(*currentTheme),0); |
315 mThemeListView->themeList()->setCurrentIndex(sortedIndex, QItemSelectionModel::SelectCurrent); |
389 //set current index. |
316 } |
390 mThemeListView->themeList()->setCurrentIndex(sourceIndex, QItemSelectionModel::SelectCurrent); |
317 |
391 } |
318 |
392 } |
319 |
393 |
320 |
394 |
321 |
395 |
322 |
396 |
|
397 |
|
398 |