HRESULT CPasteCommand::Paste(IMarkupPointer* pStart, IMarkupPointer* pEnd, CSpringLoader* psl, BSTR bstrText/*=NULL*/) { HRESULT hr; IMarkupServices* pMarkupServices = GetMarkupServices(); BOOL fResult; // Delete the range first IFC(pMarkupServices->Remove(pStart, pEnd)); // If there is nothing to paste we're done if(bstrText==NULL || *bstrText==0) { return S_OK; } // InsertSanitized text checks whether we accept html or not // and handles CR LF characters appropriately IFC(GetEditor()->InsertSanitizedText(bstrText, pStart, pMarkupServices, psl, FALSE)); // Call the url autodetector IFC(pStart->IsRightOf(pEnd, &fResult)); if(fResult) { } else { } // Collapse the range IFC(pStart->IsRightOf(pEnd, &fResult)); if(fResult) { IFC(pEnd->MoveToPointer(pStart)); } else { IFC(pStart->MoveToPointer(pEnd)); } Cleanup: RRETURN(hr); }
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; }