sbClipboardHelper.cpp
Go to the documentation of this file.
1 /*
2 //
3 // BEGIN SONGBIRD GPL
4 //
5 // This file is part of the Songbird web player.
6 //
7 // Copyright(c) 2005-2008 POTI, Inc.
8 // http://songbirdnest.com
9 //
10 // This file may be licensed under the terms of of the
11 // GNU General Public License Version 2 (the "GPL").
12 //
13 // Software distributed under the License is distributed
14 // on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either
15 // express or implied. See the GPL for the specific language
16 // governing rights and limitations.
17 //
18 // You should have received a copy of the GPL along with this
19 // program. If not, go to http://www.gnu.org/licenses/gpl.html
20 // or write to the Free Software Foundation, Inc.,
21 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22 //
23 // END SONGBIRD GPL
24 //
25  */
26 
27 #include "sbClipboardHelper.h"
28 
29 #include <imgIContainer.h>
30 #include <imgITools.h>
31 #include <nsIBinaryInputStream.h>
32 #include <nsIClipboard.h>
33 #include <nsIInputStream.h>
34 #include <nsIInterfaceRequestor.h>
35 #include <nsIInterfaceRequestorUtils.h>
36 #include <nsIMIMEService.h>
37 #include <nsIStringStream.h>
38 #include <nsISupportsPrimitives.h>
39 #include <nsITransferable.h>
40 #include <nsIURL.h>
41 #include <nsNetUtil.h>
42 #include <nsStringAPI.h>
43 
44 #include "nsWidgetsCID.h"
45 
46 #define kBinaryInputStream "@mozilla.org/binaryinputstream;1"
47 
49 
51 {
52  /* member initializers and constructor code */
53 }
54 
55 sbClipboardHelper::~sbClipboardHelper()
56 {
57  /* destructor code */
58 }
59 
60 NS_IMETHODIMP
61 sbClipboardHelper::CopyImageFromClipboard(nsAString &aMimeType,
62  PRUint32 *aDataLen,
63  PRUint8 **aData)
64 {
65  nsresult rv;
66 
67  *aDataLen = 0;
68 
69  nsCOMPtr<nsIClipboard> nsClipboard =
70  do_GetService("@mozilla.org/widget/clipboard;1", &rv);
71  NS_ENSURE_SUCCESS(rv, rv);
72 
73  nsCOMPtr<nsITransferable> xferable =
74  do_CreateInstance("@mozilla.org/widget/transferable;1", &rv);
75  NS_ENSURE_SUCCESS(rv, rv);
76 
77  /*
78  * Load up the flavors we support
79  */
80  const char *flavorTypes[] = { kPNGImageMime,
81  kJPEGImageMime,
82  "image/jpeg",
83  kGIFImageMime,
84  kFileMime,
85  kUnicodeMime };
86  const int flavorTypesLen = NS_ARRAY_LENGTH(flavorTypes);
87  for (int iIndex = 0; iIndex < flavorTypesLen; iIndex++) {
88  rv = xferable->AddDataFlavor(flavorTypes[iIndex]);
89  NS_ENSURE_SUCCESS(rv, rv);
90  }
91 
92  // Check the clipboard if it has one of those flavors
93  PRBool clipboardHasData = PR_FALSE;
94  rv = nsClipboard->HasDataMatchingFlavors(flavorTypes,
95  flavorTypesLen,
96  nsIClipboard::kGlobalClipboard,
97  &clipboardHasData);
98  NS_ENSURE_SUCCESS(rv, rv);
99 
100  if (clipboardHasData) {
101  // Grab the data as a nsITransferable
102  rv = nsClipboard->GetData(xferable, nsIClipboard::kGlobalClipboard);
103  NS_ENSURE_SUCCESS(rv, rv);
104 
105  nsCOMPtr<nsISupports> clipboardData;
106  char *clipboardDataFlavor = 0;
107  PRUint32 clipboardDataLen = 0;
108 
109  rv = xferable->GetAnyTransferData(&clipboardDataFlavor,
110  getter_AddRefs(clipboardData),
111  &clipboardDataLen);
112  NS_ENSURE_SUCCESS(rv, rv);
113 
114  // Once we get a stream we can grab the data
115  nsCOMPtr<nsIInputStream> dataStream;
116 
117  // First check if this is a file/url flavor
118  if (!strcmp(clipboardDataFlavor, kUnicodeMime) ||
119  !strcmp(clipboardDataFlavor, kFileMime)) {
120 
121  // This is a file we are copying from
122  nsCOMPtr<nsILocalFile> imageFile;
123  if (!strcmp(clipboardDataFlavor, kUnicodeMime)) {
124  nsAutoString url;
125  nsCOMPtr<nsISupportsString> stringData(do_QueryInterface(clipboardData));
126  if (stringData) {
127  stringData->GetData(url);
128  }
129 
130  if (url.IsEmpty()) {
131  // Nothing to work with so abort
132  return NS_OK;
133  }
134 
135  imageFile = do_CreateInstance("@mozilla.org/file/local;1", &rv);
136  NS_ENSURE_SUCCESS(rv, rv);
137 
138  rv = imageFile->InitWithPath(url);
139  if (NS_FAILED(rv)) {
140  return NS_OK;
141  }
142  } else {
143  // it already is a file :)
144  imageFile = do_QueryInterface(clipboardData);
145  if (!imageFile) {
146  return NS_OK;
147  }
148  }
149 
150  // Get the mime type from the file
151  nsCOMPtr<nsIMIMEService> mimeService =
152  do_CreateInstance("@mozilla.org/mime;1", &rv);
153  NS_ENSURE_SUCCESS(rv, rv);
154 
155  nsCAutoString mimeType;
156  rv = mimeService->GetTypeFromFile(imageFile, mimeType);
157  NS_ENSURE_SUCCESS(rv, rv);
158 
159  aMimeType.Assign(NS_ConvertUTF8toUTF16(mimeType));
160 
161  // Now set up an input stream for the file
162  nsCOMPtr<nsIFileInputStream> fileStream =
163  do_CreateInstance("@mozilla.org/network/file-input-stream;1", &rv);
164  NS_ENSURE_SUCCESS(rv, rv);
165 
166  rv = fileStream->Init(imageFile, 0x01, 0600, 0);
167  NS_ENSURE_SUCCESS(rv, rv);
168 
169  dataStream = do_QueryInterface(fileStream, &rv);
170  NS_ENSURE_SUCCESS(rv, rv);
171  } else {
172  // Assume it is a image then
173  // Here we have to force the image/jpg mime type as image/jpeg because
174  // the windows clipboard does not like image/jpg. The other systems work
175  // either way.
176  if(strcmp(clipboardDataFlavor, kJPEGImageMime)) {
177  aMimeType.AssignLiteral(clipboardDataFlavor);
178  }
179  else {
180  aMimeType.AssignLiteral("image/jpeg");
181  }
182 
183  dataStream = do_QueryInterface(clipboardData, &rv);
184  NS_ENSURE_SUCCESS(rv, rv);
185  }
186 
187  // Now read in the data from the stream
188  PRUint32 dataSize;
189  rv = dataStream->Available(&dataSize);
190  NS_ENSURE_SUCCESS(rv, rv);
191 
192  nsCOMPtr<nsIBinaryInputStream> imageDataStream =
193  do_CreateInstance(kBinaryInputStream, &rv);
194  NS_ENSURE_SUCCESS(rv, rv);
195 
196  rv = imageDataStream->SetInputStream(dataStream);
197  NS_ENSURE_SUCCESS(rv, rv);
198 
199  rv = imageDataStream->ReadByteArray(dataSize, aData);
200  NS_ENSURE_SUCCESS(rv, rv);
201  *aDataLen = dataSize;
202  }
203 
204  return NS_OK;
205 }
206 
207 NS_IMETHODIMP
208 sbClipboardHelper::PasteImageToClipboard(const nsACString &aMimeType,
209  const PRUint8 *aData,
210  PRUint32 aDataLen)
211 {
212  nsresult rv;
213 
214  nsCOMPtr<imgITools> imgtool = do_CreateInstance("@mozilla.org/image/tools;1",
215  &rv);
216  NS_ENSURE_SUCCESS(rv, rv);
217 
218  // Convert the image data to a stream so we can use the imagITools
219  nsCOMPtr<nsIStringInputStream> stream = do_CreateInstance("@mozilla.org/io/string-input-stream;1",
220  &rv);
221  NS_ENSURE_SUCCESS(rv, rv);
222  stream->ShareData(reinterpret_cast<const char*>(aData), aDataLen);
223 
224  // decode image
225  nsCOMPtr<imgIContainer> image;
226  rv = imgtool->DecodeImageData(stream, aMimeType, getter_AddRefs(image));
227  NS_ENSURE_SUCCESS(rv, rv);
228 
229  // Now create a Transferable so we can copy to the clipboard
230  nsCOMPtr<nsITransferable> xferable = do_CreateInstance("@mozilla.org/widget/transferable;1", &rv);
231  NS_ENSURE_SUCCESS(rv, rv);
232 
233  nsCOMPtr<nsISupportsInterfacePointer>
234  imgPtr(do_CreateInstance(NS_SUPPORTS_INTERFACE_POINTER_CONTRACTID, &rv));
235  NS_ENSURE_SUCCESS(rv, rv);
236 
237  rv = imgPtr->SetData(image);
238  NS_ENSURE_SUCCESS(rv, rv);
239 
240  // copy the image data onto the transferable
241  rv = xferable->SetTransferData(kNativeImageMime,
242  imgPtr,
243  sizeof(nsISupportsInterfacePointer*));
244  NS_ENSURE_SUCCESS(rv, rv);
245 
246  // get clipboard
247  nsCOMPtr<nsIClipboard> clipboard(do_GetService("@mozilla.org/widget/clipboard;1", &rv));
248  NS_ENSURE_SUCCESS(rv, rv);
249 
250  // check whether the system supports the selection clipboard or not.
251  PRBool selectionSupported;
252  rv = clipboard->SupportsSelectionClipboard(&selectionSupported);
253  NS_ENSURE_SUCCESS(rv, rv);
254 
255  // put the transferable on the clipboard
256  if (selectionSupported) {
257  rv = clipboard->SetData(xferable, nsnull, nsIClipboard::kSelectionClipboard);
258  NS_ENSURE_SUCCESS(rv, rv);
259  }
260 
261  return clipboard->SetData(xferable, nsnull, nsIClipboard::kGlobalClipboard);
262 }
263 
return NS_OK
NS_IMPL_ISUPPORTS1(sbDeviceCapabilitiesUtils, sbIDeviceCapabilitiesUtils) sbDeviceCapabilitiesUtils
function stringData(literalOrResource)
function url(spec)
#define kBinaryInputStream
_updateTextAndScrollDataForFrame aData