Bug 867104 - Add a crashtest. r=ehsan
[gecko.git] / widget / qt / nsDragService.cpp
blob01736901d8ee800a111351cd5cd2fbe860cb3d30
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* vim:expandtab:shiftwidth=4:tabstop=4:
3 */
4 /* This Source Code Form is subject to the terms of the Mozilla Public
5 * License, v. 2.0. If a copy of the MPL was not distributed with this
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
8 #include "qmimedata.h"
9 #include "qwidget.h"
10 #include "qapplication.h"
11 #include "qthread.h"
13 #include "nsDragService.h"
14 #include "nsISupportsPrimitives.h"
15 #include "nsXPIDLString.h"
16 #include "nsIDOMMouseEvent.h"
18 NS_IMPL_ADDREF_INHERITED(nsDragService, nsBaseDragService)
19 NS_IMPL_RELEASE_INHERITED(nsDragService, nsBaseDragService)
20 NS_IMPL_QUERY_INTERFACE2(nsDragService, nsIDragService, nsIDragSession )
22 nsDragService::nsDragService() : mDrag(NULL), mHiddenWidget(NULL)
26 nsDragService::~nsDragService()
28 /* destructor code */
29 delete mHiddenWidget;
32 NS_IMETHODIMP
33 nsDragService::SetDropActionType( uint32_t aActionType )
35 mDropAction = Qt::IgnoreAction;
37 if (aActionType & DRAGDROP_ACTION_COPY)
39 mDropAction |= Qt::CopyAction;
41 if (aActionType & DRAGDROP_ACTION_MOVE)
43 mDropAction |= Qt::MoveAction;
45 if (aActionType & DRAGDROP_ACTION_LINK)
47 mDropAction |= Qt::LinkAction;
50 return NS_OK;
53 NS_IMETHODIMP
54 nsDragService::SetupDragSession(
55 nsISupportsArray *aTransferables,
56 uint32_t aActionType)
58 uint32_t itemCount = 0;
59 aTransferables->Count(&itemCount);
60 if (0 == itemCount)
62 NS_WARNING("No items to drag?");
63 return NS_ERROR_FAILURE;
66 if (1 != itemCount)
68 NS_WARNING("Dragging more than one item, cannot do (yet?)");
69 return NS_ERROR_NOT_IMPLEMENTED;
72 SetDropActionType(aActionType);
74 QMimeData *mimeData = new QMimeData;
76 nsCOMPtr<nsISupports> genericItem;
77 aTransferables->GetElementAt(0, getter_AddRefs(genericItem));
78 nsCOMPtr<nsITransferable> transferable(do_QueryInterface(genericItem));
80 if (transferable)
82 nsCOMPtr <nsISupportsArray> flavorList;
83 transferable->FlavorsTransferableCanExport(getter_AddRefs(flavorList));
85 if (flavorList)
87 uint32_t flavorCount;
88 flavorList->Count( &flavorCount );
90 for (uint32_t flavor=0; flavor < flavorCount; flavor++)
92 nsCOMPtr<nsISupports> genericWrapper;
93 flavorList->GetElementAt(flavor, getter_AddRefs(genericWrapper));
94 nsCOMPtr<nsISupportsCString> currentFlavor;
95 currentFlavor = do_QueryInterface(genericWrapper);
97 if (currentFlavor)
99 nsCOMPtr<nsISupports> data;
100 uint32_t dataLen = 0;
101 nsXPIDLCString flavorStr;
102 currentFlavor->ToString(getter_Copies(flavorStr));
104 // Is it some flavor we think we could support?
105 if (!strcmp(kURLMime, flavorStr.get())
106 || !strcmp(kURLDataMime, flavorStr.get())
107 || !strcmp(kURLDescriptionMime, flavorStr.get())
108 || !strcmp(kHTMLMime, flavorStr.get())
109 || !strcmp(kUnicodeMime, flavorStr.get())
112 transferable->GetTransferData(flavorStr,getter_AddRefs(data),&dataLen);
114 nsCOMPtr<nsISupportsString> wideString;
115 wideString = do_QueryInterface(data);
116 if (!wideString)
118 return NS_ERROR_FAILURE;
121 nsAutoString utf16string;
122 wideString->GetData(utf16string);
123 QByteArray ba((const char*) utf16string.get(), dataLen);
125 mimeData->setData(flavorStr.get(), ba);
132 if (qApp->thread() != QThread::currentThread()) {
133 NS_WARNING("Cannot initialize drag session in non main thread");
134 return NS_OK;
137 if (!mHiddenWidget) {
138 mHiddenWidget = new QWidget();
140 mDrag = new QDrag( mHiddenWidget ); // TODO: Better drag source here?
141 mDrag->setMimeData(mimeData);
143 // mDrag and mimeData SHOULD NOT be destroyed. They are destroyed by QT.
145 return NS_OK;
148 /* void invokeDragSession (in nsIDOMNode aDOMNode, in nsISupportsArray aTransferables, in nsIScriptableRegion aRegion, in unsigned long aActionType); */
149 NS_IMETHODIMP
150 nsDragService::InvokeDragSession(
151 nsIDOMNode *aDOMNode,
152 nsISupportsArray *aTransferables,
153 nsIScriptableRegion *aRegion,
154 uint32_t aActionType)
156 nsBaseDragService::InvokeDragSession(
157 aDOMNode,
158 aTransferables,
159 aRegion,
160 aActionType);
162 SetupDragSession( aTransferables, aActionType);
164 return NS_OK;
167 NS_IMETHODIMP
168 nsDragService::ExecuteDrag()
170 if (qApp->thread() == QThread::currentThread()) {
171 mDrag->exec(mDropAction);
174 return NS_OK;
177 /* void invokeDragSessionWithImage ( nsIDOMNode DOMNode , nsISupportsArray transferableArray , nsIScriptableRegion region , uint32_t actionType , nsIDOMNode image , int32_t imageX , int32_t imageY , nsIDOMMouseEvent dragEvent ); */
178 NS_IMETHODIMP
179 nsDragService::InvokeDragSessionWithImage(
180 nsIDOMNode *aDOMNode,
181 nsISupportsArray*aTransferables,
182 nsIScriptableRegion* aRegion,
183 uint32_t aActionType,
184 nsIDOMNode* aImage,
185 int32_t aImageX,
186 int32_t aImageY,
187 nsIDOMDragEvent* aDragEvent,
188 nsIDOMDataTransfer* aDataTransfer)
190 nsBaseDragService::InvokeDragSessionWithImage(
191 aDOMNode, aTransferables,
192 aRegion, aActionType,
193 aImage,
194 aImageX, aImageY,
195 aDragEvent,
196 aDataTransfer);
198 SetupDragSession( aTransferables, aActionType);
200 // Setup Image, and other stuff
201 if (aImage)
203 // Use the custom image
204 // (aImageX,aImageY) specifies the offset "within the image where
205 // the cursor would be positioned"
207 // So, convert the aImage to QPixmap and X and Y to q QPoint
208 // and then:
209 // mDrag->setPixmap( pixmap ) or mDrag->setDragCursor( pixmap );
210 // mDrad->setHotSpot( point );
211 // TODO: Not implemented yet as this cannot be currently tested
212 NS_WARNING("Support for drag image not implemented");
215 return ExecuteDrag();
218 NS_IMETHODIMP
219 nsDragService::InvokeDragSessionWithSelection(nsISelection* aSelection,
220 nsISupportsArray* aTransferableArray,
221 uint32_t aActionType,
222 nsIDOMDragEvent* aDragEvent,
223 nsIDOMDataTransfer* aDataTransfer)
225 nsBaseDragService::InvokeDragSessionWithSelection(
226 aSelection,
227 aTransferableArray,
228 aActionType,
229 aDragEvent,
230 aDataTransfer);
232 SetupDragSession( aTransferableArray, aActionType);
234 // Setup selection related properties
235 // There is however nothing that needs to be set
237 return ExecuteDrag();
240 /* nsIDragSession getCurrentSession (); */
241 NS_IMETHODIMP
242 nsDragService::GetCurrentSession(nsIDragSession **_retval)
244 return NS_ERROR_NOT_IMPLEMENTED;
247 /* void startDragSession (); */
248 NS_IMETHODIMP
249 nsDragService::StartDragSession()
251 return nsBaseDragService::StartDragSession();
254 /* void endDragSession (in bool aDoneDrag); */
255 NS_IMETHODIMP
256 nsDragService::EndDragSession(bool aDoneDrag)
258 return nsBaseDragService::EndDragSession(aDoneDrag);
261 /* void fireDragEventAtSource (in unsigned long aMsg); */
262 NS_IMETHODIMP
263 nsDragService::FireDragEventAtSource(uint32_t aMsg)
265 return nsBaseDragService::FireDragEventAtSource(aMsg);
268 /* TODO: What is this? */
269 NS_IMETHODIMP
270 nsDragService::Suppress()
272 return nsBaseDragService::Suppress();
275 /* TODO: What is this? */
276 NS_IMETHODIMP
277 nsDragService::Unsuppress()
279 return nsBaseDragService::Unsuppress();
282 NS_IMETHODIMP
283 nsDragService::DragMoved(int32_t aX, int32_t aY)
285 return nsBaseDragService::DragMoved(aX, aY);