Beispiel #1
0
/*!
  copy the given subset of the given document to the
  system clipboard in a variety of formats.

  to minimize the effects of race-conditions, we create
  all of the buffers we need and then post them to the
  server (well sorta) all at one time.
  \param pDocRange a range of the document to be copied
*/
void AP_UnixApp::copyToClipboard(PD_DocumentRange * pDocRange, bool bUseClipboard)
{

    UT_ByteBuf bufRTF;
    UT_ByteBuf bufHTML4;
    UT_ByteBuf bufXHTML;
    UT_ByteBuf bufTEXT;
    UT_ByteBuf bufODT;

    // create RTF buffer to put on the clipboard
		
    IE_Exp_RTF * pExpRtf = new IE_Exp_RTF(pDocRange->m_pDoc);
    if (pExpRtf)
    {
		pExpRtf->copyToBuffer(pDocRange,&bufRTF);
		DELETEP(pExpRtf);
    }

	// create XHTML buffer to put on the clipboard

	IE_Exp_HTML * pExpHtml = new IE_Exp_HTML(pDocRange->m_pDoc);
	if (pExpHtml)
		{
			pExpHtml->set_HTML4 (false);
			pExpHtml->copyToBuffer (pDocRange, &bufXHTML);
			DELETEP(pExpHtml);
		}

	// create HTML4 buffer to put on the clipboard
	
	pExpHtml = new IE_Exp_HTML(pDocRange->m_pDoc);
	if (pExpHtml)
		{
			pExpHtml->set_HTML4 (true);
			pExpHtml->copyToBuffer(pDocRange, &bufHTML4);
			DELETEP(pExpHtml);
		}

	// Look to see if the ODT plugin is loaded

	IEFileType ftODT = IE_Exp::fileTypeForMimetype("application/vnd.oasis.opendocument.text");
	bool bExpODT = false;
	if(ftODT != IEFT_Unknown)
	{
		// ODT plugin is present construct an exporter
		//
		IE_Exp * pODT = NULL;
		IEFileType genIEFT = IEFT_Unknown;
		GsfOutput * outBuf =  gsf_output_memory_new();
		UT_Error err = IE_Exp::constructExporter(pDocRange->m_pDoc,outBuf,
												 ftODT,&pODT,& genIEFT);
		if(pODT && (genIEFT == ftODT))
		{
			//												 
			// Copy to the buffer
			//
			err = pODT->copyToBuffer(pDocRange, &bufODT);
			bExpODT = (err == UT_OK);
            UT_DEBUGMSG(("Putting ODF on the clipboard...e:%d bExpODT:%d\n", err, bExpODT ));

#ifdef DUMP_CLIPBOARD_COPY
            std::ofstream oss("/tmp/abiword-clipboard-copy.odt");
            oss.write( (const char*)bufODT.getPointer (0), bufODT.getLength () );
            oss.close();
#endif
		}
	}

    // create UTF-8 text buffer to put on the clipboard
		
    IE_Exp_Text * pExpText = new IE_Exp_Text(pDocRange->m_pDoc, "UTF-8");
    if (pExpText)
    {
		pExpText->copyToBuffer(pDocRange,&bufTEXT);
		DELETEP(pExpText);
    }

    // NOTE: this clearData() will actually release our ownership of
    // NOTE: the CLIPBOARD property in addition to clearing any
    // NOTE: stored buffers.  I'm omitting it since we seem to get
    // NOTE: clr callback after we have done some other processing
    // NOTE: (like adding the new stuff).
    // m_pClipboard->clearData(true,false);
	
    // TODO: handle CLIPBOARD vs PRIMARY
    XAP_UnixClipboard::T_AllowGet target = ((bUseClipboard)
					    ? XAP_UnixClipboard::TAG_ClipboardOnly
					    : XAP_UnixClipboard::TAG_PrimaryOnly);

	if (bufRTF.getLength () > 0)
		m_pClipboard->addRichTextData (target, bufRTF.getPointer (0), bufRTF.getLength ());
	if (bufXHTML.getLength () > 0)
		m_pClipboard->addHtmlData (target, bufXHTML.getPointer (0), bufXHTML.getLength (), true);
	if (bufHTML4.getLength () > 0)
		m_pClipboard->addHtmlData (target, bufHTML4.getPointer (0), bufHTML4.getLength (), false);
	if (bExpODT && bufODT.getLength () > 0)
		m_pClipboard->addODTData (target, bufODT.getPointer (0), bufODT.getLength ());
	if (bufTEXT.getLength () > 0)
		m_pClipboard->addTextData (target, bufTEXT.getPointer (0), bufTEXT.getLength ());

	{
		// TODO: we have to make a good way to tell if the current selection is just an image
		FV_View * pView = NULL;
		if(getLastFocussedFrame())
			pView = static_cast<FV_View*>(getLastFocussedFrame()->getCurrentView());

		if (pView && !pView->isSelectionEmpty())
			{
				// don't own, don't g_free
				const UT_ByteBuf * png = 0;
	  
				pView->saveSelectedImage (&png);
				if (png && png->getLength() > 0)
					{
						m_pClipboard->addPNGData(target, static_cast<const UT_Byte*>(png->getPointer(0)), png->getLength());
					}
			}
    }

	m_pClipboard->finishedAddingData();

    return;
}
Beispiel #2
0
//
// AbiPaint editImage
// ------------------
//   This is the function that we actually call to invoke the image editor.
//
//   parameters are:
//     AV_View* v
//     EV_EditMethodCallData *d
//
static DECLARE_ABI_PLUGIN_METHOD(editImage)
{
	UT_UNUSED(v);
    // Get the current view that the user is in.
    XAP_Frame *pFrame = XAP_App::getApp()->getLastFocussedFrame();
    FV_View* pView = static_cast<FV_View*>(pFrame->getCurrentView());

//
// get values from preference (initial plugin execution should have set sensible defaults)
//
	UT_String imageApp;  // holds MAXPATH\appName <space> MAXPATH\imagefilename
	bool bLeaveImageAsPNG;

	// read stuff from the preference value
	if (!prefsScheme->getValue(ABIPAINT_PREF_KEY_szProgramName, imageApp))
	{
		UT_ASSERT(UT_SHOULD_NOT_HAPPEN);
		getDefaultApp(imageApp, bLeaveImageAsPNG);
	}
	
	// now that we have program name, try to get other flag (allows overriding default value)
	// Note: we allow overriding, otherwise if we don't adhere to user's setting
	//       then the use BMP or not menu should be greyed to note it has no effect
	prefsScheme->getValueBool(ABIPAINT_PREF_KEY_bLeaveImageAsPNG, &bLeaveImageAsPNG);


//
// generate a temp file name...
//
	char *szTempFileName = NULL;
	GError *err = NULL;
	gint fp = g_file_open_tmp ("XXXXXX", &szTempFileName, &err);
	if (err) {
		g_warning ("%s", err->message);
		g_error_free (err); err = NULL;
		return FALSE;
	}
	close(fp);

	UT_String szTmpPng = szTempFileName;
	szTmpPng += ".png";
	UT_String szTmp = szTmpPng; // default: our temp file is the created png file
	
	PT_DocPosition pos = pView->saveSelectedImage((const char *)szTmpPng.c_str());
	if(pos == 0)
	{
		remove(szTempFileName);
		g_free (szTempFileName); szTempFileName = NULL;
		pFrame->showMessageBox("You must select an Image before editing it", XAP_Dialog_MessageBox::b_O,XAP_Dialog_MessageBox::a_OK);
		return false;
	}

#ifdef ENABLE_BMP
//
// Convert png into bmp for best compatibility with Windows programs
// NOTE: probably looses detail/information though!!! so if possible use PNG
//
	if (!bLeaveImageAsPNG)
	{
		szTmp = szTempFileName;
		szTmp += ".bmp";	// our temp file is a bmp file

		if (convertPNG2BMP(szTmpPng.c_str(), szTmp.c_str()))
		{
			pFrame->showMessageBox("Unable to convert PNG image data to BMP for external program use!", XAP_Dialog_MessageBox::b_O,XAP_Dialog_MessageBox::a_OK);
			UT_ASSERT(UT_SHOULD_NOT_HAPPEN);

			remove(szTempFileName);
			g_free (szTempFileName); szTempFileName = NULL;
			remove(szTmpPng.c_str());
			return false;
		}
		// remove(szTmpPng.c_str());

	}
#endif
	
	// remove the temp file (that lacks proper extension)
	remove(szTempFileName);
	g_free (szTempFileName); szTempFileName = NULL;

//
// Get the initial file status.
//
	struct stat myFileStat;
	int ok = stat(szTmp.c_str(),&myFileStat);
	if(ok < 0)
	{
		UT_ASSERT(UT_SHOULD_NOT_HAPPEN);
		remove(szTmpPng.c_str());
		remove(szTmp.c_str());	// should silently fail if exporting as PNG file
		return false;
	}
	time_t mod_time = myFileStat.st_mtime;

//	
// Fire up the image editor...
//
	ProcessInfo procInfo;
	if (!createChildProcess(imageApp.c_str(), szTmp.c_str(), &procInfo))

	{
		UT_String msg = "Unable to run program: ";  msg += imageApp + " " + szTmp;
		pFrame->showMessageBox(msg.c_str(), XAP_Dialog_MessageBox::b_O,XAP_Dialog_MessageBox::a_OK);

		// failed to spawn stuff, so do some cleanup and return failure
		remove(szTmpPng.c_str());
		remove(szTmp.c_str());	// should silently fail if exporting as PNG file
		return false;
	}

	lockGUI(d);

	while (isProcessStillAlive(procInfo))
	{
		UT_usleep(10000); // wait 10 milliseconds
		pFrame->nullUpdate();
		ok = stat(szTmp.c_str(),&myFileStat);
		if(ok == 0)
		{ 
			if(myFileStat.st_mtime != mod_time)
			{
				// wait for changes to settle (program done writing changes)
				// we use both modified time & file size, but really we
				// could just use file size as mod time doesn't appear to change for small images
				mod_time = myFileStat.st_mtime;
				off_t size = myFileStat.st_size;
				UT_usleep(100000); // wait 100 milliseconds (so program may have time to write something)
				ok = stat(szTmp.c_str(),&myFileStat);
				while((mod_time != myFileStat.st_mtime) || !size || (size > 0 && size != myFileStat.st_size))
				{
					mod_time = myFileStat.st_mtime;
					size = myFileStat.st_size;
					ok = stat(szTmp.c_str(),&myFileStat);
					UT_usleep(500000); // wait a while, let program write its data

					// just make sure the program is still running, otherwise we could get stuck in a loop
					if (!isProcessStillAlive(procInfo))
					{
						pFrame->showMessageBox("External image editor appears to have been terminated unexpectedly.", 
								XAP_Dialog_MessageBox::b_O,XAP_Dialog_MessageBox::a_OK);
						//procInfo.hProcess = 0;
						goto Cleanup;
					}
				}
				mod_time = myFileStat.st_mtime;
				UT_usleep(100000); // wait a while just to make sure program is done with file

//
// OK replace the current image with this.
//
				IEGraphicFileType iegft = IEGFT_Unknown;
				FG_Graphic* pFG;
		
				UT_Error errorCode;
		
#ifdef ENABLE_BMP
//
// Convert bmp back to png (as we can not assume AbiWord has builtin BMP support [as its now an optional plugin])
// NOTE: probably looses detail/information though!!! so if possible use only PNG
//
				if (!bLeaveImageAsPNG)
				{
					if (convertBMP2PNG(szTmp.c_str(), szTmpPng.c_str()))
					{
						pFrame->showMessageBox("Unable to convert BMP image data back to PNG for AbiWord to import!", XAP_Dialog_MessageBox::b_O,XAP_Dialog_MessageBox::a_OK);
						UT_ASSERT(UT_SHOULD_NOT_HAPPEN);
						goto Cleanup;
					}
				}
#endif

				errorCode = IE_ImpGraphic::loadGraphic(szTmpPng.c_str(), iegft, &pFG);
				if(errorCode)
				{
					UT_ASSERT(UT_SHOULD_NOT_HAPPEN);
					pFrame->showMessageBox("Error making pFG. Could not put image back into Abiword", XAP_Dialog_MessageBox::b_O,XAP_Dialog_MessageBox::a_OK);
					goto Cleanup;
				}

				unlockGUI(d);

				pView->cmdUnselectSelection();
				pView->setPoint(pos);
				pView->extSelHorizontal(true, 1); // move point forward one
				errorCode = pView->cmdInsertGraphic(pFG);
				if (errorCode)
				{
					pFrame->showMessageBox("Could not put image back into Abiword", XAP_Dialog_MessageBox::b_O,XAP_Dialog_MessageBox::a_OK);
					UT_ASSERT(UT_SHOULD_NOT_HAPPEN);
					DELETEP(pFG);
					goto Cleanup;
				}
				DELETEP(pFG);
//
// Reselect the image
//
				pView->setPoint(pos);
				pView->extSelHorizontal(true, 1); // move point forward one

				lockGUI(d);
			}
		}
	}

//
// Normal exit, delete the tempfile and return success
//
	remove(szTmpPng.c_str());
	remove(szTmp.c_str());	// should silently fail if exporting as PNG file
	unlockGUI(d);
	return true;

//
// Something went wrong.
//
 Cleanup: 
	remove(szTmpPng.c_str());
	remove(szTmp.c_str());	// should silently fail if exporting as PNG file
	unlockGUI(d);
//
// Kill the image editor.
//
	endProcess(procInfo);
	return false;
}
Beispiel #3
0
/*! 
  get the current contents of the selection in the
  window last known to have a selection using one
  of the formats in the given list.

  \param formatList the list of acceptable formats
  \param ppData
  \param pLen a pointer to an integer representing the length
  \param pszFormatFound a pointer for the data to be returned in
  \return True if successful, false otherwise.
*/
bool AP_UnixApp::getCurrentSelection(const char** formatList,
									 void ** ppData, UT_uint32 * pLen,
									 const char **pszFormatFound)
{
    int j;
	
    *ppData = NULL;				// assume failure
    *pLen = 0;
    *pszFormatFound = NULL;
	
    if (!m_pViewSelection || !m_pFrameSelection || !m_bHasSelection)
		return false;		// can't do it, give up.

    PD_DocumentRange dr;

    if (m_cacheSelectionView == m_pViewSelection)
    {
		dr = m_cacheDocumentRangeOfSelection;
    }
    else
    {
		// TODO if we ever support multiple view types, we'll have to
		// TODO change this.
		FV_View * pFVView = static_cast<FV_View *>(m_pViewSelection);
	
		pFVView->getDocumentRangeOfCurrentSelection(&dr);
    }
	
    m_selectionByteBuf.truncate(0);

    for (j=0; (formatList[j]); j++)
    {
		if ( AP_UnixClipboard::isRichTextTag(formatList[j]) )
		{
			IE_Exp_RTF * pExpRtf = new IE_Exp_RTF(dr.m_pDoc);
			if (!pExpRtf)
				return false;		// give up on memory errors

			pExpRtf->copyToBuffer(&dr,&m_selectionByteBuf);
			DELETEP(pExpRtf);
			goto ReturnThisBuffer;
		}

		if ( AP_UnixClipboard::isHTMLTag(formatList[j]) )
		{
			IE_Exp_HTML * pExpHTML = new IE_Exp_HTML(dr.m_pDoc);
			if (!pExpHTML)
				return false;

			pExpHTML->set_HTML4 (!strcmp (formatList[j], "text/html"));
			pExpHTML->copyToBuffer(&dr,&m_selectionByteBuf);
			DELETEP(pExpHTML);
			goto ReturnThisBuffer;
		}

		if ( AP_UnixClipboard::isImageTag(formatList[j]) )
		{
			// TODO: we have to make a good way to tell if the current selection is just an image
			FV_View * pView = NULL;
			if(getLastFocussedFrame())
				pView = static_cast<FV_View*>(getLastFocussedFrame()->getCurrentView());

			if (pView && !pView->isSelectionEmpty())
				{
					// don't own, don't g_free
					const UT_ByteBuf * png = 0;
	  
					pView->saveSelectedImage (&png);
					if (png && png->getLength() > 0)
						{
							m_selectionByteBuf.ins (0, png->getPointer (0), png->getLength ());
							goto ReturnThisBuffer;
						}
				}
		}
			
		if ( AP_UnixClipboard::isTextTag(formatList[j]) )
		{
			IE_Exp_Text * pExpText = new IE_Exp_Text(dr.m_pDoc, "UTF-8");
			if (!pExpText)
				return false;

			pExpText->copyToBuffer(&dr,&m_selectionByteBuf);
			DELETEP(pExpText);
			goto ReturnThisBuffer;
		}

		// TODO add other formats as necessary
    }

    UT_DEBUGMSG(("Clipboard::getCurrentSelection: cannot create anything in one of requested formats.\n"));
    return false;

 ReturnThisBuffer:
    UT_DEBUGMSG(("Clipboard::getCurrentSelection: copying %d bytes in format [%s].\n",
		 m_selectionByteBuf.getLength(),formatList[j]));
    *ppData = const_cast<void *>(static_cast<const void *>(m_selectionByteBuf.getPointer(0)));
    *pLen = m_selectionByteBuf.getLength();
    *pszFormatFound = formatList[j];
    return true;
}
Beispiel #4
0
//
// AbiPaint saveAsBmp
// ------------------
//   This is the function exports selected image as a Windows BMP file.
//
//   parameters are:
//     AV_View* v
//     EV_EditMethodCallData *d)
//
static DECLARE_ABI_PLUGIN_METHOD(saveAsBmp)
{
	// Get a frame (for error messages) and (to) get the current view that the user is in.
	XAP_Frame *pFrame = XAP_App::getApp()->getLastFocussedFrame();
	FV_View* pView = static_cast<FV_View*>(pFrame->getCurrentView());

	char *szTempFileName = NULL;
	GError *err = NULL;
	gint fp = g_file_open_tmp ("XXXXXX", &szTempFileName, &err);
	if (err) {
		g_warning (err->message);
		g_error_free (err); err = NULL;
		return FALSE;
	}
	close(fp);

	UT_String szTmpPng = szTempFileName;
	szTmpPng += ".png";
	remove(szTempFileName);
	g_free (szTempFileName); szTempFileName = NULL;
	
	PT_DocPosition pos = pView->saveSelectedImage((const char *)szTmpPng.c_str());
	if(pos == 0)
	{
		pFrame->showMessageBox("You must select an Image before trying to save it as a BMP file!", XAP_Dialog_MessageBox::b_O,XAP_Dialog_MessageBox::a_OK);
		return false;
	}

	//
	// Convert png into bmp
	// NOTE: probably looses detail/information though!!!
	//

	UT_String szBMPFile = pFrame->getFilename(); // perhaps a different default directory should be used???
	{
		const char * szDescList[2];
		const char * szSuffixList[2];
		IEGraphicFileType ft[2];
		{
			// IE_ImpGraphicBMP_Sniffer tmp;
			// tmp.getDlgLabels(szDescList, szSuffixList, ft);
			szDescList[0] = "Windows Bitmap (*.bmp)";
			szSuffixList[0] = "*.bmp";
			ft[0] = IEGFT_BMP;
		}
		szDescList[1] = szSuffixList[1] = NULL;
		ft[1] = IEGFT_Unknown;

		if (getFileName(szBMPFile, pFrame, XAP_DIALOG_ID_FILE_SAVEAS, szDescList, szSuffixList, ft))
		{
			// user canceled
			remove(szTmpPng.c_str());
			return true;
		}
	}

	if (convertPNG2BMP(szTmpPng.c_str(), szBMPFile.c_str()))
	{
		pFrame->showMessageBox("Unable to convert PNG image data to BMP.", XAP_Dialog_MessageBox::b_O,XAP_Dialog_MessageBox::a_OK);
		UT_ASSERT(UT_SHOULD_NOT_HAPPEN);

		remove(szTmpPng.c_str());
		return false;
	}
	remove(szTmpPng.c_str());
	return true;
}