[cstdstring] demise Format, replacing with StringUtils::Format
[vuplus_xbmc] / xbmc / interfaces / legacy / Dialog.cpp
1  /*
2  *      Copyright (C) 2005-2013 Team XBMC
3  *      http://xbmc.org
4  *
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, or (at your option)
8  *  any later version.
9  *
10  *  This Program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with XBMC; see the file COPYING.  If not, see
17  *  <http://www.gnu.org/licenses/>.
18  *
19  */
20 #include "LanguageHook.h"
21
22 #include "dialogs/GUIDialogOK.h"
23 #include "dialogs/GUIDialogYesNo.h"
24 #include "dialogs/GUIDialogSelect.h"
25 #include "guilib/GUIWindowManager.h"
26 #include "dialogs/GUIDialogFileBrowser.h"
27 #include "dialogs/GUIDialogNumeric.h"
28 #include "settings/MediaSourceSettings.h"
29 #include "dialogs/GUIDialogKaiToast.h"
30 #include "ModuleXbmcgui.h"
31 #include "guilib/GUIKeyboardFactory.h"
32 #include "utils/StringUtils.h"
33
34 #define ACTIVE_WINDOW g_windowManager.GetActiveWindow()
35
36 namespace XBMCAddon
37 {
38   namespace xbmcgui
39   {
40     static void XBMCWaitForThreadMessage(int message, int param1, int param2)
41     {
42       ThreadMessage tMsg = {(DWORD)message, (DWORD)param1, (DWORD)param2};
43       CApplicationMessenger::Get().SendMessage(tMsg, true);
44     }
45
46     Dialog::~Dialog() {}
47
48     bool Dialog::yesno(const String& heading, const String& line1, 
49                        const String& line2,
50                        const String& line3,
51                        const String& nolabel,
52                        const String& yeslabel,
53                        int autoclose) throw (WindowException)
54     {
55       DelayedCallGuard dcguard(languageHook);
56       const int window = WINDOW_DIALOG_YES_NO;
57       CGUIDialogYesNo* pDialog = (CGUIDialogYesNo*)g_windowManager.GetWindow(window);
58       if (pDialog == NULL)
59         throw WindowException("Error: Window is NULL, this is not possible :-)");
60
61       // get lines, last 4 lines are optional.
62       if (!heading.empty())
63         pDialog->SetHeading(heading);
64       if (!line1.empty())
65         pDialog->SetLine(0, line1);
66       if (!line2.empty())
67         pDialog->SetLine(1, line2);
68       if (!line3.empty())
69         pDialog->SetLine(2, line3);
70
71       if (!nolabel.empty())
72         pDialog->SetChoice(0,nolabel);
73       if (!yeslabel.empty())
74         pDialog->SetChoice(1,yeslabel);
75
76       if (autoclose > 0)
77         pDialog->SetAutoClose(autoclose);
78
79       //send message and wait for user input
80       XBMCWaitForThreadMessage(TMSG_DIALOG_DOMODAL, window, ACTIVE_WINDOW);
81
82       return pDialog->IsConfirmed();
83     }
84
85     int Dialog::select(const String& heading, const std::vector<String>& list, int autoclose) throw (WindowException)
86     {
87       DelayedCallGuard dcguard(languageHook);
88       const int window = WINDOW_DIALOG_SELECT;
89       CGUIDialogSelect* pDialog= (CGUIDialogSelect*)g_windowManager.GetWindow(window);
90       if (pDialog == NULL)
91         throw WindowException("Error: Window is NULL, this is not possible :-)");
92
93       pDialog->Reset();
94       if (!heading.empty())
95         pDialog->SetHeading(heading);
96
97       String listLine;
98       for(unsigned int i = 0; i < list.size(); i++)
99       {
100         listLine = list[i];
101           pDialog->Add(listLine);
102       }
103       if (autoclose > 0)
104         pDialog->SetAutoClose(autoclose);
105
106       //send message and wait for user input
107       XBMCWaitForThreadMessage(TMSG_DIALOG_DOMODAL, window, ACTIVE_WINDOW);
108
109       return pDialog->GetSelectedLabel();
110     }
111
112     bool Dialog::ok(const String& heading, const String& line1, 
113                     const String& line2,
114                     const String& line3) throw (WindowException)
115     {
116       DelayedCallGuard dcguard(languageHook);
117       const int window = WINDOW_DIALOG_OK;
118
119       CGUIDialogOK* pDialog = (CGUIDialogOK*)g_windowManager.GetWindow(window);
120       if (pDialog == NULL)
121         throw WindowException("Error: Window is NULL, this is not possible :-)");
122
123       if (!heading.empty())
124         pDialog->SetHeading(heading);
125       if (!line1.empty())
126         pDialog->SetLine(0, line1);
127       if (!line2.empty())
128         pDialog->SetLine(1, line2);
129       if (!line3.empty())
130         pDialog->SetLine(2, line3);
131
132       //send message and wait for user input
133       XBMCWaitForThreadMessage(TMSG_DIALOG_DOMODAL, window, ACTIVE_WINDOW);
134
135       return pDialog->IsConfirmed();
136     }
137
138     Alternative<String, std::vector<String> > Dialog::browse(int type, const String& heading, 
139                                 const String& s_shares, const String& maskparam, bool useThumbs, 
140                                 bool useFileDirectories, const String& defaultt,
141                                 bool enableMultiple) throw (WindowException)
142     {
143       Alternative<String, std::vector<String> > ret;
144       if (enableMultiple)
145         ret.later() = browseMultiple(type,heading,s_shares,maskparam,useThumbs,useFileDirectories,defaultt);
146       else
147         ret.former() = browseSingle(type,heading,s_shares,maskparam,useThumbs,useFileDirectories,defaultt);
148       return ret;
149     }
150
151     String Dialog::browseSingle(int type, const String& heading, const String& s_shares,
152                                 const String& maskparam, bool useThumbs, 
153                                 bool useFileDirectories, 
154                                 const String& defaultt ) throw (WindowException)
155     {
156       DelayedCallGuard dcguard(languageHook);
157       CStdString value;
158       std::string mask = maskparam;
159       VECSOURCES *shares = CMediaSourceSettings::Get().GetSources(s_shares);
160       if (!shares) 
161         throw WindowException("Error: GetSources given %s is NULL.",s_shares.c_str());
162
163       if (useFileDirectories && (!maskparam.empty() && !maskparam.size() == 0))
164         mask += "|.rar|.zip";
165
166       value = defaultt;
167       if (type == 1)
168           CGUIDialogFileBrowser::ShowAndGetFile(*shares, mask, heading, value, useThumbs, useFileDirectories);
169       else if (type == 2)
170         CGUIDialogFileBrowser::ShowAndGetImage(*shares, heading, value);
171       else
172         CGUIDialogFileBrowser::ShowAndGetDirectory(*shares, heading, value, type != 0);
173       return value;
174     }
175
176     std::vector<String> Dialog::browseMultiple(int type, const String& heading, const String& s_shares,
177                           const String& mask, bool useThumbs, 
178                           bool useFileDirectories, const String& defaultt ) throw (WindowException)
179     {
180       DelayedCallGuard dcguard(languageHook);
181       VECSOURCES *shares = CMediaSourceSettings::Get().GetSources(s_shares);
182       CStdStringArray tmpret;
183       String lmask = mask;
184       if (!shares) 
185         throw WindowException("Error: GetSources given %s is NULL.",s_shares.c_str());
186
187       if (useFileDirectories && (!lmask.empty() && !(lmask.size() == 0)))
188         lmask += "|.rar|.zip";
189
190       if (type == 1)
191         CGUIDialogFileBrowser::ShowAndGetFileList(*shares, lmask, heading, tmpret, useThumbs, useFileDirectories);
192       else if (type == 2)
193         CGUIDialogFileBrowser::ShowAndGetImageList(*shares, heading, tmpret);
194       else
195         throw WindowException("Error: Cannot retreive multuple directories using browse %s is NULL.",s_shares.c_str());
196
197       std::vector<String> valuelist;
198       int index = 0;
199       for (CStdStringArray::iterator iter = tmpret.begin(); iter != tmpret.end(); ++iter)
200         valuelist[index++] = (*iter);
201
202       return valuelist;
203     }
204
205     String Dialog::numeric(int inputtype, const String& heading, const String& defaultt)
206     {
207       DelayedCallGuard dcguard(languageHook);
208       CStdString value;
209       SYSTEMTIME timedate;
210       GetLocalTime(&timedate);
211
212       if (!heading.empty())
213       {
214         if (inputtype == 1)
215         {
216           if (!defaultt.empty() && defaultt.size() == 10)
217           {
218             CStdString sDefault = defaultt;
219             timedate.wDay = atoi(sDefault.Left(2));
220             timedate.wMonth = atoi(sDefault.Mid(3,4));
221             timedate.wYear = atoi(sDefault.Right(4));
222           }
223           if (CGUIDialogNumeric::ShowAndGetDate(timedate, heading))
224             value = StringUtils::Format("%2d/%2d/%4d", timedate.wDay, timedate.wMonth, timedate.wYear);
225           else
226             return emptyString;
227         }
228         else if (inputtype == 2)
229         {
230           if (!defaultt.empty() && defaultt.size() == 5)
231           {
232             CStdString sDefault = defaultt;
233             timedate.wHour = atoi(sDefault.Left(2));
234             timedate.wMinute = atoi(sDefault.Right(2));
235           }
236           if (CGUIDialogNumeric::ShowAndGetTime(timedate, heading))
237             value = StringUtils::Format("%2d:%02d", timedate.wHour, timedate.wMinute);
238           else
239             return emptyString;
240         }
241         else if (inputtype == 3)
242         {
243           value = defaultt;
244           if (!CGUIDialogNumeric::ShowAndGetIPAddress(value, heading))
245             return emptyString;
246         }
247         else
248         {
249           value = defaultt;
250           if (!CGUIDialogNumeric::ShowAndGetNumber(value, heading))
251             return emptyString;
252         }
253       }
254       return value;
255     }
256
257     void Dialog::notification(const String& heading, const String& message, const String& icon, int time, bool sound)
258     {
259       DelayedCallGuard dcguard(languageHook);
260
261       CStdString strIcon = getNOTIFICATION_INFO();
262       int iTime = TOAST_DISPLAY_TIME;
263
264       if (time > 0)
265         iTime = time;
266       if (!icon.empty())
267         strIcon = icon;
268       
269       if (strIcon.Equals(getNOTIFICATION_INFO()))
270         CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Info, heading, message, iTime, sound);
271       else if (strIcon.Equals(getNOTIFICATION_WARNING()))
272         CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Warning, heading, message, iTime, sound);
273       else if (strIcon.Equals(getNOTIFICATION_ERROR()))
274         CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Error, heading, message, iTime, sound);
275       else
276         CGUIDialogKaiToast::QueueNotification(strIcon, heading, message, iTime, sound);
277     }
278     
279     String Dialog::input(const String& heading, const String& defaultt, int type, int option, int autoclose) throw (WindowException)
280     {
281       DelayedCallGuard dcguard(languageHook);
282       CStdString value(defaultt);
283       SYSTEMTIME timedate;
284       GetLocalTime(&timedate);
285
286       switch (type)
287       {
288         case INPUT_ALPHANUM:
289           {
290             bool bHiddenInput = option & ALPHANUM_HIDE_INPUT;
291             if (!CGUIKeyboardFactory::ShowAndGetInput(value, heading, true, bHiddenInput, autoclose))
292               value = emptyString;
293           }
294           break;
295         case INPUT_NUMERIC:
296           {
297             if (!CGUIDialogNumeric::ShowAndGetNumber(value, heading, autoclose))
298               value = emptyString;
299           }
300           break;
301         case INPUT_DATE:
302           {
303             if (!defaultt.empty() && defaultt.size() == 10)
304             {
305               CStdString sDefault = defaultt;
306               timedate.wDay = atoi(sDefault.Left(2));
307               timedate.wMonth = atoi(sDefault.Mid(3,4));
308               timedate.wYear = atoi(sDefault.Right(4));
309             }
310             if (CGUIDialogNumeric::ShowAndGetDate(timedate, heading))
311               value = StringUtils::Format("%2d/%2d/%4d", timedate.wDay, timedate.wMonth, timedate.wYear);
312             else
313               value = emptyString;
314           }
315           break;
316         case INPUT_TIME:
317           {
318             if (!defaultt.empty() && defaultt.size() == 5)
319             {
320               CStdString sDefault = defaultt;
321               timedate.wHour = atoi(sDefault.Left(2));
322               timedate.wMinute = atoi(sDefault.Right(2));
323             }
324             if (CGUIDialogNumeric::ShowAndGetTime(timedate, heading))
325               value = StringUtils::Format("%2d:%02d", timedate.wHour, timedate.wMinute);
326             else
327               value = emptyString;
328           }
329           break;
330         case INPUT_IPADDRESS:
331           {
332             if (!CGUIDialogNumeric::ShowAndGetIPAddress(value, heading))
333               value = emptyString;
334           }
335           break;
336         case INPUT_PASSWORD:
337           {
338             bool bResult = false;
339
340             if (option & PASSWORD_VERIFY)
341               bResult = CGUIKeyboardFactory::ShowAndVerifyPassword(value, heading, 0, autoclose) == 0 ? true : false;
342             else
343               bResult = CGUIKeyboardFactory::ShowAndVerifyNewPassword(value, heading, true, autoclose);
344
345             if (!bResult)
346               value = emptyString;
347           }
348         default:
349           value = emptyString;
350           break;
351       }
352
353       return value;
354     }
355
356     DialogProgress::~DialogProgress() { XBMC_TRACE; deallocating(); }
357
358     void DialogProgress::deallocating()
359     {
360       XBMC_TRACE;
361
362       if (dlg)
363       {
364         DelayedCallGuard dg;
365         dlg->Close();
366       }
367     }
368
369     void DialogProgress::create(const String& heading, const String& line1, 
370                                 const String& line2,
371                                 const String& line3) throw (WindowException)
372     {
373       DelayedCallGuard dcguard(languageHook);
374       CGUIDialogProgress* pDialog= (CGUIDialogProgress*)g_windowManager.GetWindow(WINDOW_DIALOG_PROGRESS);
375
376       if (pDialog == NULL)
377         throw WindowException("Error: Window is NULL, this is not possible :-)");
378
379       dlg = pDialog;
380
381       pDialog->SetHeading(heading);
382
383       if (!line1.empty())
384         pDialog->SetLine(0, line1);
385       if (!line2.empty())
386         pDialog->SetLine(1, line2);
387       if (!line3.empty())
388         pDialog->SetLine(2, line3);
389
390       pDialog->StartModal();
391     }
392
393     void DialogProgress::update(int percent, const String& line1, 
394                                 const String& line2,
395                                 const String& line3) throw (WindowException)
396     {
397       DelayedCallGuard dcguard(languageHook);
398       CGUIDialogProgress* pDialog= dlg;
399
400       if (pDialog == NULL)
401         throw WindowException("Error: Window is NULL, this is not possible :-)");
402
403       if (percent >= 0 && percent <= 100)
404       {
405         pDialog->SetPercentage(percent);
406         pDialog->ShowProgressBar(true);
407       }
408       else
409       {
410         pDialog->ShowProgressBar(false);
411       }
412
413       if (!line1.empty())
414         pDialog->SetLine(0, line1);
415       if (!line2.empty())
416         pDialog->SetLine(1, line2);
417       if (!line3.empty())
418         pDialog->SetLine(2, line3);
419     }
420
421     void DialogProgress::close()
422     {
423       DelayedCallGuard dcguard(languageHook);
424       dlg->Close();
425     }
426
427     bool DialogProgress::iscanceled()
428     {
429       return dlg->IsCanceled();
430     }
431
432     DialogProgressBG::~DialogProgressBG() { XBMC_TRACE; deallocating(); }
433
434     void DialogProgressBG::deallocating()
435     {
436       XBMC_TRACE;
437
438       if (dlg)
439       {
440         DelayedCallGuard dg;
441         dlg->Close();
442       }
443     }
444
445     void DialogProgressBG::create(const String& heading, const String& message) throw (WindowException)
446     {
447       DelayedCallGuard dcguard(languageHook);
448       CGUIDialogExtendedProgressBar* pDialog = 
449           (CGUIDialogExtendedProgressBar*)g_windowManager.GetWindow(WINDOW_DIALOG_EXT_PROGRESS);
450
451       if (pDialog == NULL)
452         throw WindowException("Error: Window is NULL, this is not possible :-)");
453
454       CGUIDialogProgressBarHandle* pHandle = pDialog->GetHandle(heading);
455
456       dlg = pDialog;
457       handle = pHandle;
458
459       pHandle->SetTitle(heading);
460       if (!message.empty())
461         pHandle->SetText(message);
462     }
463
464     void DialogProgressBG::update(int percent, const String& heading, const String& message) throw (WindowException)
465     {
466       DelayedCallGuard dcguard(languageHook);
467       CGUIDialogExtendedProgressBar* pDialog = dlg;
468       CGUIDialogProgressBarHandle* pHandle = handle;
469
470       if (pDialog == NULL)
471         throw WindowException("Error: Window is NULL, this is not possible :-)");
472
473       if (percent >= 0 && percent <= 100)
474         pHandle->SetPercentage((float)percent);
475       if (!heading.empty())
476         pHandle->SetTitle(heading);
477       if (!message.empty())
478         pHandle->SetText(message);
479     }
480
481     void DialogProgressBG::close()
482     {
483       DelayedCallGuard dcguard(languageHook);
484       handle->MarkFinished();
485     }
486
487     bool DialogProgressBG::isFinished()
488     {
489       return handle->IsFinished();
490     }
491
492   }
493 }