Exemple #1
0
STDMETHODIMP wxIDataObject::EnumFormatEtc(DWORD dwDir,
                                          IEnumFORMATETC **ppenumFormatEtc)
{
    wxLogTrace(wxTRACE_OleCalls, wxT("wxIDataObject::EnumFormatEtc"));

    wxDataObject::Direction dir = dwDir == DATADIR_GET ? wxDataObject::Get
                                                       : wxDataObject::Set;

    // format count is total of user specified and system formats.
    const size_t ourFormatCount = m_pDataObject->GetFormatCount(dir);
    const size_t sysFormatCount = m_systemData.size();

    const ULONG
        nFormatCount = wx_truncate_cast(ULONG, ourFormatCount + sysFormatCount);

    // fill format array with formats ...
    wxScopedArray<wxDataFormat> formats(nFormatCount);

    // ... from content data (supported formats)
    m_pDataObject->GetAllFormats(formats.get(), dir);

    // ... from system data
    for ( size_t j = 0; j < sysFormatCount; j++ )
    {
        SystemDataEntry* entry = m_systemData[j];
        wxDataFormat& format = formats[ourFormatCount + j];
        format = entry->pformatetc->cfFormat;
    }

    wxIEnumFORMATETC *pEnum = new wxIEnumFORMATETC(formats.get(), nFormatCount);
    pEnum->AddRef();
    *ppenumFormatEtc = pEnum;

    return S_OK;
}
Exemple #2
0
STDMETHODIMP wxIDataObject::GetDataHere(FORMATETC *pformatetc,
                                        STGMEDIUM *pmedium)
{
    wxLogTrace(wxTRACE_OleCalls, wxT("wxIDataObject::GetDataHere"));

    // put data in caller provided medium
    switch ( pmedium->tymed )
    {
        case TYMED_GDI:
            if ( !m_pDataObject->GetDataHere(wxDF_BITMAP, &pmedium->hBitmap) )
                return E_UNEXPECTED;
            break;

        case TYMED_ENHMF:
            if ( !m_pDataObject->GetDataHere(wxDF_ENHMETAFILE,
                                             &pmedium->hEnhMetaFile) )
                return E_UNEXPECTED;
            break;

        case TYMED_MFPICT:
            // fall through - we pass METAFILEPICT through HGLOBAL

        case TYMED_HGLOBAL:
            {
                // copy data
                HGLOBAL hGlobal = pmedium->hGlobal;
                void *pBuf = GlobalLock(hGlobal);
                if ( pBuf == NULL ) {
                    wxLogLastError(wxT("GlobalLock"));
                    return E_OUTOFMEMORY;
                }

                wxDataFormat format = pformatetc->cfFormat;

                // possibly put the size in the beginning of the buffer
                pBuf = m_pDataObject->SetSizeInBuffer
                                      (
                                        pBuf,
                                        ::GlobalSize(hGlobal),
                                        format
                                      );

                if ( !m_pDataObject->GetDataHere(format, pBuf) )
                    return E_UNEXPECTED;

                GlobalUnlock(hGlobal);
            }
            break;

        default:
            return DV_E_TYMED;
    }

    return S_OK;
}
Exemple #3
0
// get the data for a specific wxDataFormat that stored as a property in Root window
void GetClipboardData(Display* disp, Window win, wxDataObject &data, wxDataFormat dfFormat)
{
    unsigned char *clipbrdData = NULL;

    // some variables that used to get the data in window property
    unsigned long len;

    switch ( dfFormat )
    {
        case wxDF_INVALID:
        {
            return;
        }
        case wxDF_BITMAP:
        {
            wxVector<Atom> atomVector;
            atomVector.push_back(XA_IMAGE_BMP);
            atomVector.push_back(XA_IMAGE_JPG);
            atomVector.push_back(XA_IMAGE_TIFF);
            atomVector.push_back(XA_IMAGE_PNG);

            // check the four atoms in clipboard, try to find whether there has data
            // stored in one of these atom.
            for ( unsigned i = 0; i < atomVector.size(); i++ )
            {

                clipbrdData  = GetClipboardDataByFormat(disp, win, XA_CLIPBOARD,
                                                        atomVector.at(i), &len);
                if ( clipbrdData != NULL )
                    break;
            }
            // if we got any data, copy it.
            if ( clipbrdData )
            {
                data.SetData(dfFormat, len, (char*)clipbrdData);
            }
            break;
        }
        default:
        {
            clipbrdData  = GetClipboardDataByFormat(disp, win, XA_CLIPBOARD, XA_UTF8_STRING, &len);
            // if we got any data, copy it.
            if ( clipbrdData  )
            {
                data.SetData(dfFormat, len, (char*)clipbrdData);
            }
        }
    }
}
Exemple #4
0
// information functions
STDMETHODIMP wxIDataObject::QueryGetData(FORMATETC *pformatetc)
{
    // do we accept data in this format?
    if ( pformatetc == NULL ) {
        wxLogTrace(wxTRACE_OleCalls,
                   wxT("wxIDataObject::QueryGetData: invalid ptr."));

        return E_INVALIDARG;
    }

    // the only one allowed by current COM implementation
    if ( pformatetc->lindex != -1 ) {
        wxLogTrace(wxTRACE_OleCalls,
                   wxT("wxIDataObject::QueryGetData: bad lindex %ld"),
                   pformatetc->lindex);

        return DV_E_LINDEX;
    }

    // we don't support anything other (THUMBNAIL, ICON, DOCPRINT...)
    if ( pformatetc->dwAspect != DVASPECT_CONTENT ) {
        wxLogTrace(wxTRACE_OleCalls,
                   wxT("wxIDataObject::QueryGetData: bad dwAspect %ld"),
                   pformatetc->dwAspect);

        return DV_E_DVASPECT;
    }

    // and now check the type of data requested
    wxDataFormat format = pformatetc->cfFormat;
    if ( m_pDataObject->IsSupportedFormat(format) ) {
        wxLogTrace(wxTRACE_OleCalls, wxT("wxIDataObject::QueryGetData: %s ok"),
                   wxGetFormatName(format));
    }
    else {
        wxLogTrace(wxTRACE_OleCalls,
                   wxT("wxIDataObject::QueryGetData: %s unsupported"),
                   wxGetFormatName(format));

        return DV_E_FORMATETC;
    }

    // we only transfer data by global memory, except for some particular cases
    DWORD tymed = pformatetc->tymed;
    if ( (format == wxDF_BITMAP && !(tymed & TYMED_GDI)) &&
         !(tymed & TYMED_HGLOBAL) ) {
        // it's not what we're waiting for
        wxLogTrace(wxTRACE_OleCalls,
                   wxT("wxIDataObject::QueryGetData: %s != %s"),
                   GetTymedName(tymed),
                   GetTymedName(format == wxDF_BITMAP ? TYMED_GDI
                                                      : TYMED_HGLOBAL));

        return DV_E_TYMED;
    }

    return S_OK;
}
Exemple #5
0
void CIDataObject::GetDataHere(
  const wxDataFormat&               rFormat
, char*                             pzBuffer
, ULONG                             WXUNUSED(ulLen)
)
{
    m_pDataObject->GetDataHere( rFormat
                               ,(void*)pzBuffer
                              );
} // end of CIDataObject::GetDataHere
Exemple #6
0
void CIDataObject::SetData (
  const wxDataFormat&               rFormat
, char*                             pzBuffer
)
{
    ULONG                           ulSize = 0;

    switch (rFormat.GetType())
    {
        case wxDF_TEXT:
        case wxDF_OEMTEXT:
        case wxDF_FILENAME:
        case wxDF_HTML:
            ulSize = strlen((const char *)pzBuffer);
            break;

#if wxUSE_UNICODE
        case wxDF_UNICODETEXT:
             ulSize = ::wcslen((const wchar_t *)pzBuffer);
             break;
#endif

        case wxDF_BITMAP:
        case wxDF_METAFILE:
        case wxDF_ENHMETAFILE:
        case wxDF_TIFF:
        case wxDF_DIB:
            ulSize = 0; // pass via a handle
            break;


        case wxDF_SYLK:
        case wxDF_DIF:
        case wxDF_PALETTE:
        case wxDF_PENDATA:
        case wxDF_RIFF:
        case wxDF_WAVE:
        case wxDF_LOCALE:
            //PUNT
            break;

        case wxDF_PRIVATE:
            size_t*                 p = (size_t *)pzBuffer;

            ulSize = *p++;
            pzBuffer = (char*)p;
            break;
    }
    m_pDataObject->SetData( rFormat
                           ,ulSize
                           ,(void*)pzBuffer
                          );
} // end of CIDataObject::SetData
Exemple #7
0
bool wxClipboard::GetData( wxDataObject& data )
{
    // get formats count in the wxDataObject
    // for each data format, search it in x11 selection
    // and store it to wxDataObject
    size_t count = data.GetFormatCount();
    wxDataFormatScopedArray dfarr(count);
    data.GetAllFormats(dfarr.get());

    // prepare and find the root window,
    // the copied data stored in the root window as window property
    Display* xdisplay = wxGlobalDisplay();
    int xscreen = DefaultScreen(xdisplay);
    Window window = RootWindow(xdisplay, xscreen);

    // retrieve the data in each format.
    for( size_t i = 0; i < count; ++i )
    {
        GetClipboardData(xdisplay, window, data, dfarr[i]);
    }
    return true;
}
Exemple #8
0
STDMETHODIMP wxIDataObject::EnumFormatEtc(DWORD dwDir,
                                          IEnumFORMATETC **ppenumFormatEtc)
{
    wxLogTrace(wxTRACE_OleCalls, wxT("wxIDataObject::EnumFormatEtc"));

    wxDataObject::Direction dir = dwDir == DATADIR_GET ? wxDataObject::Get
                                                       : wxDataObject::Set;

    ULONG nFormatCount = wx_truncate_cast(ULONG, m_pDataObject->GetFormatCount(dir));
    wxDataFormat format;
    wxDataFormat *formats;
    formats = nFormatCount == 1 ? &format : new wxDataFormat[nFormatCount];
    m_pDataObject->GetAllFormats(formats, dir);

    wxIEnumFORMATETC *pEnum = new wxIEnumFORMATETC(formats, nFormatCount);
    pEnum->AddRef();
    *ppenumFormatEtc = pEnum;

    if ( formats != &format ) {
        delete [] formats;
    }

    return S_OK;
}
bool wxClipboard::GetData( wxDataObject& data )
{
    if ( IsUsingPrimarySelection() )
        return false;

    wxCHECK_MSG( m_open, false, wxT("clipboard not open") );

    size_t formatcount = data.GetFormatCount() + 1;
    wxDataFormat *array = new wxDataFormat[ formatcount ];
    array[0] = data.GetPreferredFormat();
    data.GetAllFormats( &array[1] );

    bool transferred = false;

    if ( m_data )
    {
        for (size_t i = 0; !transferred && i < formatcount; i++)
        {
            wxDataFormat format = array[ i ];
            if ( m_data->IsSupported( format ) )
            {
                int dataSize = m_data->GetDataSize( format );
                transferred = true;

                if (dataSize == 0)
                {
                    data.SetData( format, 0, 0 );
                }
                else
                {
                    char *d = new char[ dataSize ];
                    m_data->GetDataHere( format, (void*)d );
                    data.SetData( format, dataSize, d );
                    delete [] d;
                }
            }
        }
    }

    // get formats from wxDataObjects
    if ( !transferred )
    {
        transferred = data.GetFromPasteboard( m_pasteboard ) ;
    }

    delete [] array;

    return transferred;
}
Exemple #10
0
bool CIDataObject::GetData ( const wxDataFormat& rFormat,
                             char* pzBuffer,
                             ULONG ulLen )
{
    QueryGetData(rFormat);
    if (rFormat.GetType() == wxDF_INVALID)
        return false;

    ULONG                           ulSize = m_pDataObject->GetDataSize(rFormat);

    if (ulSize == 0)
    {
        //
        // It probably means that the method is just not implemented
        //
        return false;
    }
    if (rFormat.GetType() == wxDF_PRIVATE)
    {
        //
        // For custom formats, put the size with the data - alloc the
        // space for it
        //
        ulSize += sizeof(ULONG);
    }

    if (ulSize > ulLen) // not enough room to copy
        return false;

    //
    // Copy the data
    //
    GetDataHere( rFormat
                ,pzBuffer
                ,ulSize
               );
    return true;
} // end of CIDataObject::GetData
Exemple #11
0
bool wxClipboard::GetData( wxDataObject& data )
{
    wxCHECK_MSG( m_open, false, wxT("clipboard not open") );

    // get all supported formats from wxDataObjects: notice that we are setting
    // the object data, so we need them in "Set" direction
    const size_t count = data.GetFormatCount(wxDataObject::Set);
    wxDataFormatArray formats(new wxDataFormat[count]);
    data.GetAllFormats(formats.get(), wxDataObject::Set);

    for ( size_t i = 0; i < count; i++ )
    {
        const wxDataFormat format(formats[i]);

        // is this format supported by clipboard ?
        if ( !DoIsSupported(format) )
            continue;

        wxLogTrace(TRACE_CLIPBOARD, wxT("Requesting format %s"),
                   format.GetId().c_str());

        // these variables will be used by our GTKOnSelectionReceived()
        m_receivedData = &data;
        m_formatSupported = false;

        {
            wxClipboardSync sync(*this);

            gtk_selection_convert(m_clipboardWidget,
                                  GTKGetClipboardAtom(),
                                  format,
                                  (guint32) GDK_CURRENT_TIME );
        } // wait until we get the results

        /*
           Normally this is a true error as we checked for the presence of such
           data before, but there are applications that may return an empty
           string (e.g. Gnumeric-1.6.1 on Linux if an empty cell is copied)
           which would produce a false error message here, so we check for the
           size of the string first. With ANSI, GetDataSize returns an extra
           value (for the closing null?), with unicode, the exact number of
           tokens is given (that is more than 1 for non-ASCII characters)
           (tested with Gnumeric-1.6.1 and OpenOffice.org-2.0.2)
         */
#if wxUSE_UNICODE
        if ( format != wxDF_UNICODETEXT || data.GetDataSize(format) > 0 )
#else // !UNICODE
        if ( format != wxDF_TEXT || data.GetDataSize(format) > 1 )
#endif // UNICODE / !UNICODE
        {
            wxCHECK_MSG( m_formatSupported, false,
                         wxT("error retrieving data from clipboard") );
        }

        return true;
    }

    wxLogTrace(TRACE_CLIPBOARD, wxT("GetData(): format not found"));

    return false;
}
Exemple #12
0
bool wxClipboard::GetData( wxDataObject& data )
{
    wxCHECK_MSG( m_open, false, "clipboard not open" );

    Display* xdisplay = wxGlobalDisplay();
    Window xwindow = XtWindow( (Widget)wxTheApp->GetTopLevelRealizedWidget() );
    Time timestamp = XtLastTimestampProcessed( xdisplay );

    wxDataFormat chosenFormat;
    int retval;

    ///////////////////////////////////////////////////////////////////////////
    // determine if the cliboard holds any format we like
    ///////////////////////////////////////////////////////////////////////////
    while( ( retval = XmClipboardStartRetrieve( xdisplay, xwindow,
                      timestamp ) )
            == XmClipboardLocked );
    if( retval != XmClipboardSuccess )
        return false;

    wxClipboardEndRetrieve endRetrieve( xdisplay, xwindow );

    int count;
    unsigned long max_name_length;
    size_t dfcount = data.GetFormatCount( wxDataObject::Set );
    wxDataFormatScopedArray dfarr(dfcount);
    data.GetAllFormats( dfarr.get(), wxDataObject::Set );

    if( XmClipboardInquireCount( xdisplay, xwindow, &count, &max_name_length )
            == XmClipboardSuccess )
    {
        wxCharBuffer buf( max_name_length + 1 );
        unsigned long copied;

        for( int i = 0; i < count; ++i )
        {
            if( XmClipboardInquireFormat( xdisplay, xwindow, i + 1,
                                          (XtPointer)buf.data(),
                                          max_name_length, &copied )
                    != XmClipboardSuccess )
                continue;

            buf.data()[copied] = '\0';

            // try preferred format
            if( buf == data.GetPreferredFormat( wxDataObject::Set ).GetId() )
            {
                chosenFormat = data.GetPreferredFormat( wxDataObject::Set );
                break;
            }

            // try all other formats
            for( size_t i = 0; i < dfcount; ++i )
            {
                if( buf == dfarr[i].GetId() )
                    chosenFormat = dfarr[i];
            }
        }
    }

    if( chosenFormat == wxDF_INVALID )
        return false;

    ///////////////////////////////////////////////////////////////////////////
    // now retrieve the data
    ///////////////////////////////////////////////////////////////////////////
    unsigned long length, dummy1;
    long dummy2;
    wxString id = chosenFormat.GetId();

    while( ( retval = XmClipboardInquireLength( xdisplay, xwindow,
                      id.char_str(),
                      &length ) )
            == XmClipboardLocked );
    if( retval != XmClipboardSuccess )
        return false;

    wxCharBuffer buf(length);

    while( ( retval = XmClipboardRetrieve( xdisplay, xwindow,
                                           id.char_str(),
                                           (XtPointer)buf.data(),
                                           length, &dummy1, &dummy2 ) )
            == XmClipboardLocked );
    if( retval != XmClipboardSuccess )
        return false;

    if( !data.SetData( chosenFormat, length, buf.data() ) )
        return false;

    return true;
}
Exemple #13
0
// set data functions
STDMETHODIMP wxIDataObject::SetData(FORMATETC *pformatetc,
                                    STGMEDIUM *pmedium,
                                    BOOL       fRelease)
{
    wxLogTrace(wxTRACE_OleCalls, wxT("wxIDataObject::SetData"));

    switch ( pmedium->tymed )
    {
        case TYMED_GDI:
            m_pDataObject->SetData(wxDF_BITMAP, 0, &pmedium->hBitmap);
            break;

        case TYMED_ENHMF:
            m_pDataObject->SetData(wxDF_ENHMETAFILE, 0, &pmedium->hEnhMetaFile);
            break;

        case TYMED_ISTREAM:
            // check if this format is supported
            if ( !m_pDataObject->IsSupported(pformatetc->cfFormat,
                                             wxDataObject::Set) )
            {
                // As this is not a supported format (content data), assume it
                // is system data and save it.
                return SaveSystemData(pformatetc, pmedium, fRelease);
            }
            break;

        case TYMED_MFPICT:
            // fall through - we pass METAFILEPICT through HGLOBAL
        case TYMED_HGLOBAL:
            {
                wxDataFormat format = pformatetc->cfFormat;

                format = HtmlFormatFixup(format);

                // check if this format is supported
                if ( !m_pDataObject->IsSupported(format, wxDataObject::Set) ) {
                    // As above, assume that unsupported format must be system
                    // data and just save it.
                    return SaveSystemData(pformatetc, pmedium, fRelease);
                }

                // copy data
                const void *pBuf = GlobalLock(pmedium->hGlobal);
                if ( pBuf == NULL ) {
                    wxLogLastError(wxT("GlobalLock"));

                    return E_OUTOFMEMORY;
                }

                // we've got a problem with SetData() here because the base
                // class version requires the size parameter which we don't
                // have anywhere in OLE data transfer - so we need to
                // synthetise it for known formats and we suppose that all data
                // in custom formats starts with a DWORD containing the size
                size_t size;
                switch ( format )
                {
                    case wxDF_HTML:
                    case CF_TEXT:
                    case CF_OEMTEXT:
                        size = strlen((const char *)pBuf);
                        break;
#if !(defined(__BORLANDC__) && (__BORLANDC__ < 0x500))
                    case CF_UNICODETEXT:
#if ( defined(__BORLANDC__) && (__BORLANDC__ > 0x530) )
                        size = std::wcslen((const wchar_t *)pBuf) * sizeof(wchar_t);
#else
                        size = wxWcslen((const wchar_t *)pBuf) * sizeof(wchar_t);
#endif
                        break;
#endif
                    case CF_BITMAP:
#ifndef __WXWINCE__
                    case CF_HDROP:
                        // these formats don't use size at all, anyhow (but
                        // pass data by handle, which is always a single DWORD)
                        size = 0;
                        break;
#endif

                    case CF_DIB:
                        // the handler will calculate size itself (it's too
                        // complicated to do it here)
                        size = 0;
                        break;

#ifndef __WXWINCE__
                    case CF_METAFILEPICT:
                        size = sizeof(METAFILEPICT);
                        break;
#endif
                    default:
                        pBuf = m_pDataObject->
                                    GetSizeFromBuffer(pBuf, &size, format);
                        size -= m_pDataObject->GetBufferOffset(format);
                }

                bool ok = m_pDataObject->SetData(format, size, pBuf);

                GlobalUnlock(pmedium->hGlobal);

                if ( !ok ) {
                    return E_UNEXPECTED;
                }
            }
            break;

        default:
            return DV_E_TYMED;
    }

    if ( fRelease ) {
        // we own the medium, so we must release it - but do *not* free any
        // data we pass by handle because we have copied it elsewhere
        switch ( pmedium->tymed )
        {
            case TYMED_GDI:
                pmedium->hBitmap = 0;
                break;

            case TYMED_MFPICT:
                pmedium->hMetaFilePict = 0;
                break;

            case TYMED_ENHMF:
                pmedium->hEnhMetaFile = 0;
                break;
        }

        ReleaseStgMedium(pmedium);
    }

    return S_OK;
}
Exemple #14
0
// get data functions
STDMETHODIMP wxIDataObject::GetData(FORMATETC *pformatetcIn, STGMEDIUM *pmedium)
{
    wxLogTrace(wxTRACE_OleCalls, wxT("wxIDataObject::GetData"));

    // is data is in our format?
    HRESULT hr = QueryGetData(pformatetcIn);
    if ( FAILED(hr) )
        return hr;

    // for the bitmaps and metafiles we use the handles instead of global memory
    // to pass the data
    wxDataFormat format = (wxDataFormat::NativeFormat)pformatetcIn->cfFormat;
    format = HtmlFormatFixup(format);

    // is this system data?
    if ( GetSystemData(format, pmedium) )
    {
        // pmedium is already filled with corresponding data, so we're ready.
        return S_OK;
    }

    switch ( format )
    {
        case wxDF_BITMAP:
            pmedium->tymed = TYMED_GDI;
            break;

        case wxDF_ENHMETAFILE:
            pmedium->tymed = TYMED_ENHMF;
            break;

#ifndef __WXWINCE__
        case wxDF_METAFILE:
            pmedium->hGlobal = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE,
                                           sizeof(METAFILEPICT));
            if ( !pmedium->hGlobal ) {
                wxLogLastError(wxT("GlobalAlloc"));
                return E_OUTOFMEMORY;
            }
            pmedium->tymed = TYMED_MFPICT;
            break;
#endif
        default:
            // alloc memory
            size_t size = m_pDataObject->GetDataSize(format);
            if ( !size ) {
                // it probably means that the method is just not implemented
                wxLogDebug(wxT("Invalid data size - can't be 0"));

                return DV_E_FORMATETC;
            }

            // we may need extra space for the buffer size
            size += m_pDataObject->GetBufferOffset( format );

            HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE, size);
            if ( hGlobal == NULL ) {
                wxLogLastError(wxT("GlobalAlloc"));
                return E_OUTOFMEMORY;
            }

            // copy data
            pmedium->tymed   = TYMED_HGLOBAL;
            pmedium->hGlobal = hGlobal;
    }

    pmedium->pUnkForRelease = NULL;

    // do copy the data
    hr = GetDataHere(pformatetcIn, pmedium);
    if ( FAILED(hr) ) {
        // free resources we allocated
        if ( pmedium->tymed & (TYMED_HGLOBAL | TYMED_MFPICT) ) {
            GlobalFree(pmedium->hGlobal);
        }

        return hr;
    }

    return S_OK;
}
Exemple #15
0
void CIDataObject::QueryGetData (
  const wxDataFormat&               rFormat
)
{
    m_pDataObject->IsSupportedFormat(rFormat);
} // end of CIDataObject::QueryGetData
Exemple #16
0
bool wxClipboard::GetData( wxDataObject& data )
{
    wxCHECK_MSG( m_open, false, wxT("clipboard not open") );

    /* get formats from wxDataObjects */
    wxDataFormat *array = new wxDataFormat[ data.GetFormatCount() ];
    data.GetAllFormats( array );

    for (size_t i = 0; i < data.GetFormatCount(); i++)
    {
        wxDataFormat format( array[i] );

        wxLogTrace( TRACE_CLIPBOARD,
                    wxT("wxClipboard::GetData: requested format: %s"),
                    format.GetId().c_str() );

        /* is data supported by clipboard ? */

        /* store requested format to be asked for by callbacks */
        m_targetRequested = format;

        wxCHECK_MSG( m_targetRequested, false, wxT("invalid clipboard format") );

        m_formatSupported = false;

       /* perform query. this will set m_formatSupported to
          true if m_targetRequested is supported.
          also, we have to wait for the "answer" from the
          clipboard owner which is an asynchronous process.
          therefore we set m_waiting = true here and wait
          until the callback "targets_selection_received"
          sets it to false */

        m_waiting = true;

        gtk_selection_convert( m_targetsWidget,
                           m_usePrimary ? (GdkAtom)GDK_SELECTION_PRIMARY
                                        : g_clipboardAtom,
                           g_targetsAtom,
                           (guint32) GDK_CURRENT_TIME );

        while (m_waiting) gtk_main_iteration();

        if (!m_formatSupported) continue;

        /* store pointer to data object to be filled up by callbacks */
        m_receivedData = &data;

        /* store requested format to be asked for by callbacks */
        m_targetRequested = format;

        wxCHECK_MSG( m_targetRequested, false, wxT("invalid clipboard format") );

        /* start query */
        m_formatSupported = false;

        /* ask for clipboard contents.  this will set
           m_formatSupported to true if m_targetRequested
           is supported.
           also, we have to wait for the "answer" from the
           clipboard owner which is an asynchronous process.
           therefore we set m_waiting = true here and wait
           until the callback "targets_selection_received"
           sets it to false */

        m_waiting = true;

        wxLogTrace( TRACE_CLIPBOARD,
                    wxT("wxClipboard::GetData: format found, start convert") );

        gtk_selection_convert( m_clipboardWidget,
                               m_usePrimary ? (GdkAtom)GDK_SELECTION_PRIMARY
                                            : g_clipboardAtom,
                               m_targetRequested,
                               (guint32) GDK_CURRENT_TIME );

        while (m_waiting) gtk_main_iteration();

        /*
           Normally this is a true error as we checked for the presence of such
           data before, but there are applications that may return an empty
           string (e.g. Gnumeric-1.6.1 on Linux if an empty cell is copied)
           which would produce a false error message here, so we check for the
           size of the string first. In ansi, GetDataSize returns an extra
           value (for the closing null?), with unicode, the exact number of
           tokens is given (that is more than 1 for special characters)
           (tested with Gnumeric-1.6.1 and OpenOffice.org-2.0.2)
         */
#if wxUSE_UNICODE
        if ( format != wxDF_UNICODETEXT || data.GetDataSize(format) > 0 )
#else // !UNICODE
        if ( format != wxDF_TEXT || data.GetDataSize(format) > 1 )
#endif // UNICODE / !UNICODE
        {
            wxCHECK_MSG( m_formatSupported, false,
                         wxT("error retrieving data from clipboard") );
        }

        /* return success */
        delete[] array;
        return true;
    }

    wxLogTrace( TRACE_CLIPBOARD,
                wxT("wxClipboard::GetData: format not found") );

    /* return failure */
    delete[] array;
    return false;
}
Exemple #17
0
bool wxClipboard::GetData( wxDataObject& data )
{
#if wxUSE_OLE_CLIPBOARD
    IDataObject *pDataObject = NULL;
    HRESULT hr = OleGetClipboard(&pDataObject);
    if ( FAILED(hr) || !pDataObject )
    {
        wxLogSysError(hr, _("Failed to get data from the clipboard"));

        return false;
    }

    // build the list of supported formats
    size_t nFormats = data.GetFormatCount(wxDataObject::Set);
    wxDataFormat format;
    wxDataFormat *formats;
    if ( nFormats == 1 )
    {
        // the most common case
        formats = &format;
    }
    else
    {
        // bad luck, need to alloc mem
        formats = new wxDataFormat[nFormats];
    }

    data.GetAllFormats(formats, wxDataObject::Set);

    // get the data for the given formats
    FORMATETC formatEtc;
    CLIPFORMAT cf;
    bool result = false;

    // enumerate all explicit formats on the clipboard.
    // note that this does not include implicit / synthetic (automatically
    // converted) formats.
#ifdef __WXDEBUG__
    // get the format enumerator
    IEnumFORMATETC *pEnumFormatEtc = NULL;
    hr = pDataObject->EnumFormatEtc(DATADIR_GET, &pEnumFormatEtc);
    if ( FAILED(hr) || !pEnumFormatEtc )
    {
        wxLogSysError(hr,
                      _("Failed to retrieve the supported clipboard formats"));
    }
    else
    {
        // ask for the supported formats and see if there are any we support
        for ( ;; )
        {
            ULONG nCount;
            hr = pEnumFormatEtc->Next(1, &formatEtc, &nCount);

            // don't use FAILED() because S_FALSE would pass it
            if ( hr != S_OK )
            {
                // no more formats
                break;
            }

            cf = formatEtc.cfFormat;

            wxLogTrace(wxTRACE_OleCalls,
                       wxT("Object on the clipboard supports format %s."),
                       wxDataObject::GetFormatName(cf));
        }

        pEnumFormatEtc->Release();
    }
#endif // Debug

    STGMEDIUM medium;
    // stop at the first valid format found on the clipboard
    for ( size_t n = 0; !result && (n < nFormats); n++ )
    {
        // convert to NativeFormat Id
        cf = formats[n].GetFormatId();

        // if the format is not available, try the next one
        // this test includes implicit / sythetic formats
        if ( !::IsClipboardFormatAvailable(cf) )
            continue;

        formatEtc.cfFormat = cf;
        formatEtc.ptd      = NULL;
        formatEtc.dwAspect = DVASPECT_CONTENT;
        formatEtc.lindex   = -1;

        // use the appropriate tymed
        switch ( formatEtc.cfFormat )
        {
            case CF_BITMAP:
                formatEtc.tymed = TYMED_GDI;
                break;

#ifndef __WXWINCE__
            case CF_METAFILEPICT:
                formatEtc.tymed = TYMED_MFPICT;
                break;

            case CF_ENHMETAFILE:
                formatEtc.tymed = TYMED_ENHMF;
                break;
#endif

            default:
                formatEtc.tymed = TYMED_HGLOBAL;
        }

        // try to get data
        hr = pDataObject->GetData(&formatEtc, &medium);
        if ( FAILED(hr) )
        {
            // try other tymed for GDI objects
            if ( formatEtc.cfFormat == CF_BITMAP )
            {
                formatEtc.tymed = TYMED_HGLOBAL;
                hr = pDataObject->GetData(&formatEtc, &medium);
            }
        }

        if ( SUCCEEDED(hr) )
        {
            // pass the data to the data object
            hr = data.GetInterface()->SetData(&formatEtc, &medium, true);
            if ( FAILED(hr) )
            {
                wxLogDebug(wxT("Failed to set data in wxIDataObject"));

                // IDataObject only takes the ownership of data if it
                // successfully got it - which is not the case here
                ReleaseStgMedium(&medium);
            }
            else
            {
                result = true;
            }
        }
        //else: unsupported tymed?
    }

    if ( formats != &format )
    {
        delete [] formats;
    }
    //else: we didn't allocate any memory

    // clean up and return
    pDataObject->Release();

    return result;
#elif wxUSE_DATAOBJ
    wxCHECK_MSG( wxIsClipboardOpened(), false, wxT("clipboard not open") );

    wxDataFormat format = data.GetPreferredFormat();
    switch ( format )
    {
        case wxDF_TEXT:
        case wxDF_OEMTEXT:
        {
            wxTextDataObject& textDataObject = (wxTextDataObject &)data;
            char* s = (char*)wxGetClipboardData(format);
            if ( !s )
                return false;

            textDataObject.SetText(wxString::FromAscii(s));
            delete [] s;

            return true;
        }

        case wxDF_BITMAP:
        case wxDF_DIB:
        {
            wxBitmapDataObject& bitmapDataObject = (wxBitmapDataObject &)data;
            wxBitmap* bitmap = (wxBitmap *)wxGetClipboardData(data.GetPreferredFormat());
            if ( !bitmap )
                return false;

            bitmapDataObject.SetBitmap(*bitmap);
            delete bitmap;

            return true;
        }
#if wxUSE_METAFILE
        case wxDF_METAFILE:
        {
            wxMetafileDataObject& metaFileDataObject = (wxMetafileDataObject &)data;
            wxMetafile* metaFile = (wxMetafile *)wxGetClipboardData(wxDF_METAFILE);
            if ( !metaFile )
                return false;

            metaFileDataObject.SetMetafile(*metaFile);
            delete metaFile;

            return true;
        }
#endif // wxUSE_METAFILE
    }
    return false;
#else // !wxUSE_DATAOBJ
    wxFAIL_MSG( wxT("no clipboard implementation") );
    return false;
#endif // wxUSE_OLE_CLIPBOARD/wxUSE_DATAOBJ
}
Exemple #18
0
bool wxClipboard::GetData( wxDataObject& data )
{
    wxCHECK_MSG( m_open, false, wxT("clipboard not open") );

    /* get formats from wxDataObjects */
    wxDataFormat *array = new wxDataFormat[ data.GetFormatCount() ];
    data.GetAllFormats( array );

    for (size_t i = 0; i < data.GetFormatCount(); i++)
    {
        wxDataFormat format( array[i] );

        wxLogTrace( TRACE_CLIPBOARD,
                    wxT("wxClipboard::GetData: requested format: %s"),
                    format.GetId().c_str() );

        /* is data supported by clipboard ? */

        /* store requested format to be asked for by callbacks */
        m_targetRequested = format;

        wxCHECK_MSG( m_targetRequested, false, wxT("invalid clipboard format") );

        m_formatSupported = false;

       /* perform query. this will set m_formatSupported to
          true if m_targetRequested is supported.
          also, we have to wait for the "answer" from the
          clipboard owner which is an asynchronous process.
          therefore we set m_waiting = true here and wait
          until the callback "targets_selection_received"
          sets it to false */

        m_waiting = true;

#if 0
        gtk_selection_convert( m_targetsWidget,
                           m_usePrimary ? (GdkAtom)GDK_SELECTION_PRIMARY
                                        : g_clipboardAtom,
                           g_targetsAtom,
                           (guint32) GDK_CURRENT_TIME );

        while (m_waiting) gtk_main_iteration();
#endif

        if (!m_formatSupported) continue;

        /* store pointer to data object to be filled up by callbacks */
        m_receivedData = &data;

        /* store requested format to be asked for by callbacks */
        m_targetRequested = format;

        wxCHECK_MSG( m_targetRequested, false, wxT("invalid clipboard format") );

        /* start query */
        m_formatSupported = false;

        /* ask for clipboard contents.  this will set
           m_formatSupported to true if m_targetRequested
           is supported.
           also, we have to wait for the "answer" from the
           clipboard owner which is an asynchronous process.
           therefore we set m_waiting = true here and wait
           until the callback "targets_selection_received"
           sets it to false */

        m_waiting = true;

        wxLogTrace( TRACE_CLIPBOARD,
                    wxT("wxClipboard::GetData: format found, start convert") );

#if 0
        gtk_selection_convert( m_clipboardWidget,
                               m_usePrimary ? (GdkAtom)GDK_SELECTION_PRIMARY
                                            : g_clipboardAtom,
                               m_targetRequested,
                               (guint32) GDK_CURRENT_TIME );

        while (m_waiting) gtk_main_iteration();
#endif

        /* this is a true error as we checked for the presence of such data before */
        wxCHECK_MSG( m_formatSupported, false, wxT("error retrieving data from clipboard") );

        /* return success */
        delete[] array;
        return true;
    }

    wxLogTrace( TRACE_CLIPBOARD,
                wxT("wxClipboard::GetData: format not found") );

    /* return failure */
    delete[] array;
    return false;
}