--- abi/src/wp/ap/xp/ap_EditMethods.cpp~overrun-correction.patch 2004-09-14 12:06:08.000000000 +0100 +++ abi/src/wp/ap/xp/ap_EditMethods.cpp 2004-09-14 12:34:37.000000000 +0100 @@ -1160,10 +1160,24 @@ static bool _openURL(AV_View* pAV_View, const char* url); static UT_Timer * s_pToUpdateCursor = NULL; +static UT_Worker * s_pFrequentRepeat = NULL; static XAP_Frame * s_pLoadingFrame = NULL; static AD_Document * s_pLoadingDoc = NULL; static bool s_LockOutGUI = false; +class _Freq +{ +public: + _Freq(AV_View * pView,EV_EditMethodCallData * pData, void(* exe)(AV_View * pView,EV_EditMethodCallData * pData)): + m_pView (pView), + m_pData(pData), + m_pExe(exe) + {}; + AV_View * m_pView; + EV_EditMethodCallData * m_pData; + void(* m_pExe)(AV_View * ,EV_EditMethodCallData *) ; +}; + /*! This little macro locks out loading frames from any activity thus preventing segfaults. @@ -1176,6 +1190,10 @@ { return true; } + if(s_pFrequentRepeat != NULL) + { + return true; + } XAP_Frame * pFrame = XAP_App::getApp()->getLastFocussedFrame(); AV_View * pView = NULL; if(pFrame) @@ -1218,6 +1236,26 @@ #define CHECK_FRAME if(s_EditMethods_check_frame()) return true; + +/*! + * use this code to execute a one-off operation in an idle loop. + * This allows us to drop frequent events like those that come from arrow keys + * so we never get ahead of ourselves. + */ +static void _sFrequentRepeat(UT_Worker * pWorker) +{ + _Freq * pFreq = static_cast<_Freq *>(pWorker->getInstanceData()); + pFreq->m_pExe(pFreq->m_pView,pFreq->m_pData); +// +// Once then delete, stop and set to NULL +// + DELETEP(pFreq->m_pData); + delete pFreq; + s_pFrequentRepeat->stop(); + delete s_pFrequentRepeat; + s_pFrequentRepeat = NULL; +} + Defun1(toggleAutoSpell) { CHECK_FRAME; @@ -3449,11 +3487,11 @@ return true; } -Defun1(warpInsPtLeft) + +static void sActualMoveLeft(AV_View * pAV_View, EV_EditMethodCallData * pCallData) { - CHECK_FRAME; ABIWORD_VIEW; - pView->cmdCharMotion(pView->getCurrentBlock()->getDominantDirection() == FRIBIDI_TYPE_RTL,1); + pView->cmdCharMotion(false,1); if(pView->getGraphics() && pView->getGraphics()->getCaret()) { // @@ -3461,21 +3499,79 @@ // pView->getGraphics()->getCaret()->forceDraw(); } - return true; } -Defun1(warpInsPtRight) +Defun1(warpInsPtLeft) { CHECK_FRAME; ABIWORD_VIEW; - pView->cmdCharMotion(pView->getCurrentBlock()->getDominantDirection() != FRIBIDI_TYPE_RTL,1); +// +// Do this operation in an idle loop so when can reject queued events +// +// +// This code sets things up to handle the warp right in an idle loop. +// + int inMode = UT_WorkerFactory::IDLE | UT_WorkerFactory::TIMER; + UT_WorkerFactory::ConstructMode outMode = UT_WorkerFactory::NONE; + GR_Graphics * pG = pView->getGraphics(); + _Freq * pFreq = new _Freq(pView,NULL,sActualMoveLeft); + s_pFrequentRepeat = UT_WorkerFactory::static_constructor (_sFrequentRepeat,pFreq, inMode, outMode, pG); + + UT_ASSERT(s_pFrequentRepeat); + UT_ASSERT(outMode != UT_WorkerFactory::NONE); + + // If the worker is working on a timer instead of in the idle + // time, set the frequency of the checks. + if ( UT_WorkerFactory::TIMER == outMode ) + { + // this is really a timer, so it's safe to static_cast it + static_cast(s_pFrequentRepeat)->set(1); + } + s_pFrequentRepeat->start(); + return true; +} + +static void sActualMoveRight(AV_View * pAV_View, EV_EditMethodCallData * pCallData) +{ + ABIWORD_VIEW; + pView->cmdCharMotion(true,1); if(pView->getGraphics() && pView->getGraphics()->getCaret()) { // -// Draw fsking caret for sure!!! +// Draw the fsking caret for sure!!! // pView->getGraphics()->getCaret()->forceDraw(); } + return; +} + +Defun1(warpInsPtRight) +{ + CHECK_FRAME; + ABIWORD_VIEW; +// +// Do this operation in an idle loop so when can reject queued events +// +// +// This code sets things up to handle the warp right in an idle loop. +// + int inMode = UT_WorkerFactory::IDLE | UT_WorkerFactory::TIMER; + UT_WorkerFactory::ConstructMode outMode = UT_WorkerFactory::NONE; + GR_Graphics * pG = pView->getGraphics(); + _Freq * pFreq = new _Freq(pView,NULL,sActualMoveRight); + s_pFrequentRepeat = UT_WorkerFactory::static_constructor (_sFrequentRepeat,pFreq, inMode, outMode, pG); + + UT_ASSERT(s_pFrequentRepeat); + UT_ASSERT(outMode != UT_WorkerFactory::NONE); + + // If the worker is working on a timer instead of in the idle + // time, set the frequency of the checks. + if ( UT_WorkerFactory::TIMER == outMode ) + { + // this is really a timer, so it's safe to static_cast it + static_cast(s_pFrequentRepeat)->set(1); + } + s_pFrequentRepeat->start(); return true; } @@ -3647,11 +3743,11 @@ } // PSION-ABL END. pView->warpInsPtNextPrevLine(false); - if(pView->getGraphics() && pView->getGraphics()->getCaret()) - { // -// Draw fsking caret for sure!!! +// patch for disappearing caret // + if(pView->getGraphics() && pView->getGraphics()->getCaret()) + { pView->getGraphics()->getCaret()->forceDraw(); } return true; @@ -3672,11 +3768,11 @@ } // PSION-ABL END. pView->warpInsPtNextPrevLine(true); - if(pView->getGraphics() && pView->getGraphics()->getCaret()) - { // -// Draw fsking caret for sure!!! +// patch for disappearing caret // + if(pView->getGraphics() && pView->getGraphics()->getCaret()) + { pView->getGraphics()->getCaret()->forceDraw(); } return true; @@ -4345,23 +4441,80 @@ return true; } +static void sActualDelLeft(AV_View * pAV_View, EV_EditMethodCallData * pCallData) +{ + ABIWORD_VIEW; + pView->cmdCharDelete(false,1); +} Defun1(delLeft) { CHECK_FRAME; ABIWORD_VIEW; - pView->cmdCharDelete(false,1); +// +// Do this operation in an idle loop so when can reject queued events +// +// +// This code sets things up to handle the warp right in an idle loop. +// + int inMode = UT_WorkerFactory::IDLE | UT_WorkerFactory::TIMER; + UT_WorkerFactory::ConstructMode outMode = UT_WorkerFactory::NONE; + GR_Graphics * pG = pView->getGraphics(); + _Freq * pFreq = new _Freq(pView,NULL,sActualDelLeft); + s_pFrequentRepeat = UT_WorkerFactory::static_constructor (_sFrequentRepeat,pFreq, inMode, outMode, pG); + + UT_ASSERT(s_pFrequentRepeat); + UT_ASSERT(outMode != UT_WorkerFactory::NONE); + + // If the worker is working on a timer instead of in the idle + // time, set the frequency of the checks. + if ( UT_WorkerFactory::TIMER == outMode ) + { + // this is really a timer, so it's safe to static_cast it + static_cast(s_pFrequentRepeat)->set(1); + } + s_pFrequentRepeat->start(); return true; } + +static void sActualDelRight(AV_View * pAV_View, EV_EditMethodCallData * pCallData) +{ + ABIWORD_VIEW; + pView->cmdCharDelete(true,1); +} + Defun1(delRight) { CHECK_FRAME; ABIWORD_VIEW; - pView->cmdCharDelete(true,1); +// +// Do this operation in an idle loop so when can reject queued events +// +// +// This code sets things up to handle the warp right in an idle loop. +// + int inMode = UT_WorkerFactory::IDLE | UT_WorkerFactory::TIMER; + UT_WorkerFactory::ConstructMode outMode = UT_WorkerFactory::NONE; + GR_Graphics * pG = pView->getGraphics(); + _Freq * pFreq = new _Freq(pView,NULL,sActualDelRight); + s_pFrequentRepeat = UT_WorkerFactory::static_constructor (_sFrequentRepeat,pFreq, inMode, outMode, pG); + + UT_ASSERT(s_pFrequentRepeat); + UT_ASSERT(outMode != UT_WorkerFactory::NONE); + + // If the worker is working on a timer instead of in the idle + // time, set the frequency of the checks. + if ( UT_WorkerFactory::TIMER == outMode ) + { + // this is really a timer, so it's safe to static_cast it + static_cast(s_pFrequentRepeat)->set(1); + } + s_pFrequentRepeat->start(); return true; } + Defun1(delBOL) { CHECK_FRAME; @@ -4438,11 +4591,40 @@ return true; } +static void sActualInsertData(AV_View * pAV_View, EV_EditMethodCallData * pCallData) +{ + ABIWORD_VIEW; + pView->cmdCharInsert(pCallData->m_pData, pCallData->m_dataLength); + return; +} Defun(insertData) { CHECK_FRAME; ABIWORD_VIEW; - pView->cmdCharInsert(pCallData->m_pData, pCallData->m_dataLength); +// +// Do this operation in an idle loop so when can reject queued events +// +// +// This code sets things up to handle the warp right in an idle loop. +// + int inMode = UT_WorkerFactory::IDLE | UT_WorkerFactory::TIMER; + UT_WorkerFactory::ConstructMode outMode = UT_WorkerFactory::NONE; + GR_Graphics * pG = pView->getGraphics(); + EV_EditMethodCallData * pNewData = new EV_EditMethodCallData(pCallData->m_pData,pCallData->m_dataLength); + _Freq * pFreq = new _Freq(pView,pNewData,sActualInsertData); + s_pFrequentRepeat = UT_WorkerFactory::static_constructor (_sFrequentRepeat,pFreq, inMode, outMode, pG); + + UT_ASSERT(s_pFrequentRepeat); + UT_ASSERT(outMode != UT_WorkerFactory::NONE); + + // If the worker is working on a timer instead of in the idle + // time, set the frequency of the checks. + if ( UT_WorkerFactory::TIMER == outMode ) + { + // this is really a timer, so it's safe to static_cast it + static_cast(s_pFrequentRepeat)->set(1); + } + s_pFrequentRepeat->start(); return true; } @@ -5597,11 +5779,40 @@ return true; } +static void sActualPaste(AV_View * pAV_View, EV_EditMethodCallData * pCallData) +{ + ABIWORD_VIEW; + pView->cmdPaste(); + return; +} + Defun1(paste) { CHECK_FRAME; ABIWORD_VIEW; - pView->cmdPaste(); +// +// Do this operation in an idle loop so when can reject queued events +// +// +// This code sets things up to handle the warp right in an idle loop. +// + int inMode = UT_WorkerFactory::IDLE | UT_WorkerFactory::TIMER; + UT_WorkerFactory::ConstructMode outMode = UT_WorkerFactory::NONE; + GR_Graphics * pG = pView->getGraphics(); + _Freq * pFreq = new _Freq(pView,NULL,sActualPaste); + s_pFrequentRepeat = UT_WorkerFactory::static_constructor (_sFrequentRepeat,pFreq, inMode, outMode, pG); + + UT_ASSERT(s_pFrequentRepeat); + UT_ASSERT(outMode != UT_WorkerFactory::NONE); + + // If the worker is working on a timer instead of in the idle + // time, set the frequency of the checks. + if ( UT_WorkerFactory::TIMER == outMode ) + { + // this is really a timer, so it's safe to static_cast it + static_cast(s_pFrequentRepeat)->set(1); + } + s_pFrequentRepeat->start(); return true; }