//---------------------------------------------------------------------------------------- nsresult nsMacCommandLine::AddToCommandLine(const char* inOptionString, const FSSpec& inFileSpec) //---------------------------------------------------------------------------------------- { // Convert the filespec to a URL FSSpec nonConstSpec = inFileSpec; nsCOMPtr<nsILocalFileMac> inFile; nsresult rv = NS_NewLocalFileWithFSSpec(&nonConstSpec, PR_TRUE, getter_AddRefs(inFile)); if (NS_FAILED(rv)) return rv; nsCAutoString specBuf; rv = NS_GetURLSpecFromFile(inFile, specBuf); if (NS_FAILED(rv)) return rv; AddToCommandLine(inOptionString); AddToCommandLine(specBuf.get()); return NS_OK; }
//---------------------------------------------------------------------------------------- OSErr nsMacCommandLine::HandleOpenOneDoc(const FSSpec& inFileSpec, OSType inFileType) //---------------------------------------------------------------------------------------- { nsCOMPtr<nsILocalFileMac> inFile; nsresult rv = NS_NewLocalFileWithFSSpec(&inFileSpec, PR_TRUE, getter_AddRefs(inFile)); if (NS_FAILED(rv)) return errAEEventNotHandled; if (!mStartedUp) { // Is it the right type to be a command-line file? if (inFileType == 'TEXT' || inFileType == 'CMDL') { // Can we open the file? FILE *fp = 0; rv = inFile->OpenANSIFileDesc("r", &fp); if (NS_SUCCEEDED(rv)) { Boolean foundArgs = false; Boolean foundEnv = false; char chars[1024]; static const char kCommandLinePrefix[] = "ARGS:"; static const char kEnvVarLinePrefix[] = "ENV:"; while (ReadLine(fp, chars, sizeof(chars)) != -1) { // See if there are any command line or environment var settings if (PL_strstr(chars, kCommandLinePrefix) == chars) { (void)AddToCommandLine(chars + sizeof(kCommandLinePrefix) - 1); foundArgs = true; } else if (PL_strstr(chars, kEnvVarLinePrefix) == chars) { (void)AddToEnvironmentVars(chars + sizeof(kEnvVarLinePrefix) - 1); foundEnv = true; } } fclose(fp); #ifndef XP_MACOSX // If we found any environment vars we need to re-init NSPR's logging // so that it knows what the new vars are if (foundEnv) PR_Init_Log(); #endif // If we found a command line or environment vars we want to return now // raather than trying to open the file as a URL if (foundArgs || foundEnv) return noErr; } } // If it's not a command-line argument, and we are starting up the application, // add a command-line "-url" argument to the global list. This means that if // the app is opened with documents on the mac, they'll be handled the same // way as if they had been typed on the command line in Unix or DOS. return AddToCommandLine("-url", inFileSpec); } // Final case: we're not just starting up. How do we handle this? nsCAutoString specBuf; rv = NS_GetURLSpecFromFile(inFile, specBuf); if (NS_FAILED(rv)) return errAEEventNotHandled; return OpenURL(specBuf.get()); }
// // GetData // // Pull data out of the OS drag item at the requested index and stash it into the // given transferable. Only put in the data with the highest fidelity asked for and // stop as soon as we find a match. // NS_IMETHODIMP nsDragService::GetData ( nsITransferable * aTransferable, PRUint32 aItemIndex ) { nsresult errCode = NS_ERROR_FAILURE; // make sure we have a good transferable if ( !aTransferable ) return NS_ERROR_INVALID_ARG; // get flavor list that includes all acceptable flavors (including ones obtained through // conversion). Flavors are nsISupportsCStrings so that they can be seen from JS. nsCOMPtr<nsISupportsArray> 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. ItemReference itemRef; ::GetDragItemReferenceNumber ( mDragRef, aItemIndex + 1, &itemRef ); // create a mime mapper to help us out based on data in a special flavor for this item char* mappings = LookupMimeMappingsForItem(mDragRef, itemRef); nsMimeMapperMac theMapper ( mappings ); nsMemory::Free ( mappings ); // 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 ( &cnt ); for (PRUint32 i = 0; i < cnt; ++i) { nsCOMPtr<nsISupports> genericWrapper; flavorList->GetElementAt ( i, getter_AddRefs(genericWrapper) ); nsCOMPtr<nsISupportsCString> currentFlavor ( do_QueryInterface(genericWrapper) ); if ( currentFlavor ) { // find MacOS flavor (but don't add it if it's not there) nsCAutoString flavorStr; currentFlavor->GetData(flavorStr); FlavorType macOSFlavor = theMapper.MapMimeTypeToMacOSType(flavorStr.get(), PR_FALSE); #if DEBUG_DD printf("looking for data in type %s, mac flavor %ld\n", flavorStr.get(), macOSFlavor); #endif // check if it is present in the current drag item. FlavorFlags unused; PRBool dataFound = PR_FALSE; void* dataBuff = nsnull; PRUint32 dataSize = 0; if ( macOSFlavor && ::GetFlavorFlags(mDragRef, itemRef, macOSFlavor, &unused) == noErr ) { nsresult loadResult = ExtractDataFromOS(mDragRef, itemRef, macOSFlavor, &dataBuff, &dataSize); if ( NS_SUCCEEDED(loadResult) && dataBuff ) dataFound = PR_TRUE; } else { // if we are looking for text/unicode and we fail to find it on the clipboard first, // try again with text/plain. If that is present, convert it to unicode. if ( strcmp(flavorStr.get(), kUnicodeMime) == 0 ) { if ( ::GetFlavorFlags(mDragRef, itemRef, 'TEXT', &unused) == noErr ) { // if 'styl' is available, we can get a script of the first run // and use it for converting 'TEXT' nsresult loadResult = ExtractDataFromOS(mDragRef, itemRef, 'styl', &dataBuff, &dataSize); if (NS_SUCCEEDED(loadResult) && dataBuff && (dataSize >= (sizeof(ScrpSTElement) + 2))) { StScrpRec *scrpRecP = (StScrpRec *) dataBuff; ScrpSTElement *styl = scrpRecP->scrpStyleTab; ScriptCode script = styl ? ::FontToScript(styl->scrpFont) : smCurrentScript; // free 'styl' and get 'TEXT' nsMemory::Free(dataBuff); loadResult = ExtractDataFromOS(mDragRef, itemRef, 'TEXT', &dataBuff, &dataSize); if ( NS_SUCCEEDED(loadResult) && dataBuff ) { PRUnichar* convertedText = nsnull; PRInt32 convertedTextLen = 0; errCode = nsMacNativeUnicodeConverter::ConvertScripttoUnicode(script, (const char *) dataBuff, dataSize, &convertedText, &convertedTextLen); if (NS_SUCCEEDED(errCode) && convertedText) { nsMemory::Free(dataBuff); dataBuff = convertedText; dataSize = convertedTextLen * sizeof(PRUnichar); dataFound = PR_TRUE; } } } if (!dataFound) { loadResult = ExtractDataFromOS(mDragRef, itemRef, 'TEXT', &dataBuff, &dataSize); if ( NS_SUCCEEDED(loadResult) && dataBuff ) { const char* castedText = NS_REINTERPRET_CAST(char*, dataBuff); PRUnichar* convertedText = nsnull; PRInt32 convertedTextLen = 0; nsPrimitiveHelpers::ConvertPlatformPlainTextToUnicode ( castedText, dataSize, &convertedText, &convertedTextLen ); if ( convertedText ) { // out with the old, in with the new nsMemory::Free(dataBuff); dataBuff = convertedText; dataSize = convertedTextLen * 2; dataFound = PR_TRUE; } } // if plain text data on clipboard } } // if plain text flavor present } // if looking for text/unicode } // else we try one last ditch effort to find our data if ( dataFound ) { nsCOMPtr<nsISupports> genericDataWrapper; if ( strcmp(flavorStr.get(), kFileMime) == 0 ) { // we have a HFSFlavor struct in |dataBuff|. Create an nsLocalFileMac object. HFSFlavor* fileData = NS_REINTERPRET_CAST(HFSFlavor*, dataBuff); NS_ASSERTION ( sizeof(HFSFlavor) == dataSize, "Ooops, we really don't have a HFSFlavor" ); nsCOMPtr<nsILocalFileMac> file; if ( NS_SUCCEEDED(NS_NewLocalFileWithFSSpec(&fileData->fileSpec, PR_TRUE, getter_AddRefs(file))) ) genericDataWrapper = do_QueryInterface(file); } else if ((strcmp(flavorStr.get(), kURLDataMime) == 0) || (strcmp(flavorStr.get(), kURLDescriptionMime) == 0)) {