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; }
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; }
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; }
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 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 }
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; }
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; }
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; }
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; }