//------------------------------------------------------------------------- NS_IMETHODIMP nsDragService::GetNumDropItems(uint32_t * aNumItems) { if (!mDataObject) { *aNumItems = 0; return NS_OK; } if (IsCollectionObject(mDataObject)) { nsDataObjCollection * dataObjCol = GetDataObjCollection(mDataObject); if (dataObjCol) { *aNumItems = dataObjCol->GetNumDataObjects(); } else { // If the count cannot be determined just return 0. // This can happen if we have collection data of type // MULTI_MIME ("Mozilla/IDataObjectCollectionFormat") on the clipboard // from another process but we can't obtain an IID_IDataObjCollection // from this process. *aNumItems = 0; } } else { // Next check if we have a file drop. Return the number of files in // the file drop as the number of items we have, pretending like we // actually have > 1 drag item. FORMATETC fe2; SET_FORMATETC(fe2, CF_HDROP, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL); if (mDataObject->QueryGetData(&fe2) == S_OK) { STGMEDIUM stm; if (mDataObject->GetData(&fe2, &stm) == S_OK) { HDROP hdrop = (HDROP)GlobalLock(stm.hGlobal); *aNumItems = ::DragQueryFileW(hdrop, 0xFFFFFFFF, NULL, 0); ::GlobalUnlock(stm.hGlobal); ::ReleaseStgMedium(&stm); // Data may be provided later, so assume we have 1 item if (*aNumItems == 0) *aNumItems = 1; } else *aNumItems = 1; } else *aNumItems = 1; } return NS_OK; }
//------------------------------------------------------------------------- NS_IMETHODIMP nsDragService::GetData(nsITransferable * aTransferable, PRUint32 anItem) { // This typcially happens on a drop, the target would be asking // for it's transferable to be filled in // Use a static clipboard utility method for this if (!mDataObject) return NS_ERROR_FAILURE; nsresult dataFound = NS_ERROR_FAILURE; if (IsCollectionObject(mDataObject)) { // multiple items, use |anItem| as an index into our collection nsDataObjCollection * dataObjCol = GetDataObjCollection(mDataObject); PRUint32 cnt = dataObjCol->GetNumDataObjects(); if (anItem >= 0 && anItem < cnt) { IDataObject * dataObj = dataObjCol->GetDataObjectAt(anItem); dataFound = nsClipboard::GetDataFromDataObject(dataObj, 0, nsnull, aTransferable); } else NS_WARNING("Index out of range!"); } else { // If they are asking for item "0", we can just get it... if (anItem == 0) { dataFound = nsClipboard::GetDataFromDataObject(mDataObject, anItem, nsnull, aTransferable); } else { // It better be a file drop, or else non-zero indexes are invalid! FORMATETC fe2; SET_FORMATETC(fe2, CF_HDROP, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL); if (mDataObject->QueryGetData(&fe2) == S_OK) dataFound = nsClipboard::GetDataFromDataObject(mDataObject, anItem, nsnull, aTransferable); else NS_WARNING("Reqesting non-zero index, but clipboard data is not a collection!"); } } return dataFound; }
//------------------------------------------------------------------------- NS_IMETHODIMP nsDragService::IsDataFlavorSupported(const char *aDataFlavor, PRBool *_retval) { if (!aDataFlavor || !mDataObject || !_retval) return NS_ERROR_FAILURE; #ifdef NS_DEBUG if (strcmp(aDataFlavor, kTextMime) == 0) NS_WARNING("DO NOT USE THE text/plain DATA FLAVOR ANY MORE. USE text/unicode INSTEAD"); #endif *_retval = PR_FALSE; FORMATETC fe; UINT format = 0; if (IsCollectionObject(mDataObject)) { // We know we have one of our special collection objects. format = nsClipboard::GetFormat(aDataFlavor); SET_FORMATETC(fe, format, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL | TYMED_FILE | TYMED_GDI); // See if any one of the IDataObjects in the collection supports // this data type nsDataObjCollection* dataObjCol = GetDataObjCollection(mDataObject); if (dataObjCol) { PRUint32 cnt = dataObjCol->GetNumDataObjects(); for (PRUint32 i=0;i<cnt;++i) { IDataObject * dataObj = dataObjCol->GetDataObjectAt(i); if (S_OK == dataObj->QueryGetData(&fe)) *_retval = PR_TRUE; // found it! } } } // if special collection object else { // Ok, so we have a single object. Check to see if has the correct // data type. Since this can come from an outside app, we also // need to see if we need to perform text->unicode conversion if // the client asked for unicode and it wasn't available. format = nsClipboard::GetFormat(aDataFlavor); SET_FORMATETC(fe, format, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL | TYMED_FILE | TYMED_GDI); if (mDataObject->QueryGetData(&fe) == S_OK) *_retval = PR_TRUE; // found it! else { // We haven't found the exact flavor the client asked for, but // maybe we can still find it from something else that's on the // clipboard if (strcmp(aDataFlavor, kUnicodeMime) == 0) { // client asked for unicode and it wasn't present, check if we // have CF_TEXT. We'll handle the actual data substitution in // the data object. format = nsClipboard::GetFormat(kTextMime); SET_FORMATETC(fe, format, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL | TYMED_FILE | TYMED_GDI); if (mDataObject->QueryGetData(&fe) == S_OK) *_retval = PR_TRUE; // found it! } else if (strcmp(aDataFlavor, kURLMime) == 0) { // client asked for a url and it wasn't present, but if we // have a file, then we have a URL to give them (the path, or // the internal URL if an InternetShortcut). format = nsClipboard::GetFormat(kFileMime); SET_FORMATETC(fe, format, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL | TYMED_FILE | TYMED_GDI); if (mDataObject->QueryGetData(&fe) == S_OK) *_retval = PR_TRUE; // found it! } } // else try again } return NS_OK; }