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