Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/toolkit/components/printingui/nsPrintProgress.cpp
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
/* This Source Code Form is subject to the terms of the Mozilla Public
3
 * License, v. 2.0. If a copy of the MPL was not distributed with this
4
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5
6
#include "nsPrintProgress.h"
7
8
#include "nsArray.h"
9
#include "nsIBaseWindow.h"
10
#include "nsIDocShell.h"
11
#include "nsIDocShellTreeOwner.h"
12
#include "nsIInterfaceRequestorUtils.h"
13
#include "nsIXULWindow.h"
14
#include "nsXPCOM.h"
15
#include "nsISupportsPrimitives.h"
16
#include "nsIComponentManager.h"
17
#include "nsPIDOMWindow.h"
18
#include "nsXULAppAPI.h"
19
20
21
NS_IMPL_ADDREF(nsPrintProgress)
22
NS_IMPL_RELEASE(nsPrintProgress)
23
24
0
NS_INTERFACE_MAP_BEGIN(nsPrintProgress)
25
0
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIPrintProgress)
26
0
   NS_INTERFACE_MAP_ENTRY(nsIPrintProgress)
27
0
   NS_INTERFACE_MAP_ENTRY(nsIWebProgressListener)
28
0
NS_INTERFACE_MAP_END
29
30
31
nsPrintProgress::nsPrintProgress(nsIPrintSettings* aPrintSettings)
32
0
{
33
0
  m_closeProgress = false;
34
0
  m_processCanceled = false;
35
0
  m_pendingStateFlags = -1;
36
0
  m_pendingStateValue = NS_OK;
37
0
  m_PrintSetting = aPrintSettings;
38
0
}
39
40
nsPrintProgress::~nsPrintProgress()
41
0
{
42
0
  (void)ReleaseListeners();
43
0
}
44
45
NS_IMETHODIMP nsPrintProgress::OpenProgressDialog(mozIDOMWindowProxy *parent,
46
                                                  const char *dialogURL,
47
                                                  nsISupports *parameters,
48
                                                  nsIObserver *openDialogObserver,
49
                                                  bool *notifyOnOpen)
50
0
{
51
0
  *notifyOnOpen = true;
52
0
  m_observer = openDialogObserver;
53
0
  nsresult rv = NS_ERROR_FAILURE;
54
0
55
0
  if (m_dialog)
56
0
    return NS_ERROR_ALREADY_INITIALIZED;
57
0
58
0
  if (!dialogURL || !*dialogURL)
59
0
    return NS_ERROR_INVALID_ARG;
60
0
61
0
  if (parent)
62
0
  {
63
0
    // Set up window.arguments[0]...
64
0
    nsCOMPtr<nsIMutableArray> array = nsArray::Create();
65
0
66
0
    nsCOMPtr<nsISupportsInterfacePointer> ifptr =
67
0
      do_CreateInstance(NS_SUPPORTS_INTERFACE_POINTER_CONTRACTID, &rv);
68
0
    NS_ENSURE_SUCCESS(rv, rv);
69
0
70
0
    ifptr->SetData(static_cast<nsIPrintProgress*>(this));
71
0
    ifptr->SetDataIID(&NS_GET_IID(nsIPrintProgress));
72
0
73
0
    array->AppendElement(ifptr);
74
0
75
0
    array->AppendElement(parameters);
76
0
77
0
    // We will set the opener of the dialog to be the nsIDOMWindow for the
78
0
    // browser XUL window itself, as opposed to the content. That way, the
79
0
    // progress window has access to the opener.
80
0
    nsCOMPtr<nsPIDOMWindowOuter> pParentWindow = nsPIDOMWindowOuter::From(parent);
81
0
    NS_ENSURE_STATE(pParentWindow);
82
0
    nsCOMPtr<nsIDocShell> docShell = pParentWindow->GetDocShell();
83
0
    NS_ENSURE_STATE(docShell);
84
0
85
0
    nsCOMPtr<nsIDocShellTreeOwner> owner;
86
0
    docShell->GetTreeOwner(getter_AddRefs(owner));
87
0
88
0
    nsCOMPtr<nsIXULWindow> ownerXULWindow = do_GetInterface(owner);
89
0
    nsCOMPtr<mozIDOMWindowProxy> ownerWindow = do_GetInterface(ownerXULWindow);
90
0
    NS_ENSURE_STATE(ownerWindow);
91
0
92
0
    nsCOMPtr<nsPIDOMWindowOuter> piOwnerWindow = nsPIDOMWindowOuter::From(ownerWindow);
93
0
94
0
    // Open the dialog.
95
0
    nsCOMPtr<nsPIDOMWindowOuter> newWindow;
96
0
97
0
    rv = piOwnerWindow->OpenDialog(NS_ConvertASCIItoUTF16(dialogURL),
98
0
                                   NS_LITERAL_STRING("_blank"),
99
0
                                   NS_LITERAL_STRING("chrome,titlebar,dependent,centerscreen"),
100
0
                                   array, getter_AddRefs(newWindow));
101
0
  }
102
0
103
0
  return rv;
104
0
}
105
106
NS_IMETHODIMP nsPrintProgress::CloseProgressDialog(bool forceClose)
107
0
{
108
0
  m_closeProgress = true;
109
0
  // XXX Invalid cast of bool to nsresult (bug 778106)
110
0
  return OnStateChange(nullptr, nullptr, nsIWebProgressListener::STATE_STOP,
111
0
                       (nsresult)forceClose);
112
0
}
113
114
NS_IMETHODIMP nsPrintProgress::GetPrompter(nsIPrompt **_retval)
115
0
{
116
0
  NS_ENSURE_ARG_POINTER(_retval);
117
0
  *_retval = nullptr;
118
0
119
0
  if (! m_closeProgress && m_dialog) {
120
0
    nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryInterface(m_dialog);
121
0
    MOZ_ASSERT(window);
122
0
    return window->GetPrompter(_retval);
123
0
  }
124
0
125
0
  return NS_ERROR_FAILURE;
126
0
}
127
128
NS_IMETHODIMP nsPrintProgress::GetProcessCanceledByUser(bool *aProcessCanceledByUser)
129
0
{
130
0
  NS_ENSURE_ARG_POINTER(aProcessCanceledByUser);
131
0
  *aProcessCanceledByUser = m_processCanceled;
132
0
  return NS_OK;
133
0
}
134
NS_IMETHODIMP nsPrintProgress::SetProcessCanceledByUser(bool aProcessCanceledByUser)
135
0
{
136
0
  if (XRE_IsE10sParentProcess()) {
137
0
    MOZ_ASSERT(m_observer);
138
0
    m_observer->Observe(nullptr, "cancelled", nullptr);
139
0
  }
140
0
  if(m_PrintSetting)
141
0
    m_PrintSetting->SetIsCancelled(true);
142
0
  m_processCanceled = aProcessCanceledByUser;
143
0
  OnStateChange(nullptr, nullptr, nsIWebProgressListener::STATE_STOP, NS_OK);
144
0
  return NS_OK;
145
0
}
146
147
NS_IMETHODIMP nsPrintProgress::RegisterListener(nsIWebProgressListener * listener)
148
0
{
149
0
  if (!listener) //Nothing to do with a null listener!
150
0
    return NS_OK;
151
0
152
0
  m_listenerList.AppendObject(listener);
153
0
  if (m_closeProgress || m_processCanceled)
154
0
    listener->OnStateChange(nullptr, nullptr, nsIWebProgressListener::STATE_STOP, NS_OK);
155
0
  else
156
0
  {
157
0
    listener->OnStatusChange(nullptr, nullptr, NS_OK, m_pendingStatus.get());
158
0
    if (m_pendingStateFlags != -1)
159
0
      listener->OnStateChange(nullptr, nullptr, m_pendingStateFlags, m_pendingStateValue);
160
0
  }
161
0
162
0
  return NS_OK;
163
0
}
164
165
NS_IMETHODIMP nsPrintProgress::UnregisterListener(nsIWebProgressListener *listener)
166
0
{
167
0
  if (listener)
168
0
    m_listenerList.RemoveObject(listener);
169
0
170
0
  return NS_OK;
171
0
}
172
173
NS_IMETHODIMP nsPrintProgress::DoneIniting()
174
0
{
175
0
  if (m_observer) {
176
0
    m_observer->Observe(nullptr, nullptr, nullptr);
177
0
  }
178
0
  return NS_OK;
179
0
}
180
181
NS_IMETHODIMP nsPrintProgress::OnStateChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, uint32_t aStateFlags, nsresult aStatus)
182
0
{
183
0
  if (XRE_IsE10sParentProcess() &&
184
0
      aStateFlags & nsIWebProgressListener::STATE_STOP) {
185
0
    // If we're in an e10s parent, m_observer is a PrintProgressDialogParent,
186
0
    // so we let it know that printing has completed, because it might mean that
187
0
    // its PrintProgressDialogChild has already been deleted.
188
0
    m_observer->Observe(nullptr, "completed", nullptr);
189
0
  }
190
0
191
0
  m_pendingStateFlags = aStateFlags;
192
0
  m_pendingStateValue = aStatus;
193
0
194
0
  uint32_t count = m_listenerList.Count();
195
0
  for (uint32_t i = count - 1; i < count; i --)
196
0
  {
197
0
    nsCOMPtr<nsIWebProgressListener> progressListener = m_listenerList.SafeObjectAt(i);
198
0
    if (progressListener)
199
0
      progressListener->OnStateChange(aWebProgress, aRequest, aStateFlags, aStatus);
200
0
  }
201
0
202
0
  return NS_OK;
203
0
}
204
205
NS_IMETHODIMP nsPrintProgress::OnProgressChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, int32_t aCurSelfProgress, int32_t aMaxSelfProgress, int32_t aCurTotalProgress, int32_t aMaxTotalProgress)
206
0
{
207
0
  if (XRE_IsE10sParentProcess() && aCurSelfProgress &&
208
0
      aCurSelfProgress >= aMaxSelfProgress) {
209
0
    // If we're in an e10s parent, m_observer is a PrintProgressDialogParent,
210
0
    // so we let it know that printing has completed, because it might mean that
211
0
    // its PrintProgressDialogChild has already been deleted.
212
0
    m_observer->Observe(nullptr, "completed", nullptr);
213
0
  }
214
0
215
0
  uint32_t count = m_listenerList.Count();
216
0
  for (uint32_t i = count - 1; i < count; i --)
217
0
  {
218
0
    nsCOMPtr<nsIWebProgressListener> progressListener = m_listenerList.SafeObjectAt(i);
219
0
    if (progressListener)
220
0
      progressListener->OnProgressChange(aWebProgress, aRequest, aCurSelfProgress, aMaxSelfProgress, aCurTotalProgress, aMaxTotalProgress);
221
0
  }
222
0
223
0
  return NS_OK;
224
0
}
225
226
NS_IMETHODIMP nsPrintProgress::OnLocationChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, nsIURI *location, uint32_t aFlags)
227
0
{
228
0
    return NS_ERROR_NOT_IMPLEMENTED;
229
0
}
230
231
NS_IMETHODIMP nsPrintProgress::OnStatusChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, nsresult aStatus, const char16_t *aMessage)
232
0
{
233
0
  if (aMessage && *aMessage)
234
0
  m_pendingStatus = aMessage;
235
0
236
0
  uint32_t count = m_listenerList.Count();
237
0
  for (uint32_t i = count - 1; i < count; i --)
238
0
  {
239
0
    nsCOMPtr<nsIWebProgressListener> progressListener = m_listenerList.SafeObjectAt(i);
240
0
    if (progressListener)
241
0
      progressListener->OnStatusChange(aWebProgress, aRequest, aStatus, aMessage);
242
0
  }
243
0
244
0
  return NS_OK;
245
0
}
246
247
NS_IMETHODIMP nsPrintProgress::OnSecurityChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, uint32_t state)
248
0
{
249
0
    return NS_OK;
250
0
}
251
252
nsresult nsPrintProgress::ReleaseListeners()
253
0
{
254
0
  m_listenerList.Clear();
255
0
256
0
  return NS_OK;
257
0
}
258