bool fl_FrameLayout::bl_doclistener_insertEndFrame(fl_ContainerLayout*, const PX_ChangeRecord_Strux * pcrx, PL_StruxDocHandle sdh, PL_ListenerId lid, void (* pfnBindHandles)(PL_StruxDocHandle sdhNew, PL_ListenerId lid, PL_StruxFmtHandle sfhNew)) { // The endFrame strux actually needs a format handle to to this Frame layout. // so we bind to this layout. PL_StruxFmtHandle sfhNew = static_cast<PL_StruxFmtHandle>(this); pfnBindHandles(sdh,lid,sfhNew); // // increment the insertion point in the view. // FV_View* pView = m_pLayout->getView(); if (pView && (pView->isActive() || pView->isPreview())) { pView->setPoint(pcrx->getPosition() + fl_BLOCK_STRUX_OFFSET); } else if(pView && pView->getPoint() > pcrx->getPosition()) { pView->setPoint(pView->getPoint() + fl_BLOCK_STRUX_OFFSET); } if(pView) pView->updateCarets(pcrx->getPosition(),1); m_bHasEndFrame = true; return true; }
bool fl_EmbedLayout::bl_doclistener_insertEndEmbed(fl_ContainerLayout*, const PX_ChangeRecord_Strux * pcrx, pf_Frag_Strux* sdh, PL_ListenerId lid, void (* pfnBindHandles)(pf_Frag_Strux* sdhNew, PL_ListenerId lid, fl_ContainerLayout* sfhNew)) { // The endFootnote strux actually needs a format handle to to this Footnote layout. // so we bind to this layout. fl_ContainerLayout* sfhNew = this; pfnBindHandles(sdh,lid,sfhNew); // // increment the insertion point in the view. // FV_View* pView = m_pLayout->getView(); if (pView && (pView->isActive() || pView->isPreview())) { pView->setPoint(pcrx->getPosition() + fl_BLOCK_STRUX_OFFSET); } else if(pView && pView->getPoint() > pcrx->getPosition()) { pView->setPoint(pView->getPoint() + fl_BLOCK_STRUX_OFFSET); } m_bHasEndFootnote = true; fl_BlockLayout * pBL = static_cast<fl_BlockLayout *>(getFirstLayout()); pBL->updateEnclosingBlockIfNeeded(); return true; }
/*! * This code actually inserts a block AFTER the frame in the docsectionlayout * Code copied from tablelayout */ bool fl_FrameLayout::insertBlockAfter(fl_ContainerLayout* /*pLBlock*/, const PX_ChangeRecord_Strux * pcrx, PL_StruxDocHandle sdh, PL_ListenerId lid, void (* pfnBindHandles)(PL_StruxDocHandle sdhNew, PL_ListenerId lid, PL_StruxFmtHandle sfhNew)) { UT_ASSERT(pcrx->getType()==PX_ChangeRecord::PXT_InsertStrux); UT_ASSERT(pcrx->getStruxType()==PTX_Block); fl_ContainerLayout * pNewCL = NULL; fl_ContainerLayout * pMyCL = myContainingLayout(); pNewCL = pMyCL->insert(sdh,this,pcrx->getIndexAP(), FL_CONTAINER_BLOCK); fl_BlockLayout * pBlock = static_cast<fl_BlockLayout *>(pNewCL); // // Set the sectionlayout of this frame to that of the block since it is that scope // pBlock->setSectionLayout(static_cast<fl_SectionLayout *>(myContainingLayout())); pNewCL->setContainingLayout(myContainingLayout()); // Must call the bind function to complete the exchange of handles // with the document (piece table) *** before *** anything tries // to call down into the document (like all of the view // listeners). PL_StruxFmtHandle sfhNew = static_cast<PL_StruxFmtHandle>(pNewCL); pfnBindHandles(sdh,lid,sfhNew); // // increment the insertion point in the view. // FV_View* pView = m_pLayout->getView(); if (pView && (pView->isActive() || pView->isPreview())) { pView->setPoint(pcrx->getPosition() + fl_BLOCK_STRUX_OFFSET); } else if(pView && pView->getPoint() > pcrx->getPosition()) { pView->setPoint(pView->getPoint() + fl_BLOCK_STRUX_OFFSET); } if(pView) pView->updateCarets(pcrx->getPosition(),1); return true; }
// // 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; }