diff --git a/editor/base/nsEditorEventListeners.cpp b/editor/base/nsEditorEventListeners.cpp index c7fc7a3d0a0..f5e5f958941 100644 --- a/editor/base/nsEditorEventListeners.cpp +++ b/editor/base/nsEditorEventListeners.cpp @@ -50,6 +50,7 @@ #include "nsIFormatConverter.h" #include "nsIContentIterator.h" #include "nsIContent.h" +#include "nsISupportsPrimitives.h" #include "nsLayoutCID.h" // Drag & Drop, Clipboard Support @@ -1296,20 +1297,16 @@ nsTextEditorDragListener::DragGesture(nsIDOMEvent* aDragEvent) nsresult nsTextEditorDragListener::DragEnter(nsIDOMEvent* aDragEvent) { - nsIDragService* dragService; - nsresult rv = nsServiceManager::GetService(kCDragServiceCID, - nsIDragService::GetIID(), - (nsISupports **)&dragService); - if (NS_OK == rv) { + nsresult rv; + NS_WITH_SERVICE ( nsIDragService, dragService, kCDragServiceCID, &rv ); + if ( NS_SUCCEEDED(rv) ) { nsCOMPtr dragSession(do_QueryInterface(dragService)); - - nsAutoString textFlavor(kTextMime); - if (dragSession && - (NS_OK == dragSession->IsDataFlavorSupported(&textFlavor))) { - dragSession->SetCanDrop(PR_TRUE); + if ( dragSession ) { + PRBool flavorSupported = PR_FALSE; + dragSession->IsDataFlavorSupported(kTextMime, &flavorSupported); + if ( flavorSupported ) + dragSession->SetCanDrop(PR_TRUE); } - - nsServiceManager::ReleaseService(kCDragServiceCID, dragService); } return NS_OK; @@ -1319,18 +1316,16 @@ nsTextEditorDragListener::DragEnter(nsIDOMEvent* aDragEvent) nsresult nsTextEditorDragListener::DragOver(nsIDOMEvent* aDragEvent) { - nsIDragService* dragService; - nsresult rv = nsServiceManager::GetService(kCDragServiceCID, - nsIDragService::GetIID(), - (nsISupports **)&dragService); - if (NS_OK == rv) { + nsresult rv; + NS_WITH_SERVICE ( nsIDragService, dragService, kCDragServiceCID, &rv ); + if ( NS_SUCCEEDED(rv) ) { nsCOMPtr dragSession(do_QueryInterface(dragService)); - nsAutoString textFlavor(kTextMime); - if (dragSession && NS_OK == dragSession->IsDataFlavorSupported(&textFlavor)) { - dragSession->SetCanDrop(PR_TRUE); + if ( dragSession ) { + PRBool flavorSupported = PR_FALSE; + dragSession->IsDataFlavorSupported(kTextMime, &flavorSupported); + if ( flavorSupported ) + dragSession->SetCanDrop(PR_TRUE); } - - nsServiceManager::ReleaseService(kCDragServiceCID, dragService); } return NS_OK; @@ -1348,9 +1343,6 @@ nsTextEditorDragListener::DragExit(nsIDOMEvent* aDragEvent) nsresult nsTextEditorDragListener::DragDrop(nsIDOMEvent* aMouseEvent) { - // String for doing paste - nsString stuffToPaste; - // Create drag service for getting state of drag nsIDragService* dragService; nsresult rv = nsServiceManager::GetService(kCDragServiceCID, @@ -1370,8 +1362,7 @@ nsTextEditorDragListener::DragDrop(nsIDOMEvent* aMouseEvent) // Add the text Flavor to the transferable, // because that is the only type of data we are // looking for at the moment. - nsAutoString textMime (kTextMime); - trans->AddDataFlavor(&textMime); + trans->AddDataFlavor(kTextMime); //trans->AddDataFlavor(mImageDataFlavor); // Fill the transferable with data for each drag item in succession @@ -1386,17 +1377,19 @@ nsTextEditorDragListener::DragDrop(nsIDOMEvent* aMouseEvent) // Get the string data out of the transferable // Note: the transferable owns the pointer to the data - char *str = 0; + nsCOMPtr genericDataObj; PRUint32 len; - trans->GetAnyTransferData(&textMime, (void **)&str, &len); - + char* whichFlavor; + trans->GetAnyTransferData(&whichFlavor, getter_AddRefs(genericDataObj), &len); + nsCOMPtr textDataObj( do_QueryInterface(genericDataObj) ); // If the string was not empty then paste it in - if (str) + if ( textDataObj ) { + char* text = nsnull; + textDataObj->toString(&text); nsCOMPtr htmlEditor = do_QueryInterface(mEditor); - stuffToPaste.SetString(str, len); - if (htmlEditor) - htmlEditor->InsertText(stuffToPaste); + if ( htmlEditor && text ) + htmlEditor->InsertText(text); dragSession->SetCanDrop(PR_TRUE); } diff --git a/editor/base/nsHTMLEditor.cpp b/editor/base/nsHTMLEditor.cpp index f58f2ef7e40..f51c1e5b926 100644 --- a/editor/base/nsHTMLEditor.cpp +++ b/editor/base/nsHTMLEditor.cpp @@ -62,6 +62,7 @@ #include "nsIImage.h" #include "nsAOLCiter.h" #include "nsInternetCiter.h" +#include "nsISupportsPrimitives.h" // netwerk #include "nsIURI.h" @@ -2787,23 +2788,26 @@ NS_IMETHODIMP nsHTMLEditor::PasteAsPlaintextQuotation() if (NS_SUCCEEDED(rv) && trans) { // We only handle plaintext pastes here - nsAutoString flavor(kTextMime); - trans->AddDataFlavor(&flavor); + trans->AddDataFlavor(kTextMime); - // Get the Data from the clipboard + // Get the Data from the clipboard clipboard->GetData(trans); // Now we ask the transferable for the data // it still owns the data, we just have a pointer to it. // If it can't support a "text" output of the data the call will fail - char *str = 0; - PRUint32 len; - rv = trans->GetTransferData(&flavor, (void **)&str, &len); - if (NS_SUCCEEDED(rv) && str && len > 0) + nsCOMPtr genericDataObj; + PRUint32 len = 0; + rv = trans->GetTransferData(kTextMime, getter_AddRefs(genericDataObj), &len); + if (NS_SUCCEEDED(rv) && genericDataObj && len > 0) { - nsString stuffToPaste; - stuffToPaste.SetString(str, len); - rv = InsertAsPlaintextQuotation(stuffToPaste); + nsCOMPtr dataObj ( do_QueryInterface(genericDataObj) ); + if ( dataObj ) { + PRUnichar* textData = nsnull; + dataObj->toString ( &textData ); + nsAutoString text ( textData ); + rv = InsertAsPlaintextQuotation(text); + } } } nsServiceManager::ReleaseService(kCClipboardCID, clipboard); @@ -2989,11 +2993,11 @@ NS_IMETHODIMP nsHTMLEditor::Paste() nsString stuffToPaste; // Get Clipboard Service - nsIClipboard* clipboard; - nsresult rv = nsServiceManager::GetService(kCClipboardCID, - nsIClipboard::GetIID(), - (nsISupports **)&clipboard); - + nsresult rv; + NS_WITH_SERVICE ( nsIClipboard, clipboard, kCClipboardCID, &rv ); + if ( NS_FAILED(rv) ) + return rv; + // Create generic Transferable for getting the data nsCOMPtr trans; rv = nsComponentManager::CreateInstance(kCTransferableCID, nsnull, @@ -3006,45 +3010,50 @@ NS_IMETHODIMP nsHTMLEditor::Paste() { // Create the desired DataFlavor for the type of data // we want to get out of the transferable - nsAutoString imageFlavor(kJPEGImageMime); - nsAutoString htmlFlavor(kHTMLMime); - nsAutoString textFlavor(kTextMime); - if ((mFlags & eEditorPlaintextMask) == 0) // This should only happen in html editors, not plaintext { - trans->AddDataFlavor(&imageFlavor); - trans->AddDataFlavor(&htmlFlavor); + trans->AddDataFlavor(kJPEGImageMime); + trans->AddDataFlavor(kHTMLMime); } - trans->AddDataFlavor(&textFlavor); + trans->AddDataFlavor(kTextMime); // Get the Data from the clipboard if (NS_SUCCEEDED(clipboard->GetData(trans))) { - nsAutoString flavor; - char * data; - PRUint32 len; - if (NS_SUCCEEDED(trans->GetAnyTransferData(&flavor, (void **)&data, &len))) + char* bestFlavor = nsnull; + nsCOMPtr genericDataObj; + PRUint32 len = 0; + if ( NS_SUCCEEDED(trans->GetAnyTransferData(&bestFlavor, getter_AddRefs(genericDataObj), &len)) ) { + nsAutoString flavor ( bestFlavor ); // just so we can use flavor.Equals() #ifdef DEBUG_akkana - printf("Got flavor [%s]\n", flavor.ToNewCString()); + printf("Got flavor [%s]\n", flavor); #endif - if (flavor.Equals(htmlFlavor)) + if (flavor.Equals(kHTMLMime)) { - if (data && len > 0) // stuffToPaste is ready for insertion into the content + nsCOMPtr textDataObj ( do_QueryInterface(genericDataObj) ); + if (textDataObj && len > 0) { - stuffToPaste.SetString((PRUnichar *)data, len/2); + PRUnichar* text = nsnull; + textDataObj->toString ( &text ); + nsAutoString stuffToPaste; + stuffToPaste.SetString ( text, len / 2 ); rv = InsertHTML(stuffToPaste); } } - else if (flavor.Equals(textFlavor)) + else if (flavor.Equals(kTextMime)) { - if (data && len > 0) // stuffToPaste is ready for insertion into the content + nsCOMPtr textDataObj ( do_QueryInterface(genericDataObj) ); + if (textDataObj && len > 0) { - stuffToPaste.SetString(data, len); + char* text = nsnull; + textDataObj->toString ( &text ); + nsAutoString stuffToPaste; + stuffToPaste.SetString ( text, len ); rv = InsertText(stuffToPaste); } } - else if (flavor.Equals(imageFlavor)) + else if (flavor.Equals(kJPEGImageMime)) { // Insert Image code here printf("Don't know how to insert an image yet!\n"); @@ -3057,7 +3066,6 @@ NS_IMETHODIMP nsHTMLEditor::Paste() } } } - nsServiceManager::ReleaseService(kCClipboardCID, clipboard); return rv; } diff --git a/editor/libeditor/html/nsHTMLEditor.cpp b/editor/libeditor/html/nsHTMLEditor.cpp index f58f2ef7e40..f51c1e5b926 100644 --- a/editor/libeditor/html/nsHTMLEditor.cpp +++ b/editor/libeditor/html/nsHTMLEditor.cpp @@ -62,6 +62,7 @@ #include "nsIImage.h" #include "nsAOLCiter.h" #include "nsInternetCiter.h" +#include "nsISupportsPrimitives.h" // netwerk #include "nsIURI.h" @@ -2787,23 +2788,26 @@ NS_IMETHODIMP nsHTMLEditor::PasteAsPlaintextQuotation() if (NS_SUCCEEDED(rv) && trans) { // We only handle plaintext pastes here - nsAutoString flavor(kTextMime); - trans->AddDataFlavor(&flavor); + trans->AddDataFlavor(kTextMime); - // Get the Data from the clipboard + // Get the Data from the clipboard clipboard->GetData(trans); // Now we ask the transferable for the data // it still owns the data, we just have a pointer to it. // If it can't support a "text" output of the data the call will fail - char *str = 0; - PRUint32 len; - rv = trans->GetTransferData(&flavor, (void **)&str, &len); - if (NS_SUCCEEDED(rv) && str && len > 0) + nsCOMPtr genericDataObj; + PRUint32 len = 0; + rv = trans->GetTransferData(kTextMime, getter_AddRefs(genericDataObj), &len); + if (NS_SUCCEEDED(rv) && genericDataObj && len > 0) { - nsString stuffToPaste; - stuffToPaste.SetString(str, len); - rv = InsertAsPlaintextQuotation(stuffToPaste); + nsCOMPtr dataObj ( do_QueryInterface(genericDataObj) ); + if ( dataObj ) { + PRUnichar* textData = nsnull; + dataObj->toString ( &textData ); + nsAutoString text ( textData ); + rv = InsertAsPlaintextQuotation(text); + } } } nsServiceManager::ReleaseService(kCClipboardCID, clipboard); @@ -2989,11 +2993,11 @@ NS_IMETHODIMP nsHTMLEditor::Paste() nsString stuffToPaste; // Get Clipboard Service - nsIClipboard* clipboard; - nsresult rv = nsServiceManager::GetService(kCClipboardCID, - nsIClipboard::GetIID(), - (nsISupports **)&clipboard); - + nsresult rv; + NS_WITH_SERVICE ( nsIClipboard, clipboard, kCClipboardCID, &rv ); + if ( NS_FAILED(rv) ) + return rv; + // Create generic Transferable for getting the data nsCOMPtr trans; rv = nsComponentManager::CreateInstance(kCTransferableCID, nsnull, @@ -3006,45 +3010,50 @@ NS_IMETHODIMP nsHTMLEditor::Paste() { // Create the desired DataFlavor for the type of data // we want to get out of the transferable - nsAutoString imageFlavor(kJPEGImageMime); - nsAutoString htmlFlavor(kHTMLMime); - nsAutoString textFlavor(kTextMime); - if ((mFlags & eEditorPlaintextMask) == 0) // This should only happen in html editors, not plaintext { - trans->AddDataFlavor(&imageFlavor); - trans->AddDataFlavor(&htmlFlavor); + trans->AddDataFlavor(kJPEGImageMime); + trans->AddDataFlavor(kHTMLMime); } - trans->AddDataFlavor(&textFlavor); + trans->AddDataFlavor(kTextMime); // Get the Data from the clipboard if (NS_SUCCEEDED(clipboard->GetData(trans))) { - nsAutoString flavor; - char * data; - PRUint32 len; - if (NS_SUCCEEDED(trans->GetAnyTransferData(&flavor, (void **)&data, &len))) + char* bestFlavor = nsnull; + nsCOMPtr genericDataObj; + PRUint32 len = 0; + if ( NS_SUCCEEDED(trans->GetAnyTransferData(&bestFlavor, getter_AddRefs(genericDataObj), &len)) ) { + nsAutoString flavor ( bestFlavor ); // just so we can use flavor.Equals() #ifdef DEBUG_akkana - printf("Got flavor [%s]\n", flavor.ToNewCString()); + printf("Got flavor [%s]\n", flavor); #endif - if (flavor.Equals(htmlFlavor)) + if (flavor.Equals(kHTMLMime)) { - if (data && len > 0) // stuffToPaste is ready for insertion into the content + nsCOMPtr textDataObj ( do_QueryInterface(genericDataObj) ); + if (textDataObj && len > 0) { - stuffToPaste.SetString((PRUnichar *)data, len/2); + PRUnichar* text = nsnull; + textDataObj->toString ( &text ); + nsAutoString stuffToPaste; + stuffToPaste.SetString ( text, len / 2 ); rv = InsertHTML(stuffToPaste); } } - else if (flavor.Equals(textFlavor)) + else if (flavor.Equals(kTextMime)) { - if (data && len > 0) // stuffToPaste is ready for insertion into the content + nsCOMPtr textDataObj ( do_QueryInterface(genericDataObj) ); + if (textDataObj && len > 0) { - stuffToPaste.SetString(data, len); + char* text = nsnull; + textDataObj->toString ( &text ); + nsAutoString stuffToPaste; + stuffToPaste.SetString ( text, len ); rv = InsertText(stuffToPaste); } } - else if (flavor.Equals(imageFlavor)) + else if (flavor.Equals(kJPEGImageMime)) { // Insert Image code here printf("Don't know how to insert an image yet!\n"); @@ -3057,7 +3066,6 @@ NS_IMETHODIMP nsHTMLEditor::Paste() } } } - nsServiceManager::ReleaseService(kCClipboardCID, clipboard); return rv; } diff --git a/editor/libeditor/text/nsEditorEventListeners.cpp b/editor/libeditor/text/nsEditorEventListeners.cpp index c7fc7a3d0a0..f5e5f958941 100644 --- a/editor/libeditor/text/nsEditorEventListeners.cpp +++ b/editor/libeditor/text/nsEditorEventListeners.cpp @@ -50,6 +50,7 @@ #include "nsIFormatConverter.h" #include "nsIContentIterator.h" #include "nsIContent.h" +#include "nsISupportsPrimitives.h" #include "nsLayoutCID.h" // Drag & Drop, Clipboard Support @@ -1296,20 +1297,16 @@ nsTextEditorDragListener::DragGesture(nsIDOMEvent* aDragEvent) nsresult nsTextEditorDragListener::DragEnter(nsIDOMEvent* aDragEvent) { - nsIDragService* dragService; - nsresult rv = nsServiceManager::GetService(kCDragServiceCID, - nsIDragService::GetIID(), - (nsISupports **)&dragService); - if (NS_OK == rv) { + nsresult rv; + NS_WITH_SERVICE ( nsIDragService, dragService, kCDragServiceCID, &rv ); + if ( NS_SUCCEEDED(rv) ) { nsCOMPtr dragSession(do_QueryInterface(dragService)); - - nsAutoString textFlavor(kTextMime); - if (dragSession && - (NS_OK == dragSession->IsDataFlavorSupported(&textFlavor))) { - dragSession->SetCanDrop(PR_TRUE); + if ( dragSession ) { + PRBool flavorSupported = PR_FALSE; + dragSession->IsDataFlavorSupported(kTextMime, &flavorSupported); + if ( flavorSupported ) + dragSession->SetCanDrop(PR_TRUE); } - - nsServiceManager::ReleaseService(kCDragServiceCID, dragService); } return NS_OK; @@ -1319,18 +1316,16 @@ nsTextEditorDragListener::DragEnter(nsIDOMEvent* aDragEvent) nsresult nsTextEditorDragListener::DragOver(nsIDOMEvent* aDragEvent) { - nsIDragService* dragService; - nsresult rv = nsServiceManager::GetService(kCDragServiceCID, - nsIDragService::GetIID(), - (nsISupports **)&dragService); - if (NS_OK == rv) { + nsresult rv; + NS_WITH_SERVICE ( nsIDragService, dragService, kCDragServiceCID, &rv ); + if ( NS_SUCCEEDED(rv) ) { nsCOMPtr dragSession(do_QueryInterface(dragService)); - nsAutoString textFlavor(kTextMime); - if (dragSession && NS_OK == dragSession->IsDataFlavorSupported(&textFlavor)) { - dragSession->SetCanDrop(PR_TRUE); + if ( dragSession ) { + PRBool flavorSupported = PR_FALSE; + dragSession->IsDataFlavorSupported(kTextMime, &flavorSupported); + if ( flavorSupported ) + dragSession->SetCanDrop(PR_TRUE); } - - nsServiceManager::ReleaseService(kCDragServiceCID, dragService); } return NS_OK; @@ -1348,9 +1343,6 @@ nsTextEditorDragListener::DragExit(nsIDOMEvent* aDragEvent) nsresult nsTextEditorDragListener::DragDrop(nsIDOMEvent* aMouseEvent) { - // String for doing paste - nsString stuffToPaste; - // Create drag service for getting state of drag nsIDragService* dragService; nsresult rv = nsServiceManager::GetService(kCDragServiceCID, @@ -1370,8 +1362,7 @@ nsTextEditorDragListener::DragDrop(nsIDOMEvent* aMouseEvent) // Add the text Flavor to the transferable, // because that is the only type of data we are // looking for at the moment. - nsAutoString textMime (kTextMime); - trans->AddDataFlavor(&textMime); + trans->AddDataFlavor(kTextMime); //trans->AddDataFlavor(mImageDataFlavor); // Fill the transferable with data for each drag item in succession @@ -1386,17 +1377,19 @@ nsTextEditorDragListener::DragDrop(nsIDOMEvent* aMouseEvent) // Get the string data out of the transferable // Note: the transferable owns the pointer to the data - char *str = 0; + nsCOMPtr genericDataObj; PRUint32 len; - trans->GetAnyTransferData(&textMime, (void **)&str, &len); - + char* whichFlavor; + trans->GetAnyTransferData(&whichFlavor, getter_AddRefs(genericDataObj), &len); + nsCOMPtr textDataObj( do_QueryInterface(genericDataObj) ); // If the string was not empty then paste it in - if (str) + if ( textDataObj ) { + char* text = nsnull; + textDataObj->toString(&text); nsCOMPtr htmlEditor = do_QueryInterface(mEditor); - stuffToPaste.SetString(str, len); - if (htmlEditor) - htmlEditor->InsertText(stuffToPaste); + if ( htmlEditor && text ) + htmlEditor->InsertText(text); dragSession->SetCanDrop(PR_TRUE); } diff --git a/layout/base/nsPresShell.cpp b/layout/base/nsPresShell.cpp index 05969a2fd9f..acc50d0422c 100644 --- a/layout/base/nsPresShell.cpp +++ b/layout/base/nsPresShell.cpp @@ -60,6 +60,7 @@ #include "nsIFrameSelection.h" #include "nsViewsCID.h" #include "nsIFrameManager.h" +#include "nsISupportsPrimitives.h" // Drag & Drop, Clipboard #include "nsWidgetsCID.h" @@ -1462,43 +1463,46 @@ PresShell::DoCopy() NS_IF_RELEASE(sel); // Get the Clipboard - nsIClipboard* clipboard; + nsIClipboard* clipboard = nsnull; nsresult rv = nsServiceManager::GetService(kCClipboardCID, nsIClipboard::GetIID(), (nsISupports **)&clipboard); - if (NS_OK == rv) { - - // Create a data flavor to tell the transferable - // that it is about to receive XIF - nsAutoString flavor(kXIFMime); - + if ( clipboard ) { // Create a transferable for putting data on the Clipboard nsCOMPtr trans; rv = nsComponentManager::CreateInstance(kCTransferableCID, nsnull, nsITransferable::GetIID(), (void**) getter_AddRefs(trans)); - if (NS_OK == rv) { + if ( trans ) { // The data on the clipboard will be in "XIF" format // so give the clipboard transferable a "XIFConverter" for // converting from XIF to other formats nsCOMPtr xifConverter; rv = nsComponentManager::CreateInstance(kCXIFConverterCID, nsnull, - nsIFormatConverter::GetIID(), (void**) getter_AddRefs(xifConverter)); - if (NS_OK == rv) { + NS_GET_IID(nsIFormatConverter), getter_AddRefs(xifConverter)); + if ( xifConverter ) { // Add the XIF DataFlavor to the transferable // this tells the transferable that it can handle receiving the XIF format - trans->AddDataFlavor(&flavor); + trans->AddDataFlavor(kXIFMime); // Add the converter for going from XIF to other formats trans->SetConverter(xifConverter); - // Now add the XIF data to the transferable + // Now add the XIF data to the transferable, placing it into a nsISupportsWString object. // the transferable wants the number bytes for the data and since it is double byte - // we multiply by 2 - trans->SetTransferData(&flavor, buffer.ToNewUnicode(), buffer.Length()*2); - //trans->SetTransferData(&flavor, buffer.ToNewCString(), buffer.Length()); - + // we multiply by 2. + nsCOMPtr dataWrapper; + rv = nsComponentManager::CreateInstance(NS_SUPPORTS_WSTRING_PROGID, nsnull, + NS_GET_IID(nsISupportsWString), getter_AddRefs(dataWrapper)); + if ( dataWrapper ) { + dataWrapper->SetData ( NS_CONST_CAST(PRUnichar*,buffer.GetUnicode()) ); + // QI the data object an |nsISupports| so that when the transferable holds + // onto it, it will addref the correct interface. + nsCOMPtr genericDataObj ( do_QueryInterface(dataWrapper) ); + trans->SetTransferData(kXIFMime, genericDataObj, buffer.Length()*2); + } + // put the transferable on the clipboard clipboard->SetData(trans, nsnull); } diff --git a/layout/html/base/src/nsPresShell.cpp b/layout/html/base/src/nsPresShell.cpp index 05969a2fd9f..acc50d0422c 100644 --- a/layout/html/base/src/nsPresShell.cpp +++ b/layout/html/base/src/nsPresShell.cpp @@ -60,6 +60,7 @@ #include "nsIFrameSelection.h" #include "nsViewsCID.h" #include "nsIFrameManager.h" +#include "nsISupportsPrimitives.h" // Drag & Drop, Clipboard #include "nsWidgetsCID.h" @@ -1462,43 +1463,46 @@ PresShell::DoCopy() NS_IF_RELEASE(sel); // Get the Clipboard - nsIClipboard* clipboard; + nsIClipboard* clipboard = nsnull; nsresult rv = nsServiceManager::GetService(kCClipboardCID, nsIClipboard::GetIID(), (nsISupports **)&clipboard); - if (NS_OK == rv) { - - // Create a data flavor to tell the transferable - // that it is about to receive XIF - nsAutoString flavor(kXIFMime); - + if ( clipboard ) { // Create a transferable for putting data on the Clipboard nsCOMPtr trans; rv = nsComponentManager::CreateInstance(kCTransferableCID, nsnull, nsITransferable::GetIID(), (void**) getter_AddRefs(trans)); - if (NS_OK == rv) { + if ( trans ) { // The data on the clipboard will be in "XIF" format // so give the clipboard transferable a "XIFConverter" for // converting from XIF to other formats nsCOMPtr xifConverter; rv = nsComponentManager::CreateInstance(kCXIFConverterCID, nsnull, - nsIFormatConverter::GetIID(), (void**) getter_AddRefs(xifConverter)); - if (NS_OK == rv) { + NS_GET_IID(nsIFormatConverter), getter_AddRefs(xifConverter)); + if ( xifConverter ) { // Add the XIF DataFlavor to the transferable // this tells the transferable that it can handle receiving the XIF format - trans->AddDataFlavor(&flavor); + trans->AddDataFlavor(kXIFMime); // Add the converter for going from XIF to other formats trans->SetConverter(xifConverter); - // Now add the XIF data to the transferable + // Now add the XIF data to the transferable, placing it into a nsISupportsWString object. // the transferable wants the number bytes for the data and since it is double byte - // we multiply by 2 - trans->SetTransferData(&flavor, buffer.ToNewUnicode(), buffer.Length()*2); - //trans->SetTransferData(&flavor, buffer.ToNewCString(), buffer.Length()); - + // we multiply by 2. + nsCOMPtr dataWrapper; + rv = nsComponentManager::CreateInstance(NS_SUPPORTS_WSTRING_PROGID, nsnull, + NS_GET_IID(nsISupportsWString), getter_AddRefs(dataWrapper)); + if ( dataWrapper ) { + dataWrapper->SetData ( NS_CONST_CAST(PRUnichar*,buffer.GetUnicode()) ); + // QI the data object an |nsISupports| so that when the transferable holds + // onto it, it will addref the correct interface. + nsCOMPtr genericDataObj ( do_QueryInterface(dataWrapper) ); + trans->SetTransferData(kXIFMime, genericDataObj, buffer.Length()*2); + } + // put the transferable on the clipboard clipboard->SetData(trans, nsnull); } diff --git a/layout/xul/base/src/nsToolbarDragListener.cpp b/layout/xul/base/src/nsToolbarDragListener.cpp index 53c5ddbc3db..b48316690b0 100644 --- a/layout/xul/base/src/nsToolbarDragListener.cpp +++ b/layout/xul/base/src/nsToolbarDragListener.cpp @@ -32,6 +32,7 @@ #include "nsIDOMElement.h" #include "nsXULAtoms.h" #include "nsIEventStateManager.h" +#include "nsISupportsPrimitives.h" #include "nsISupportsArray.h" #include "nsIViewManager.h" @@ -153,20 +154,17 @@ nsToolbarDragListener::DragGesture(nsIDOMEvent* aDragEvent) if (isLegalChild) { // Start Drag - nsIDragService* dragService; - rv = nsServiceManager::GetService(kCDragServiceCID, - nsIDragService::GetIID(), - (nsISupports **)&dragService); - if (NS_OK == rv) { + NS_WITH_SERVICE ( nsIDragService, dragService, kCDragServiceCID, &rv ); + if ( NS_SUCCEEDED(rv) ) { // XXX NOTE! // Here you need to create a special transferable // for handling RDF nodes (instead of this text transferable) nsCOMPtr trans; rv = nsComponentManager::CreateInstance(kCTransferableCID, nsnull, nsITransferable::GetIID(), getter_AddRefs(trans)); - if (NS_OK == rv && trans) { - nsString ddFlavor; - nsString dragText; + if ( trans ) { + const char* ddFlavor; + nsAutoString dragText; if (onChild) { ddFlavor = TOOLBARITEM_MIME; dragText = "toolbar item"; @@ -174,22 +172,35 @@ nsToolbarDragListener::DragGesture(nsIDOMEvent* aDragEvent) ddFlavor = TOOLBAR_MIME; dragText = "toolbar"; } - trans->AddDataFlavor(&ddFlavor); - PRUint32 len = dragText.Length(); - trans->SetTransferData(&ddFlavor, dragText.ToNewCString(), len); // transferable consumes the data + trans->AddDataFlavor(ddFlavor); + PRUint32 len = dragText.Length() * 2; // len of unicode + nsCOMPtr dataObj; // hack note: has to be wstring because not plain text flavor + rv = nsComponentManager::CreateInstance(NS_SUPPORTS_WSTRING_PROGID, nsnull, + NS_GET_IID(nsISupportsWString), getter_AddRefs(dataObj)); + if ( dataObj ) { + PRUnichar* data = dragText.ToNewUnicode(); + dataObj->SetData ( data ); + // QI the data object an |nsISupports| so that when the transferable holds + // onto it, it will addref the correct interface. + nsCOMPtr genericDataObj ( do_QueryInterface(dataObj) ); + trans->SetTransferData(ddFlavor, genericDataObj, len); - nsCOMPtr items; - NS_NewISupportsArray(getter_AddRefs(items)); - if ( items ) { - items->AppendElement(trans); - dragService->InvokeDragSession(items, nsnull, nsIDragService::DRAGDROP_ACTION_COPY | nsIDragService::DRAGDROP_ACTION_MOVE); + nsCOMPtr items; + NS_NewISupportsArray(getter_AddRefs(items)); + if ( items ) { + // QI the transferable to an |nsISupports| so that when the array holds + // onto it, it will addref the correct interface. + nsCOMPtr genericTrans ( do_QueryInterface(trans) ); + items->AppendElement(genericTrans); + dragService->InvokeDragSession(items, nsnull, nsIDragService::DRAGDROP_ACTION_COPY | nsIDragService::DRAGDROP_ACTION_MOVE); + } + delete [] data; } } - nsServiceManager::ReleaseService(kCDragServiceCID, dragService); } - } else { // when it is isn't a legal child then don't consume + } else // when it is isn't a legal child then don't consume return NS_OK; // don't consume event - } + rv = NS_ERROR_BASE; // consumes the event } return rv; @@ -202,22 +213,25 @@ nsToolbarDragListener::DragEnter(nsIDOMEvent* aDragEvent) { mCurrentDropLoc = -1; - nsIDragService* dragService; - nsresult rv = nsServiceManager::GetService(kCDragServiceCID, - nsIDragService::GetIID(), - (nsISupports **)&dragService); - if (NS_OK == rv) { + nsresult rv; + NS_WITH_SERVICE ( nsIDragService, dragService, kCDragServiceCID, &rv ); + if ( NS_SUCCEEDED(rv) ) { nsCOMPtr dragSession(do_QueryInterface(dragService)); - nsAutoString toolbarItemFlavor(TOOLBARITEM_MIME); - if (dragSession && (NS_OK == dragSession->IsDataFlavorSupported(&toolbarItemFlavor))) { - dragSession->SetCanDrop(PR_TRUE); - } else { - rv = NS_ERROR_BASE; // don't consume event + if ( dragSession ) { + PRBool flavorSupported = PR_FALSE; + dragSession->IsDataFlavorSupported ( TOOLBARITEM_MIME, &flavorSupported ); + if ( flavorSupported ) { + dragSession->SetCanDrop(PR_TRUE); + rv = NS_ERROR_BASE; // consume event + } + else + rv = NS_OK; // don't consume event } - - nsServiceManager::ReleaseService(kCDragServiceCID, dragService); } + else + rv = NS_OK; + return rv; } @@ -350,33 +364,36 @@ nsToolbarDragListener::DragOver(nsIDOMEvent* aDragEvent) nsresult rv = nsServiceManager::GetService(kCDragServiceCID, nsIDragService::GetIID(), (nsISupports **)&dragService); - if (NS_OK == rv) { + if ( NS_SUCCEEDED(rv) ) { nsCOMPtr dragSession(do_QueryInterface(dragService)); - nsAutoString toolbarItemFlavor(TOOLBARITEM_MIME); - if (dragSession && NS_OK == dragSession->IsDataFlavorSupported(&toolbarItemFlavor)) { - dragSession->SetCanDrop(PR_TRUE); + if ( dragSession ) { + PRBool flavorSupported = PR_FALSE; + dragSession->IsDataFlavorSupported(TOOLBARITEM_MIME, &flavorSupported); + if ( flavorSupported ) { + dragSession->SetCanDrop(PR_TRUE); - // Check to see if the mouse is over an item - nscoord xLoc; - PRBool isLegalChild; - IsOnToolbarItem(aDragEvent, xLoc, isLegalChild); + // Check to see if the mouse is over an item + nscoord xLoc; + PRBool isLegalChild; + IsOnToolbarItem(aDragEvent, xLoc, isLegalChild); - if (xLoc != mCurrentDropLoc) { - mToolbar->SetDropfeedbackLocation(xLoc); + if (xLoc != mCurrentDropLoc) { + mToolbar->SetDropfeedbackLocation(xLoc); - // force the toolbar frame to redraw - ForceDrawFrame(mToolbar); + // force the toolbar frame to redraw + ForceDrawFrame(mToolbar); - // cache the current drop location - mCurrentDropLoc = xLoc; + // cache the current drop location + mCurrentDropLoc = xLoc; - rv = NS_ERROR_BASE; // means I am consuming the event - } - } + rv = NS_ERROR_BASE; // means I am consuming the event + } + } + } nsServiceManager::ReleaseService(kCDragServiceCID, dragService); - } else { + } + else rv = NS_OK; // don't consume event - } // NS_OK means event is NOT consumed return rv; @@ -388,23 +405,22 @@ nsresult nsToolbarDragListener::DragExit(nsIDOMEvent* aDragEvent) { // now tell the drag session whether we can drop here - nsIDragService* dragService; - nsresult rv = nsServiceManager::GetService(kCDragServiceCID, - nsIDragService::GetIID(), - (nsISupports **)&dragService); - if (NS_OK == rv) { + nsresult rv; + NS_WITH_SERVICE ( nsIDragService, dragService, kCDragServiceCID, &rv ); + if ( NS_SUCCEEDED(rv) ) { nsCOMPtr dragSession(do_QueryInterface(dragService)); - nsAutoString toolbarItemFlavor(TOOLBARITEM_MIME); - if (dragSession && NS_OK == dragSession->IsDataFlavorSupported(&toolbarItemFlavor)) { - mToolbar->SetDropfeedbackLocation(-1); // clears drawing of marker - ForceDrawFrame(mToolbar); - rv = NS_ERROR_BASE; // consume event - } - - nsServiceManager::ReleaseService(kCDragServiceCID, dragService); - } else { - rv = NS_OK; // don't consume event + if ( dragSession ) { + PRBool flavorSupported = PR_FALSE; + dragSession->IsDataFlavorSupported(TOOLBARITEM_MIME, &flavorSupported); + if ( flavorSupported ) { + mToolbar->SetDropfeedbackLocation(-1); // clears drawing of marker + ForceDrawFrame(mToolbar); + rv = NS_ERROR_BASE; // consume event + } + } } + else + rv = NS_OK; // don't consume event return rv; } @@ -422,9 +438,6 @@ nsToolbarDragListener::DragDrop(nsIDOMEvent* aMouseEvent) // that will be translated into some RDF form ForceDrawFrame(mToolbar); - // String for doing paste - nsString stuffToPaste; - // Create drag service for getting state of drag nsIDragService* dragService; nsresult rv = nsServiceManager::GetService(kCDragServiceCID, @@ -441,13 +454,10 @@ nsToolbarDragListener::DragDrop(nsIDOMEvent* aMouseEvent) nsITransferable::GetIID(), (void**) getter_AddRefs(trans)); if ( NS_SUCCEEDED(rv) && trans ) { - // Add the text Flavor to the transferable, - // because that is the only type of data we are - // looking for at the moment. - nsAutoString toolbarItemMime (TOOLBARITEM_MIME); - trans->AddDataFlavor(&toolbarItemMime); - //trans->AddDataFlavor(mImageDataFlavor); - + // Add the toolbar item flavor to the transferable, + // because that is the only type of data we are looking for at the moment. + trans->AddDataFlavor(TOOLBARITEM_MIME); + // Fill the transferable with data for each drag item in succession PRUint32 numItems = 0; if (NS_SUCCEEDED(dragSession->GetNumDropItems(&numItems))) { @@ -458,26 +468,28 @@ nsToolbarDragListener::DragDrop(nsIDOMEvent* aMouseEvent) for (i=0;iGetData(trans, i))) { - // Get the string data out of the transferable - // Note: the transferable owns the pointer to the data - char *str = 0; + // Get the string data out of the transferable. This obviously needs to be rewritten ;) PRUint32 len; - trans->GetAnyTransferData(&toolbarItemMime, (void **)&str, &len); - - // If the string was not empty then paste it in - if (str) { - char buf[256]; - strncpy(buf, str, len); - buf[len] = 0; - printf("Dropped: %s\n", buf); - stuffToPaste.SetString(str, len); - //mEditor->InsertText(stuffToPaste); - dragSession->SetCanDrop(PR_TRUE); + char* toolbarItemMime; + nsCOMPtr genericDataObj; + trans->GetAnyTransferData(&toolbarItemMime, getter_AddRefs(genericDataObj), &len); + if ( genericDataObj ) { + nsCOMPtr dataObj ( do_QueryInterface(genericDataObj) ); + if ( dataObj ) { + // If the string was not empty then paste it in + PRUnichar* buf; + dataObj->toString(&buf); + if ( buf ) { + nsAutoString converter(buf); + char* lame = converter.ToNewCString(); + printf("Dropped Data: %s\n", lame); + //XXX do real stuff here + dragSession->SetCanDrop(PR_TRUE); + delete [] lame; + } + delete [] buf; + } } - - // XXX This is where image support might go - //void * data; - //trans->GetTransferData(mImageDataFlavor, (void **)&data, &len); } } // foreach drag item diff --git a/layout/xul/base/src/nsToolboxFrame.cpp b/layout/xul/base/src/nsToolboxFrame.cpp index f4965567e78..367fe56ad83 100644 --- a/layout/xul/base/src/nsToolboxFrame.cpp +++ b/layout/xul/base/src/nsToolboxFrame.cpp @@ -50,6 +50,9 @@ #include "nsIDOMDragListener.h" #include "nsIDOMEventReceiver.h" #include "nsIDOMEventListener.h" +#include "nsISupportsPrimitives.h" +#include "nsISupportsArray.h" + // Drag & Drop, Clipboard Support static NS_DEFINE_CID(kCDragServiceCID, NS_DRAGSERVICE_CID); @@ -57,11 +60,6 @@ static NS_DEFINE_CID(kCTransferableCID, NS_TRANSFERABLE_CID); static NS_DEFINE_IID(kCDataFlavorCID, NS_DATAFLAVOR_CID); static NS_DEFINE_IID(kCXIFFormatConverterCID, NS_XIFFORMATCONVERTER_CID); -static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); -static NS_DEFINE_IID(kIDOMEventReceiverIID, NS_IDOMEVENTRECEIVER_IID); - -#include "nsISupportsArray.h" - NS_IMPL_ADDREF(nsToolboxFrame::DragListenerDelegate); NS_IMPL_RELEASE(nsToolboxFrame::DragListenerDelegate); @@ -590,21 +588,6 @@ nsToolboxFrame :: HandleEvent ( nsIPresContext& aPresContext, OnMouseExit ( ); break; - case NS_DRAGDROP_ENTER: - // show drop feedback - break; - - case NS_DRAGDROP_OVER: - break; - - case NS_DRAGDROP_EXIT: - // remove drop feedback - break; - - case NS_DRAGDROP_DROP: - // do drop coolness stuff - break; - default: break; @@ -771,13 +754,16 @@ nsToolboxFrame::DragEnter(nsIDOMEvent* aDragEvent) nsresult rv = nsServiceManager::GetService(kCDragServiceCID, nsIDragService::GetIID(), (nsISupports **)&dragService); - if (NS_OK == rv) { + if ( NS_SUCCEEDED(rv) ) { nsCOMPtr dragSession(do_QueryInterface(dragService)); - nsAutoString toolbarFlavor(TOOLBAR_MIME); - if (dragSession && (NS_OK == dragSession->IsDataFlavorSupported(&toolbarFlavor))) { - dragSession->SetCanDrop(PR_TRUE); - rv = NS_ERROR_BASE; // consume event + if ( dragSession ) { + PRBool flavorSupported = PR_FALSE; + dragSession->IsDataFlavorSupported(TOOLBAR_MIME, &flavorSupported); + if ( flavorSupported ) { + dragSession->SetCanDrop(PR_TRUE); + rv = NS_ERROR_BASE; // consume event + } } nsServiceManager::ReleaseService(kCDragServiceCID, dragService); @@ -794,19 +780,20 @@ nsToolboxFrame::DragOver(nsIDOMEvent* aDragEvent) { // now tell the drag session whether we can drop here nsIDragService* dragService; - nsresult rv = nsServiceManager::GetService(kCDragServiceCID, - nsIDragService::GetIID(), - (nsISupports **)&dragService); - if (NS_OK == rv) { + nsresult rv = nsServiceManager::GetService(kCDragServiceCID, nsIDragService::GetIID(), + (nsISupports **)&dragService); + if ( NS_SUCCEEDED(rv) ) { nsCOMPtr dragSession(do_QueryInterface(dragService)); - nsAutoString toolbarFlavor(TOOLBAR_MIME); - if (dragSession && NS_OK == dragSession->IsDataFlavorSupported(&toolbarFlavor)) { + if ( dragSession ) { + PRBool flavorSupported = PR_FALSE; + dragSession->IsDataFlavorSupported(TOOLBAR_MIME, &flavorSupported); + if ( flavorSupported ) { + // Right here you need to figure out where the mouse is + // and whether you can drop here - // Right here you need to figure out where the mouse is - // and whether you can drop here - - dragSession->SetCanDrop(PR_TRUE); - rv = NS_ERROR_BASE; // consume event + dragSession->SetCanDrop(PR_TRUE); + rv = NS_ERROR_BASE; // consume event + } } nsServiceManager::ReleaseService(kCDragServiceCID, dragService); @@ -830,9 +817,6 @@ nsToolboxFrame::DragExit(nsIDOMEvent* aDragEvent) nsresult nsToolboxFrame::DragDrop(nsIDOMEvent* aMouseEvent) { - // String for doing paste - nsString stuffToPaste; - // Create drag service for getting state of drag nsIDragService* dragService; nsresult rv = nsServiceManager::GetService(kCDragServiceCID, @@ -849,12 +833,9 @@ nsToolboxFrame::DragDrop(nsIDOMEvent* aMouseEvent) nsITransferable::GetIID(), (void**) getter_AddRefs(trans)); if ( NS_SUCCEEDED(rv) && trans ) { - // Add the text Flavor to the transferable, - // because that is the only type of data we are + // Add the toolbar Flavor to the transferable, because that is the only type of data we are // looking for at the moment. - nsAutoString toolbarMime (TOOLBAR_MIME); - trans->AddDataFlavor(&toolbarMime); - //trans->AddDataFlavor(mImageDataFlavor); + trans->AddDataFlavor(TOOLBAR_MIME); // Fill the transferable with data for each drag item in succession PRUint32 numItems = 0; @@ -866,19 +847,18 @@ nsToolboxFrame::DragDrop(nsIDOMEvent* aMouseEvent) for (i=0;iGetData(trans, i))) { - // Get the string data out of the transferable - // Note: the transferable owns the pointer to the data - char *str = 0; + // Get the string data out of the transferable as a nsISupportsString. + nsCOMPtr data; PRUint32 len; - trans->GetAnyTransferData(&toolbarMime, (void **)&str, &len); + char* whichFlavor; + trans->GetAnyTransferData(&whichFlavor, getter_AddRefs(data), &len); + nsCOMPtr dataAsString ( do_QueryInterface(data) ); - // If the string was not empty then paste it in - if (str) { - char buf[256]; - strncpy(buf, str, len); - buf[len] = 0; - printf("Dropped: %s\n", buf); - stuffToPaste.SetString(str, len); + // If the string was not empty then make it so. + if ( dataAsString ) { + char* stuffToPaste; + dataAsString->toString ( &stuffToPaste ); + printf("Dropped: %s\n", stuffToPaste); dragSession->SetCanDrop(PR_TRUE); } } diff --git a/widget/macbuild/widgetIDL.mcp b/widget/macbuild/widgetIDL.mcp index 1b27a4356b0..11abfc80e48 100644 Binary files a/widget/macbuild/widgetIDL.mcp and b/widget/macbuild/widgetIDL.mcp differ diff --git a/widget/public/MANIFEST b/widget/public/MANIFEST index 88cadd49926..bc5aaf6af2a 100644 --- a/widget/public/MANIFEST +++ b/widget/public/MANIFEST @@ -2,13 +2,8 @@ # This is a list of local files which get copied to the mozilla:dist:widget directory # -nsIDragSessionMac.h -nsIFormatConverter.h nsIClipboardOwner.h nsIClipboard.h -nsITransferable.h -nsIDragService.h -nsIDragSession.h nsIDragSessionMac.h nsui.h nsIWidget.h diff --git a/widget/public/MANIFEST_IDL b/widget/public/MANIFEST_IDL index e1fd5e2aa99..fcfcfd73642 100644 --- a/widget/public/MANIFEST_IDL +++ b/widget/public/MANIFEST_IDL @@ -3,4 +3,8 @@ # nsIFileSpecWithUI.idl -nsISound.idl \ No newline at end of file +nsISound.idl +nsITransferable.idl +nsIDragSession.idl +nsIDragService.idl +nsIFormatConverter.idl \ No newline at end of file diff --git a/widget/public/Makefile.in b/widget/public/Makefile.in index c318884e3ba..c4099920bef 100644 --- a/widget/public/Makefile.in +++ b/widget/public/Makefile.in @@ -28,7 +28,6 @@ EXPORTS = \ nsIFontSizeIterator.h \ nsIFontNameIterator.h \ nsIFontRetrieverService.h \ - nsIFileListTransferable.h \ nsIMenuBar.h \ nsIMenu.h \ nsIMenuItem.h \ @@ -62,12 +61,7 @@ EXPORTS = \ nsIPopUpMenu.h \ nsIContentConnector.h \ nsIClipboard.h \ - nsITransferable.h \ - nsIFileListTransferable.h \ - nsIDragService.h \ - nsIDragSession.h \ nsIClipboardOwner.h \ - nsIFormatConverter.h \ nsIFontNameIterator.h \ nsIFontSizeIterator.h \ nsIFontRetrieverService.h \ @@ -82,6 +76,10 @@ XPIDL_MODULE = widget XPIDLSRCS = \ nsIFileSpecWithUI.idl \ nsISound.idl \ + nsITransferable.idl \ + nsIDragSession.idl \ + nsIDragService.idl \ + nsIFormatConverter.idl \ $(NULL) include $(topsrcdir)/config/config.mk diff --git a/widget/public/makefile.win b/widget/public/makefile.win index ff5078e0161..068e75c417f 100644 --- a/widget/public/makefile.win +++ b/widget/public/makefile.win @@ -25,20 +25,19 @@ XPIDL_MODULE=widget XPIDLSRCS = \ .\nsIFileSpecWithUI.idl \ .\nsISound.idl \ + .\nsITransferable.idl \ + .\nsIDragSession.idl \ + .\nsIDragService.idl \ + .\nsIFormatConverter.idl \ $(NULL) EXPORTS=nsui.h \ nsIFontSizeIterator.h \ nsIFontNameIterator.h \ nsIFontRetrieverService.h \ - nsIFileListTransferable.h \ - nsIFormatConverter.h \ nsIClipboardOwner.h \ nsIClipboard.h \ nsIFileWidget.h \ - nsITransferable.h \ - nsIDragService.h \ - nsIDragSession.h \ nsIWidget.h \ nsIButton.h \ nsICheckButton.h \ diff --git a/widget/src/build/nsWinWidgetFactory.cpp b/widget/src/build/nsWinWidgetFactory.cpp index 558518a1dc6..4dbda5e09be 100644 --- a/widget/src/build/nsWinWidgetFactory.cpp +++ b/widget/src/build/nsWinWidgetFactory.cpp @@ -1,298 +1,587 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * - * The contents of this file are subject to the Netscape Public License - * Version 1.0 (the "NPL"); you may not use this file except in - * compliance with the NPL. You may obtain a copy of the NPL at - * http://www.mozilla.org/NPL/ - * - * Software distributed under the NPL is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL - * for the specific language governing rights and limitations under the - * NPL. - * - * The Initial Developer of this code under the NPL is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1998 Netscape Communications Corporation. All Rights - * Reserved. - */ - -#include "nsIFactory.h" -#include "nsISupports.h" -#include "nsdefs.h" -#include "nsWidgetsCID.h" - -#include "nsButton.h" -#include "nsCheckButton.h" -#include "nsComboBox.h" -#include "nsFileWidget.h" -#include "nsFileSpecWithUIImpl.h" -#include "nsListBox.h" -#include "nsLookAndFeel.h" -#include "nsRadioButton.h" -#include "nsScrollbar.h" -#include "nsTextAreaWidget.h" -#include "nsTextHelper.h" -#include "nsTextWidget.h" -#include "nsToolkit.h" -#include "nsWindow.h" -#include "nsLabel.h" -#include "nsMenuBar.h" -#include "nsMenu.h" -#include "nsMenuItem.h" -#include "nsContextMenu.h" -#include "nsPopUpMenu.h" -#include "nsAppShell.h" -#include "nsIServiceManager.h" -#include "nsFontRetrieverService.h" -#include "nsSound.h" - -// Drag & Drop, Clipboard -#include "nsClipboard.h" -#include "nsTransferable.h" -#include "nsXIFFormatConverter.h" -#include "nsDragService.h" -#include "nsFileListTransferable.h" - -static NS_DEFINE_IID(kCWindow, NS_WINDOW_CID); -static NS_DEFINE_IID(kCChild, NS_CHILD_CID); -static NS_DEFINE_IID(kCButton, NS_BUTTON_CID); -static NS_DEFINE_IID(kCCheckButton, NS_CHECKBUTTON_CID); -static NS_DEFINE_IID(kCCombobox, NS_COMBOBOX_CID); -static NS_DEFINE_IID(kCFileOpen, NS_FILEWIDGET_CID); -static NS_DEFINE_IID(kCListbox, NS_LISTBOX_CID); -static NS_DEFINE_IID(kCRadioButton, NS_RADIOBUTTON_CID); -static NS_DEFINE_IID(kCHorzScrollbar, NS_HORZSCROLLBAR_CID); -static NS_DEFINE_IID(kCVertScrollbar, NS_VERTSCROLLBAR_CID); -static NS_DEFINE_IID(kCTextArea, NS_TEXTAREA_CID); -static NS_DEFINE_IID(kCTextField, NS_TEXTFIELD_CID); -static NS_DEFINE_IID(kCAppShell, NS_APPSHELL_CID); -static NS_DEFINE_IID(kCToolkit, NS_TOOLKIT_CID); -static NS_DEFINE_IID(kCLookAndFeel, NS_LOOKANDFEEL_CID); -static NS_DEFINE_IID(kCLabel, NS_LABEL_CID); -static NS_DEFINE_IID(kCMenuBar, NS_MENUBAR_CID); -static NS_DEFINE_IID(kCMenu, NS_MENU_CID); -static NS_DEFINE_IID(kCMenuItem, NS_MENUITEM_CID); -static NS_DEFINE_IID(kCContextMenu, NS_CONTEXTMENU_CID); -static NS_DEFINE_IID(kCPopUpMenu, NS_POPUPMENU_CID); -static NS_DEFINE_IID(kCFontRetrieverService, NS_FONTRETRIEVERSERVICE_CID); - -// Drag & Drop, Clipboard -static NS_DEFINE_IID(kCDataObj, NS_DATAOBJ_CID); -static NS_DEFINE_IID(kCClipboard, NS_CLIPBOARD_CID); -static NS_DEFINE_IID(kCTransferable, NS_TRANSFERABLE_CID); -static NS_DEFINE_IID(kCXIFFormatConverter, NS_XIFFORMATCONVERTER_CID); -static NS_DEFINE_IID(kCDragService, NS_DRAGSERVICE_CID); -static NS_DEFINE_IID(kCFileListTransferable, NS_FILELISTTRANSFERABLE_CID); - -static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); -static NS_DEFINE_IID(kIFactoryIID, NS_IFACTORY_IID); - -// Sound services (just Beep for now) -static NS_DEFINE_CID(kCSound, NS_SOUND_CID); -static NS_DEFINE_CID(kCFileSpecWithUI, NS_FILESPECWITHUI_CID); - -class nsWidgetFactory : public nsIFactory -{ -public: - // nsISupports methods - NS_DECL_ISUPPORTS - - // nsIFactory methods - NS_IMETHOD CreateInstance(nsISupports *aOuter, - const nsIID &aIID, - void **aResult); - - NS_IMETHOD LockFactory(PRBool aLock); - - nsWidgetFactory(const nsCID &aClass); - ~nsWidgetFactory(); - -private: - nsCID mClassID; -}; - -NS_IMPL_ADDREF(nsWidgetFactory) -NS_IMPL_RELEASE(nsWidgetFactory) - - -nsWidgetFactory::nsWidgetFactory(const nsCID &aClass) -{ - NS_INIT_REFCNT(); - mClassID = aClass; -} - -nsWidgetFactory::~nsWidgetFactory() -{ - NS_ASSERTION(mRefCnt == 0, "Reference count not zero in destructor"); -} - -nsresult nsWidgetFactory::QueryInterface(const nsIID &aIID, - void **aResult) -{ - if (aResult == NULL) { - return NS_ERROR_NULL_POINTER; - } - - // Always NULL result, in case of failure - *aResult = NULL; - - if (aIID.Equals(kISupportsIID)) { - *aResult = (void *)(nsISupports*)this; - } else if (aIID.Equals(kIFactoryIID)) { - *aResult = (void *)(nsIFactory*)this; - } - - if (*aResult == NULL) { - return NS_NOINTERFACE; - } - - NS_ADDREF_THIS(); // Increase reference count for caller - return NS_OK; -} - - -nsresult nsWidgetFactory::CreateInstance( nsISupports* aOuter, - const nsIID &aIID, - void **aResult) -{ - if (aResult == NULL) { - return NS_ERROR_NULL_POINTER; - } - *aResult = NULL; - if (nsnull != aOuter) { - return NS_ERROR_NO_AGGREGATION; - } - - nsISupports *inst = nsnull; - if (mClassID.Equals(kCWindow)) { - inst = (nsISupports*)new nsWindow(); - } - else if (mClassID.Equals(kCChild)) { - inst = (nsISupports*)new ChildWindow(); - } - else if (mClassID.Equals(kCButton)) { - inst = (nsISupports*)(nsWindow*)new nsButton(); - } - else if (mClassID.Equals(kCCheckButton)) { - inst = (nsISupports*)(nsWindow*)new nsCheckButton(); - } - else if (mClassID.Equals(kCCombobox)) { - inst = (nsISupports*)(nsWindow*)new nsComboBox(); - } - else if (mClassID.Equals(kCRadioButton)) { - inst = (nsISupports*)(nsWindow*)new nsRadioButton(); - } - else if (mClassID.Equals(kCFileOpen)) { - inst = (nsISupports*)new nsFileWidget(); - } - else if (mClassID.Equals(kCListbox)) { - inst = (nsISupports*)(nsWindow*)new nsListBox(); - } - else if (mClassID.Equals(kCHorzScrollbar)) { - inst = (nsISupports*)(nsWindow*)new nsScrollbar(PR_FALSE); - } - else if (mClassID.Equals(kCVertScrollbar)) { - inst = (nsISupports*)(nsWindow*)new nsScrollbar(PR_TRUE); - } - else if (mClassID.Equals(kCTextArea)) { - inst = (nsISupports*)(nsWindow*)new nsTextAreaWidget(); - } - else if (mClassID.Equals(kCTextField)) { - inst = (nsISupports*)(nsWindow*)new nsTextWidget(); - } - else if (mClassID.Equals(kCAppShell)) { - inst = (nsISupports*)new nsAppShell(); - } - else if (mClassID.Equals(kCToolkit)) { - inst = (nsISupports*)new nsToolkit(); - } - else if (mClassID.Equals(kCLookAndFeel)) { - inst = (nsISupports*)new nsLookAndFeel(); - } - else if (mClassID.Equals(kCLabel)) { - inst = (nsISupports*)(nsWindow*)new nsLabel(); - } - else if (mClassID.Equals(kCMenuBar)) { - inst = (nsISupports*)(nsIMenuBar*)new nsMenuBar(); - } - else if (mClassID.Equals(kCMenu)) { - inst = (nsISupports*)(nsIMenu*)new nsMenu(); - } - else if (mClassID.Equals(kCMenuItem)) { - inst = (nsISupports*)(nsIMenuItem*)new nsMenuItem(); - } - else if (mClassID.Equals(kCContextMenu)) { - inst = (nsISupports*)(nsIContextMenu*)new nsContextMenu(); - } - else if (mClassID.Equals(kCPopUpMenu)) { - inst = (nsISupports*)new nsPopUpMenu(); - } - else if (mClassID.Equals(kCSound)) { - nsISound* aSound = nsnull; - NS_NewSound(&aSound); - inst = (nsISupports*) aSound; - } - else if (mClassID.Equals(kCFileSpecWithUI)) - inst = (nsISupports*) (nsIFileSpecWithUI *) new nsFileSpecWithUIImpl; - else if (mClassID.Equals(kCTransferable)) { - inst = (nsISupports*)new nsTransferable(); - } - else if (mClassID.Equals(kCXIFFormatConverter)) { - inst = (nsISupports*)new nsXIFFormatConverter(); - } - else if (mClassID.Equals(kCClipboard)) { - inst = (nsISupports*)(nsBaseClipboard *)new nsClipboard(); - } - else if (mClassID.Equals(kCDragService)) { - inst = (nsISupports*)(nsIDragService *)new nsDragService(); - } - else if (mClassID.Equals(kCFontRetrieverService)) { - inst = (nsISupports*)(nsIFontRetrieverService *)new nsFontRetrieverService(); - } - else if (mClassID.Equals(kCFileListTransferable)) { - inst = (nsISupports*)(nsITransferable *)new nsFileListTransferable(); - } - /* */ - - if (inst == NULL) { - return NS_ERROR_OUT_OF_MEMORY; - } - - nsresult res = inst->QueryInterface(aIID, aResult); - - if (res != NS_OK) { - // We didn't get the right interface, so clean up - delete inst; - } - - return res; -} - -nsresult nsWidgetFactory::LockFactory(PRBool aLock) -{ - // Not implemented in simplest case. - return NS_OK; -} - -// return the proper factory to the caller -extern "C" NS_WIDGET nsresult -NSGetFactory(nsISupports* serviceMgr, - const nsCID &aClass, - const char *aClassName, - const char *aProgID, - nsIFactory **aFactory) -{ - if (nsnull == aFactory) { - return NS_ERROR_NULL_POINTER; - } - - *aFactory = new nsWidgetFactory(aClass); - - if (nsnull == aFactory) { - return NS_ERROR_OUT_OF_MEMORY; - } - - return (*aFactory)->QueryInterface(kIFactoryIID, (void**)aFactory); -} - - +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- + + * + + * The contents of this file are subject to the Netscape Public License + + * Version 1.0 (the "NPL"); you may not use this file except in + + * compliance with the NPL. You may obtain a copy of the NPL at + + * http://www.mozilla.org/NPL/ + + * + + * Software distributed under the NPL is distributed on an "AS IS" basis, + + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + + * for the specific language governing rights and limitations under the + + * NPL. + + * + + * The Initial Developer of this code under the NPL is Netscape + + * Communications Corporation. Portions created by Netscape are + + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + + * Reserved. + + */ + + + +#include "nsIFactory.h" + +#include "nsISupports.h" + +#include "nsdefs.h" + +#include "nsWidgetsCID.h" + + + +#include "nsButton.h" + +#include "nsCheckButton.h" + +#include "nsComboBox.h" + +#include "nsFileWidget.h" + +#include "nsFileSpecWithUIImpl.h" + +#include "nsListBox.h" + +#include "nsLookAndFeel.h" + +#include "nsRadioButton.h" + +#include "nsScrollbar.h" + +#include "nsTextAreaWidget.h" + +#include "nsTextHelper.h" + +#include "nsTextWidget.h" + +#include "nsToolkit.h" + +#include "nsWindow.h" + +#include "nsLabel.h" + +#include "nsMenuBar.h" + +#include "nsMenu.h" + +#include "nsMenuItem.h" + +#include "nsContextMenu.h" + +#include "nsPopUpMenu.h" + +#include "nsAppShell.h" + +#include "nsIServiceManager.h" + +#include "nsFontRetrieverService.h" + +#include "nsSound.h" + + + +// Drag & Drop, Clipboard + +#include "nsClipboard.h" + +#include "nsTransferable.h" + +#include "nsXIFFormatConverter.h" + +#include "nsDragService.h" + + + +static NS_DEFINE_IID(kCWindow, NS_WINDOW_CID); + +static NS_DEFINE_IID(kCChild, NS_CHILD_CID); + +static NS_DEFINE_IID(kCButton, NS_BUTTON_CID); + +static NS_DEFINE_IID(kCCheckButton, NS_CHECKBUTTON_CID); + +static NS_DEFINE_IID(kCCombobox, NS_COMBOBOX_CID); + +static NS_DEFINE_IID(kCFileOpen, NS_FILEWIDGET_CID); + +static NS_DEFINE_IID(kCListbox, NS_LISTBOX_CID); + +static NS_DEFINE_IID(kCRadioButton, NS_RADIOBUTTON_CID); + +static NS_DEFINE_IID(kCHorzScrollbar, NS_HORZSCROLLBAR_CID); + +static NS_DEFINE_IID(kCVertScrollbar, NS_VERTSCROLLBAR_CID); + +static NS_DEFINE_IID(kCTextArea, NS_TEXTAREA_CID); + +static NS_DEFINE_IID(kCTextField, NS_TEXTFIELD_CID); + +static NS_DEFINE_IID(kCAppShell, NS_APPSHELL_CID); + +static NS_DEFINE_IID(kCToolkit, NS_TOOLKIT_CID); + +static NS_DEFINE_IID(kCLookAndFeel, NS_LOOKANDFEEL_CID); + +static NS_DEFINE_IID(kCLabel, NS_LABEL_CID); + +static NS_DEFINE_IID(kCMenuBar, NS_MENUBAR_CID); + +static NS_DEFINE_IID(kCMenu, NS_MENU_CID); + +static NS_DEFINE_IID(kCMenuItem, NS_MENUITEM_CID); + +static NS_DEFINE_IID(kCContextMenu, NS_CONTEXTMENU_CID); + +static NS_DEFINE_IID(kCPopUpMenu, NS_POPUPMENU_CID); + +static NS_DEFINE_IID(kCFontRetrieverService, NS_FONTRETRIEVERSERVICE_CID); + + + +// Drag & Drop, Clipboard + +static NS_DEFINE_IID(kCDataObj, NS_DATAOBJ_CID); + +static NS_DEFINE_IID(kCClipboard, NS_CLIPBOARD_CID); + +static NS_DEFINE_IID(kCTransferable, NS_TRANSFERABLE_CID); + +static NS_DEFINE_IID(kCXIFFormatConverter, NS_XIFFORMATCONVERTER_CID); + +static NS_DEFINE_IID(kCDragService, NS_DRAGSERVICE_CID); + + + +static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); + +static NS_DEFINE_IID(kIFactoryIID, NS_IFACTORY_IID); + + + +// Sound services (just Beep for now) + +static NS_DEFINE_CID(kCSound, NS_SOUND_CID); + +static NS_DEFINE_CID(kCFileSpecWithUI, NS_FILESPECWITHUI_CID); + + + +class nsWidgetFactory : public nsIFactory + +{ + +public: + + // nsISupports methods + + NS_DECL_ISUPPORTS + + + + // nsIFactory methods + + NS_IMETHOD CreateInstance(nsISupports *aOuter, + + const nsIID &aIID, + + void **aResult); + + + + NS_IMETHOD LockFactory(PRBool aLock); + + + + nsWidgetFactory(const nsCID &aClass); + + ~nsWidgetFactory(); + + + +private: + + nsCID mClassID; + +}; + + + +NS_IMPL_ADDREF(nsWidgetFactory) + +NS_IMPL_RELEASE(nsWidgetFactory) + + + + + +nsWidgetFactory::nsWidgetFactory(const nsCID &aClass) + +{ + + NS_INIT_REFCNT(); + + mClassID = aClass; + +} + + + +nsWidgetFactory::~nsWidgetFactory() + +{ + + NS_ASSERTION(mRefCnt == 0, "Reference count not zero in destructor"); + +} + + + +nsresult nsWidgetFactory::QueryInterface(const nsIID &aIID, + + void **aResult) + +{ + + if (aResult == NULL) { + + return NS_ERROR_NULL_POINTER; + + } + + + + // Always NULL result, in case of failure + + *aResult = NULL; + + + + if (aIID.Equals(kISupportsIID)) { + + *aResult = (void *)(nsISupports*)this; + + } else if (aIID.Equals(kIFactoryIID)) { + + *aResult = (void *)(nsIFactory*)this; + + } + + + + if (*aResult == NULL) { + + return NS_NOINTERFACE; + + } + + + + NS_ADDREF_THIS(); // Increase reference count for caller + + return NS_OK; + +} + + + + + +nsresult nsWidgetFactory::CreateInstance( nsISupports* aOuter, + + const nsIID &aIID, + + void **aResult) + +{ + + if (aResult == NULL) { + + return NS_ERROR_NULL_POINTER; + + } + + *aResult = NULL; + + if (nsnull != aOuter) { + + return NS_ERROR_NO_AGGREGATION; + + } + + + + nsISupports *inst = nsnull; + + if (mClassID.Equals(kCWindow)) { + + inst = (nsISupports*)new nsWindow(); + + } + + else if (mClassID.Equals(kCChild)) { + + inst = (nsISupports*)new ChildWindow(); + + } + + else if (mClassID.Equals(kCButton)) { + + inst = (nsISupports*)(nsWindow*)new nsButton(); + + } + + else if (mClassID.Equals(kCCheckButton)) { + + inst = (nsISupports*)(nsWindow*)new nsCheckButton(); + + } + + else if (mClassID.Equals(kCCombobox)) { + + inst = (nsISupports*)(nsWindow*)new nsComboBox(); + + } + + else if (mClassID.Equals(kCRadioButton)) { + + inst = (nsISupports*)(nsWindow*)new nsRadioButton(); + + } + + else if (mClassID.Equals(kCFileOpen)) { + + inst = (nsISupports*)new nsFileWidget(); + + } + + else if (mClassID.Equals(kCListbox)) { + + inst = (nsISupports*)(nsWindow*)new nsListBox(); + + } + + else if (mClassID.Equals(kCHorzScrollbar)) { + + inst = (nsISupports*)(nsWindow*)new nsScrollbar(PR_FALSE); + + } + + else if (mClassID.Equals(kCVertScrollbar)) { + + inst = (nsISupports*)(nsWindow*)new nsScrollbar(PR_TRUE); + + } + + else if (mClassID.Equals(kCTextArea)) { + + inst = (nsISupports*)(nsWindow*)new nsTextAreaWidget(); + + } + + else if (mClassID.Equals(kCTextField)) { + + inst = (nsISupports*)(nsWindow*)new nsTextWidget(); + + } + + else if (mClassID.Equals(kCAppShell)) { + + inst = (nsISupports*)new nsAppShell(); + + } + + else if (mClassID.Equals(kCToolkit)) { + + inst = (nsISupports*)new nsToolkit(); + + } + + else if (mClassID.Equals(kCLookAndFeel)) { + + inst = (nsISupports*)new nsLookAndFeel(); + + } + + else if (mClassID.Equals(kCLabel)) { + + inst = (nsISupports*)(nsWindow*)new nsLabel(); + + } + + else if (mClassID.Equals(kCMenuBar)) { + + inst = (nsISupports*)(nsIMenuBar*)new nsMenuBar(); + + } + + else if (mClassID.Equals(kCMenu)) { + + inst = (nsISupports*)(nsIMenu*)new nsMenu(); + + } + + else if (mClassID.Equals(kCMenuItem)) { + + inst = (nsISupports*)(nsIMenuItem*)new nsMenuItem(); + + } + + else if (mClassID.Equals(kCContextMenu)) { + + inst = (nsISupports*)(nsIContextMenu*)new nsContextMenu(); + + } + + else if (mClassID.Equals(kCPopUpMenu)) { + + inst = (nsISupports*)new nsPopUpMenu(); + + } + + else if (mClassID.Equals(kCSound)) { + + nsISound* aSound = nsnull; + + NS_NewSound(&aSound); + + inst = (nsISupports*) aSound; + + } + + else if (mClassID.Equals(kCFileSpecWithUI)) + + inst = (nsISupports*) (nsIFileSpecWithUI *) new nsFileSpecWithUIImpl; + + else if (mClassID.Equals(kCTransferable)) { + + inst = (nsISupports*)new nsTransferable(); + + } + + else if (mClassID.Equals(kCXIFFormatConverter)) { + + inst = (nsISupports*)new nsXIFFormatConverter(); + + } + + else if (mClassID.Equals(kCClipboard)) { + + inst = (nsISupports*)(nsBaseClipboard *)new nsClipboard(); + + } + + else if (mClassID.Equals(kCDragService)) { + + inst = (nsISupports*)(nsIDragService *)new nsDragService(); + + } + + else if (mClassID.Equals(kCFontRetrieverService)) { + + inst = (nsISupports*)(nsIFontRetrieverService *)new nsFontRetrieverService(); + + } + + + /* */ + + + + if (inst == NULL) { + + return NS_ERROR_OUT_OF_MEMORY; + + } + + + + nsresult res = inst->QueryInterface(aIID, aResult); + + + + if (res != NS_OK) { + + // We didn't get the right interface, so clean up + + delete inst; + + } + + + + return res; + +} + + + +nsresult nsWidgetFactory::LockFactory(PRBool aLock) + +{ + + // Not implemented in simplest case. + + return NS_OK; + +} + + + +// return the proper factory to the caller + +extern "C" NS_WIDGET nsresult + +NSGetFactory(nsISupports* serviceMgr, + + const nsCID &aClass, + + const char *aClassName, + + const char *aProgID, + + nsIFactory **aFactory) + +{ + + if (nsnull == aFactory) { + + return NS_ERROR_NULL_POINTER; + + } + + + + *aFactory = new nsWidgetFactory(aClass); + + + + if (nsnull == aFactory) { + + return NS_ERROR_OUT_OF_MEMORY; + + } + + + + return (*aFactory)->QueryInterface(kIFactoryIID, (void**)aFactory); + +} + + + + + diff --git a/widget/src/gtk/nsClipboard.cpp b/widget/src/gtk/nsClipboard.cpp index 244e9497557..d60de45b082 100644 --- a/widget/src/gtk/nsClipboard.cpp +++ b/widget/src/gtk/nsClipboard.cpp @@ -23,6 +23,7 @@ #include "nsISupportsArray.h" #include "nsIClipboardOwner.h" #include "nsITransferable.h" // kTextMime +#include "nsISupportsPrimitives.h" #include "nsIWidget.h" #include "nsIComponentManager.h" @@ -274,24 +275,29 @@ NS_IMETHODIMP nsClipboard::SetNativeClipboardData() if (have_selection == 0) return NS_ERROR_FAILURE; + // get flavor list that includes all flavors that can be written (including ones + // obtained through conversion) + nsCOMPtr flavorList; + nsresult errCode = mTransferable->FlavorsTransferableCanExport ( getter_AddRefs(flavorList) ); + if ( NS_FAILED(errCode) ) + return NS_ERROR_FAILURE; - nsString *df; - int i = 0; - nsVoidArray *dfList; - // find out what types this data can be - mTransferable->FlavorsTransferableCanExport(&dfList); - - int cnt = dfList->Count(); - - for (i=0;iCount(&cnt); + for ( PRUint32 i=0; iElementAt(i); - if (nsnull != df) { - gint format = GetFormat(*df); + nsCOMPtr genericFlavor; + flavorList->GetElementAt ( i, getter_AddRefs(genericFlavor) ); + nsCOMPtr currentFlavor ( do_QueryInterface(genericFlavor) ); + if ( currentFlavor ) { + char* flavorStr; + currentFlavor->toString(&flavorStr); + gint format = GetFormat(flavorStr); // add these types as selection targets RegisterFormat(format); - + + delete [] flavorStr; } } @@ -529,8 +535,6 @@ PRBool nsClipboard::DoConvert(gint format) NS_IMETHODIMP nsClipboard::GetNativeClipboardData(nsITransferable * aTransferable) { - nsString *df; - int i = 0; #ifdef DEBUG_CLIPBOARD printf("nsClipboard::GetNativeClipboardData()\n"); @@ -542,24 +546,34 @@ nsClipboard::GetNativeClipboardData(nsITransferable * aTransferable) return NS_ERROR_FAILURE; } - // Get the transferable list of data flavors - nsVoidArray *dfList; - aTransferable->FlavorsTransferableCanImport(&dfList); + // get flavor list that includes all acceptable flavors (including ones obtained through + // conversion) + nsCOMPtr flavorList; + nsresult errCode = aTransferable->FlavorsTransferableCanImport ( getter_AddRefs(flavorList) ); + if ( NS_FAILED(errCode) ) + return NS_ERROR_FAILURE; // Walk through flavors and see which flavor matches the one being pasted: - int cnt = dfList->Count(); + PRUint32 cnt; + flavorList->Count(&cnt); + char* foundFlavor = nsnull; + for ( int i = 0; i < cnt; ++i ) { + nsCOMPtr genericFlavor; + flavorList->GetElementAt ( i, getter_AddRefs(genericFlavor) ); + nsCOMPtr currentFlavor ( do_QueryInterface(genericFlavor) ); + if ( currentFlavor ) { + char* flavorStr; + currentFlavor->toString ( &flavorStr ); + gint format = GetFormat(flavorStr); - for (i=0;iElementAt(i); - if (nsnull != df) { - gint format = GetFormat(*df); - - if (DoConvert(format)) + if (DoConvert(format)) { + foundFlavor = flavorStr; break; + } + delete [] flavorStr; } } - #ifdef DEBUG_CLIPBOARD printf(" Got the callback: '%s', %d\n", mSelectionData.data, mSelectionData.length); @@ -573,18 +587,23 @@ nsClipboard::GetNativeClipboardData(nsITransferable * aTransferable) // We just have to copy it to the transferable. // - - nsString *name = new nsString((const char*)gdk_atom_name(mSelectionData.type)); - +#if 0 +// pinkerton - we have the flavor already from above, so we don't need +// to re-derrive it. + nsString *name = new nsString((const char*)gdk_atom_name(mSelectionData.type)); int format = GetFormat(*name); - df->SetString((const char*)gdk_atom_name(sSelTypes[format])); - aTransferable->SetTransferData(df, - mSelectionData.data, +#endif + + nsCOMPtr genericDataWrapper; + CreatePrimitiveForData ( foundFlavor, mSelectionData.data, mSelectionData.length, getter_AddRefs(genericDataWrapper) ); + aTransferable->SetTransferData(foundFlavor, + genericDataWrapper, mSelectionData.length); - delete name; - +//delete name; + delete [] foundFlavor; + // transferable is now copying the data, so we can free it. // g_free(mSelectionData.data); mSelectionData.data = nsnull; @@ -748,7 +767,7 @@ void nsClipboard::SelectionGetCB(GtkWidget *widget, g_print(" aInfo == %d -", aInfo); #endif - nsString dataFlavor; + char* dataFlavor; // switch aInfo (atom) to our enum int type = TARGET_NONE; @@ -799,10 +818,11 @@ void nsClipboard::SelectionGetCB(GtkWidget *widget, #endif // Get data out of transferable. - rv = cb->mTransferable->GetTransferData(&dataFlavor, - &clipboardData, + nsCOMPtr genericDataWrapper; + rv = cb->mTransferable->GetTransferData(dataFlavor, + getter_AddRefs(genericDataWrapper), &dataLength); - + CreateDataFromPrimitive ( dataFlavor, genericDataWrapper, &clipboardData, dataLength ); if (NS_SUCCEEDED(rv) && clipboardData && dataLength > 0) { size_t size = 1; // find the number of bytes in the data for the below thing @@ -813,6 +833,7 @@ void nsClipboard::SelectionGetCB(GtkWidget *widget, aInfo, size*8, (unsigned char *)clipboardData, dataLength); + delete [] clipboardData; } else printf("Transferable didn't support the data flavor\n"); diff --git a/widget/src/mac/nsClipboard.cpp b/widget/src/mac/nsClipboard.cpp index 61df99bd28c..85d9399b043 100644 --- a/widget/src/mac/nsClipboard.cpp +++ b/widget/src/mac/nsClipboard.cpp @@ -37,13 +37,15 @@ #include "nsMimeMapper.h" #include "nsIComponentManager.h" -#include "nsWidgetsCID.h" +#include "nsISupportsPrimitives.h" #include NS_IMPL_ADDREF_INHERITED(nsClipboard, nsBaseClipboard) NS_IMPL_RELEASE_INHERITED(nsClipboard, nsBaseClipboard) +//NS_IMPL_QUERY_INTERFACE1(nsClipboard, nsIClipboard) + // // nsClipboard constructor @@ -113,29 +115,37 @@ nsClipboard :: SetNativeClipboardData() // get flavor list that includes all flavors that can be written (including ones // obtained through conversion) - nsVoidArray * flavorList; - errCode = mTransferable->FlavorsTransferableCanExport ( &flavorList ); - if ( errCode != NS_OK ) + nsCOMPtr flavorList; + errCode = mTransferable->FlavorsTransferableCanExport ( getter_AddRefs(flavorList) ); + if ( NS_FAILED(errCode) ) return NS_ERROR_FAILURE; // For each flavor present (either directly in the transferable or that its // converter knows about) put it on the clipboard. Luckily, GetTransferData() // handles conversions for us, so we really don't need to know if a conversion // is required or not. - PRUint32 cnt = flavorList->Count(); + PRUint32 cnt; + flavorList->Count(&cnt); for ( int i = 0; i < cnt; ++i ) { - nsString * currentFlavor = (nsString *)flavorList->ElementAt(i); - if ( nsnull != currentFlavor ) { + nsCOMPtr genericFlavor; + flavorList->GetElementAt ( i, getter_AddRefs(genericFlavor) ); + nsCOMPtr currentFlavor ( do_QueryInterface(genericFlavor) ); + if ( currentFlavor ) { + char* flavorStr; + currentFlavor->toString(&flavorStr); + // find MacOS flavor - ResType macOSFlavor = theMapper.MapMimeTypeToMacOSType(*currentFlavor); + ResType macOSFlavor = theMapper.MapMimeTypeToMacOSType(flavorStr); // get data. This takes converters into account. We don't own the data // so make sure not to delete it. void* data = nsnull; PRUint32 dataSize = 0; - errCode = mTransferable->GetTransferData ( currentFlavor, &data, &dataSize ); + nsCOMPtr genericDataWrapper; + errCode = mTransferable->GetTransferData ( flavorStr, getter_AddRefs(genericDataWrapper), &dataSize ); + CreateDataFromPrimitive ( flavorStr, genericDataWrapper, &data, dataSize ); #ifdef NS_DEBUG - if ( errCode != NS_OK ) printf("nsClipboard:: Error getting data from transferable\n"); + if ( NS_FAILED(errCode) ) printf("nsClipboard:: Error getting data from transferable\n"); #endif // stash on clipboard @@ -144,9 +154,9 @@ nsClipboard :: SetNativeClipboardData() errCode = NS_ERROR_FAILURE; delete [] data; + delete [] flavorStr; } } // foreach flavor in transferable - delete flavorList; // write out the mapping data in a special flavor on the clipboard. |mappingLen| // includes the NULL terminator. @@ -178,8 +188,8 @@ nsClipboard :: GetNativeClipboardData(nsITransferable * aTransferable) // get flavor list that includes all acceptable flavors (including ones obtained through // conversion) - nsVoidArray * flavorList; - errCode = aTransferable->FlavorsTransferableCanImport ( &flavorList ); + nsCOMPtr flavorList; + errCode = aTransferable->FlavorsTransferableCanImport ( getter_AddRefs(flavorList) ); if ( NS_FAILED(errCode) ) return NS_ERROR_FAILURE; @@ -194,29 +204,38 @@ nsClipboard :: GetNativeClipboardData(nsITransferable * aTransferable) // Now walk down the list of flavors. When we find one that is actually on the // clipboard, copy out the data into the transferable in that format. SetTransferData() // implicitly handles conversions. - PRUint32 cnt = flavorList->Count(); + PRUint32 cnt; + flavorList->Count(&cnt); for ( int i = 0; i < cnt; ++i ) { - nsString * currentFlavor = (nsString *)flavorList->ElementAt(i); - if ( nsnull != currentFlavor ) { + nsCOMPtr genericFlavor; + flavorList->GetElementAt ( i, getter_AddRefs(genericFlavor) ); + nsCOMPtr currentFlavor ( do_QueryInterface(genericFlavor) ); + if ( currentFlavor ) { + char* flavorStr; + currentFlavor->toString ( &flavorStr ); + // find MacOS flavor - ResType macOSFlavor = theMapper.MapMimeTypeToMacOSType(*currentFlavor); + ResType macOSFlavor = theMapper.MapMimeTypeToMacOSType(flavorStr); char* clipboardData = nsnull; long dataSize = 0L; nsresult loadResult = GetDataOffClipboard ( macOSFlavor, &clipboardData, &dataSize ); if ( NS_SUCCEEDED(loadResult) && clipboardData ) { // put it into the transferable - errCode = aTransferable->SetTransferData ( currentFlavor, clipboardData, dataSize ); + nsCOMPtr genericDataWrapper; + CreatePrimitiveForData ( flavorStr, clipboardData, dataSize, getter_AddRefs(genericDataWrapper) ); + errCode = aTransferable->SetTransferData ( flavorStr, genericDataWrapper, dataSize ); #ifdef NS_DEBUG if ( errCode != NS_OK ) printf("nsClipboard:: Error setting data into transferable\n"); #endif // we found one, get out of this loop! + delete [] flavorStr; break; } // if flavor found on clipboard + delete [] flavorStr; } } // foreach flavor - delete flavorList; return errCode; } diff --git a/widget/src/mac/nsDragService.cpp b/widget/src/mac/nsDragService.cpp index 6e1add422f3..f8992ff82b0 100644 --- a/widget/src/mac/nsDragService.cpp +++ b/widget/src/mac/nsDragService.cpp @@ -30,10 +30,11 @@ #include "nsITransferable.h" #include "nsString.h" #include "nsMimeMapper.h" -#include "nsWidgetsCID.h" #include "nsClipboard.h" #include "nsIRegion.h" #include "nsVoidArray.h" +#include "nsISupportsPrimitives.h" +#include "nsCOMPtr.h" DragSendDataUPP nsDragService::sDragSendDataUPP = NewDragSendDataProc(DragSendDataProc); @@ -196,19 +197,26 @@ nsDragService :: RegisterDragItemsAndFlavors ( nsISupportsArray * inArray ) for ( int itemIndex = 0; itemIndex < numDragItems; ++itemIndex ) { nsMimeMapperMac theMapper; - // (assumes that the items were placed into the transferable as nsITranferable*'s, not - // nsISupports*'s. Don't forget ElementAt() addRefs for us) - nsCOMPtr currItem = dont_AddRef(NS_STATIC_CAST(nsITransferable*,inArray->ElementAt(itemIndex))); + nsCOMPtr genericItem; + inArray->GetElementAt ( itemIndex, getter_AddRefs(genericItem) ); + nsCOMPtr currItem ( do_QueryInterface(genericItem) ); if ( currItem ) { - nsVoidArray* flavorList = nsnull; - if ( NS_SUCCEEDED(currItem->FlavorsTransferableCanExport(&flavorList)) ) { - for ( int flavorIndex = 0; flavorIndex < flavorList->Count(); ++flavorIndex ) { + nsCOMPtr flavorList; + if ( NS_SUCCEEDED(currItem->FlavorsTransferableCanExport(getter_AddRefs(flavorList))) ) { + PRUint32 numFlavors; + flavorList->Count ( &numFlavors ); + for ( int flavorIndex = 0; flavorIndex < numFlavors; ++flavorIndex ) { - nsString* currentFlavor = NS_STATIC_CAST(nsString*, (*flavorList)[flavorIndex]); - if ( nsnull != currentFlavor ) { - FlavorType macOSFlavor = theMapper.MapMimeTypeToMacOSType(*currentFlavor); + nsCOMPtr genericWrapper; + flavorList->GetElementAt ( flavorIndex, getter_AddRefs(genericWrapper) ); + nsCOMPtr currentFlavor ( do_QueryInterface(genericWrapper) ); + if ( currentFlavor ) { + char* flavorStr = nsnull; + currentFlavor->toString ( &flavorStr ); + FlavorType macOSFlavor = theMapper.MapMimeTypeToMacOSType(flavorStr); ::AddDragItemFlavor ( mDragRef, itemIndex, macOSFlavor, NULL, 0, flags ); - } + delete [] flavorStr; + } } // foreach flavor in item } // if valid flavor list @@ -237,7 +245,7 @@ nsDragService :: RegisterDragItemsAndFlavors ( nsISupportsArray * inArray ) // stop as soon as we find a match. // NS_IMETHODIMP -nsDragService :: GetData (nsITransferable * aTransferable, PRUint32 aItemIndex) +nsDragService :: GetData ( nsITransferable * aTransferable, PRUint32 aItemIndex ) { nsresult errCode = NS_ERROR_FAILURE; @@ -246,11 +254,11 @@ nsDragService :: GetData (nsITransferable * aTransferable, PRUint32 aItemIndex) return NS_ERROR_INVALID_ARG; // get flavor list that includes all acceptable flavors (including ones obtained through - // conversion) - nsVoidArray* flavorList; - errCode = aTransferable->FlavorsTransferableCanImport ( &flavorList ); - if ( errCode != NS_OK ) - return NS_ERROR_FAILURE; + // conversion). Flavors are nsISupportsStrings so that they can be seen from JS. + nsCOMPtr flavorList; + errCode = aTransferable->FlavorsTransferableCanImport ( getter_AddRefs(flavorList) ); + if ( NS_FAILED(errCode) ) + return errCode; // get the data for the requested drag item. Remember that GetDragItemReferenceNumber() // is one-based NOT zero-based like |aItemIndex| is. @@ -265,13 +273,18 @@ nsDragService :: GetData (nsITransferable * aTransferable, PRUint32 aItemIndex) // Now walk down the list of flavors. When we find one that is actually present, // copy out the data into the transferable in that format. SetTransferData() // implicitly handles conversions. - PRUint32 cnt = flavorList->Count(); + PRUint32 cnt; + flavorList->Count ( &cnt ); for ( int i = 0; i < cnt; ++i ) { - nsString * currentFlavor = NS_STATIC_CAST(nsString*, (*flavorList)[i]); - if ( nsnull != currentFlavor ) { + nsCOMPtr genericWrapper; + flavorList->GetElementAt ( i, getter_AddRefs(genericWrapper) ); + nsCOMPtr currentFlavor ( do_QueryInterface(genericWrapper) ); + if ( currentFlavor ) { // find MacOS flavor - FlavorType macOSFlavor = theMapper.MapMimeTypeToMacOSType(*currentFlavor); -printf("looking for data in type %s, mac flavor %ld\n", currentFlavor->ToNewCString(), macOSFlavor); + char* flavorStr; + currentFlavor->toString ( &flavorStr ); + FlavorType macOSFlavor = theMapper.MapMimeTypeToMacOSType(flavorStr); +printf("looking for data in type %s, mac flavor %ld\n", flavorStr, macOSFlavor); // check if it is present in the current drag item. FlavorFlags unused; @@ -297,11 +310,15 @@ printf("flavor data size is %ld\n", dataSize); return NS_ERROR_FAILURE; } - // put it into the transferable - errCode = aTransferable->SetTransferData ( currentFlavor, dataBuff, dataSize ); + // put it into the transferable. + nsCOMPtr genericDataWrapper; + CreatePrimitiveForData ( flavorStr, dataBuff, dataSize, getter_AddRefs(genericDataWrapper) ); + errCode = aTransferable->SetTransferData ( flavorStr, genericDataWrapper, dataSize ); #ifdef NS_DEBUG if ( errCode != NS_OK ) printf("nsDragService:: Error setting data into transferable\n"); #endif + + delete [] dataBuff; } else { #ifdef NS_DEBUG @@ -313,11 +330,11 @@ printf("flavor data size is %ld\n", dataSize); // we found one, get out of this loop! break; - } // if a flavor found - } + } // if a flavor found + + delete [] flavorStr; + } } // foreach flavor - - delete flavorList; return errCode; } @@ -333,15 +350,18 @@ printf("flavor data size is %ld\n", dataSize); // еее╩and index to this API // NS_IMETHODIMP -nsDragService :: IsDataFlavorSupported(nsString * aDataFlavor) +nsDragService :: IsDataFlavorSupported(const char *aDataFlavor, PRBool *_retval) { - nsresult flavorSupported = NS_ERROR_FAILURE; + if ( !_retval ) + return NS_ERROR_INVALID_ARG; + + *_retval = PR_FALSE; // convert to 4 character MacOS type //еее this is wrong because it doesn't take the mime mappings present in the //еее drag item flavor into account. FIX ME! nsMimeMapperMac theMapper; - FlavorType macFlavor = theMapper.MapMimeTypeToMacOSType(*aDataFlavor); + FlavorType macFlavor = theMapper.MapMimeTypeToMacOSType(aDataFlavor); // search through all drag items looking for something with this flavor. Recall // that drag item indices are 1-based. @@ -356,10 +376,10 @@ nsDragService :: IsDataFlavorSupported(nsString * aDataFlavor) FlavorFlags ignored; char foundFlavor = ::GetFlavorFlags(mDragRef, currItem, macFlavor, &ignored) == noErr; if ( foundFlavor ) - flavorSupported = NS_OK; + *_retval = PR_TRUE; } // for each item in drag - return flavorSupported; + return NS_OK; } // IsDataFlavorSupported @@ -452,19 +472,26 @@ nsDragService :: GetDataForFlavor ( nsISupportsArray* inDragItems, DragReference // (assumes that the items were placed into the transferable as nsITranferable*'s, not // nsISupports*'s. Don't forget ElementAt() addRefs for us.) - nsCOMPtr item = dont_AddRef(NS_STATIC_CAST(nsITransferable*,inDragItems->ElementAt(inItemIndex))); + nsCOMPtr genericItem; + inDragItems->GetElementAt ( inItemIndex, getter_AddRefs(genericItem) ); + nsCOMPtr item ( do_QueryInterface(genericItem) ); if ( item ) { nsString mimeFlavor; // create a mime mapper to help us out based on data in a special flavor for this item. char* mappings = LookupMimeMappingsForItem(inDragRef, inItemIndex) ; - nsMimeMapperMac theMapper ( mappings ); - theMapper.MapMacOSTypeToMimeType ( inFlavor, mimeFlavor ); + nsMimeMapperMac theMapper ( mappings ); + theMapper.MapMacOSTypeToMimeType ( inFlavor, mimeFlavor ); delete [] mappings; *outDataSize = 0; - if ( NS_FAILED(item->GetTransferData(&mimeFlavor, outData, outDataSize)) ) - retVal = cantGetFlavorErr; + char* mimeStr = mimeFlavor.ToNewCString(); + nsCOMPtr data; + if ( NS_SUCCEEDED(item->GetTransferData(mimeStr, getter_AddRefs(data), outDataSize)) ) + CreateDataFromPrimitive ( mimeStr, data, outData, *outDataSize ); + else + retVal = cantGetFlavorErr; + delete [] mimeStr; } // if valid item return retVal; diff --git a/widget/src/mac/nsDragService.h b/widget/src/mac/nsDragService.h index fd0d752fc9c..a1f3dd211e5 100644 --- a/widget/src/mac/nsDragService.h +++ b/widget/src/mac/nsDragService.h @@ -52,7 +52,7 @@ public: //nsIDragSession NS_IMETHOD GetData (nsITransferable * aTransferable, PRUint32 aItemIndex); - NS_IMETHOD IsDataFlavorSupported(nsString * aDataFlavor); + NS_IMETHOD IsDataFlavorSupported(const char *aDataFlavor, PRBool *_retval); NS_IMETHOD GetNumDropItems (PRUint32 * aNumItems); //nsIDragSessionMac diff --git a/widget/src/windows/nsClipboard.cpp b/widget/src/windows/nsClipboard.cpp index 1a2d3bfa22e..32d4e20581f 100644 --- a/widget/src/windows/nsClipboard.cpp +++ b/widget/src/windows/nsClipboard.cpp @@ -27,6 +27,8 @@ #include "nsString.h" #include "nsIFormatConverter.h" #include "nsITransferable.h" +#include "nsCOMPtr.h" +#include "nsISupportsPrimitives.h" #include "nsIWidget.h" #include "nsIComponentManager.h" @@ -131,17 +133,22 @@ nsresult nsClipboard::SetupNativeDataObject(nsITransferable * aTransferable, IDa dObj->SetTransferable(aTransferable); // Get the transferable list of data flavors - nsVoidArray * dfList; - aTransferable->FlavorsTransferableCanExport(&dfList); + nsCOMPtr dfList; + aTransferable->FlavorsTransferableCanExport(getter_AddRefs(dfList)); // Walk through flavors that contain data and register them // into the DataObj as supported flavors PRUint32 i; - PRUint32 cnt = dfList->Count(); + PRUint32 cnt; + dfList->Count(&cnt); for (i=0;iElementAt(i); - if (nsnull != df) { - UINT format = GetFormat(*df); + nsCOMPtr genericFlavor; + dfList->GetElementAt ( i, getter_AddRefs(genericFlavor) ); + nsCOMPtr currentFlavor ( do_QueryInterface(genericFlavor) ); + if ( currentFlavor ) { + char* flavorStr; + currentFlavor->toString(&flavorStr); + UINT format = GetFormat(flavorStr); // check here to see if we can the data back from global member // XXX need IStream support, or file support @@ -150,11 +157,11 @@ nsresult nsClipboard::SetupNativeDataObject(nsITransferable * aTransferable, IDa // Now tell the native IDataObject about both the DataFlavor and // the native data format - dObj->AddDataFlavor(df, &fe); + dObj->AddDataFlavor(flavorStr, &fe); + + delete [] flavorStr; } } - // Delete the data flavors list - delete dfList; return NS_OK; } @@ -508,24 +515,31 @@ nsresult nsClipboard::GetDataFromDataObject(IDataObject * aDataObject, nsIWidget * aWindow, nsITransferable * aTransferable) { + // make sure we have a good transferable + if ( !aTransferable ) + return NS_ERROR_INVALID_ARG; + nsresult res = NS_ERROR_FAILURE; - // make sure we have a good transferable - if (nsnull == aTransferable) { - return res; - } - - // Get the transferable list of data flavors - nsVoidArray * dfList; - aTransferable->GetTransferDataFlavors(&dfList); + // get flavor list that includes all flavors that can be written (including ones + // obtained through conversion) + nsCOMPtr flavorList; + res = aTransferable->FlavorsTransferableCanImport ( getter_AddRefs(flavorList) ); + if ( NS_FAILED(res) ) + return NS_ERROR_FAILURE; // Walk through flavors and see which flavor is on the clipboard them on the native clipboard, PRUint32 i; - PRUint32 cnt = dfList->Count(); + PRUint32 cnt; + flavorList->Count(&cnt); for (i=0;iElementAt(i); - if (nsnull != df) { - UINT format = GetFormat(*df); + nsCOMPtr genericFlavor; + flavorList->GetElementAt ( i, getter_AddRefs(genericFlavor) ); + nsCOMPtr currentFlavor ( do_QueryInterface(genericFlavor) ); + if ( currentFlavor ) { + char* flavorStr; + currentFlavor->toString(&flavorStr); + UINT format = GetFormat(flavorStr); void * data; PRUint32 dataLen; @@ -533,19 +547,24 @@ nsresult nsClipboard::GetDataFromDataObject(IDataObject * aDataObject, if (nsnull != aDataObject) { res = GetNativeDataOffClipboard(aDataObject, format, &data, &dataLen); if (NS_OK == res) { - aTransferable->SetTransferData(df, data, dataLen); + nsCOMPtr genericDataWrapper; + CreatePrimitiveForData ( flavorStr, data, dataLen, getter_AddRefs(genericDataWrapper) ); + aTransferable->SetTransferData(flavorStr, genericDataWrapper, dataLen); break; } } else if (nsnull != aWindow) { res = GetNativeDataOffClipboard(aWindow, format, &data, &dataLen); if (NS_OK == res) { - aTransferable->SetTransferData(df, data, dataLen); + nsCOMPtr genericDataWrapper; + CreatePrimitiveForData ( flavorStr, data, dataLen, getter_AddRefs(genericDataWrapper) ); + aTransferable->SetTransferData(flavorStr, genericDataWrapper, dataLen); break; } - } + } + + delete [] flavorStr; } } - delete dfList; return res; } @@ -615,24 +634,34 @@ NS_IMETHODIMP nsClipboard::ForceDataToClipboard() ::OpenClipboard(nativeWin); ::EmptyClipboard(); - // Get the transferable list of data flavors - nsVoidArray * dfList; - mTransferable->GetTransferDataFlavors(&dfList); + // get flavor list that includes all flavors that can be written (including ones + // obtained through conversion) + nsCOMPtr flavorList; + nsresult errCode = mTransferable->FlavorsTransferableCanExport ( getter_AddRefs(flavorList) ); + if ( NS_FAILED(errCode) ) + return NS_ERROR_FAILURE; // Walk through flavors and see which flavor is on the native clipboard, PRUint32 i; - PRUint32 cnt = dfList->Count(); + PRUint32 cnt; + flavorList->Count(&cnt); for (i=0;iElementAt(i); - if (nsnull != df) { - UINT format = GetFormat(*df); + nsCOMPtr genericFlavor; + flavorList->GetElementAt ( i, getter_AddRefs(genericFlavor) ); + nsCOMPtr currentFlavor ( do_QueryInterface(genericFlavor) ); + if ( currentFlavor ) { + char* flavorStr; + currentFlavor->toString(&flavorStr); + UINT format = GetFormat(flavorStr); void * data; - PRUint32 dataLen; + PRUint32 dataLen = 0; // Get the data as a bunch-o-bytes from the clipboard // this call hands back new memory with the contents copied into it - mTransferable->GetTransferData(df, &data, &dataLen); + nsCOMPtr genericDataWrapper; + mTransferable->GetTransferData(flavorStr, getter_AddRefs(genericDataWrapper), &dataLen); + CreateDataFromPrimitive ( flavorStr, genericDataWrapper, &data, dataLen ); // now place it on the Clipboard if (nsnull != data) { @@ -641,9 +670,10 @@ NS_IMETHODIMP nsClipboard::ForceDataToClipboard() // Now, delete the memory that was created by the transferable delete [] data; + delete [] flavorStr; } } - delete dfList; + ::CloseClipboard(); return NS_OK; diff --git a/widget/src/windows/nsDataObj.cpp b/widget/src/windows/nsDataObj.cpp index 2eafc25136e..24215911896 100644 --- a/widget/src/windows/nsDataObj.cpp +++ b/widget/src/windows/nsDataObj.cpp @@ -20,7 +20,10 @@ #include "nsString.h" #include "nsVoidArray.h" #include "nsITransferable.h" +#include "nsISupportsPrimitives.h" #include "IENUMFE.h" +#include "nsCOMPtr.h" +#include "nsIComponentManager.h" #include "OLE2.h" #include "URLMON.h" @@ -41,6 +44,12 @@ EXTERN_C GUID CDECL CLSID_nsDataObj = { 0x1bba7640, 0xdf52, 0x11cf, { 0x82, 0x7b, 0, 0xa0, 0x24, 0x3a, 0xe5, 0x05 } }; +// I don't like having to define these here, but all this should be going away for a generic +// mechanism at some point in the future. +void CreateDataFromPrimitive ( const char* aFlavor, nsISupports* aPrimitive, void** aDataBuff, PRUint32 aDataLen ) ; +void CreatePrimitiveForData ( const char* aFlavor, void* aDataBuff, PRUint32 aDataLen, nsISupports** aPrimitive ) ; + + /* * Class nsDataObj */ @@ -326,14 +335,19 @@ HRESULT nsDataObj::GetDib(FORMATETC&, STGMEDIUM&) //----------------------------------------------------- HRESULT nsDataObj::GetText(nsString * aDF, FORMATETC& aFE, STGMEDIUM& aSTG) { - char * data; + void* data; PRUint32 len; + + char* flavorStr = aDF->ToNewCString(); - // NOTE: Transferable creates new memory, that needs to be deleted - mTransferable->GetTransferData(aDF, (void **)&data, &len); + // NOTE: CreateDataFromPrimitive creates new memory, that needs to be deleted + nsCOMPtr genericDataWrapper; + mTransferable->GetTransferData(flavorStr, getter_AddRefs(genericDataWrapper), &len); if (0 == len) { return ResultFromScode(E_FAIL); } + CreateDataFromPrimitive ( flavorStr, genericDataWrapper, &data, len ); + delete [] flavorStr; HGLOBAL hGlobalMemory = NULL; PSTR pGlobalMemory = NULL; @@ -375,7 +389,7 @@ HRESULT nsDataObj::GetText(nsString * aDF, FORMATETC& aFE, STGMEDIUM& aSTG) //PSTR pstr = pGlobalMemory; // need to use memcpy here - char* s = data; + char* s = NS_REINTERPRET_CAST(char*, data); PRUint32 inx; for (inx=0; inx < len; inx++) { *pstr++ = *s++; @@ -387,7 +401,7 @@ HRESULT nsDataObj::GetText(nsString * aDF, FORMATETC& aFE, STGMEDIUM& aSTG) aSTG.hGlobal = hGlobalMemory; - // Now, delete the memory that was created by the transferable + // Now, delete the memory that was created by CreateDataFromPrimitive delete [] data; return ResultFromScode(S_OK); @@ -449,13 +463,13 @@ CLSID nsDataObj::GetClassID() const //----------------------------------------------------- // Registers a the DataFlavor/FE pair //----------------------------------------------------- -void nsDataObj::AddDataFlavor(nsString * aDataFlavor, LPFORMATETC aFE) +void nsDataObj::AddDataFlavor(nsString & aDataFlavor, LPFORMATETC aFE) { // These two lists are the mapping to and from data flavors and FEs // Later, OLE will tell us it's needs a certain type of FORMATETC (text, unicode, etc) // so we will look up data flavor that corresponds to the FE // and then ask the transferable for that type of data - mDataFlavors->AppendElement(new nsString(*aDataFlavor)); + mDataFlavors->AppendElement(new nsString(aDataFlavor)); m_enumFE->AddFE(aFE); } @@ -476,3 +490,58 @@ void nsDataObj::SetTransferable(nsITransferable * aTransferable) return; } + + +//еее skanky hack until i can correctly re-create primitives from native data. i know this code sucks, +//еее please forgive me. +void +CreatePrimitiveForData ( const char* aFlavor, void* aDataBuff, PRUint32 aDataLen, nsISupports** aPrimitive ) +{ + if ( !aPrimitive ) + return; + + if ( strcmp(aFlavor,kTextMime) == 0 ) { + nsCOMPtr primitive; + nsresult rv = nsComponentManager::CreateInstance(NS_SUPPORTS_STRING_PROGID, nsnull, + NS_GET_IID(nsISupportsString), getter_AddRefs(primitive)); + if ( primitive ) { + primitive->SetData ( (char*)aDataBuff ); + nsCOMPtr genericPrimitive ( do_QueryInterface(primitive) ); + *aPrimitive = genericPrimitive; + NS_ADDREF(*aPrimitive); + } + } + else { + nsCOMPtr primitive; + nsresult rv = nsComponentManager::CreateInstance(NS_SUPPORTS_WSTRING_PROGID, nsnull, + NS_GET_IID(nsISupportsWString), getter_AddRefs(primitive)); + if ( primitive ) { + primitive->SetData ( (unsigned short*)aDataBuff ); + nsCOMPtr genericPrimitive ( do_QueryInterface(primitive) ); + *aPrimitive = genericPrimitive; + NS_ADDREF(*aPrimitive); + } + } + +} // CreatePrimitiveForData + + +void +CreateDataFromPrimitive ( const char* aFlavor, nsISupports* aPrimitive, void** aDataBuff, PRUint32 aDataLen ) +{ + if ( !aDataBuff ) + return; + + if ( strcmp(aFlavor,kTextMime) == 0 ) { + nsCOMPtr plainText ( do_QueryInterface(aPrimitive) ); + if ( plainText ) + plainText->GetData ( (char**)aDataBuff ); + } + else { + nsCOMPtr doubleByteText ( do_QueryInterface(aPrimitive) ); + if ( doubleByteText ) + doubleByteText->GetData ( (unsigned short**)aDataBuff ); + } + +} + diff --git a/widget/src/windows/nsDataObj.h b/widget/src/windows/nsDataObj.h index 3d77a534356..c0a9ee8c69e 100644 --- a/widget/src/windows/nsDataObj.h +++ b/widget/src/windows/nsDataObj.h @@ -60,7 +60,7 @@ class nsDataObj : public IDataObject virtual HRESULT SetMetafilePict(FORMATETC& FE, STGMEDIUM& STM); // support for clipboard - void AddDataFlavor(nsString * aDataFlavor, LPFORMATETC aFE); + void AddDataFlavor(nsString & aDataFlavor, LPFORMATETC aFE); void SetTransferable(nsITransferable * aTransferable); virtual HRESULT GetText(nsString * aDF, FORMATETC& FE, STGMEDIUM& STM); diff --git a/widget/src/windows/nsDragService.cpp b/widget/src/windows/nsDragService.cpp index bbede46511a..3789731362c 100644 --- a/widget/src/windows/nsDragService.cpp +++ b/widget/src/windows/nsDragService.cpp @@ -31,9 +31,6 @@ #include "OLEIDL.H" -static NS_DEFINE_IID(kIDragServiceIID, NS_IDRAGSERVICE_IID); -static NS_DEFINE_IID(kIDragSessionIID, NS_IDRAGSESSION_IID); - NS_IMPL_ADDREF_INHERITED(nsDragService, nsBaseDragService) NS_IMPL_RELEASE_INHERITED(nsDragService, nsBaseDragService) @@ -62,12 +59,14 @@ nsDragService::~nsDragService() NS_IF_RELEASE(mDataObject); } + /** * @param aIID The name of the class implementing the method * @param _classiiddef The name of the #define symbol that defines the IID * for the class (e.g. NS_ISUPPORTS_IID) * -*/ +*/ +// clean me up! ;) nsresult nsDragService::QueryInterface(const nsIID& aIID, void** aInstancePtr) { @@ -80,13 +79,13 @@ nsresult nsDragService::QueryInterface(const nsIID& aIID, void** aInstancePtr) return NS_OK; } - if (aIID.Equals(kIDragServiceIID)) { + if (aIID.Equals(NS_GET_IID(nsIDragService))) { *aInstancePtr = (void*) ((nsIDragService*)this); NS_ADDREF_THIS(); return NS_OK; } - if (aIID.Equals(kIDragSessionIID)) { + if (aIID.Equals(NS_GET_IID(nsIDragSession))) { *aInstancePtr = (void*) ((nsIDragSession*)this); NS_ADDREF_THIS(); return NS_OK; @@ -113,12 +112,14 @@ NS_IMETHODIMP nsDragService::InvokeDragSession (nsISupportsArray * anArrayTransf IDataObject * dataObj = nsnull; PRUint32 i; for (i=0;iElementAt(i); + nsCOMPtr supports; + anArrayTransferables->GetElementAt(i, getter_AddRefs(supports)); nsCOMPtr trans(do_QueryInterface(supports)); - NS_RELEASE(supports); - nsClipboard::CreateNativeDataObject(trans, &dataObj); - dataObjCollection->AddDataObject(dataObj); - NS_IF_RELEASE(dataObj); + if ( trans ) { + nsClipboard::CreateNativeDataObject(trans, &dataObj); + dataObjCollection->AddDataObject(dataObj); + NS_IF_RELEASE(dataObj); + } } StartInvokingDragSession((IDataObject *)dataObjCollection, aActionType); @@ -229,11 +230,10 @@ NS_IMETHODIMP nsDragService::SetIDataObject (IDataObject * aDataObj) } //------------------------------------------------------------------------- -NS_IMETHODIMP nsDragService::IsDataFlavorSupported(nsString * aDataFlavor) +NS_IMETHODIMP nsDragService::IsDataFlavorSupported(const char *aDataFlavor, PRBool *_retval) { - if (nsnull == aDataFlavor || nsnull == mDataObject) { + if ( !aDataFlavor || !mDataObject || !_retval ) return NS_ERROR_FAILURE; - } // First check to see if the mDataObject is is Collection of IDataObjects UINT format = nsClipboard::GetFormat(MULTI_MIME); @@ -243,7 +243,7 @@ NS_IMETHODIMP nsDragService::IsDataFlavorSupported(nsString * aDataFlavor) if (S_OK != mDataObject->QueryGetData(&fe)) { // Ok, so we have a single object // now check to see if has the correct data type - format = nsClipboard::GetFormat(*aDataFlavor); + format = nsClipboard::GetFormat(aDataFlavor); SET_FORMATETC(fe, format, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL | TYMED_FILE | TYMED_GDI); if (S_OK == mDataObject->QueryGetData(&fe)) { @@ -254,7 +254,7 @@ NS_IMETHODIMP nsDragService::IsDataFlavorSupported(nsString * aDataFlavor) } // Set it up for the data flavor - format = nsClipboard::GetFormat(*aDataFlavor); + format = nsClipboard::GetFormat(aDataFlavor); SET_FORMATETC(fe, format, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL | TYMED_FILE | TYMED_GDI); // Ok, now see if any one of the IDataObjects in the collection @@ -275,10 +275,10 @@ NS_IMETHODIMP nsDragService::IsDataFlavorSupported(nsString * aDataFlavor) //------------------------------------------------------------------------- NS_IMETHODIMP nsDragService::GetCurrentSession (nsIDragSession ** aSession) { - if (nsnull == aSession) { + if ( !aSession ) return NS_ERROR_FAILURE; - } + *aSession = (nsIDragSession *)this; - NS_ADDREF(this); + NS_ADDREF(*aSession); return NS_OK; } diff --git a/widget/src/windows/nsDragService.h b/widget/src/windows/nsDragService.h index e70291c909f..16ea4787355 100644 --- a/widget/src/windows/nsDragService.h +++ b/widget/src/windows/nsDragService.h @@ -47,7 +47,7 @@ public: // nsIDragSession NS_IMETHOD GetData (nsITransferable * aTransferable, PRUint32 anItem); NS_IMETHOD GetNumDropItems (PRUint32 * aNumItems); - NS_IMETHOD IsDataFlavorSupported(nsString * aDataFlavor); + NS_IMETHOD IsDataFlavorSupported(const char *aDataFlavor, PRBool *_retval); // native impl. NS_IMETHOD SetIDataObject (IDataObject * aDataObj); diff --git a/widget/src/xpwidgets/Makefile.in b/widget/src/xpwidgets/Makefile.in index 88fa73fe311..ad9ad3ed343 100644 --- a/widget/src/xpwidgets/Makefile.in +++ b/widget/src/xpwidgets/Makefile.in @@ -34,7 +34,6 @@ CPPSRCS= \ nsXIFFormatConverter.cpp \ nsBaseDragService.cpp \ nsBaseClipboard.cpp \ - nsFileListTransferable.cpp \ nsFileSpecWithUIImpl.cpp \ $(NULL) diff --git a/widget/src/xpwidgets/makefile.win b/widget/src/xpwidgets/makefile.win index c6c7b66b28c..da88dbc72fc 100644 --- a/widget/src/xpwidgets/makefile.win +++ b/widget/src/xpwidgets/makefile.win @@ -23,7 +23,6 @@ REQUIRES=xpcom gfxwin raptor dom js network netlib DEFINES =-D_IMPL_NS_WIDGET CPPSRCS = \ - nsFileListTransferable.cpp \ nsBaseDragService.cpp \ nsBaseWidget.cpp \ nsFileSpecWithUIImpl.cpp \ @@ -35,7 +34,6 @@ CPPSRCS = \ MODULE=raptor OBJS= \ - .\$(OBJDIR)\nsFileListTransferable.obj \ .\$(OBJDIR)\nsBaseDragService.obj \ .\$(OBJDIR)\nsBaseWidget.obj \ .\$(OBJDIR)\nsFileSpecWithUIImpl.obj \ diff --git a/widget/src/xpwidgets/nsBaseClipboard.cpp b/widget/src/xpwidgets/nsBaseClipboard.cpp index 4e6658a4ca4..47ec0175459 100644 --- a/widget/src/xpwidgets/nsBaseClipboard.cpp +++ b/widget/src/xpwidgets/nsBaseClipboard.cpp @@ -23,11 +23,9 @@ #include "nsIWidget.h" #include "nsIComponentManager.h" -#include "nsWidgetsCID.h" +#include "nsCOMPtr.h" +#include "nsISupportsPrimitives.h" -// interface definitions -//static NS_DEFINE_IID(kIWidgetIID, NS_IWIDGET_IID); -static NS_DEFINE_IID(kWindowCID, NS_WINDOW_CID); NS_IMPL_ADDREF(nsBaseClipboard) NS_IMPL_RELEASE(nsBaseClipboard) @@ -159,3 +157,58 @@ NS_IMETHODIMP nsBaseClipboard::ForceDataToClipboard() { return NS_OK; } + + +//еее skanky hack until i can correctly re-create primitives from native data. i know this code sucks, +//еее please forgive me. +void +nsBaseClipboard :: CreatePrimitiveForData ( const char* aFlavor, void* aDataBuff, PRUint32 aDataLen, nsISupports** aPrimitive ) +{ + if ( !aPrimitive ) + return; + + if ( strcmp(aFlavor,kTextMime) == 0 ) { + nsCOMPtr primitive; + nsresult rv = nsComponentManager::CreateInstance(NS_SUPPORTS_STRING_PROGID, nsnull, + NS_GET_IID(nsISupportsString), getter_AddRefs(primitive)); + if ( primitive ) { + primitive->SetData ( (char*)aDataBuff ); + nsCOMPtr genericPrimitive ( do_QueryInterface(primitive) ); + *aPrimitive = genericPrimitive; + NS_ADDREF(*aPrimitive); + } + } + else { + nsCOMPtr primitive; + nsresult rv = nsComponentManager::CreateInstance(NS_SUPPORTS_WSTRING_PROGID, nsnull, + NS_GET_IID(nsISupportsWString), getter_AddRefs(primitive)); + if ( primitive ) { + primitive->SetData ( (unsigned short*)aDataBuff ); + nsCOMPtr genericPrimitive ( do_QueryInterface(primitive) ); + *aPrimitive = genericPrimitive; + NS_ADDREF(*aPrimitive); + } + } + +} // CreatePrimitiveForData + + +void +nsBaseClipboard :: CreateDataFromPrimitive ( const char* aFlavor, nsISupports* aPrimitive, void** aDataBuff, PRUint32 aDataLen ) +{ + if ( !aDataBuff ) + return; + + if ( strcmp(aFlavor,kTextMime) == 0 ) { + nsCOMPtr plainText ( do_QueryInterface(aPrimitive) ); + if ( plainText ) + plainText->GetData ( (char**)aDataBuff ); + } + else { + nsCOMPtr doubleByteText ( do_QueryInterface(aPrimitive) ); + if ( doubleByteText ) + doubleByteText->GetData ( (unsigned short**)aDataBuff ); + } + +} + diff --git a/widget/src/xpwidgets/nsBaseClipboard.h b/widget/src/xpwidgets/nsBaseClipboard.h index 0e683c8ee69..3883dca7803 100644 --- a/widget/src/xpwidgets/nsBaseClipboard.h +++ b/widget/src/xpwidgets/nsBaseClipboard.h @@ -54,6 +54,9 @@ protected: NS_IMETHOD SetNativeClipboardData() = 0; NS_IMETHOD GetNativeClipboardData(nsITransferable * aTransferable) = 0; + static void CreatePrimitiveForData ( const char* aFlavor, void* aDataBuff, PRUint32 aDataLen, nsISupports** aPrimitive ); + static void CreateDataFromPrimitive ( const char* aFlavor, nsISupports* aPrimitive, void** aDataBuff, PRUint32 aDataLen ); + PRBool mIgnoreEmptyNotification; nsIClipboardOwner * mClipboardOwner; nsITransferable * mTransferable; diff --git a/widget/src/xpwidgets/nsBaseDragService.cpp b/widget/src/xpwidgets/nsBaseDragService.cpp index b9e5aebdd6d..6741ffac213 100644 --- a/widget/src/xpwidgets/nsBaseDragService.cpp +++ b/widget/src/xpwidgets/nsBaseDragService.cpp @@ -20,11 +20,12 @@ #include "nsITransferable.h" #include "nsIServiceManager.h" -#include "nsWidgetsCID.h" #include "nsITransferable.h" #include "nsISupportsArray.h" #include "nsSize.h" #include "nsIRegion.h" +#include "nsISupportsPrimitives.h" +#include "nsCOMPtr.h" NS_IMPL_ADDREF(nsBaseDragService) @@ -147,7 +148,7 @@ NS_IMETHODIMP nsBaseDragService::GetData (nsITransferable * aTransferable, PRUin } //------------------------------------------------------------------------- -NS_IMETHODIMP nsBaseDragService::IsDataFlavorSupported(nsString * aDataFlavor) +NS_IMETHODIMP nsBaseDragService::IsDataFlavorSupported(const char *aDataFlavor, PRBool *_retval) { return NS_ERROR_FAILURE; } @@ -168,8 +169,8 @@ NS_IMETHODIMP nsBaseDragService::GetCurrentSession (nsIDragSession ** aSession) // "this" also implements a drag session, so say we are one but only if there // is currently a drag going on. if ( mDoingDrag ) { - NS_ADDREF_THIS(); // addRef because we're a "getter" *aSession = this; + NS_ADDREF(*aSession); // addRef because we're a "getter" } else *aSession = nsnull; @@ -196,3 +197,57 @@ NS_IMETHODIMP nsBaseDragService::EndDragSession () mDoingDrag = PR_FALSE; return NS_OK; } + + +//еее skanky hack until i can correctly re-create primitives from native data. i know this code sucks, +//еее please forgive me. +void +nsBaseDragService :: CreatePrimitiveForData ( const char* aFlavor, void* aDataBuff, PRUint32 aDataLen, nsISupports** aPrimitive ) +{ + if ( !aPrimitive ) + return; + + if ( strcmp(aFlavor,kTextMime) == 0 ) { + nsCOMPtr primitive; + nsresult rv = nsComponentManager::CreateInstance(NS_SUPPORTS_STRING_PROGID, nsnull, + NS_GET_IID(nsISupportsString), getter_AddRefs(primitive)); + if ( primitive ) { + primitive->SetData ( (char*)aDataBuff ); + nsCOMPtr genericPrimitive ( do_QueryInterface(primitive) ); + *aPrimitive = genericPrimitive; + NS_ADDREF(*aPrimitive); + } + } + else { + nsCOMPtr primitive; + nsresult rv = nsComponentManager::CreateInstance(NS_SUPPORTS_WSTRING_PROGID, nsnull, + NS_GET_IID(nsISupportsWString), getter_AddRefs(primitive)); + if ( primitive ) { + primitive->SetData ( (unsigned short*)aDataBuff ); + nsCOMPtr genericPrimitive ( do_QueryInterface(primitive) ); + *aPrimitive = genericPrimitive; + NS_ADDREF(*aPrimitive); + } + } + +} // CreatePrimitiveForData + + +void +nsBaseDragService :: CreateDataFromPrimitive ( const char* aFlavor, nsISupports* aPrimitive, void** aDataBuff, PRUint32 aDataLen ) +{ + if ( !aDataBuff ) + return; + + if ( strcmp(aFlavor,kTextMime) == 0 ) { + nsCOMPtr plainText ( do_QueryInterface(aPrimitive) ); + if ( plainText ) + plainText->GetData ( (char**)aDataBuff ); + } + else { + nsCOMPtr doubleByteText ( do_QueryInterface(aPrimitive) ); + if ( doubleByteText ) + doubleByteText->GetData ( (unsigned short**)aDataBuff ); + } + +} diff --git a/widget/src/xpwidgets/nsBaseDragService.h b/widget/src/xpwidgets/nsBaseDragService.h index dc0b3b0487a..ba9c222d2ac 100644 --- a/widget/src/xpwidgets/nsBaseDragService.h +++ b/widget/src/xpwidgets/nsBaseDragService.h @@ -22,7 +22,6 @@ #include "nsIDragService.h" #include "nsIDragSession.h" #include "nsITransferable.h" -#include "nsSize.h" #include "nsISupportsArray.h" #include "nsCOMPtr.h" @@ -58,10 +57,13 @@ public: NS_IMETHOD GetData (nsITransferable * aTransferable, PRUint32 aItemIndex); NS_IMETHOD GetNumDropItems (PRUint32 * aNumItems); - NS_IMETHOD IsDataFlavorSupported(nsString * aDataFlavor); + NS_IMETHOD IsDataFlavorSupported(const char *aDataFlavor, PRBool *_retval); protected: + static void CreatePrimitiveForData ( const char* aFlavor, void* aDataBuff, PRUint32 aDataLen, nsISupports** aPrimitive ); + static void CreateDataFromPrimitive ( const char* aFlavor, nsISupports* aPrimitive, void** aDataBuff, PRUint32 aDataLen ); + nsCOMPtr mTransArray; PRBool mCanDrop; PRBool mDoingDrag; diff --git a/widget/src/xpwidgets/nsTransferable.cpp b/widget/src/xpwidgets/nsTransferable.cpp index 0c6448bc842..05ac7d7f20c 100644 --- a/widget/src/xpwidgets/nsTransferable.cpp +++ b/widget/src/xpwidgets/nsTransferable.cpp @@ -16,14 +16,25 @@ * Reserved. */ +/* +Notes to self: + +- fix QI +- should DataStruct.mFlavor be a string or a nsISupportsString internally? Would save + on having to recreate it each time it is asked for externally. Would complicate things + if this the list is used internally a lot + +*/ + + #include "nsTransferable.h" #include "nsString.h" -#include "nsWidgetsCID.h" #include "nsVoidArray.h" #include "nsIFormatConverter.h" #include "nsVoidArray.h" #include "nsIComponentManager.h" #include "nsCOMPtr.h" +#include "nsISupportsPrimitives.h" #include "nsIFileSpec.h" #include "nsIOutputStream.h" @@ -33,110 +44,95 @@ NS_IMPL_ADDREF(nsTransferable) NS_IMPL_RELEASE(nsTransferable) +// NS_IMPL_QUERY_INTERFACE1(nsITransferable) +NS_IMPL_QUERY_INTERFACE(nsTransferable, NS_GET_IID(nsITransferable)) + // million bytes #define LARGE_DATASET_SIZE 1000000 //#define LARGE_DATASET_SIZE 10 -struct DataStruct { - DataStruct (const nsString & aString) - : mFlavor(aString), mData(nsnull), mDataLen(0), mCacheFileName(nsnull) { } + +struct DataStruct +{ + DataStruct ( const char* aFlavor ) + : mFlavor(aFlavor), mDataLen(0), mCacheFileName(nsnull) { } ~DataStruct(); - void SetData( char* aData, PRUint32 aDataLen ); - void GetData( char** aData, PRUint32 *aDataLen ); + void SetData( nsISupports* inData, PRUint32 inDataLen ); + void GetData( nsISupports** outData, PRUint32 *outDataLen ); nsIFileSpec * GetFileSpec(const char * aFileName); - PRBool IsDataAvilable() { return (nsnull != mData && mDataLen > 0) || (nsnull == mData && nsnull != mCacheFileName); } + PRBool IsDataAvilable() { return (mData && mDataLen > 0) || (!mData && mCacheFileName); } nsString mFlavor; protected: - nsresult WriteCache(char* aData, PRUint32 aDataLen ); - nsresult ReadCache(char** aData, PRUint32* aDataLen ); - + nsresult WriteCache(nsISupports* aData, PRUint32 aDataLen ); + nsresult ReadCache(nsISupports** aData, PRUint32* aDataLen ); - char * mData; + nsCOMPtr mData; // OWNER - some varient of primitive wrapper PRUint32 mDataLen; char * mCacheFileName; }; + //------------------------------------------------------------------------- DataStruct::~DataStruct() { - if (mData) - delete [] mData; - - if (mCacheFileName) { - delete [] mCacheFileName; + delete [] mCacheFileName; //nsIFileSpec * cacheFile = GetFileSpec(mCacheFileName); //cacheFile->Remove(); - } } //------------------------------------------------------------------------- -void DataStruct::SetData ( char* aData, PRUint32 aDataLen ) +void +DataStruct::SetData ( nsISupports* aData, PRUint32 aDataLen ) { - // check to see if we already have data and then delete it - if ( mData ) { - delete [] mData; - mData = nsnull; - } - // Now, check to see if we consider the data to be "too large" if (aDataLen > LARGE_DATASET_SIZE) { // if so, cache it to disk instead of memory - if (NS_OK == WriteCache(aData, aDataLen)) { + if ( NS_SUCCEEDED(WriteCache(aData, aDataLen)) ) { printf("->>>>>>>>>>>>>> Wrote Clipboard to cache file\n"); return; } } else { printf("->>>>>>>>>>>>>> Write Clipboard to memory\n"); } - mData = aData; - mDataLen = aDataLen; + mData = aData; + mDataLen = aDataLen; } -//------------------------------------------------------------------------- -void DataStruct::GetData ( char** aData, PRUint32 *aDataLen ) -{ +//------------------------------------------------------------------------- +void +DataStruct::GetData ( nsISupports** aData, PRUint32 *aDataLen ) +{ // check here to see if the data is cached on disk - if (nsnull == mData && nsnull != mCacheFileName) { + if ( !mData && mCacheFileName ) { // if so, read it in and pass it back // ReadCache creates memory and copies the data into it. - if (NS_OK == ReadCache(aData, aDataLen)) { + if ( NS_SUCCEEDED(ReadCache(aData, aDataLen)) ) { printf("->>>>>>>>>>>>>> Read Clipboard from cache file\n"); return; } } else { printf("->>>>>>>>>>>>>> Read Clipboard from memory\n"); } - // OK, we create memory and copy the contents into it. - char * data = new char[mDataLen]; - if (nsnull != mData && mDataLen > 0) { - memcpy(data, mData, mDataLen); - *aData = data; - } else { - // zeros it out - *aData = nsnull; - } + + *aData = mData; + NS_ADDREF(*aData); *aDataLen = mDataLen; } + //------------------------------------------------------------------------- -nsIFileSpec * DataStruct::GetFileSpec(const char * aFileName) +nsIFileSpec* +DataStruct::GetFileSpec(const char * aFileName) { nsIFileSpec* cacheFile = nsnull; - nsresult rv; - // There is no locator component. Or perhaps there is a locator, but the - // locator couldn't find where to put it. So put it in the cwd (NB, viewer comes here.) - // #include nsIComponentManager.h - rv = nsComponentManager::CreateInstance( - (const char*)NS_FILESPEC_PROGID, - (nsISupports*)nsnull, - (const nsID&)nsCOMTypeInfo::GetIID(), - (void**)&cacheFile); + nsresult rv = nsComponentManager::CreateInstance( NS_FILESPEC_PROGID, nsnull, NS_GET_IID(nsIFileSpec), + NS_REINTERPRET_CAST(void**,&cacheFile)); NS_ASSERTION(NS_SUCCEEDED(rv), "ERROR: Could not make a Clipboard Cache file spec."); // Get the system temp directory path @@ -146,7 +142,7 @@ nsIFileSpec * DataStruct::GetFileSpec(const char * aFileName) // if the param aFileName contains a name we should use that // because the file probably already exists // otherwise create a unique name - if (nsnull == aFileName) { + if (!aFileName) { *sysCacheFile += "clipboardcache"; sysCacheFile->MakeUnique(); } else { @@ -159,65 +155,68 @@ nsIFileSpec * DataStruct::GetFileSpec(const char * aFileName) // delete the temp for getting the system info delete sysCacheFile; - // return the nsIFileSpec + // return the nsIFileSpec. The addref comes from CreateInstance() return cacheFile; } + //------------------------------------------------------------------------- -nsresult DataStruct::WriteCache(char* aData, PRUint32 aDataLen) +nsresult +DataStruct::WriteCache(nsISupports* aData, PRUint32 aDataLen) { // Get a new path and file to the temp directory - nsIFileSpec * cacheFile = GetFileSpec(mCacheFileName); - if (nsnull != cacheFile) { + nsCOMPtr cacheFile ( getter_AddRefs(GetFileSpec(mCacheFileName)) ); + if (cacheFile) { // remember the file name - if (nsnull == mCacheFileName) { + if (!mCacheFileName) cacheFile->GetLeafName(&mCacheFileName); - } + // write out the contents of the clipboard // to the file - PRUint32 bytes; - nsIOutputStream * outStr; - cacheFile->GetOutputStream(&outStr); - outStr->Write(aData, aDataLen, &bytes); + //PRUint32 bytes; + nsCOMPtr outStr; + cacheFile->GetOutputStream( getter_AddRefs(outStr) ); + + //XXX broken until i can stream/inflate these primitive objects. + //outStr->Write(aData, aDataLen, &bytes); - // clean up - NS_RELEASE(outStr); - NS_RELEASE(cacheFile); return NS_OK; } return NS_ERROR_FAILURE; } + //------------------------------------------------------------------------- -nsresult DataStruct::ReadCache(char** aData, PRUint32* aDataLen) +nsresult +DataStruct::ReadCache(nsISupports** aData, PRUint32* aDataLen) { // if we don't have a cache filename we are out of luck - if (nsnull == mCacheFileName) { + if (!mCacheFileName) return NS_ERROR_FAILURE; - } // get the path and file name - nsIFileSpec * cacheFile = GetFileSpec(mCacheFileName); - if (nsnull != cacheFile && Exists(cacheFile)) { + nsCOMPtr cacheFile ( getter_AddRefs(GetFileSpec(mCacheFileName)) ); + if ( cacheFile && Exists(cacheFile)) { // get the size of the file PRUint32 fileSize; cacheFile->GetFileSize(&fileSize); // create new memory for the large clipboard data char * data = new char[fileSize]; - + if ( !data ) + return NS_ERROR_OUT_OF_MEMORY; + // now read it all in - nsIInputStream * inStr; - cacheFile->GetInputStream(&inStr); + nsCOMPtr inStr; + cacheFile->GetInputStream( getter_AddRefs(inStr) ); nsresult rv = inStr->Read(data, fileSize, aDataLen); - // clean up file & stream - NS_RELEASE(inStr); - NS_RELEASE(cacheFile); // make sure we got all the data ok - if (NS_OK == rv && *aDataLen == (PRUint32)fileSize) { + if ( NS_SUCCEEDED(rv) && *aDataLen == (PRUint32)fileSize) { *aDataLen = fileSize; - *aData = data; + + //XXX broken until i can inflate primitive objects + //*aData = data; return NS_OK; } @@ -226,16 +225,15 @@ nsresult DataStruct::ReadCache(char** aData, PRUint32* aDataLen) delete[] data; *aData = nsnull; *aDataLen = 0; - return NS_ERROR_FAILURE; } - // this is necessary because we may have created - // a proper cacheFile but it might not exist - NS_IF_RELEASE(cacheFile); return NS_ERROR_FAILURE; } +#pragma mark - + + //------------------------------------------------------------------------- // // Transferable constructor @@ -244,7 +242,7 @@ nsresult DataStruct::ReadCache(char** aData, PRUint32* aDataLen) nsTransferable::nsTransferable() { NS_INIT_REFCNT(); - mDataArray = new nsVoidArray(); + mDataArray = new nsVoidArray(); } //------------------------------------------------------------------------- @@ -257,113 +255,114 @@ nsTransferable::~nsTransferable() PRInt32 i; for (i=0;iCount();i++) { DataStruct * data = (DataStruct *)mDataArray->ElementAt(i); - if (data) - delete data; + delete data; } delete mDataArray; } -/** - * @param aIID The name of the class implementing the method - * @param _classiiddef The name of the #define symbol that defines the IID - * for the class (e.g. NS_ISUPPORTS_IID) - * -*/ -nsresult nsTransferable::QueryInterface(const nsIID& aIID, void** aInstancePtr) + +// +// GetTransferDataFlavors +// +// Returns a copy of the internal list of flavors. This does NOT take into +// account any converter that may be registered. This list consists of +// nsISupportsString objects so that the flavor list can be accessed from JS. +// +NS_IMETHODIMP +nsTransferable :: GetTransferDataFlavors(nsISupportsArray ** aDataFlavorList) { + if (!aDataFlavorList) + return NS_ERROR_INVALID_ARG; - if (NULL == aInstancePtr) { - return NS_ERROR_NULL_POINTER; - } - - nsresult rv = NS_NOINTERFACE; - - if (aIID.Equals(nsCOMTypeInfo::GetIID())) { - *aInstancePtr = (void*) ((nsITransferable*)this); - NS_ADDREF_THIS(); - return NS_OK; + nsresult rv = NS_OK; + + NS_NewISupportsArray ( aDataFlavorList ); + if ( *aDataFlavorList ) { + for ( PRInt32 i=0; iCount(); ++i ) { + DataStruct * data = (DataStruct *)mDataArray->ElementAt(i); + nsCOMPtr flavorWrapper; + rv = nsComponentManager::CreateInstance(NS_SUPPORTS_STRING_PROGID, nsnull, + NS_GET_IID(nsISupportsString), getter_AddRefs(flavorWrapper)); + if ( flavorWrapper ) { + char* tempBecauseNSStringIsLame = data->mFlavor.ToNewCString(); + flavorWrapper->SetData ( tempBecauseNSStringIsLame ); + nsCOMPtr genericWrapper ( do_QueryInterface(flavorWrapper) ); + (*aDataFlavorList)->AppendElement( genericWrapper ); + delete [] tempBecauseNSStringIsLame; + } + } } + else + rv = NS_ERROR_OUT_OF_MEMORY; return rv; } -/** - * - * - */ -NS_IMETHODIMP nsTransferable::GetTransferDataFlavors(nsVoidArray ** aDataFlavorList) +// +// GetTransferData +// +// Returns the data of the requested flavor, obtained from either having the data on hand or +// using a converter to get it. The data is wrapped in a nsISupports primitive so that it is +// accessable from JS. +// +NS_IMETHODIMP +nsTransferable :: GetTransferData(const char *aFlavor, nsISupports **aData, PRUint32 *aDataLen) { - if (nsnull == aDataFlavorList) { - return NS_ERROR_FAILURE; - } - - nsVoidArray * array = new nsVoidArray(); - if (nsnull != array) { - PRInt32 i; - for (i=0;iCount();i++) { - DataStruct * data = (DataStruct *)mDataArray->ElementAt(i); - array->AppendElement(&data->mFlavor); - } - *aDataFlavorList = array; - } else { - aDataFlavorList = nsnull; - } - return NS_OK; -} - -/** - * The transferable owns the data (memory) and only gives the aData a copy of the pointer address to it. - * - */ -NS_IMETHODIMP nsTransferable::GetTransferData(nsString * aDataFlavor, void ** aData, PRUint32 * aDataLen) -{ - if (nsnull == aDataFlavor || nsnull == aData || nsnull == aDataLen) { - return NS_ERROR_FAILURE; - } + if ( !aFlavor || !aData ||!aDataLen ) + return NS_ERROR_INVALID_ARG; + PRBool found = PR_FALSE; + + // first look and see if the data is present in one of the intrinsic flavors PRInt32 i; - for (i=0;iCount();i++) { + for ( i=0; iCount(); ++i ) { DataStruct * data = (DataStruct *)mDataArray->ElementAt(i); - if (aDataFlavor->Equals(data->mFlavor)) { - data->GetData((char **)aData, aDataLen); - if (nsnull != *aData && *aDataLen > 0) { - return NS_OK; - } + if ( data->mFlavor.Equals(aFlavor) ) { + data->GetData(aData, aDataLen); + if (*aData && *aDataLen > 0) + found = PR_TRUE; } } - if ( mFormatConv ) { + // if not, try using a format converter to get the requested flavor + if ( !found && mFormatConv ) { for (i=0;iCount();i++) { DataStruct * data = (DataStruct *)mDataArray->ElementAt(i); - if (NS_OK == mFormatConv->CanConvert(&data->mFlavor, aDataFlavor)) { - char * dataBytes; + char* tempBecauseNSStringIsLame = data->mFlavor.ToNewCString(); + PRBool canConvert = PR_FALSE; + mFormatConv->CanConvert(tempBecauseNSStringIsLame, aFlavor, &canConvert); + if ( canConvert ) { + nsCOMPtr dataBytes; PRUint32 len; - data->GetData(&dataBytes, &len); - mFormatConv->Convert(&data->mFlavor, dataBytes, len, aDataFlavor, aData, aDataLen); - return NS_OK; + data->GetData(getter_AddRefs(dataBytes), &len); + mFormatConv->Convert(tempBecauseNSStringIsLame, dataBytes, len, aFlavor, aData, aDataLen); + found = PR_TRUE; } + delete [] tempBecauseNSStringIsLame; } } - return NS_ERROR_FAILURE; + return found ? NS_OK : NS_ERROR_FAILURE; } -/** - * The transferable owns the data (memory) and only gives the aData a copy of the pointer address to it. - * - */ -NS_IMETHODIMP nsTransferable::GetAnyTransferData(nsString * aDataFlavor, void ** aData, PRUint32 * aDataLen) -{ - if (nsnull == aDataFlavor || nsnull == aData || nsnull == aDataLen) { - return NS_ERROR_FAILURE; - } - PRInt32 i; - for (i=0;iCount();i++) { +// +// GetAnyTransferData +// +// Returns the data of the first flavor found. Caller is responsible for deleting the +// flavor string. +// +NS_IMETHODIMP +nsTransferable::GetAnyTransferData(char **aFlavor, nsISupports **aData, PRUint32 *aDataLen) +{ + if ( !aFlavor || !aData || !aDataLen ) + return NS_ERROR_FAILURE; + + for ( PRInt32 i=0; i < mDataArray->Count(); ++i ) { DataStruct * data = (DataStruct *)mDataArray->ElementAt(i); if (data->IsDataAvilable()) { - *aDataFlavor = data->mFlavor; - data->GetData((char **)aData, aDataLen); + *aFlavor = data->mFlavor.ToNewCString(); + data->GetData(aData, aDataLen); return NS_OK; } } @@ -371,21 +370,22 @@ NS_IMETHODIMP nsTransferable::GetAnyTransferData(nsString * aDataFlavor, void ** return NS_ERROR_FAILURE; } -/** - * The transferable now owns the data (the memory pointing to it) - * - */ -NS_IMETHODIMP nsTransferable::SetTransferData(nsString * aDataFlavor, void * aData, PRUint32 aDataLen) -{ - if (nsnull == aDataFlavor) { - return NS_ERROR_FAILURE; - } - PRInt32 i; - for (i=0;iCount();i++) { +// +// SetTransferData +// +// +// +NS_IMETHODIMP +nsTransferable::SetTransferData(const char *aFlavor, nsISupports *aData, PRUint32 aDataLen) +{ + if ( !aFlavor ) + return NS_ERROR_FAILURE; + + for ( PRInt32 i=0; iCount(); ++i ) { DataStruct * data = (DataStruct *)mDataArray->ElementAt(i); - if (aDataFlavor->Equals(data->mFlavor)) { - data->SetData ( NS_STATIC_CAST(char*,aData), aDataLen ); + if ( data->mFlavor.Equals(aFlavor) ) { + data->SetData ( aData, aDataLen ); return NS_OK; } } @@ -393,66 +393,70 @@ NS_IMETHODIMP nsTransferable::SetTransferData(nsString * aDataFlavor, void * aDa return NS_OK; } -/** - * - * - */ -NS_IMETHODIMP nsTransferable::AddDataFlavor(nsString * aDataFlavor) -{ - if (nsnull == aDataFlavor) { - return NS_ERROR_FAILURE; - } +// +// AddDataFlavor +// +// Adds a data flavor to our list with no data. Error if it already exists. +// +NS_IMETHODIMP +nsTransferable :: AddDataFlavor(const char *aDataFlavor) +{ // Do we have the data flavor already? PRInt32 i; for (i=0;iCount();i++) { DataStruct * data = (DataStruct *)mDataArray->ElementAt(i); - if (aDataFlavor->Equals(data->mFlavor)) { + if ( data->mFlavor.Equals(aDataFlavor) ) return NS_ERROR_FAILURE; - } } // Create a new "slot" for the data - DataStruct * data = new DataStruct ( *aDataFlavor ) ; + DataStruct * data = new DataStruct ( aDataFlavor ) ; mDataArray->AppendElement((void *)data); return NS_OK; } -/** - * - * - */ -NS_IMETHODIMP nsTransferable::RemoveDataFlavor(nsString * aDataFlavor) -{ - if (nsnull == aDataFlavor) { - return NS_ERROR_FAILURE; - } +// +// RemoveDataFlavor +// +// Removes a data flavor (and causes the data to be destroyed). Error if +// the requested flavor is not present. +// +NS_IMETHODIMP +nsTransferable::RemoveDataFlavor(const char *aDataFlavor) +{ // Do we have the data flavor already? - PRInt32 i; - for (i=0;iCount();i++) { + for ( PRInt32 i=0; iCount(); ++i ) { DataStruct * data = (DataStruct *)mDataArray->ElementAt(i); - if (aDataFlavor->Equals(data->mFlavor)) { + if ( data->mFlavor.Equals(aDataFlavor) ) { mDataArray->RemoveElementAt(i); delete data; return NS_OK; } } - return NS_ERROR_FAILURE; } + /** * * */ -NS_IMETHODIMP_(PRBool) nsTransferable::IsLargeDataSet() +NS_IMETHODIMP +nsTransferable::IsLargeDataSet(PRBool *_retval) { - return PR_FALSE; + if ( !_retval ) + return NS_ERROR_FAILURE; + + *_retval = PR_FALSE; + + return NS_OK; } + /** * * @@ -463,18 +467,22 @@ NS_IMETHODIMP nsTransferable::SetConverter(nsIFormatConverter * aConverter) return NS_OK; } + /** * * */ -NS_IMETHODIMP nsTransferable::GetConverter(nsIFormatConverter ** aConverter) +NS_IMETHODIMP nsTransferable::GetConverter(nsIFormatConverter * *aConverter) { + if ( !aConverter ) + return NS_ERROR_FAILURE; + if ( mFormatConv ) { *aConverter = mFormatConv; NS_ADDREF(*aConverter); - } else { + } else *aConverter = nsnull; - } + return NS_OK; } @@ -486,28 +494,28 @@ NS_IMETHODIMP nsTransferable::GetConverter(nsIFormatConverter ** aConverter) // intrinsic knowledge or input data converters. // NS_IMETHODIMP -nsTransferable :: FlavorsTransferableCanImport ( nsVoidArray** outFlavorList ) +nsTransferable :: FlavorsTransferableCanImport(nsISupportsArray **_retval) { - if ( !outFlavorList ) + if ( !_retval ) return NS_ERROR_INVALID_ARG; // Get the flavor list, and on to the end of it, append the list of flavors we // can also get to through a converter. This is so that we can just walk the list // in one go, looking for the desired flavor. - GetTransferDataFlavors(outFlavorList); // addrefs + GetTransferDataFlavors(_retval); // addrefs nsCOMPtr converter; GetConverter(getter_AddRefs(converter)); if ( converter ) { - nsVoidArray * convertedList; - converter->GetInputDataFlavors(&convertedList); - if ( nsnull != convertedList ) { - PRUint32 i; - PRUint32 cnt = convertedList->Count(); - for (i=0;iElementAt(i); - (*outFlavorList)->AppendElement(temp); + nsCOMPtr convertedList; + converter->GetInputDataFlavors(getter_AddRefs(convertedList)); + if ( convertedList ) { + PRUint32 importListLen; + convertedList->Count(&importListLen); + for ( PRUint32 i=0; i < importListLen; ++i ) { + nsCOMPtr genericFlavor; + convertedList->GetElementAt ( i, getter_AddRefs(genericFlavor) ); + (*_retval)->AppendElement(genericFlavor); } // foreach flavor that can be converted to - delete convertedList; } } // if a converter exists @@ -523,26 +531,27 @@ nsTransferable :: FlavorsTransferableCanImport ( nsVoidArray** outFlavorList ) // intrinsic knowledge or output data converters. // NS_IMETHODIMP -nsTransferable :: FlavorsTransferableCanExport ( nsVoidArray** outFlavorList ) +nsTransferable :: FlavorsTransferableCanExport(nsISupportsArray **_retval) { - if ( !outFlavorList ) + if ( !_retval ) return NS_ERROR_INVALID_ARG; // Get the flavor list, and on to the end of it, append the list of flavors we // can also get to through a converter. This is so that we can just walk the list // in one go, looking for the desired flavor. - GetTransferDataFlavors(outFlavorList); // addrefs + GetTransferDataFlavors(_retval); // addrefs nsCOMPtr converter; GetConverter(getter_AddRefs(converter)); if ( converter ) { - nsVoidArray * convertedList; - converter->GetOutputDataFlavors(&convertedList); - if ( nsnull != convertedList ) { - PRUint32 i; - PRUint32 cnt = convertedList->Count(); - for (i=0;iElementAt(i); - (*outFlavorList)->AppendElement(temp); // this addref's for us + nsCOMPtr convertedList; + converter->GetOutputDataFlavors(getter_AddRefs(convertedList)); + PRUint32 importListLen; + if ( convertedList ) { + convertedList->Count(&importListLen); + for ( PRUint32 i=0; i < importListLen; ++i ) { + nsCOMPtr genericFlavor; + convertedList->GetElementAt ( i, getter_AddRefs(genericFlavor) ); + (*_retval)->AppendElement(genericFlavor); } // foreach flavor that can be converted to } } // if a converter exists diff --git a/widget/src/xpwidgets/nsTransferable.h b/widget/src/xpwidgets/nsTransferable.h index 584149a9615..f9d5bf20675 100644 --- a/widget/src/xpwidgets/nsTransferable.h +++ b/widget/src/xpwidgets/nsTransferable.h @@ -36,38 +36,31 @@ class nsVoidArray; class nsTransferable : public nsITransferable { - public: + nsTransferable(); virtual ~nsTransferable(); - //nsISupports + // nsISupports NS_DECL_ISUPPORTS - - //nsITransferable - NS_IMETHOD FlavorsTransferableCanExport ( nsVoidArray** outFlavorList ) ; - NS_IMETHOD GetTransferDataFlavors(nsVoidArray ** aDataFlavorList); - - // Transferable still owns |aData|. Do not delete it. - NS_IMETHOD GetTransferData(nsString * aFlavor, void ** aData, PRUint32 * aDataLen); - NS_IMETHOD GetAnyTransferData(nsString * aFlavor, void ** aData, PRUint32 * aDataLen); - NS_IMETHOD_(PRBool) IsLargeDataSet(); - - NS_IMETHOD FlavorsTransferableCanImport ( nsVoidArray** outFlavorList ) ; - - // Transferable consumes |aData|. Do not delete it. - NS_IMETHOD SetTransferData(nsString * aFlavor, void * aData, PRUint32 aDataLen); - - NS_IMETHOD AddDataFlavor(nsString * aDataFlavor); - NS_IMETHOD RemoveDataFlavor(nsString * aDataFlavor); - + // nsITransferable + NS_IMETHOD FlavorsTransferableCanExport(nsISupportsArray **_retval) ; + NS_IMETHOD GetTransferData(const char *aFlavor, nsISupports **aData, PRUint32 *aDataLen); + NS_IMETHOD GetAnyTransferData(char **aFlavor, nsISupports **aData, PRUint32 *aDataLen); + NS_IMETHOD IsLargeDataSet(PRBool *_retval); + NS_IMETHOD FlavorsTransferableCanImport(nsISupportsArray **_retval) ; + NS_IMETHOD SetTransferData(const char *aFlavor, nsISupports *aData, PRUint32 aDataLen); + NS_IMETHOD AddDataFlavor(const char *aDataFlavor) ; + NS_IMETHOD RemoveDataFlavor(const char *aDataFlavor) ; + NS_IMETHOD GetConverter(nsIFormatConverter * *aConverter); NS_IMETHOD SetConverter(nsIFormatConverter * aConverter); - NS_IMETHOD GetConverter(nsIFormatConverter ** aConverter); - protected: + // get flavors w/out converter + NS_IMETHOD GetTransferDataFlavors(nsISupportsArray** aDataFlavorList); + nsVoidArray * mDataArray; nsCOMPtr mFormatConv; diff --git a/widget/src/xpwidgets/nsXIFFormatConverter.cpp b/widget/src/xpwidgets/nsXIFFormatConverter.cpp index 60c1abd3033..fd246ccbf95 100644 --- a/widget/src/xpwidgets/nsXIFFormatConverter.cpp +++ b/widget/src/xpwidgets/nsXIFFormatConverter.cpp @@ -17,11 +17,12 @@ */ #include "nsString.h" -#include "nsWidgetsCID.h" -#include "nsVoidArray.h" +#include "nsISupportsArray.h" #include "nsRepository.h" +#include "nsCOMPtr.h" +#include "nsISupportsPrimitives.h" -#include "nsITransferable.h" // for mime defs +#include "nsITransferable.h" // for mime defs, this is BAD // These are temporary @@ -44,15 +45,12 @@ #include "nsWidgetsCID.h" #include "nsXIFFormatConverter.h" -static NS_DEFINE_IID(kIXIFFormatConverterIID, NS_IFORMATCONVERTER_IID); -static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); -//static NS_DEFINE_IID(kCXIFConverterCID, NS_XIFCONVERTER_CID); -static NS_DEFINE_IID(kCParserIID, NS_IPARSER_IID); static NS_DEFINE_IID(kCParserCID, NS_PARSER_IID); NS_IMPL_ADDREF(nsXIFFormatConverter) NS_IMPL_RELEASE(nsXIFFormatConverter) +NS_IMPL_QUERY_INTERFACE(nsXIFFormatConverter, NS_GET_IID(nsIFormatConverter)) //------------------------------------------------------------------------- // @@ -73,69 +71,223 @@ nsXIFFormatConverter::~nsXIFFormatConverter() { } -/** - * @param aIID The name of the class implementing the method - * @param _classiiddef The name of the #define symbol that defines the IID - * for the class (e.g. NS_ISUPPORTS_IID) - * -*/ -nsresult nsXIFFormatConverter::QueryInterface(const nsIID& aIID, void** aInstancePtr) + +// +// GetInputDataFlavors +// +// Creates a new list and returns the list of all the flavors this converter +// knows how to import. In this case, it's just XIF. +// +// Flavors (strings) are wrapped in a primitive object so that JavaScript can +// access them easily via XPConnect. +// +NS_IMETHODIMP +nsXIFFormatConverter::GetInputDataFlavors(nsISupportsArray **_retval) { - - if (NULL == aInstancePtr) { - return NS_ERROR_NULL_POINTER; - } - - nsresult rv = NS_NOINTERFACE; - - if (aIID.Equals(kIXIFFormatConverterIID)) { - *aInstancePtr = (void*) ((nsIFormatConverter*)this); - NS_ADDREF_THIS(); - return NS_OK; - } - - if (aIID.Equals(kISupportsIID)) { - *aInstancePtr = (void*)(nsISupports*)this; - NS_ADDREF_THIS(); - return NS_OK; - } - - + if ( !_retval ) + return NS_ERROR_INVALID_ARG; + + nsresult rv = NS_NewISupportsArray ( _retval ); // addrefs for us + if ( NS_SUCCEEDED(rv) ) + rv = AddFlavorToList ( *_retval, kXIFMime ); + return rv; -} + +} // GetInputDataFlavors -/** - * - * - */ -NS_IMETHODIMP nsXIFFormatConverter::GetInputDataFlavors(nsVoidArray ** aDataFlavorList) +// +// GetOutputDataFlavors +// +// Creates a new list and returns the list of all the flavors this converter +// knows how to export (convert). In this case, it's all sorts of things that XIF can be +// converted to. +// +// Flavors (strings) are wrapped in a primitive object so that JavaScript can +// access them easily via XPConnect. +// +NS_IMETHODIMP +nsXIFFormatConverter::GetOutputDataFlavors(nsISupportsArray **_retval) { - nsVoidArray * array = new nsVoidArray(); - if (nsnull != array) { - array->AppendElement(new nsString(kXIFMime)); - *aDataFlavorList = array; + if ( !_retval ) + return NS_ERROR_INVALID_ARG; + + nsresult rv = NS_NewISupportsArray ( _retval ); // addrefs for us + if ( NS_SUCCEEDED(rv) ) { + rv = AddFlavorToList ( *_retval, kXIFMime ); + if ( NS_FAILED(rv) ) + return rv; + rv = AddFlavorToList ( *_retval, kHTMLMime ); + if ( NS_FAILED(rv) ) + return rv; + rv = AddFlavorToList ( *_retval, kUnicodeMime ); + if ( NS_FAILED(rv) ) + return rv; + rv = AddFlavorToList ( *_retval, kTextMime ); + if ( NS_FAILED(rv) ) + return rv; + rv = AddFlavorToList ( *_retval, kAOLMailMime ); + if ( NS_FAILED(rv) ) + return rv; + } + return rv; + +} // GetOutputDataFlavors + + +// +// AddFlavorToList +// +// Convenience routine for adding a flavor wrapped in an nsISupportsString object +// to a list +// +nsresult +nsXIFFormatConverter :: AddFlavorToList ( nsISupportsArray* inList, const char* inFlavor ) +{ + nsCOMPtr dataFlavor; + nsresult rv = nsComponentManager::CreateInstance(NS_SUPPORTS_STRING_PROGID, nsnull, + NS_GET_IID(nsISupportsString), getter_AddRefs(dataFlavor)); + if ( dataFlavor ) { + dataFlavor->SetData ( NS_CONST_CAST(char*, inFlavor) ); + // add to list as an nsISupports so the correct interface gets the addref + // in AppendElement() + nsCOMPtr genericFlavor ( do_QueryInterface(dataFlavor) ); + inList->AppendElement ( genericFlavor); + } + return rv; + +} // AddFlavorToList + + +// +// CanConvert +// +// Determines if we support the given conversion. Currently, this method only +// converts from XIF to others. +// +NS_IMETHODIMP +nsXIFFormatConverter::CanConvert(const char *aFromDataFlavor, const char *aToDataFlavor, PRBool *_retval) +{ + if ( !_retval ) + return NS_ERROR_INVALID_ARG; + + *_retval = PR_FALSE; + nsAutoString fromFlavor ( aFromDataFlavor ); + if ( fromFlavor.Equals(kXIFMime) ) { + nsAutoString toFlavor ( aToDataFlavor ); + if ( toFlavor.Equals(kTextMime) ) + *_retval = PR_TRUE; + else if ( toFlavor.Equals(kHTMLMime) ) + *_retval = PR_TRUE; + else if ( toFlavor.Equals(kUnicodeMime) ) + *_retval = PR_TRUE; + else if ( toFlavor.Equals(kAOLMailMime) ) + *_retval = PR_TRUE; } return NS_OK; -} -/** - * - * - */ -NS_IMETHODIMP nsXIFFormatConverter::GetOutputDataFlavors(nsVoidArray ** aDataFlavorList) +} // CanConvert + + + +// +// Convert +// +// Convert data from one flavor to another. The data is wrapped in primitive objects so that it is +// accessable from JS. Currently, this only accepts XIF input, so anything else is invalid. +// +//XXX This method copies the data WAAAAY too many time for my liking. Grrrrrr. Mostly it's because +//XXX we _must_ put things into nsStrings so that the parser will accept it. Lame lame lame lame. We +//XXX also can't just get raw unicode out of the nsString, so we have to allocate heap to get +//XXX unicode out of the string. Lame lame lame. +// +NS_IMETHODIMP +nsXIFFormatConverter::Convert(const char *aFromDataFlavor, nsISupports *aFromData, PRUint32 aDataLen, + const char *aToDataFlavor, nsISupports **aToData, PRUint32 *aDataToLen) { - nsVoidArray * array = new nsVoidArray(); - if (nsnull != array) { - array->AppendElement(new nsString(kXIFMime)); - array->AppendElement(new nsString(kHTMLMime)); - array->AppendElement(new nsString(kUnicodeMime)); - array->AppendElement(new nsString(kTextMime)); - array->AppendElement(new nsString(kAOLMailMime)); - *aDataFlavorList = array; - } - return NS_OK; -} + if ( !aToData || !aDataToLen ) + return NS_ERROR_INVALID_ARG; + + nsresult rv = NS_OK; + + nsAutoString fromFlavor ( aFromDataFlavor ); + if ( fromFlavor.Equals(kXIFMime) ) { + nsAutoString toFlavor ( aToDataFlavor ); + + // XIF on clipboard is going to always be double byte so it will be in a primitive + // class of nsISupportsWString. Also, since the data is in two byte chunks the + // length represents the length in 1-byte chars, so we need to divide by two. + nsCOMPtr dataWrapper ( do_QueryInterface(aFromData) ); + if ( dataWrapper ) { + PRUnichar* data = nsnull; + dataWrapper->toString ( &data ); + if ( data ) { + nsAutoString dataStr ( data ); + nsAutoString outStr; + + if ( toFlavor.Equals(kTextMime) ) { + if ( NS_SUCCEEDED(ConvertFromXIFToText(dataStr, outStr)) ) { + nsCOMPtr dataWrapper; + nsComponentManager::CreateInstance(NS_SUPPORTS_STRING_PROGID, nsnull, + NS_GET_IID(nsISupportsString), getter_AddRefs(dataWrapper) ); + if ( dataWrapper ) { + char* holderBecauseNSStringIsLame = outStr.ToNewCString(); + dataWrapper->SetData ( holderBecauseNSStringIsLame ); + nsCOMPtr genericDataWrapper ( do_QueryInterface(dataWrapper) ); + *aToData = genericDataWrapper; + NS_ADDREF(*aToData); + *aDataToLen = outStr.Length(); + delete [] holderBecauseNSStringIsLame; + } + } + } // if plain text + else if ( toFlavor.Equals(kHTMLMime) ) { + if ( NS_SUCCEEDED(ConvertFromXIFToHTML(dataStr, outStr)) ) { + nsCOMPtr dataWrapper; + nsComponentManager::CreateInstance(NS_SUPPORTS_WSTRING_PROGID, nsnull, + NS_GET_IID(nsISupportsWString), getter_AddRefs(dataWrapper) ); + if ( dataWrapper ) { + PRUnichar* holderBecauseNSStringIsLame = outStr.ToNewUnicode(); + dataWrapper->SetData ( holderBecauseNSStringIsLame ); + nsCOMPtr genericDataWrapper ( do_QueryInterface(dataWrapper) ); + *aToData = genericDataWrapper; + NS_ADDREF(*aToData); + *aDataToLen = outStr.Length() * 2; + delete [] holderBecauseNSStringIsLame; + } + } + } // else if HTML + else if ( toFlavor.Equals(kAOLMailMime) ) { + if ( NS_SUCCEEDED(ConvertFromXIFToAOLMail(dataStr, outStr)) ) { + nsCOMPtr dataWrapper; + nsComponentManager::CreateInstance(NS_SUPPORTS_WSTRING_PROGID, nsnull, + NS_GET_IID(nsISupportsWString), getter_AddRefs(dataWrapper) ); + if ( dataWrapper ) { + PRUnichar* holderBecauseNSStringIsLame = outStr.ToNewUnicode(); + dataWrapper->SetData ( holderBecauseNSStringIsLame ); + nsCOMPtr genericDataWrapper ( do_QueryInterface(dataWrapper) ); + *aToData = genericDataWrapper; + NS_ADDREF(*aToData); + *aDataToLen = outStr.Length() * 2; + delete [] holderBecauseNSStringIsLame; + } + } + } // else if AOL mail + else { + *aToData = nsnull; + *aDataToLen = 0; + rv = NS_ERROR_FAILURE; + } + } + } + + } // if we got xif mime + else + rv = NS_ERROR_FAILURE; + + return rv; + +} // Convert @@ -143,88 +295,21 @@ NS_IMETHODIMP nsXIFFormatConverter::GetOutputDataFlavors(nsVoidArray ** aDataFla * * */ -NS_IMETHODIMP nsXIFFormatConverter::CanConvert(nsString * aFromDataFlavor, nsString * aToDataFlavor) -{ - - // This method currently only converts from XIF to the others - if (!aFromDataFlavor->Equals(kXIFMime)) { - return NS_ERROR_FAILURE; - } - - if (aToDataFlavor->Equals(kTextMime)) { - return NS_OK; - } else if (aToDataFlavor->Equals(kHTMLMime)) { - return NS_OK; - } else if (aToDataFlavor->Equals(kUnicodeMime)) { - return NS_OK; - } else if (aToDataFlavor->Equals(kAOLMailMime)) { - return NS_OK; - } - return NS_ERROR_FAILURE; -} - -/** - * - * - */ -NS_IMETHODIMP nsXIFFormatConverter::Convert(nsString * aFromDataFlavor, void * aFromData, PRUint32 aDataLen, - nsString * aToDataFlavor, void ** aToData, PRUint32 * aDataToLen) -{ - - // This method currently only converts from XIF to the others - - if (!aFromDataFlavor->Equals(kXIFMime)) { - return NS_ERROR_FAILURE; - } - - nsAutoString text; - nsAutoString srcText; - - // XIF on clipboard is going to always be double byte - // since the data is in two byte chunks the length represents - // the length in single 8 bit chars, so we need to divide by two - srcText.SetString((PRUnichar *)aFromData, aDataLen/2); - - if (aToDataFlavor->Equals(kTextMime)) { - if (NS_OK == ConvertFromXIFToText(srcText, text)) { - *aToData = (void *)text.ToNewCString(); - *aDataToLen = text.Length(); - } - } else if (aToDataFlavor->Equals(kHTMLMime) || aToDataFlavor->Equals(kUnicodeMime)) { - if (NS_OK == ConvertFromXIFToHTML(srcText, text)) { - *aToData = (void *)text.ToNewUnicode(); - *aDataToLen = text.Length()*2; - } - } else if (aToDataFlavor->Equals(kAOLMailMime)) { - if (NS_OK == ConvertFromXIFToAOLMail(srcText, text)) { - *aToData = (void *)text.ToNewCString(); - *aDataToLen = text.Length(); - } - } - - return NS_OK; -} - - - -/** - * - * - */ -NS_IMETHODIMP nsXIFFormatConverter::ConvertFromXIFToText(const nsString & aFromStr, nsString & aToStr) +NS_IMETHODIMP +nsXIFFormatConverter::ConvertFromXIFToText(const nsString & aFromStr, nsString & aToStr) { aToStr = ""; nsIParser* parser; nsresult rv = nsComponentManager::CreateInstance(kCParserCID, nsnull, - kCParserIID, + NS_GET_IID(nsIParser), (void **)&parser); if (NS_OK != rv) return rv; nsIHTMLContentSink* sink = nsnull; - rv = NS_New_HTMLToTXT_SinkStream(&sink, &aToStr, 0); + rv = NS_New_HTMLToTXT_SinkStream(&sink,&aToStr,0); if (NS_OK == rv) { parser->SetContentSink(sink); @@ -248,21 +333,22 @@ NS_IMETHODIMP nsXIFFormatConverter::ConvertFromXIFToText(const nsString & aFromS * * */ -NS_IMETHODIMP nsXIFFormatConverter::ConvertFromXIFToHTML(const nsString & aFromStr, nsString & aToStr) +NS_IMETHODIMP +nsXIFFormatConverter::ConvertFromXIFToHTML(const nsString & aFromStr, nsString & aToStr) { aToStr = ""; nsIParser* parser; nsresult rv = nsComponentManager::CreateInstance(kCParserCID, nsnull, - kCParserIID, + NS_GET_IID(nsIParser), (void **)&parser); if (NS_OK != rv) return rv; nsIHTMLContentSink* sink = nsnull; - rv = NS_New_HTML_ContentSinkStream(&sink, &aToStr, 0); + rv = NS_New_HTML_ContentSinkStream(&sink,&aToStr,0); if (NS_OK == rv) { parser->SetContentSink(sink); @@ -285,7 +371,8 @@ NS_IMETHODIMP nsXIFFormatConverter::ConvertFromXIFToHTML(const nsString & aFromS * * */ -NS_IMETHODIMP nsXIFFormatConverter::ConvertFromXIFToAOLMail(const nsString & aFromStr, nsString & aToStr) +NS_IMETHODIMP +nsXIFFormatConverter::ConvertFromXIFToAOLMail(const nsString & aFromStr, nsString & aToStr) { nsAutoString html; if (NS_OK == ConvertFromXIFToHTML(aFromStr, html)) { diff --git a/widget/src/xpwidgets/nsXIFFormatConverter.h b/widget/src/xpwidgets/nsXIFFormatConverter.h index b613f700114..6e80a442816 100644 --- a/widget/src/xpwidgets/nsXIFFormatConverter.h +++ b/widget/src/xpwidgets/nsXIFFormatConverter.h @@ -24,30 +24,29 @@ class nsXIFFormatConverter : public nsIFormatConverter { - public: + nsXIFFormatConverter(); virtual ~nsXIFFormatConverter(); - //nsISupports + // nsISupports NS_DECL_ISUPPORTS - //nsIXIFConverter - NS_IMETHOD GetInputDataFlavors(nsVoidArray ** aDataFlavorList); - NS_IMETHOD GetOutputDataFlavors(nsVoidArray ** aDataFlavorList); - - NS_IMETHOD CanConvert(nsString * aFromDataFlavor, nsString * aToDataFlavor); - NS_IMETHOD Convert(nsString * aFromDataFlavor, void * aFromData, PRUint32 aDataLen, - nsString * aToDataFlavor, void ** aToData, PRUint32 * aDataToLen); + // nsIXIFConverter + NS_IMETHOD GetInputDataFlavors(nsISupportsArray **_retval) ; + NS_IMETHOD GetOutputDataFlavors(nsISupportsArray **_retval) ; + NS_IMETHOD CanConvert(const char *aFromDataFlavor, const char *aToDataFlavor, PRBool *_retval) ; + NS_IMETHOD Convert(const char *aFromDataFlavor, nsISupports *aFromData, PRUint32 aDataLen, + const char *aToDataFlavor, nsISupports **aToData, PRUint32 *aDataToLen) ; protected: + nsresult AddFlavorToList ( nsISupportsArray* inList, const char* inFlavor ) ; + NS_IMETHOD ConvertFromXIFToHTML(const nsString & aFromStr, nsString & aToStr); NS_IMETHOD ConvertFromXIFToText(const nsString & aFromStr, nsString & aToStr); NS_IMETHOD ConvertFromXIFToAOLMail(const nsString & aFromStr, nsString & aToStr); - //nsVoidArray * mDFList; - }; #endif // nsXIFFormatConverter_h__