michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- michael@0: * michael@0: * This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include "nsClipboardHelper.h" michael@0: michael@0: // basics michael@0: #include "nsCOMPtr.h" michael@0: #include "nsXPCOM.h" michael@0: #include "nsISupportsPrimitives.h" michael@0: #include "nsIServiceManager.h" michael@0: michael@0: // helpers michael@0: #include "nsIClipboard.h" michael@0: #include "nsIDocument.h" michael@0: #include "nsIDOMDocument.h" michael@0: #include "nsITransferable.h" michael@0: #include "nsReadableUtils.h" michael@0: michael@0: NS_IMPL_ISUPPORTS(nsClipboardHelper, nsIClipboardHelper) michael@0: michael@0: /***************************************************************************** michael@0: * nsClipboardHelper ctor / dtor michael@0: *****************************************************************************/ michael@0: michael@0: nsClipboardHelper::nsClipboardHelper() michael@0: { michael@0: } michael@0: michael@0: nsClipboardHelper::~nsClipboardHelper() michael@0: { michael@0: // no members, nothing to destroy michael@0: } michael@0: michael@0: /***************************************************************************** michael@0: * nsIClipboardHelper methods michael@0: *****************************************************************************/ michael@0: michael@0: NS_IMETHODIMP michael@0: nsClipboardHelper::CopyStringToClipboard(const nsAString& aString, michael@0: int32_t aClipboardID, michael@0: nsIDOMDocument* aDocument) michael@0: { michael@0: nsresult rv; michael@0: michael@0: // get the clipboard michael@0: nsCOMPtr michael@0: clipboard(do_GetService("@mozilla.org/widget/clipboard;1", &rv)); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: NS_ENSURE_TRUE(clipboard, NS_ERROR_FAILURE); michael@0: michael@0: bool clipboardSupported; michael@0: // don't go any further if they're asking for the selection michael@0: // clipboard on a platform which doesn't support it (i.e., unix) michael@0: if (nsIClipboard::kSelectionClipboard == aClipboardID) { michael@0: rv = clipboard->SupportsSelectionClipboard(&clipboardSupported); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: if (!clipboardSupported) michael@0: return NS_ERROR_FAILURE; michael@0: } michael@0: michael@0: // don't go any further if they're asking for the find clipboard on a platform michael@0: // which doesn't support it (i.e., non-osx) michael@0: if (nsIClipboard::kFindClipboard == aClipboardID) { michael@0: rv = clipboard->SupportsFindClipboard(&clipboardSupported); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: if (!clipboardSupported) michael@0: return NS_ERROR_FAILURE; michael@0: } michael@0: michael@0: // create a transferable for putting data on the clipboard michael@0: nsCOMPtr michael@0: trans(do_CreateInstance("@mozilla.org/widget/transferable;1", &rv)); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: NS_ENSURE_TRUE(trans, NS_ERROR_FAILURE); michael@0: michael@0: nsCOMPtr doc = do_QueryInterface(aDocument); michael@0: nsILoadContext* loadContext = doc ? doc->GetLoadContext() : nullptr; michael@0: trans->Init(loadContext); michael@0: michael@0: // Add the text data flavor to the transferable michael@0: rv = trans->AddDataFlavor(kUnicodeMime); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: // get wStrings to hold clip data michael@0: nsCOMPtr michael@0: data(do_CreateInstance("@mozilla.org/supports-string;1", &rv)); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: NS_ENSURE_TRUE(data, NS_ERROR_FAILURE); michael@0: michael@0: // populate the string michael@0: rv = data->SetData(aString); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: // qi the data object an |nsISupports| so that when the transferable holds michael@0: // onto it, it will addref the correct interface. michael@0: nsCOMPtr genericData(do_QueryInterface(data, &rv)); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: NS_ENSURE_TRUE(genericData, NS_ERROR_FAILURE); michael@0: michael@0: // set the transfer data michael@0: rv = trans->SetTransferData(kUnicodeMime, genericData, michael@0: aString.Length() * 2); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: // put the transferable on the clipboard michael@0: rv = clipboard->SetData(trans, nullptr, aClipboardID); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsClipboardHelper::CopyString(const nsAString& aString, nsIDOMDocument* aDocument) michael@0: { michael@0: nsresult rv; michael@0: michael@0: // copy to the global clipboard. it's bad if this fails in any way. michael@0: rv = CopyStringToClipboard(aString, nsIClipboard::kGlobalClipboard, aDocument); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: // unix also needs us to copy to the selection clipboard. this will michael@0: // fail in CopyStringToClipboard if we're not on a platform that michael@0: // supports the selection clipboard. (this could have been #ifdef michael@0: // XP_UNIX, but using the SupportsSelectionClipboard call is the michael@0: // more correct thing to do. michael@0: // michael@0: // if this fails in any way other than "not being unix", we'll get michael@0: // the assertion we need in CopyStringToClipboard, and we needn't michael@0: // assert again here. michael@0: CopyStringToClipboard(aString, nsIClipboard::kSelectionClipboard, aDocument); michael@0: michael@0: return NS_OK; michael@0: }