// @pymethod |PyIDocHostUIHandler|FilterDataObject|Description of FilterDataObject.
PyObject *PyIDocHostUIHandler::FilterDataObject(PyObject *self, PyObject *args)
{
	IDocHostUIHandler *pIDHUIH = GetI(self);
	if ( pIDHUIH == NULL )
		return NULL;
	// @pyparm <o PyIDataObject>|pDO||Description for pDO
	PyObject *obpDO;
	IDataObject * pDO;
	IDataObject * ppDORet;
	if ( !PyArg_ParseTuple(args, "O:FilterDataObject", &obpDO) )
		return NULL;
	if (!PyCom_InterfaceFromPyInstanceOrObject(obpDO, IID_IDataObject, (void **)&pDO, TRUE /* bNoneOK */))
		return NULL;
	HRESULT hr;
	PY_INTERFACE_PRECALL;
	hr = pIDHUIH->FilterDataObject( pDO, &ppDORet );
	if (pDO) pDO->Release();
	PY_INTERFACE_POSTCALL;
	if ( FAILED(hr) )
		return PyCom_BuildPyException(hr, pIDHUIH, IID_IDocHostUIHandler );
	return PyCom_PyObjectFromIUnknown(ppDORet, IID_IDataObject, FALSE);
}
Beispiel #2
0
HRESULT CPasteCommand::PasteFromClipboard (
       IMarkupPointer*  pPasteStart, 
       IMarkupPointer*  pPasteEnd, 
       IDataObject*     pDataObject,
       CSpringLoader*   psl)
{
    CXindowsEditor* pEditor = GetEditor();
    IDataObject*    pdoFromClipboard = NULL;
    CLIPFORMAT      cf = 0;
    HGLOBAL         hglobal = NULL;
    HRESULT         hr = DV_E_FORMATETC;
    HRESULT         hr2 = S_OK;
    HGLOBAL         hUnicode = NULL;
    int             i;
    int             nFETC;
    STGMEDIUM       medium = { 0, NULL };
    FORMATETC*      pfetc;
    LPTSTR          ptext = NULL;
    IHTMLViewServices*  pViewServices = pEditor->GetViewServices();
    IHTMLElement*       pElement = NULL;
    IHTMLElement*       pFlowElement = NULL;
    BOOL                fAcceptsHTML, fContainer;
    IMarkupServices*    pMarkupServices = pEditor->GetMarkupServices();
    IMarkupPointer*     pRangeStart   = NULL;
    IMarkupPointer*     pRangeEnd     = NULL;
    IDataObject*        pdoFiltered = NULL;
    IDocHostUIHandler*  pHostUIHandler = NULL;

    // Set up a pair of pointers for URL Autodetection after the insert
    IFC(pMarkupServices->CreateMarkupPointer(&pRangeStart));
    IFC(pRangeStart->MoveToPointer(pPasteStart));
    IFC(pRangeStart->SetGravity(POINTER_GRAVITY_Left));        

    IFC(pMarkupServices->CreateMarkupPointer(&pRangeEnd));
    IFC(pRangeEnd->MoveToPointer(pPasteStart));
    IFC(pRangeEnd->SetGravity(POINTER_GRAVITY_Right));

    pfetc = GetFETCs(&nFETC);

    Assert(pfetc);

    if(!pDataObject)
    {
        hr2 = OleGetClipboard(&pdoFromClipboard);

        if(hr2 != NOERROR)
        {
            return hr2;
        }

        Assert(pdoFromClipboard);

        // See if the host handler wants to give us a massaged data object.
        IFC(pViewServices->GetDocHostUIHandler(&pHostUIHandler));

        pDataObject = pdoFromClipboard;

        if(pHostUIHandler)
        {
            // The host may want to massage the data object to block/add
            // certain formats.
            hr = pHostUIHandler->FilterDataObject(pDataObject, &pdoFiltered);

            if(!hr && pdoFiltered)
            {
                pDataObject = pdoFiltered;
            }
            else
            {
                hr = S_OK;
            }
        }
    }

    if(pPasteEnd)
    {
        IFC(pMarkupServices->Remove(pPasteStart, pPasteEnd));
    }

    // Check if we accept HTML
    IFC(pViewServices->GetFlowElement(pPasteStart, &pFlowElement));

    if(!pFlowElement)
    {
        // Elements that do not accept HTML, e.g. TextArea, always have a flow layout.
        // If the element does not have a flow layout then it might have been created
        // using the DOM (see bug 42685). Set fAcceptsHTML to true.
        fAcceptsHTML = TRUE;
    }
    else
    {
        IFC(pViewServices->IsContainerElement(pFlowElement, &fContainer, &fAcceptsHTML));
    }

    for(i=0; i<nFETC; i++,pfetc++)
    {
        // make sure the format is either 1.) a plain text format
        // if we are in plain text mode or 2.) a rich text format
        // or 3.) matches the requested format.
        if(cf && cf!=pfetc->cfFormat)
        {
            continue;
        }

        // If we don't accept HTML and i does not correspond to text format
        // skip it
        if(fAcceptsHTML || i==iAnsiFETC || i==iUnicodeFETC)
        {
            // make sure the format is available
            if(pDataObject->QueryGetData(pfetc) != NOERROR)
            {
                continue;
            }

            // If we have one of the formats that uses an hglobal get it
            // and lock it.
            if(i==iAnsiFETC || i==iUnicodeFETC || i==iHTML)
            {
                if(pDataObject->GetData(pfetc, &medium) == NOERROR)
                {
                    Assert(medium.tymed == TYMED_HGLOBAL);

                    hglobal = medium.hGlobal;
                    ptext = (LPTSTR)GlobalLock(hglobal);
                    if(!ptext)
                    {
                        ReleaseStgMedium(&medium);
                        return E_OUTOFMEMORY;
                    }
                }
                else
                {
                    continue;
                }
            }

            switch(i)
            {
            case iHTML:
                {
                    // Fire the springloader.
                    BOOL fSamePosition = FALSE;
                    if(pPasteStart && psl
                        && (!pPasteEnd || (S_OK==pPasteStart->IsEqualTo(pPasteEnd, &fSamePosition) && fSamePosition))
                        && S_OK==psl->Fire(pPasteStart)
                        && pPasteEnd)
                    {
                        pPasteEnd->MoveToPointer(pPasteStart);
                    }

                    hr = pViewServices->DoTheDarnPasteHTML(pPasteStart, pPasteEnd, hglobal);

                    goto Cleanup;
                }
            case iRtfFETC:
                {
                    BOOL fEnabled = FALSE;

                    continue;
                }

            case iRtfAsTextFETC:
            case iAnsiFETC: // ANSI plain text. If data can be stored

                hUnicode = TextHGlobalAtoW(hglobal);
                if(hUnicode)
                {
                    ptext = (LPTSTR)GlobalLock(hUnicode);
                    if(!ptext)
                    {
                        hr = E_OUTOFMEMORY;
                        goto Cleanup;
                    }

                    hr = GetEditor()->InsertSanitizedText(ptext, pPasteStart, pMarkupServices, psl, FALSE);

                    GlobalUnlock(hUnicode);
                }

                goto Cleanup;

            case iUnicodeFETC: // Unicode plain text

                ptext = (LPTSTR)GlobalLock(hglobal);
                if(!ptext)
                {
                    hr = E_OUTOFMEMORY;
                    goto Cleanup;
                }

                hr = GetEditor()->InsertSanitizedText(ptext, pPasteStart, pMarkupServices, psl, FALSE);

                goto Cleanup;
            }

            //Break out of the for loop
            break;
        }
    }

Cleanup:
    ReleaseInterface(pRangeStart);
    ReleaseInterface(pRangeEnd);

    ReleaseInterface(pElement);
    ReleaseInterface(pFlowElement);

    ReleaseInterface(pdoFiltered);
    ReleaseInterface(pHostUIHandler);

    ReleaseInterface(pdoFromClipboard);

    if(hUnicode)
    {
        GlobalFree(hUnicode);
    }

    //If we used the hglobal unlock it and free it.
    if(hglobal)
    {
        GlobalUnlock(hglobal);
        ReleaseStgMedium(&medium);
    }

    return hr;
}