Example #1
0
// Go through the flavors in the transferable and either get or set them
nsresult nsClipboard::DoClipboardAction(ClipboardAction aAction)
{
  nsresult rc = NS_ERROR_FAILURE;

  if (WinOpenClipbrd(0/*hab*/)) {

    if (aAction == Write)
      WinEmptyClipbrd(0/*hab*/);

    // Get the list of formats the transferable can handle
    nsCOMPtr<nsISupportsArray> pFormats;
    if(aAction == Read)
      rc = mTransferable->FlavorsTransferableCanImport(getter_AddRefs(pFormats));
    else
      rc = mTransferable->FlavorsTransferableCanExport(getter_AddRefs(pFormats));

    if (NS_FAILED(rc))
      return NS_ERROR_FAILURE;

    PRUint32 cFormats = 0;
    pFormats->Count(&cFormats);

    for (PRUint32 i = 0; i < cFormats; i++) {

      nsCOMPtr<nsISupports> genericFlavor;
      pFormats->GetElementAt(i, getter_AddRefs(genericFlavor));
      nsCOMPtr<nsISupportsCString> currentFlavor(do_QueryInterface(genericFlavor));

      if (currentFlavor) {
        nsXPIDLCString flavorStr;
        currentFlavor->ToString(getter_Copies(flavorStr));

        if (aAction == Read) {
          if (GetClipboardData(flavorStr))
            break;
        }
        else
          SetClipboardData(flavorStr);
      }
    }
    WinCloseClipbrd(0/*hab*/);
    rc = NS_OK;
  }
  return rc;
}
Example #2
0
// nsIObserver
NS_IMETHODIMP
nsClipboard::Observe(nsISupports *aSubject, const char *aTopic,
                     const PRUnichar *aData)
{
  // This will be called on shutdown.

  // make sure we have a good transferable
  if (!mTransferable)
    return NS_ERROR_FAILURE;

  if (WinOpenClipbrd(0/*hab*/)) {
    WinEmptyClipbrd(0/*hab*/);

    // get flavor list that includes all flavors that can be written (including ones
    // obtained through conversion)
    nsCOMPtr<nsISupportsArray> flavorList;
    nsresult errCode = mTransferable->FlavorsTransferableCanExport(getter_AddRefs(flavorList));
    if (NS_FAILED(errCode))
      return NS_ERROR_FAILURE;

    // Walk through flavors and put data on to clipboard
    PRUint32 i;
    PRUint32 cnt;
    flavorList->Count(&cnt);
    for (i = 0; i < cnt; i++) {
      nsCOMPtr<nsISupports> genericFlavor;
      flavorList->GetElementAt(i, getter_AddRefs(genericFlavor));
      nsCOMPtr<nsISupportsCString> currentFlavor(do_QueryInterface(genericFlavor));
      if (currentFlavor) {
        nsXPIDLCString flavorStr;
        currentFlavor->ToString(getter_Copies(flavorStr));
        SetClipboardData(flavorStr);
      }
    }
    WinCloseClipbrd(0/*hab*/);
  }
  return NS_OK;
}
//-------------------------------------------------------------------------
nsresult nsClipboard::GetDataFromDataObject(IDataObject     * aDataObject,
                                            UINT              anIndex,
                                            nsIWidget       * aWindow,
                                            nsITransferable * aTransferable)
{
  // make sure we have a good transferable
  if ( !aTransferable )
    return NS_ERROR_INVALID_ARG;

  nsresult res = NS_ERROR_FAILURE;

  // get flavor list that includes all flavors that can be written (including ones 
  // obtained through conversion)
  nsCOMPtr<nsISupportsArray> 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;
  flavorList->Count(&cnt);
  for (i=0;i<cnt;i++) {
    nsCOMPtr<nsISupports> genericFlavor;
    flavorList->GetElementAt ( i, getter_AddRefs(genericFlavor) );
    nsCOMPtr<nsISupportsCString> currentFlavor ( do_QueryInterface(genericFlavor) );
    if ( currentFlavor ) {
      nsXPIDLCString flavorStr;
      currentFlavor->ToString(getter_Copies(flavorStr));
      UINT format = GetFormat(flavorStr);

      // Try to get the data using the desired flavor. This might fail, but all is
      // not lost.
      void* data = nullptr;
      PRUint32 dataLen = 0;
      bool dataFound = false;
      if (nullptr != aDataObject) {
        if ( NS_SUCCEEDED(GetNativeDataOffClipboard(aDataObject, anIndex, format, flavorStr, &data, &dataLen)) )
          dataFound = true;
      } 
      else if (nullptr != aWindow) {
        if ( NS_SUCCEEDED(GetNativeDataOffClipboard(aWindow, anIndex, format, &data, &dataLen)) )
          dataFound = true;
      }

      // This is our second chance to try to find some data, having not found it
      // when directly asking for the flavor. Let's try digging around in other
      // flavors to help satisfy our craving for data.
      if ( !dataFound ) {
        if ( strcmp(flavorStr, kUnicodeMime) == 0 )
          dataFound = FindUnicodeFromPlainText ( aDataObject, anIndex, &data, &dataLen );
        else if ( strcmp(flavorStr, kURLMime) == 0 ) {
          // drags from other windows apps expose the native
          // CFSTR_INETURL{A,W} flavor
          dataFound = FindURLFromNativeURL ( aDataObject, anIndex, &data, &dataLen );
          if ( !dataFound )
            dataFound = FindURLFromLocalFile ( aDataObject, anIndex, &data, &dataLen );
        }
      } // if we try one last ditch effort to find our data

      // Hopefully by this point we've found it and can go about our business
      if ( dataFound ) {
        nsCOMPtr<nsISupports> genericDataWrapper;
          if ( strcmp(flavorStr, kFileMime) == 0 ) {
            // we have a file path in |data|. Create an nsLocalFile object.
            nsDependentString filepath(reinterpret_cast<PRUnichar*>(data));
            nsCOMPtr<nsIFile> file;
            if ( NS_SUCCEEDED(NS_NewLocalFile(filepath, false, getter_AddRefs(file))) )
              genericDataWrapper = do_QueryInterface(file);
            nsMemory::Free(data);
          }
        else if ( strcmp(flavorStr, kNativeHTMLMime) == 0) {
          // the editor folks want CF_HTML exactly as it's on the clipboard, no conversions,
          // no fancy stuff. Pull it off the clipboard, stuff it into a wrapper and hand
          // it back to them.
          if ( FindPlatformHTML(aDataObject, anIndex, &data, &dataLen) )
            nsPrimitiveHelpers::CreatePrimitiveForData ( flavorStr, data, dataLen, getter_AddRefs(genericDataWrapper) );
          else
          {
            nsMemory::Free(data);
            continue;     // something wrong with this flavor, keep looking for other data
          }
          nsMemory::Free(data);
        }
        else if ( strcmp(flavorStr, kJPEGImageMime) == 0 ||
                  strcmp(flavorStr, kJPGImageMime) == 0 ||
                  strcmp(flavorStr, kPNGImageMime) == 0) {
          nsIInputStream * imageStream = reinterpret_cast<nsIInputStream*>(data);
          genericDataWrapper = do_QueryInterface(imageStream);
          NS_IF_RELEASE(imageStream);
        }
        else {
          // we probably have some form of text. The DOM only wants LF, so convert from Win32 line 
          // endings to DOM line endings.
          PRInt32 signedLen = static_cast<PRInt32>(dataLen);
          nsLinebreakHelpers::ConvertPlatformToDOMLinebreaks ( flavorStr, &data, &signedLen );
          dataLen = signedLen;

          nsPrimitiveHelpers::CreatePrimitiveForData ( flavorStr, data, dataLen, getter_AddRefs(genericDataWrapper) );
          nsMemory::Free(data);
        }
        
        NS_ASSERTION ( genericDataWrapper, "About to put null data into the transferable" );
        aTransferable->SetTransferData(flavorStr, genericDataWrapper, dataLen);
        res = NS_OK;

        // we found one, get out of the loop
        break;
      }

    }
  } // foreach flavor

  return res;

}
//-------------------------------------------------------------------------
nsresult nsClipboard::SetupNativeDataObject(nsITransferable * aTransferable, IDataObject * aDataObj)
{
  if (nullptr == aTransferable || nullptr == aDataObj) {
    return NS_ERROR_FAILURE;
  }

  nsDataObj * dObj = static_cast<nsDataObj *>(aDataObj);

  // Now give the Transferable to the DataObject 
  // for getting the data out of it
  dObj->SetTransferable(aTransferable);

  // Get the transferable list of data flavors
  nsCOMPtr<nsISupportsArray> 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(&cnt);
  for (i=0;i<cnt;i++) {
    nsCOMPtr<nsISupports> genericFlavor;
    dfList->GetElementAt ( i, getter_AddRefs(genericFlavor) );
    nsCOMPtr<nsISupportsCString> currentFlavor ( do_QueryInterface(genericFlavor) );
    if ( currentFlavor ) {
      nsXPIDLCString flavorStr;
      currentFlavor->ToString(getter_Copies(flavorStr));
      UINT format = GetFormat(flavorStr);

      // Now tell the native IDataObject about both our mime type and 
      // the native data format
      FORMATETC fe;
      SET_FORMATETC(fe, format, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL);
      dObj->AddDataFlavor(flavorStr, &fe);
      
      // Do various things internal to the implementation, like map one
      // flavor to another or add additional flavors based on what's required
      // for the win32 impl.
      if ( strcmp(flavorStr, kUnicodeMime) == 0 ) {
        // if we find text/unicode, also advertise text/plain (which we will convert
        // on our own in nsDataObj::GetText().
        FORMATETC textFE;
        SET_FORMATETC(textFE, CF_TEXT, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL);
        dObj->AddDataFlavor(kTextMime, &textFE);
      }
      else if ( strcmp(flavorStr, kHTMLMime) == 0 ) {      
        // if we find text/html, also advertise win32's html flavor (which we will convert
        // on our own in nsDataObj::GetText().
        FORMATETC htmlFE;
        SET_FORMATETC(htmlFE, CF_HTML, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL);
        dObj->AddDataFlavor(kHTMLMime, &htmlFE);     
      }
      else if ( strcmp(flavorStr, kURLMime) == 0 ) {
        // if we're a url, in addition to also being text, we need to register
        // the "file" flavors so that the win32 shell knows to create an internet
        // shortcut when it sees one of these beasts.
        FORMATETC shortcutFE;
        SET_FORMATETC(shortcutFE, ::RegisterClipboardFormat(CFSTR_FILEDESCRIPTORA), 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL)
        dObj->AddDataFlavor(kURLMime, &shortcutFE);      
        SET_FORMATETC(shortcutFE, ::RegisterClipboardFormat(CFSTR_FILEDESCRIPTORW), 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL)
        dObj->AddDataFlavor(kURLMime, &shortcutFE);      
        SET_FORMATETC(shortcutFE, ::RegisterClipboardFormat(CFSTR_FILECONTENTS), 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL)
        dObj->AddDataFlavor(kURLMime, &shortcutFE);  
        SET_FORMATETC(shortcutFE, ::RegisterClipboardFormat(CFSTR_INETURLA), 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL)
        dObj->AddDataFlavor(kURLMime, &shortcutFE);      
        SET_FORMATETC(shortcutFE, ::RegisterClipboardFormat(CFSTR_INETURLW), 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL)
        dObj->AddDataFlavor(kURLMime, &shortcutFE);      
      }
      else if ( strcmp(flavorStr, kPNGImageMime) == 0 || strcmp(flavorStr, kJPEGImageMime) == 0 ||
                strcmp(flavorStr, kJPGImageMime) == 0 || strcmp(flavorStr, kGIFImageMime) == 0 ||
                strcmp(flavorStr, kNativeImageMime) == 0  ) {
        // if we're an image, register the native bitmap flavor
        FORMATETC imageFE;
        SET_FORMATETC(imageFE, CF_DIBV5, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL)
        dObj->AddDataFlavor(flavorStr, &imageFE);      
      }
      else if ( strcmp(flavorStr, kFilePromiseMime) == 0 ) {
         // if we're a file promise flavor, also register the 
         // CFSTR_PREFERREDDROPEFFECT format.  The data object
         // returns a value of DROPEFFECTS_MOVE to the drop target
         // when it asks for the value of this format.  This causes
         // the file to be moved from the temporary location instead
         // of being copied.  The right thing to do here is to call
         // SetData() on the data object and set the value of this format
         // to DROPEFFECTS_MOVE on this particular data object.  But,
         // since all the other clipboard formats follow the model of setting
         // data on the data object only when the drop object calls GetData(),
         // I am leaving this format's value hard coded in the data object.
         // We can change this if other consumers of this format get added to this
         // codebase and they need different values.
        FORMATETC shortcutFE;
        SET_FORMATETC(shortcutFE, ::RegisterClipboardFormat(CFSTR_PREFERREDDROPEFFECT), 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL)
        dObj->AddDataFlavor(kFilePromiseMime, &shortcutFE);
      }
    }
  }

  return NS_OK;
}
Example #5
0
//
// The blocking Paste routine
//
NS_IMETHODIMP
nsClipboard::GetNativeClipboardData(nsITransferable * aTransferable, PRInt32 aWhichClipboard )
{
#ifdef DEBUG_CLIPBOARD
  printf("  nsClipboard::GetNativeClipboardData()\n");
#endif /* DEBUG_CLIPBOARD */

  // make sure we have a good transferable
  if (nsnull == aTransferable) {
    printf("  GetNativeClipboardData: Transferable is null!\n");
    return NS_ERROR_FAILURE;
  }

  // get flavor list
  nsresult rv;
  nsCOMPtr<nsISupportsArray> flavorList;
  rv = aTransferable->FlavorsTransferableCanImport(getter_AddRefs(flavorList));
  if (NS_FAILED(rv))
    return NS_ERROR_FAILURE;

  // get native clipboard data
  if (!be_clipboard->Lock())
    return NS_ERROR_FAILURE;

  BMessage *msg = be_clipboard->Data();
  if (!msg)
    return NS_ERROR_FAILURE;  
#ifdef DEBUG_CLIPBOARD
  msg->PrintToStream();
#endif /* DEBUG_CLIPBOARD */

  PRUint32 cnt;
  flavorList->Count(&cnt);
  for (PRUint32 i = 0; i < cnt; i++) {
    nsCOMPtr<nsISupports> genericFlavor;
    flavorList->GetElementAt(i, getter_AddRefs(genericFlavor));
    nsCOMPtr<nsISupportsCString> currentFlavor(do_QueryInterface(genericFlavor));
    if (currentFlavor) {
      nsXPIDLCString flavorStr;
      currentFlavor->ToString(getter_Copies(flavorStr));

#ifdef DEBUG_CLIPBOARD
      printf("nsClipboard: %d/%d = %s\n", i, cnt, (const char *)flavorStr);
#endif /* DEBUG_CLIPBOARD */
      const void *data;
      ssize_t size;
      if (0 == strncmp(flavorStr, "text/", 5)) {
        // [Be] text/ * => [NS] text/ *
        status_t rc;
        if (0 == strcmp(flavorStr, kUnicodeMime))
          rc = msg->FindData(kTextMime, B_MIME_TYPE, &data, &size);
        else
          rc = msg->FindData(flavorStr, B_MIME_TYPE, &data, &size);
        if (rc != B_OK || !data || !size) {
#ifdef DEBUG_CLIPBOARD
          printf("nsClipboard: not found in BMessage\n");
#endif /* DEBUG_CLIPBOARD */
        } else {
          NS_ConvertUTF8toUTF16 ucs2Str((const char *)data, (PRUint32)size);
          nsCOMPtr<nsISupports> genericDataWrapper;
          nsPrimitiveHelpers::CreatePrimitiveForData(flavorStr, (void *)ucs2Str.get(), ucs2Str.Length() * 2, getter_AddRefs(genericDataWrapper));
          rv = aTransferable->SetTransferData(flavorStr, genericDataWrapper, ucs2Str.Length() * 2);
        }
      } else {
        // [Be] * / * => [NS] * / *
        if (B_OK != msg->FindData(flavorStr, B_MIME_TYPE, &data, &size)) {
#ifdef DEBUG_CLIPBOARD
          printf("nsClipboard: not found in BMessage\n");
#endif /* DEBUG_CLIPBOARD */
        } else {
          nsCOMPtr<nsISupports> genericDataWrapper;
          nsPrimitiveHelpers::CreatePrimitiveForData(flavorStr, (void *)data, (PRUint32)size, getter_AddRefs(genericDataWrapper));
          rv = aTransferable->SetTransferData(flavorStr, genericDataWrapper, size);
        }
      }
#ifdef DEBUG_CLIPBOARD
      if (NS_FAILED(rv))
        printf("nsClipboard: Error SetTransferData\n");
#endif /* DEBUG_CLIPBOARD */
    } else {
      rv = NS_ERROR_FAILURE;
#ifdef DEBUG_CLIPBOARD
      printf("nsClipboard: Error gerring flavor");
#endif /* DEBUG_CLIPBOARD */
    }
    if (rv != NS_OK)
      break;
  } /* for */

  be_clipboard->Unlock();

  return rv;
}
Example #6
0
//
// The copy routine
//
NS_IMETHODIMP nsClipboard::SetNativeClipboardData(PRInt32 aWhichClipboard)
{
  mIgnoreEmptyNotification = PR_TRUE;

#ifdef DEBUG_CLIPBOARD
  printf("  nsClipboard::SetNativeClipboardData()\n");
#endif /* DEBUG_CLIPBOARD */

  // make sure we have a good transferable
  if (nsnull == mTransferable) {
#ifdef DEBUG_CLIPBOARD
    printf("  SetNativeClipboardData: no transferable!\n");
#endif /* DEBUG_CLIPBOARD */
    return NS_ERROR_FAILURE;
  }

  // lock the native clipboard
  if (!be_clipboard->Lock())
    return NS_ERROR_FAILURE;

  // clear the native clipboard
  nsresult rv = NS_OK;
  if (B_OK == be_clipboard->Clear()) {
    // set data to the native clipboard
    if (BMessage *msg = be_clipboard->Data()) {
      // Get the transferable list of data flavors
      nsCOMPtr<nsISupportsArray> dfList;
      mTransferable->FlavorsTransferableCanExport(getter_AddRefs(dfList));

      // Walk through flavors that contain data and register them
      // into the BMessage as supported flavors
      PRUint32 i;
      PRUint32 cnt;
      dfList->Count(&cnt);
      for (i = 0; i < cnt && rv == NS_OK; i++) {
        nsCOMPtr<nsISupports> genericFlavor;
        dfList->GetElementAt(i, getter_AddRefs(genericFlavor));
        nsCOMPtr<nsISupportsCString> currentFlavor (do_QueryInterface(genericFlavor));
        if (currentFlavor) {
          nsXPIDLCString flavorStr;
          currentFlavor->ToString(getter_Copies(flavorStr));

#ifdef DEBUG_CLIPBOARD
          printf("nsClipboard: %d/%d = %s\n", i, cnt, (const char *)flavorStr);
#endif /* DEBUG_CLIPBOARD */
          if (0 == strncmp(flavorStr, "text/", 5)) {
            // [NS] text/ * => [Be] text/ *
            void *data = nsnull;
            PRUint32 dataSize = 0;
            nsCOMPtr<nsISupports> genericDataWrapper;
            rv = mTransferable->GetTransferData(flavorStr, getter_AddRefs(genericDataWrapper), &dataSize);
            nsPrimitiveHelpers::CreateDataFromPrimitive(flavorStr, genericDataWrapper, &data, dataSize);
#ifdef DEBUG_CLIPBOARD
            if (NS_FAILED(rv))
              printf("nsClipboard: Error getting data from transferable\n");
#endif /* DEBUG_CLIPBOARD */
            if (dataSize && data != nsnull) {
              NS_ConvertUCS2toUTF8 cv((const PRUnichar *)data, (PRUint32)dataSize / 2);
              const char *utf8Str = cv.get();
              uint32 utf8Len = strlen(utf8Str);
#ifdef DEBUG_CLIPBOARD
              if (0 == strcmp(flavorStr, kUnicodeMime))
                printf(" => [%s]%s\n", kTextMime, utf8Str);
              else
                printf(" => [%s]%s\n", (const char *)flavorStr, utf8Str);
#endif /* DEBUG_CLIPBOARD */
              status_t rc;
              if (0 == strcmp(flavorStr, kUnicodeMime)) {
                // [NS] text/unicode => [Be] text/plain
                rc = msg->AddData(kTextMime, B_MIME_TYPE, (void *)utf8Str, utf8Len);
              } else {
                // [NS] text/ * => [Be] text/ *
                rc = msg->AddData((const char *)flavorStr, B_MIME_TYPE, (void *)utf8Str, utf8Len);
              }
              if (rc != B_OK)
                rv = NS_ERROR_FAILURE;
            } else {
#ifdef DEBUG_CLIPBOARD
              printf("nsClipboard: Error null data from transferable\n");
#endif /* DEBUG_CLIPBOARD */
                // not fatal. force to continue...
                rv = NS_OK;
            }
          } else {
            // [NS] * / * => [Be] * / *
            void *data = nsnull;
            PRUint32 dataSize = 0;
            nsCOMPtr<nsISupports> genericDataWrapper;
            rv = mTransferable->GetTransferData(flavorStr, getter_AddRefs(genericDataWrapper), &dataSize);
            nsPrimitiveHelpers::CreateDataFromPrimitive(flavorStr, genericDataWrapper, &data, dataSize);
#ifdef DEBUG_CLIPBOARD
            if (NS_FAILED(rv))
              printf("nsClipboard: Error getting data from transferable\n");
#endif /* DEBUG_CLIPBOARD */
            if (dataSize && data != nsnull) {
#ifdef DEBUG_CLIPBOARD
              printf("[%s](binary)\n", (const char *)flavorStr);
#endif /* DEBUG_CLIPBOARD */
              if (B_OK != msg->AddData((const char *)flavorStr, B_MIME_TYPE, data, dataSize))
                rv = NS_ERROR_FAILURE;
            }
          }
        } else {
#ifdef DEBUG_CLIPBOARD
          printf("nsClipboard: Error getting flavor\n");
#endif /* DEBUG_CLIPBOARD */
          rv = NS_ERROR_FAILURE;
        }
      } /* for */
    } else {
      rv = NS_ERROR_FAILURE;
    }
  } else {
    rv = NS_ERROR_FAILURE;
  }
  if (B_OK != be_clipboard->Commit())
    rv = NS_ERROR_FAILURE;
  be_clipboard->Unlock();

  mIgnoreEmptyNotification = PR_FALSE;

  return rv;
}
Example #7
0
NS_IMETHODIMP
nsClipboard::SetNativeClipboardData( nsITransferable *aTransferable,
                                     QClipboard::Mode clipboardMode )
{
    if (nsnull == aTransferable)
    {
        qDebug("nsClipboard::SetNativeClipboardData(): no transferable!");
        return NS_ERROR_FAILURE;
    }

    // get flavor list that includes all flavors that can be written (including
    // ones obtained through conversion)
    nsCOMPtr<nsISupportsArray> flavorList;
    nsresult errCode = aTransferable->FlavorsTransferableCanExport( getter_AddRefs(flavorList) );

    if (NS_FAILED(errCode))
    {
        qDebug("nsClipboard::SetNativeClipboardData(): no FlavorsTransferable !");
        return NS_ERROR_FAILURE;
    }

    QClipboard *cb = QApplication::clipboard();
    PRUint32 flavorCount = 0;
    flavorList->Count(&flavorCount);

    for (PRUint32 i = 0; i < flavorCount; ++i)
    {
        nsCOMPtr<nsISupports> genericFlavor;
        flavorList->GetElementAt(i,getter_AddRefs(genericFlavor));
        nsCOMPtr<nsISupportsCString> currentFlavor(do_QueryInterface(genericFlavor));
        
        if (currentFlavor)
        {
            // flavorStr is the mime type
            nsXPIDLCString flavorStr;
            currentFlavor->ToString(getter_Copies(flavorStr));

            // Clip is the data which will be sent to the clipboard
            nsCOMPtr<nsISupports> clip;
            // len is the length of the data
            PRUint32 len;

            // Unicode text?
            if (!strcmp(flavorStr.get(), kUnicodeMime))
            {
                aTransferable->GetTransferData(flavorStr,getter_AddRefs(clip),&len);
                nsCOMPtr<nsISupportsString> wideString;
                wideString = do_QueryInterface(clip);
                if (!wideString)
                {
                    return NS_ERROR_FAILURE;
                }

                nsAutoString utf16string;
                wideString->GetData(utf16string);
                QString str = QString::fromUtf16(utf16string.get());

                // Set the date to the clipboard
                cb->setText(str, clipboardMode);
                break;
            }

            if ( !strcmp(flavorStr.get(), kNativeImageMime)
              || !strcmp(flavorStr.get(), kPNGImageMime)
              || !strcmp(flavorStr.get(), kJPEGImageMime)
              || !strcmp(flavorStr.get(), kGIFImageMime))
            {
                qDebug("nsClipboard::SetNativeClipboardData(): Copying image data not implemented!");
            }
        }
    }

    return NS_OK;
}
Example #8
0
// nsClipboard::GetNativeClipboardData ie. Paste
//
NS_IMETHODIMP
nsClipboard::GetNativeClipboardData(nsITransferable *aTransferable,
                                    QClipboard::Mode clipboardMode)
{
    if (nsnull == aTransferable)
    {
        qDebug("  GetNativeClipboardData: Transferable is null!");
        return NS_ERROR_FAILURE;
    }

    // get flavor list that includes all acceptable flavors (including
    // ones obtained through conversion)
    nsCOMPtr<nsISupportsArray> flavorList;
    nsresult errCode = aTransferable->FlavorsTransferableCanImport(
        getter_AddRefs(flavorList));

    if (NS_FAILED(errCode))
    {
        qDebug("nsClipboard::GetNativeClipboardData(): no FlavorsTransferable %i !",
               errCode);
        return NS_ERROR_FAILURE;
    }

    QClipboard *cb = QApplication::clipboard();
    const QMimeData *mimeData = cb->mimeData(clipboardMode);

    // Walk through flavors and see which flavor matches the one being pasted
    PRUint32 flavorCount;
    flavorList->Count(&flavorCount);
    nsCAutoString foundFlavor;

    for (PRUint32 i = 0; i < flavorCount; ++i)
    {
        nsCOMPtr<nsISupports> genericFlavor;
        flavorList->GetElementAt(i,getter_AddRefs(genericFlavor));
        nsCOMPtr<nsISupportsCString> currentFlavor(do_QueryInterface( genericFlavor) );

        if (currentFlavor)
        {
            nsXPIDLCString flavorStr;
            currentFlavor->ToString(getter_Copies(flavorStr));

            // Ok, so which flavor the data being pasted could be?
            // Text?
            if (!strcmp(flavorStr.get(), kUnicodeMime)) 
            {
                if (mimeData->hasText())
                {
                    // Clipboard has text and flavor accepts text, so lets
                    // handle the data as text
                    foundFlavor = nsCAutoString(flavorStr);

                    // Get the text data from clipboard
                    QString text = mimeData->text();
                    const QChar *unicode = text.unicode();
                    // Is there a more correct way to get the size in UTF16?
                    PRUint32 len = (PRUint32) 2*text.size();

                    // And then to genericDataWrapper
                    nsCOMPtr<nsISupports> genericDataWrapper;
                    nsPrimitiveHelpers::CreatePrimitiveForData(
                        foundFlavor.get(),
                        (void*)unicode,
                        len,
                        getter_AddRefs(genericDataWrapper));

                    // Data is good, set it to the transferable
                    aTransferable->SetTransferData(foundFlavor.get(),
                                                   genericDataWrapper,len);
                    // And thats all
                    break;
                }
            }

            // Image?
            if (!strcmp(flavorStr.get(), kJPEGImageMime)
             || !strcmp(flavorStr.get(), kPNGImageMime)
             || !strcmp(flavorStr.get(), kGIFImageMime))
            {
                qDebug("nsClipboard::GetNativeClipboardData(): Pasting image data not implemented!");
                break;
            }
        }
    }

    return NS_OK;
}
Example #9
0
//
// 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)) {
Example #10
0
//
// RegisterDragItemsAndFlavors
//
// Takes the multiple drag items from an array of transferables and registers them
// and their flavors with the MacOS DragManager. Note that we don't actually place
// any of the data there yet, but will rely on a sendDataProc to get the data as
// requested.
//
void
nsDragService::RegisterDragItemsAndFlavors(nsISupportsArray* inArray, RgnHandle inDragRgn)
{
  const FlavorFlags flags = 0;
  
  Rect      dragRgnBounds = {0, 0, 0, 0};
  if (inDragRgn)
    GetRegionBounds(inDragRgn, &dragRgnBounds);

  PRUint32 numDragItems = 0;
  inArray->Count ( &numDragItems ) ;
  for ( PRUint32 itemIndex = 0; itemIndex < numDragItems; ++itemIndex ) {
    nsMimeMapperMac theMapper;
  
    nsCOMPtr<nsISupports> genericItem;
    inArray->GetElementAt ( itemIndex, getter_AddRefs(genericItem) );
    nsCOMPtr<nsITransferable> currItem ( do_QueryInterface(genericItem) );
    if ( currItem ) {   
      nsCOMPtr<nsISupportsArray> flavorList;
      if ( NS_SUCCEEDED(currItem->FlavorsTransferableCanExport(getter_AddRefs(flavorList))) ) {
        PRUint32 numFlavors;
        flavorList->Count ( &numFlavors );
        for ( PRUint32 flavorIndex = 0; flavorIndex < numFlavors; ++flavorIndex ) {
        
          nsCOMPtr<nsISupports> genericWrapper;
          flavorList->GetElementAt ( flavorIndex, getter_AddRefs(genericWrapper) );
          nsCOMPtr<nsISupportsCString> currentFlavor ( do_QueryInterface(genericWrapper) );
  	      if ( currentFlavor ) {
  	        nsCAutoString flavorStr;
  	        currentFlavor->GetData(flavorStr);
  	        FlavorType macOSFlavor = theMapper.MapMimeTypeToMacOSType(flavorStr.get());
              
            if (macOSFlavor == kDragFlavorTypePromiseHFS) {
              // we got kFilePromiseMime
              // kDragFlavorTypePromiseHFS is special. See http://developer.apple.com/technotes/tn/tn1085.html
              PromiseHFSFlavor promiseData;
              promiseData.fileType           = 0;     // let the file extension prevail!
              promiseData.fileCreator        = 0;
              promiseData.fdFlags            = 0;
              promiseData.promisedFlavor     = kDragPromisedFlavor;

              ::AddDragItemFlavor(mDragRef, itemIndex, kDragFlavorTypePromiseHFS, &promiseData, sizeof(promiseData), flavorNotSaved);
              ::AddDragItemFlavor(mDragRef, itemIndex, kDragPromisedFlavor, NULL, 0, flavorNotSaved);
            }
            else
              ::AddDragItemFlavor(mDragRef, itemIndex, macOSFlavor, NULL, 0, flags);
  	        
  	        // If we advertise text/unicode, then make sure we add 'TEXT' to the list
  	        // of flavors supported since we will do the conversion ourselves in GetDataForFlavor()
  	        if ( strcmp(flavorStr.get(), kUnicodeMime) == 0 ) {
  	          theMapper.MapMimeTypeToMacOSType(kTextMime);
  	          ::AddDragItemFlavor ( mDragRef, itemIndex, 'TEXT', NULL, 0, flags );	        
  	          ::AddDragItemFlavor ( mDragRef, itemIndex, 'styl', NULL, 0, flags );	        
  	        }
  	      }
          
        } // foreach flavor in item              
      } // if valid flavor list
    } // if item is a transferable
    
    // put the mime mapping data for this item in a special flavor. Unlike the other data,
    // we have to put the data in now (rather than defer it) or the mappings will go out 
    // of scope by the time they are asked for. Remember that the |mappingLen|
    // includes the null, and we need to maintain that for when we parse it.
    short mappingLen;
    char* mapping = theMapper.ExportMapping(&mappingLen);
    if ( mapping && mappingLen ) {
      ::AddDragItemFlavor ( mDragRef, itemIndex, nsMimeMapperMac::MappingFlavor(), 
                               mapping, mappingLen, flags );
	    nsMemory::Free ( mapping );
    
      ::SetDragItemBounds(mDragRef, itemIndex, &dragRgnBounds);
	  }
    
  } // foreach drag item 

} // RegisterDragItemsAndFlavors