sbPrompter.cpp
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set sw=2 :miv */
3 /*
4  *=BEGIN SONGBIRD GPL
5  *
6  * This file is part of the Songbird web player.
7  *
8  * Copyright(c) 2005-2010 POTI, Inc.
9  * http://www.songbirdnest.com
10  *
11  * This file may be licensed under the terms of of the
12  * GNU General Public License Version 2 (the ``GPL'').
13  *
14  * Software distributed under the License is distributed
15  * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
16  * express or implied. See the GPL for the specific language
17  * governing rights and limitations.
18  *
19  * You should have received a copy of the GPL along with this
20  * program. If not, go to http://www.gnu.org/licenses/gpl.html
21  * or write to the Free Software Foundation, Inc.,
22  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
23  *
24  *=END SONGBIRD GPL
25  */
26 
27 //------------------------------------------------------------------------------
28 //------------------------------------------------------------------------------
29 //
30 // Songbird prompter.
31 //
32 //------------------------------------------------------------------------------
33 //------------------------------------------------------------------------------
34 
40 //------------------------------------------------------------------------------
41 //
42 // Songbird prompter imported services.
43 //
44 //------------------------------------------------------------------------------
45 
46 // Self imports.
47 #include "sbPrompter.h"
48 
49 // Mozilla imports.
50 #include <nsAutoLock.h>
51 #include <nsComponentManagerUtils.h>
52 #include <nsIDOMWindowInternal.h>
53 #include <nsIProxyObjectManager.h>
54 #include <nsPIPromptService.h>
55 #include <nsServiceManagerUtils.h>
56 #include <nsThreadUtils.h>
57 
58 
59 //------------------------------------------------------------------------------
60 //
61 // Songbird prompter defs.
62 //
63 //------------------------------------------------------------------------------
64 
65 #define kPromptURL "chrome://global/content/commonDialog.xul"
66 #define kHTMLPromptURL "chrome://global/content/commonDialog.xul?useHTML"
67 static const char kQuestionIconClass[] = "question-icon";
68 static const char kAlertIconClass[] = "alert-icon";
69 
70 
71 //------------------------------------------------------------------------------
72 //
73 // Songbird prompter nsISupports implementation.
74 //
75 //------------------------------------------------------------------------------
76 
79  nsIPromptService,
81 
82 
83 //------------------------------------------------------------------------------
84 //
85 // Songbird prompter sbIPrompter implementation.
86 //
87 //------------------------------------------------------------------------------
88 
89 
105 NS_IMETHODIMP
106 sbPrompter::OpenDialog(nsIDOMWindow* aParent,
107  const nsAString& aUrl,
108  const nsAString& aName,
109  const nsAString& aOptions,
110  nsISupports* aExtraArgument,
111  nsIDOMWindow** _retval)
112 {
113  nsresult rv;
114 
115  // If not on main thread, proxy to it.
116  if (!NS_IsMainThread()) {
117  // Get a main thread proxy.
118  nsCOMPtr<sbIPrompter> prompter;
119  rv = GetProxiedPrompter(getter_AddRefs(prompter));
120  NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
121 
122  // Call proxied prompter until a window is available.
123  while (1) {
124  // Call the proxied prompter.
125  rv = prompter->OpenDialog(aParent,
126  aUrl,
127  aName,
128  aOptions,
129  aExtraArgument,
130  _retval);
131  if (rv != NS_ERROR_NOT_AVAILABLE)
132  NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
133  if (NS_SUCCEEDED(rv))
134  break;
135 
136  // Wait for a window to be available.
137  rv = mSBWindowWatcher->WaitForWindow(mParentWindowType);
138  NS_ENSURE_SUCCESS(rv, rv);
139  }
140 
141  return NS_OK;
142  }
143 
144  // Get the parent window.
145  nsCOMPtr<nsIDOMWindow> parent = aParent;
146  if (!parent) {
147  rv = GetParent(getter_AddRefs(parent));
148  NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
149  }
150 
151  // If configured to wait for the desired window and the window is not
152  // available, return a not available error indication.
153  if (mWaitForWindow && !mParentWindowType.IsEmpty() && !parent)
154  return NS_ERROR_NOT_AVAILABLE;
155 
156  // Set up dialog options. Add the same options that nsIPromptService uses.
157  nsAutoString options(aOptions);
158  if (!options.IsEmpty())
159  options.AppendLiteral(",");
160  options.AppendLiteral("centerscreen,chrome,modal,titlebar");
161 
162  // Open the dialog.
163  rv = mWindowWatcher->OpenWindow(parent,
164  NS_ConvertUTF16toUTF8(aUrl).get(),
165  NS_ConvertUTF16toUTF8(aName).get(),
166  NS_ConvertUTF16toUTF8(options).get(),
167  aExtraArgument,
168  _retval);
169  NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
170 
171  return NS_OK;
172 }
173 
174 
189 NS_IMETHODIMP
190 sbPrompter::OpenWindow(nsIDOMWindow* aParent,
191  const nsAString& aUrl,
192  const nsAString& aName,
193  const nsAString& aOptions,
194  nsISupports* aExtraArgument,
195  nsIDOMWindow** _retval)
196 {
197  nsresult rv;
198 
199  // If not on main thread, proxy to it.
200  if (!NS_IsMainThread()) {
201  // Get a main thread proxy.
202  nsCOMPtr<sbIPrompter> prompter;
203  rv = GetProxiedPrompter(getter_AddRefs(prompter));
204  NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
205 
206  // Call proxied prompter until a window is available.
207  while (1) {
208  // Call the proxied prompter.
209  rv = prompter->OpenWindow(aParent,
210  aUrl,
211  aName,
212  aOptions,
213  aExtraArgument,
214  _retval);
215  if (rv != NS_ERROR_NOT_AVAILABLE)
216  NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
217  if (NS_SUCCEEDED(rv))
218  break;
219 
220  // Wait for a window to be available.
221  rv = mSBWindowWatcher->WaitForWindow(mParentWindowType);
222  NS_ENSURE_SUCCESS(rv, rv);
223  }
224 
225  return NS_OK;
226  }
227 
228  // Get the parent window.
229  nsCOMPtr<nsIDOMWindow> parent = aParent;
230  if (!parent) {
231  rv = GetParent(getter_AddRefs(parent));
232  NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
233  }
234 
235  // If configured to wait for the desired window and the window is not
236  // available, return a not available error indication.
237  if (mWaitForWindow && !mParentWindowType.IsEmpty() && !parent)
238  return NS_ERROR_NOT_AVAILABLE;
239 
240  // Open the dialog.
241  rv = mWindowWatcher->OpenWindow(parent,
242  NS_ConvertUTF16toUTF8(aUrl).get(),
243  NS_ConvertUTF16toUTF8(aName).get(),
244  NS_ConvertUTF16toUTF8(aOptions).get(),
245  aExtraArgument,
246  _retval);
247  NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
248 
249  return NS_OK;
250 }
251 
252 
257 NS_IMETHODIMP
258 sbPrompter::Cancel()
259 {
260  nsresult rv;
261 
262  // If not on main thread, proxy to it.
263  if (!NS_IsMainThread()) {
264  // Get a main thread proxy.
265  nsCOMPtr<sbIPrompter> prompter;
266  rv = GetProxiedPrompter(getter_AddRefs(prompter));
267  NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
268 
269  // Call proxied prompter.
270  rv = prompter->Cancel();
271  NS_ENSURE_SUCCESS(rv, rv);
272 
273  return NS_OK;
274  }
275 
276  // If there's a current prompter window, close it.
277  if (mCurrentWindow) {
278  nsCOMPtr<nsIDOMWindowInternal>
279  window = do_QueryInterface(mCurrentWindow, &rv);
280  NS_ENSURE_SUCCESS(rv, rv);
281  rv = window->Close();
282  NS_ENSURE_SUCCESS(rv, rv);
283  mCurrentWindow = nsnull;
284  }
285 
286  return NS_OK;
287 }
288 
289 
290 //
291 // Getters/setters.
292 //
293 
298 NS_IMETHODIMP
299 sbPrompter::GetParentWindowType(nsAString& aParentWindowType)
300 {
301  nsAutoLock autoLock(mPrompterLock);
302  aParentWindowType.Assign(mParentWindowType);
303  return NS_OK;
304 }
305 
306 NS_IMETHODIMP
307 sbPrompter::SetParentWindowType(const nsAString& aParentWindowType)
308 {
309  nsAutoLock autoLock(mPrompterLock);
310  mParentWindowType.Assign(aParentWindowType);
311  return NS_OK;
312 }
313 
314 
320 NS_IMETHODIMP
321 sbPrompter::GetWaitForWindow(PRBool* aWaitForWindow)
322 {
323  NS_ENSURE_ARG_POINTER(aWaitForWindow);
324  nsAutoLock autoLock(mPrompterLock);
325  *aWaitForWindow = mWaitForWindow;
326  return NS_OK;
327 }
328 
329 NS_IMETHODIMP
330 sbPrompter::SetWaitForWindow(PRBool aWaitForWindow)
331 {
332  nsAutoLock autoLock(mPrompterLock);
333  mWaitForWindow = aWaitForWindow;
334  return NS_OK;
335 }
336 
337 
342 NS_IMETHODIMP
343 sbPrompter::GetRenderHTML(PRBool* aRenderHTML)
344 {
345  NS_ENSURE_ARG_POINTER(aRenderHTML);
346  nsAutoLock autoLock(mPrompterLock);
347  *aRenderHTML = mRenderHTML;
348  return NS_OK;
349 }
350 
351 NS_IMETHODIMP
352 sbPrompter::SetRenderHTML(PRBool aRenderHTML)
353 {
354  nsAutoLock autoLock(mPrompterLock);
355  mRenderHTML = aRenderHTML;
356  return NS_OK;
357 }
358 
359 
360 //------------------------------------------------------------------------------
361 //
362 // Songbird prompter nsIPromptService implementation.
363 //
364 //------------------------------------------------------------------------------
365 
373 NS_IMETHODIMP
374 sbPrompter::Alert(nsIDOMWindow* aParent,
375  const PRUnichar* aDialogTitle,
376  const PRUnichar* aText)
377 {
378  nsresult rv;
379 
380  // If not on main thread, proxy to it.
381  if (!NS_IsMainThread()) {
382  // Get a main thread proxy.
383  nsCOMPtr<sbIPrompter> prompter;
384  rv = GetProxiedPrompter(getter_AddRefs(prompter));
385  NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
386 
387  // Call proxied prompter until a window is available.
388  while (1) {
389  // Call the proxied prompter.
390  rv = prompter->Alert(aParent, aDialogTitle, aText);
391  if (rv != NS_ERROR_NOT_AVAILABLE)
392  NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
393  if (NS_SUCCEEDED(rv))
394  break;
395 
396  // Wait for a window to be available.
397  rv = mSBWindowWatcher->WaitForWindow(mParentWindowType);
398  NS_ENSURE_SUCCESS(rv, rv);
399  }
400 
401  return NS_OK;
402  }
403 
404  // Get the parent window.
405  nsCOMPtr<nsIDOMWindow> parent = aParent;
406  if (!parent) {
407  rv = GetParent(getter_AddRefs(parent));
408  NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
409  }
410 
411  // If configured to wait for the desired window and the window is not
412  // available, return a not available error indication.
413  if (mWaitForWindow && !mParentWindowType.IsEmpty() && !parent)
414  return NS_ERROR_NOT_AVAILABLE;
415 
416  // Set up the dialog parameter block.
417  nsCOMPtr<nsIDialogParamBlock>
418  paramBlock = do_CreateInstance(NS_DIALOGPARAMBLOCK_CONTRACTID, &rv);
419  NS_ENSURE_SUCCESS(rv, rv);
420  rv = paramBlock->SetInt(nsPIPromptService::eNumberButtons, 1);
421  NS_ENSURE_SUCCESS(rv, rv);
422  rv = paramBlock->SetString(nsPIPromptService::eMsg, aText);
423  NS_ENSURE_SUCCESS(rv, rv);
424  rv = paramBlock->SetString(nsPIPromptService::eDialogTitle, aDialogTitle);
425  NS_ENSURE_SUCCESS(rv, rv);
426  rv = paramBlock->SetString(nsPIPromptService::eIconClass,
427  NS_ConvertASCIItoUTF16(kAlertIconClass).get());
428  NS_ENSURE_SUCCESS(rv, rv);
429 
430  // Present the dialog.
431  rv = PresentPrompterDialog(parent, paramBlock);
432  NS_ENSURE_SUCCESS(rv, rv);
433 
434  return NS_OK;
435 }
436 
437 
445 NS_IMETHODIMP
446 sbPrompter::AlertCheck(nsIDOMWindow* aParent,
447  const PRUnichar* aDialogTitle,
448  const PRUnichar* aText,
449  const PRUnichar* aCheckMsg,
450  PRBool* aCheckState)
451 {
452  nsresult rv;
453 
454  // Validate arguments.
455  NS_ENSURE_ARG_POINTER(aCheckState);
456 
457  // If not on main thread, proxy to it.
458  if (!NS_IsMainThread()) {
459  // Get a main thread proxy.
460  nsCOMPtr<sbIPrompter> prompter;
461  rv = GetProxiedPrompter(getter_AddRefs(prompter));
462  NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
463 
464  // Call proxied prompter until a window is available.
465  while (1) {
466  // Call the proxied prompter.
467  rv = prompter->AlertCheck(aParent,
468  aDialogTitle,
469  aText,
470  aCheckMsg,
471  aCheckState);
472  if (rv != NS_ERROR_NOT_AVAILABLE)
473  NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
474  if (NS_SUCCEEDED(rv))
475  break;
476 
477  // Wait for a window to be available.
478  rv = mSBWindowWatcher->WaitForWindow(mParentWindowType);
479  NS_ENSURE_SUCCESS(rv, rv);
480  }
481 
482  return NS_OK;
483  }
484 
485  // Get the parent window.
486  nsCOMPtr<nsIDOMWindow> parent = aParent;
487  if (!parent) {
488  rv = GetParent(getter_AddRefs(parent));
489  NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
490  }
491 
492  // If configured to wait for the desired window and the window is not
493  // available, return a not available error indication.
494  if (mWaitForWindow && !mParentWindowType.IsEmpty() && !parent)
495  return NS_ERROR_NOT_AVAILABLE;
496 
497  // Set up the dialog parameter block.
498  nsCOMPtr<nsIDialogParamBlock>
499  paramBlock = do_CreateInstance(NS_DIALOGPARAMBLOCK_CONTRACTID, &rv);
500  NS_ENSURE_SUCCESS(rv, rv);
501  rv = paramBlock->SetInt(nsPIPromptService::eNumberButtons, 1);
502  NS_ENSURE_SUCCESS(rv, rv);
503  rv = paramBlock->SetString(nsPIPromptService::eMsg, aText);
504  NS_ENSURE_SUCCESS(rv, rv);
505  rv = paramBlock->SetString(nsPIPromptService::eDialogTitle, aDialogTitle);
506  NS_ENSURE_SUCCESS(rv, rv);
507  rv = paramBlock->SetString(nsPIPromptService::eCheckboxMsg, aCheckMsg);
508  NS_ENSURE_SUCCESS(rv, rv);
509  rv = paramBlock->SetString(nsPIPromptService::eIconClass,
510  NS_ConvertASCIItoUTF16(kAlertIconClass).get());
511  NS_ENSURE_SUCCESS(rv, rv);
512 
513  // Present the dialog.
514  rv = PresentPrompterDialog(parent, paramBlock);
515  NS_ENSURE_SUCCESS(rv, rv);
516 
517  // Get the results.
518  PRInt32 checkState;
519  rv = paramBlock->GetInt(nsPIPromptService::eCheckboxState, &checkState);
520  NS_ENSURE_SUCCESS(rv, rv);
521  *aCheckState = checkState ? PR_TRUE : PR_FALSE;
522 
523  return NS_OK;
524 }
525 
526 
534 NS_IMETHODIMP
535 sbPrompter::Confirm(nsIDOMWindow* aParent,
536  const PRUnichar* aDialogTitle,
537  const PRUnichar* aText,
538  PRBool* _retval)
539 {
540  nsresult rv;
541 
542  // Validate arguments.
543  NS_ENSURE_ARG_POINTER(_retval);
544 
545  // If not on main thread, proxy to it.
546  if (!NS_IsMainThread()) {
547  // Get a main thread proxy.
548  nsCOMPtr<sbIPrompter> prompter;
549  rv = GetProxiedPrompter(getter_AddRefs(prompter));
550  NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
551 
552  // Call proxied prompter until a window is available.
553  while (1) {
554  // Call the proxied prompter.
555  rv = prompter->Confirm(aParent, aDialogTitle, aText, _retval);
556  if (rv != NS_ERROR_NOT_AVAILABLE)
557  NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
558  if (NS_SUCCEEDED(rv))
559  break;
560 
561  // Wait for a window to be available.
562  rv = mSBWindowWatcher->WaitForWindow(mParentWindowType);
563  NS_ENSURE_SUCCESS(rv, rv);
564  }
565 
566  return NS_OK;
567  }
568 
569  // Get the parent window.
570  nsCOMPtr<nsIDOMWindow> parent = aParent;
571  if (!parent) {
572  rv = GetParent(getter_AddRefs(parent));
573  NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
574  }
575 
576  // If configured to wait for the desired window and the window is not
577  // available, return a not available error indication.
578  if (mWaitForWindow && !mParentWindowType.IsEmpty() && !parent)
579  return NS_ERROR_NOT_AVAILABLE;
580 
581  // Set up the dialog parameter block.
582  nsCOMPtr<nsIDialogParamBlock>
583  paramBlock = do_CreateInstance(NS_DIALOGPARAMBLOCK_CONTRACTID, &rv);
584  NS_ENSURE_SUCCESS(rv, rv);
585  rv = paramBlock->SetInt(nsPIPromptService::eNumberButtons, 2);
586  NS_ENSURE_SUCCESS(rv, rv);
587  rv = paramBlock->SetString(nsPIPromptService::eMsg, aText);
588  NS_ENSURE_SUCCESS(rv, rv);
589  rv = paramBlock->SetString(nsPIPromptService::eDialogTitle, aDialogTitle);
590  NS_ENSURE_SUCCESS(rv, rv);
591  rv = paramBlock->SetString(nsPIPromptService::eIconClass,
592  NS_ConvertASCIItoUTF16(kQuestionIconClass).get());
593  NS_ENSURE_SUCCESS(rv, rv);
594 
595  // Present the dialog.
596  rv = PresentPrompterDialog(parent, paramBlock);
597  NS_ENSURE_SUCCESS(rv, rv);
598 
599  // Get the results.
600  PRInt32 buttonPressed = 0;
601  rv = paramBlock->GetInt(nsPIPromptService::eButtonPressed, &buttonPressed);
602  NS_ENSURE_SUCCESS(rv, rv);
603  *_retval = buttonPressed ? PR_FALSE : PR_TRUE;
604 
605  return NS_OK;
606 }
607 
608 
616 NS_IMETHODIMP
617 sbPrompter::ConfirmCheck(nsIDOMWindow* aParent,
618  const PRUnichar* aDialogTitle,
619  const PRUnichar* aText,
620  const PRUnichar* aCheckMsg,
621  PRBool* aCheckState,
622  PRBool* _retval)
623 {
624  nsresult rv;
625 
626  // Validate arguments.
627  NS_ENSURE_ARG_POINTER(aCheckState);
628  NS_ENSURE_ARG_POINTER(_retval);
629 
630  // If not on main thread, proxy to it.
631  if (!NS_IsMainThread()) {
632  // Get a main thread proxy.
633  nsCOMPtr<sbIPrompter> prompter;
634  rv = GetProxiedPrompter(getter_AddRefs(prompter));
635  NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
636 
637  // Call proxied prompter until a window is available.
638  while (1) {
639  // Call the proxied prompter.
640  rv = prompter->ConfirmCheck(aParent,
641  aDialogTitle,
642  aText,
643  aCheckMsg,
644  aCheckState,
645  _retval);
646  if (rv != NS_ERROR_NOT_AVAILABLE)
647  NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
648  if (NS_SUCCEEDED(rv))
649  break;
650 
651  // Wait for a window to be available.
652  rv = mSBWindowWatcher->WaitForWindow(mParentWindowType);
653  NS_ENSURE_SUCCESS(rv, rv);
654  }
655 
656  return NS_OK;
657  }
658 
659  // Get the parent window.
660  nsCOMPtr<nsIDOMWindow> parent = aParent;
661  if (!parent) {
662  rv = GetParent(getter_AddRefs(parent));
663  NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
664  }
665 
666  // If configured to wait for the desired window and the window is not
667  // available, return a not available error indication.
668  if (mWaitForWindow && !mParentWindowType.IsEmpty() && !parent)
669  return NS_ERROR_NOT_AVAILABLE;
670 
671  // Set up the dialog parameter block.
672  nsCOMPtr<nsIDialogParamBlock>
673  paramBlock = do_CreateInstance(NS_DIALOGPARAMBLOCK_CONTRACTID, &rv);
674  NS_ENSURE_SUCCESS(rv, rv);
675  rv = paramBlock->SetInt(nsPIPromptService::eNumberButtons, 2);
676  NS_ENSURE_SUCCESS(rv, rv);
677  rv = paramBlock->SetString(nsPIPromptService::eMsg, aText);
678  NS_ENSURE_SUCCESS(rv, rv);
679  rv = paramBlock->SetString(nsPIPromptService::eDialogTitle, aDialogTitle);
680  NS_ENSURE_SUCCESS(rv, rv);
681  rv = paramBlock->SetString(nsPIPromptService::eCheckboxMsg, aCheckMsg);
682  NS_ENSURE_SUCCESS(rv, rv);
683  rv = paramBlock->SetString(nsPIPromptService::eIconClass,
684  NS_ConvertASCIItoUTF16(kQuestionIconClass).get());
685  NS_ENSURE_SUCCESS(rv, rv);
686 
687  // Present the dialog.
688  rv = PresentPrompterDialog(parent, paramBlock);
689  NS_ENSURE_SUCCESS(rv, rv);
690 
691  // Get the button pressed results.
692  PRInt32 buttonPressed = 0;
693  rv = paramBlock->GetInt(nsPIPromptService::eButtonPressed, &buttonPressed);
694  NS_ENSURE_SUCCESS(rv, rv);
695  *_retval = buttonPressed ? PR_FALSE : PR_TRUE;
696 
697  // Get the check state results.
698  PRInt32 checkState;
699  rv = paramBlock->GetInt(nsPIPromptService::eCheckboxState, &checkState);
700  NS_ENSURE_SUCCESS(rv, rv);
701  *aCheckState = checkState ? PR_TRUE : PR_FALSE;
702 
703  return NS_OK;
704 }
705 
706 
715 NS_IMETHODIMP
716 sbPrompter::ConfirmEx(nsIDOMWindow* aParent,
717  const PRUnichar* aDialogTitle,
718  const PRUnichar* aText,
719  PRUint32 aButtonFlags,
720  const PRUnichar* aButton0Title,
721  const PRUnichar* aButton1Title,
722  const PRUnichar* aButton2Title,
723  const PRUnichar* aCheckMsg,
724  PRBool* aCheckState,
725  PRInt32* _retval)
726 {
727  nsresult rv;
728 
729  // If not on main thread, proxy to it.
730  if (!NS_IsMainThread()) {
731  // Get a main thread proxy.
732  nsCOMPtr<sbIPrompter> prompter;
733  rv = GetProxiedPrompter(getter_AddRefs(prompter));
734  NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
735 
736  // Call proxied prompter until a window is available.
737  while (1) {
738  // Call the proxied prompter.
739  rv = prompter->ConfirmEx(aParent,
740  aDialogTitle,
741  aText,
742  aButtonFlags,
743  aButton0Title,
744  aButton1Title,
745  aButton2Title,
746  aCheckMsg,
747  aCheckState,
748  _retval);
749  if (rv != NS_ERROR_NOT_AVAILABLE)
750  NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
751  if (NS_SUCCEEDED(rv))
752  break;
753 
754  // Wait for a window to be available.
755  rv = mSBWindowWatcher->WaitForWindow(mParentWindowType);
756  NS_ENSURE_SUCCESS(rv, rv);
757  }
758 
759  return NS_OK;
760  }
761 
762  // Get the parent window.
763  nsCOMPtr<nsIDOMWindow> parent = aParent;
764  if (!parent) {
765  rv = GetParent(getter_AddRefs(parent));
766  NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
767  }
768 
769  // If configured to wait for the desired window and the window is not
770  // available, return a not available error indication.
771  if (mWaitForWindow && !mParentWindowType.IsEmpty() && !parent)
772  return NS_ERROR_NOT_AVAILABLE;
773 
774  // Forward method call.
775  rv = mPromptService->ConfirmEx(parent,
776  aDialogTitle,
777  aText,
778  aButtonFlags,
779  aButton0Title,
780  aButton1Title,
781  aButton2Title,
782  aCheckMsg,
783  aCheckState,
784  _retval);
785  NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
786 
787  return NS_OK;
788 }
789 
790 
799 NS_IMETHODIMP
800 sbPrompter::Prompt(nsIDOMWindow* aParent,
801  const PRUnichar* aDialogTitle,
802  const PRUnichar* aText,
803  PRUnichar** aValue,
804  const PRUnichar* aCheckMsg,
805  PRBool* aCheckState,
806  PRBool* _retval)
807 {
808  nsresult rv;
809 
810  // If not on main thread, proxy to it.
811  if (!NS_IsMainThread()) {
812  // Get a main thread proxy.
813  nsCOMPtr<sbIPrompter> prompter;
814  rv = GetProxiedPrompter(getter_AddRefs(prompter));
815  NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
816 
817  // Call proxied prompter until a window is available.
818  while (1) {
819  // Call the proxied prompter.
820  rv = prompter->Prompt(aParent,
821  aDialogTitle,
822  aText,
823  aValue,
824  aCheckMsg,
825  aCheckState,
826  _retval);
827  if (rv != NS_ERROR_NOT_AVAILABLE)
828  NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
829  if (NS_SUCCEEDED(rv))
830  break;
831 
832  // Wait for a window to be available.
833  rv = mSBWindowWatcher->WaitForWindow(mParentWindowType);
834  NS_ENSURE_SUCCESS(rv, rv);
835  }
836 
837  return NS_OK;
838  }
839 
840  // Get the parent window.
841  nsCOMPtr<nsIDOMWindow> parent = aParent;
842  if (!parent) {
843  rv = GetParent(getter_AddRefs(parent));
844  NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
845  }
846 
847  // If configured to wait for the desired window and the window is not
848  // available, return a not available error indication.
849  if (mWaitForWindow && !mParentWindowType.IsEmpty() && !parent)
850  return NS_ERROR_NOT_AVAILABLE;
851 
852  // Forward method call.
853  rv = mPromptService->Prompt(parent,
854  aDialogTitle,
855  aText,
856  aValue,
857  aCheckMsg,
858  aCheckState,
859  _retval);
860  NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
861 
862  return NS_OK;
863 }
864 
865 
874 NS_IMETHODIMP
875 sbPrompter::PromptUsernameAndPassword(nsIDOMWindow* aParent,
876  const PRUnichar* aDialogTitle,
877  const PRUnichar* aText,
878  PRUnichar** aUsername,
879  PRUnichar** aPassword,
880  const PRUnichar* aCheckMsg,
881  PRBool* aCheckState,
882  PRBool* _retval)
883 {
884  nsresult rv;
885 
886  // If not on main thread, proxy to it.
887  if (!NS_IsMainThread()) {
888  // Get a main thread proxy.
889  nsCOMPtr<sbIPrompter> prompter;
890  rv = GetProxiedPrompter(getter_AddRefs(prompter));
891  NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
892 
893  // Call proxied prompter until a window is available.
894  while (1) {
895  // Call the proxied prompter.
896  rv = prompter->PromptUsernameAndPassword(aParent,
897  aDialogTitle,
898  aText,
899  aUsername,
900  aPassword,
901  aCheckMsg,
902  aCheckState,
903  _retval);
904  if (rv != NS_ERROR_NOT_AVAILABLE)
905  NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
906  if (NS_SUCCEEDED(rv))
907  break;
908 
909  // Wait for a window to be available.
910  rv = mSBWindowWatcher->WaitForWindow(mParentWindowType);
911  NS_ENSURE_SUCCESS(rv, rv);
912  }
913 
914  return NS_OK;
915  }
916 
917  // Get the parent window.
918  nsCOMPtr<nsIDOMWindow> parent = aParent;
919  if (!parent) {
920  rv = GetParent(getter_AddRefs(parent));
921  NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
922  }
923 
924  // If configured to wait for the desired window and the window is not
925  // available, return a not available error indication.
926  if (mWaitForWindow && !mParentWindowType.IsEmpty() && !parent)
927  return NS_ERROR_NOT_AVAILABLE;
928 
929  // Forward method call.
930  rv = mPromptService->PromptUsernameAndPassword(parent,
931  aDialogTitle,
932  aText,
933  aUsername,
934  aPassword,
935  aCheckMsg,
936  aCheckState,
937  _retval);
938  NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
939 
940  return NS_OK;
941 }
942 
943 
952 NS_IMETHODIMP
953 sbPrompter::PromptPassword(nsIDOMWindow* aParent,
954  const PRUnichar* aDialogTitle,
955  const PRUnichar* aText,
956  PRUnichar** aPassword,
957  const PRUnichar* aCheckMsg,
958  PRBool* aCheckState,
959  PRBool* _retval)
960 {
961  nsresult rv;
962 
963  // If not on main thread, proxy to it.
964  if (!NS_IsMainThread()) {
965  // Get a main thread proxy.
966  nsCOMPtr<sbIPrompter> prompter;
967  rv = GetProxiedPrompter(getter_AddRefs(prompter));
968  NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
969 
970  // Call proxied prompter until a window is available.
971  while (1) {
972  // Call the proxied prompter.
973  rv = prompter->PromptPassword(aParent,
974  aDialogTitle,
975  aText,
976  aPassword,
977  aCheckMsg,
978  aCheckState,
979  _retval);
980  if (rv != NS_ERROR_NOT_AVAILABLE)
981  NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
982  if (NS_SUCCEEDED(rv))
983  break;
984 
985  // Wait for a window to be available.
986  rv = mSBWindowWatcher->WaitForWindow(mParentWindowType);
987  NS_ENSURE_SUCCESS(rv, rv);
988  }
989 
990  return NS_OK;
991  }
992 
993  // Get the parent window.
994  nsCOMPtr<nsIDOMWindow> parent = aParent;
995  if (!parent) {
996  rv = GetParent(getter_AddRefs(parent));
997  NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
998  }
999 
1000  // If configured to wait for the desired window and the window is not
1001  // available, return a not available error indication.
1002  if (mWaitForWindow && !mParentWindowType.IsEmpty() && !parent)
1003  return NS_ERROR_NOT_AVAILABLE;
1004 
1005  // Forward method call.
1006  rv = mPromptService->PromptPassword(parent,
1007  aDialogTitle,
1008  aText,
1009  aPassword,
1010  aCheckMsg,
1011  aCheckState,
1012  _retval);
1013  NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
1014 
1015  return NS_OK;
1016 }
1017 
1018 
1027 NS_IMETHODIMP
1029  const PRUnichar* aDialogTitle,
1030  const PRUnichar* aText,
1031  PRUint32 aCount,
1032  const PRUnichar** aSelectList,
1033  PRInt32* aOutSelection,
1034  PRBool* _retval)
1035 {
1036  nsresult rv;
1037 
1038  // If not on main thread, proxy to it.
1039  if (!NS_IsMainThread()) {
1040  // Get a main thread proxy.
1041  nsCOMPtr<sbIPrompter> prompter;
1042  rv = GetProxiedPrompter(getter_AddRefs(prompter));
1043  NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
1044 
1045  // Call proxied prompter until a window is available.
1046  while (1) {
1047  // Call the proxied prompter.
1048  rv = prompter->Select(aParent,
1049  aDialogTitle,
1050  aText,
1051  aCount,
1052  aSelectList,
1053  aOutSelection,
1054  _retval);
1055  if (rv != NS_ERROR_NOT_AVAILABLE)
1056  NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
1057  if (NS_SUCCEEDED(rv))
1058  break;
1059 
1060  // Wait for a window to be available.
1061  rv = mSBWindowWatcher->WaitForWindow(mParentWindowType);
1062  NS_ENSURE_SUCCESS(rv, rv);
1063  }
1064 
1065  return NS_OK;
1066  }
1067 
1068  // Get the parent window.
1069  nsCOMPtr<nsIDOMWindow> parent = aParent;
1070  if (!parent) {
1071  rv = GetParent(getter_AddRefs(parent));
1072  NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
1073  }
1074 
1075  // If configured to wait for the desired window and the window is not
1076  // available, return a not available error indication.
1077  if (mWaitForWindow && !mParentWindowType.IsEmpty() && !parent)
1078  return NS_ERROR_NOT_AVAILABLE;
1079 
1080  // Forward method call.
1081  rv = mPromptService->Select(parent,
1082  aDialogTitle,
1083  aText,
1084  aCount,
1085  aSelectList,
1086  aOutSelection,
1087  _retval);
1088  NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
1089 
1090  return NS_OK;
1091 }
1092 
1093 
1094 //------------------------------------------------------------------------------
1095 //
1096 // Songbird prompter nsIObserver implementation.
1097 //
1098 //------------------------------------------------------------------------------
1099 
1118 NS_IMETHODIMP
1119 sbPrompter::Observe(nsISupports* aSubject,
1120  const char* aTopic,
1121  const PRUnichar* aData)
1122 {
1123  nsresult rv;
1124 
1125  // Dispatch processing of the event.
1126  if (!strcmp(aTopic, "sbPrompter::InitOnMainThread")) {
1127  rv = InitOnMainThread();
1128  NS_ENSURE_SUCCESS(rv, rv);
1129  }
1130 
1131  return NS_OK;
1132 }
1133 
1134 
1135 //------------------------------------------------------------------------------
1136 //
1137 // Songbird prompter services.
1138 //
1139 //------------------------------------------------------------------------------
1140 
1146  mRenderHTML(PR_FALSE)
1147 {
1148 }
1149 
1150 
1156 {
1157  // Dispose of prompter lock.
1158  if (mPrompterLock)
1159  nsAutoLock::DestroyLock(mPrompterLock);
1160  mPrompterLock = nsnull;
1161 }
1162 
1163 
1168 nsresult
1170 {
1171  nsresult rv;
1172 
1173  // Create a lock for the prompter.
1174  mPrompterLock = nsAutoLock::NewLock("sbPrompter::mPrompterLock");
1175  NS_ENSURE_TRUE(mPrompterLock, NS_ERROR_OUT_OF_MEMORY);
1176 
1177  // Set defaults.
1178  {
1179  nsAutoLock autoLock(mPrompterLock);
1180  mWaitForWindow = PR_FALSE;
1181  }
1182 
1183  // Perform initialization on main thread. If not already on main thread,
1184  // create a main thread proxy to this nsIObserver interface and initialize on
1185  // the main thread through it.
1186  if (NS_IsMainThread()) {
1187  rv = InitOnMainThread();
1188  NS_ENSURE_SUCCESS(rv, rv);
1189  } else {
1190  nsCOMPtr<nsIObserver> proxyObserver;
1191  nsCOMPtr<nsIProxyObjectManager>
1192  proxyObjectManager = do_GetService("@mozilla.org/xpcomproxy;1", &rv);
1193  NS_ENSURE_SUCCESS(rv, rv);
1194  rv = proxyObjectManager->GetProxyForObject
1195  (NS_PROXY_TO_MAIN_THREAD,
1196  NS_GET_IID(nsIObserver),
1197  NS_ISUPPORTS_CAST(nsIObserver*, this),
1198  nsIProxyObjectManager::INVOKE_SYNC |
1199  nsIProxyObjectManager::FORCE_PROXY_CREATION,
1200  getter_AddRefs(proxyObserver));
1201  NS_ENSURE_SUCCESS(rv, rv);
1202  rv = proxyObserver->Observe(nsnull, "sbPrompter::InitOnMainThread", nsnull);
1203  NS_ENSURE_SUCCESS(rv, rv);
1204  }
1205 
1206  return NS_OK;
1207 }
1208 
1209 
1210 //------------------------------------------------------------------------------
1211 //
1212 // Internal Songbird prompter services.
1213 //
1214 //------------------------------------------------------------------------------
1215 
1220 nsresult
1221 sbPrompter::InitOnMainThread()
1222 {
1223  nsresult rv;
1224 
1225  // Get the window watcher service.
1226  mWindowWatcher = do_GetService("@mozilla.org/embedcomp/window-watcher;1",
1227  &rv);
1228  NS_ENSURE_SUCCESS(rv, rv);
1229 
1230  // Get the Songbird window watcher service.
1231  mSBWindowWatcher =
1232  do_GetService("@songbirdnest.com/Songbird/window-watcher;1", &rv);
1233  NS_ENSURE_SUCCESS(rv, rv);
1234 
1235  // Get the prompt service.
1236  mPromptService = do_GetService("@mozilla.org/embedcomp/prompt-service;1",
1237  &rv);
1238  NS_ENSURE_SUCCESS(rv, rv);
1239 
1240  return NS_OK;
1241 }
1242 
1243 
1251 nsresult
1252 sbPrompter::GetParent(nsIDOMWindow** aParent)
1253 {
1254  nsCOMPtr<nsIDOMWindow> parent;
1255  nsresult rv;
1256 
1257  // Operate under lock.
1258  nsAutoLock autoLock(mPrompterLock);
1259 
1260  // If the Songbird window watcher is shutting down, don't wait for a window.
1261  {
1262  PRBool isShuttingDown;
1263  rv = mSBWindowWatcher->GetIsShuttingDown(&isShuttingDown);
1264  NS_ENSURE_SUCCESS(rv, rv);
1265  if (isShuttingDown)
1266  mWaitForWindow = PR_FALSE;
1267  }
1268 
1269  // Get the parent.
1270  if (mParentWindowType.Length() > 0) {
1271  rv = mSBWindowWatcher->GetWindow(mParentWindowType, getter_AddRefs(parent));
1272  NS_ENSURE_SUCCESS(rv, rv);
1273  }
1274 
1275  // If no window of the configured type is available and we're not waiting for
1276  // one, use the currently active window as the parent.
1277  if (!parent && !mWaitForWindow) {
1278  rv = mWindowWatcher->GetActiveWindow(getter_AddRefs(parent));
1279  NS_ENSURE_SUCCESS(rv, rv);
1280  }
1281 
1282  // Return results.
1283  NS_IF_ADDREF(*aParent = parent);
1284 
1285  return NS_OK;
1286 }
1287 
1288 
1295 nsresult
1296 sbPrompter::GetProxiedPrompter(sbIPrompter** aPrompter)
1297 {
1298  // Validate arguments.
1299  NS_ASSERTION(aPrompter, "aPrompter is null");
1300 
1301  // Function variables.
1302  nsresult rv;
1303 
1304  // Create a main thread proxy for the prompter.
1305  nsCOMPtr<nsIProxyObjectManager>
1306  proxyObjectManager = do_GetService("@mozilla.org/xpcomproxy;1", &rv);
1307  NS_ENSURE_SUCCESS(rv, rv);
1308  rv = proxyObjectManager->GetProxyForObject
1309  (NS_PROXY_TO_MAIN_THREAD,
1310  NS_GET_IID(sbIPrompter),
1311  NS_ISUPPORTS_CAST(sbIPrompter*, this),
1312  nsIProxyObjectManager::INVOKE_SYNC |
1313  nsIProxyObjectManager::FORCE_PROXY_CREATION,
1314  (void**) aPrompter);
1315  NS_ENSURE_SUCCESS(rv, rv);
1316 
1317  return NS_OK;
1318 }
1319 
1320 
1329 nsresult
1330 sbPrompter::PresentPrompterDialog(nsIDOMWindow* aParent,
1331  nsIDialogParamBlock* aParamBlock)
1332 {
1333  nsresult rv;
1334 
1335  // Get the prompter dialog URI spec.
1336  nsAutoString dialogURISpec;
1337  if (mRenderHTML)
1338  dialogURISpec.Assign(NS_LITERAL_STRING(kHTMLPromptURL));
1339  else
1340  dialogURISpec.Assign(NS_LITERAL_STRING(kPromptURL));
1341 
1342  // Open the prompter dialog.
1343  nsCOMPtr<nsISupports> extraArgument = do_QueryInterface(aParamBlock, &rv);
1344  NS_ENSURE_SUCCESS(rv, rv);
1345  rv = OpenDialog(aParent,
1346  dialogURISpec,
1347  NS_LITERAL_STRING("_blank"),
1348  NS_LITERAL_STRING(""),
1349  extraArgument,
1350  getter_AddRefs(mCurrentWindow));
1351  NS_ENSURE_SUCCESS(rv, rv);
1352 
1353  // Prompter dialog window is no longer open.
1354  mCurrentWindow = nsnull;
1355 
1356  return NS_OK;
1357 }
1358 
return NS_OK
NS_DECL_ISUPPORTS NS_DECL_SBIPROMPTER NS_DECL_NSIPROMPTSERVICE NS_DECL_NSIOBSERVER sbPrompter()
onPageChanged aValue
Definition: FeedWriter.js:1395
static const char kAlertIconClass[]
Definition: sbPrompter.cpp:68
NS_IMPL_THREADSAFE_ISUPPORTS3(sbPrompter, sbIPrompter, nsIPromptService, nsIObserver) NS_IMETHODIMP sbPrompter
Definition: sbPrompter.cpp:77
#define kHTMLPromptURL
Definition: sbPrompter.cpp:66
static const char kQuestionIconClass[]
Definition: sbPrompter.cpp:67
let window
const nsIDOMWindow
_updateCookies aName
Songbird Prompter Definitions.
foldersync options
Definition: options.js:13
virtual ~sbPrompter()
restoreHistoryPrecursor aCount
#define kPromptURL
Definition: sbPrompter.cpp:65
nsresult Init()
_updateTextAndScrollDataForFrame aData
Autocompleter Select