зеркало из https://github.com/mozilla/pjs.git
Fixed crashing and other problems with Replace All in Composer
This commit is contained in:
Родитель
7391b96095
Коммит
9a6b56dd7f
|
@ -3146,6 +3146,10 @@ private:
|
|||
// Trying to figure out new new insert point is too complicated
|
||||
// when moving a table, so we set this and delete AFTER inserting
|
||||
XP_Bool m_bDeleteTableAfterPasting;
|
||||
// Record an element to be "watched" here
|
||||
// After every element deleted, CleanupForDeletedElement()
|
||||
// is called to set this to 0 if element was the one deleted
|
||||
CEditElement *m_pWatchForDeletionElement;
|
||||
|
||||
CEditInternalAnchorElement* m_pStartSelectionAnchor;
|
||||
CEditInternalAnchorElement* m_pEndSelectionAnchor;
|
||||
|
@ -3961,9 +3965,11 @@ public:
|
|||
// Clear any existing cells selected if current edit element is not inside selection
|
||||
void ClearCellSelectionIfNotInside();
|
||||
|
||||
// If the supplied element is in our Table or Selection list,
|
||||
// clear the selection. Call when deleting an element
|
||||
void ClearTableIfContainsElement(CEditElement *pElement);
|
||||
// Do stuff necessary before deleting an element:
|
||||
// 1. If the supplied element is in our Table or Selection list,
|
||||
// clear the selection.
|
||||
// 2. Clear saved pointer (m_pWatchForDeletionElement) if it = pElement
|
||||
void CleanupForDeletedElement(CEditElement *pElement);
|
||||
|
||||
XP_Bool IsTableSelected() {return m_pSelectedEdTable != NULL; }
|
||||
XP_Bool IsTableOrCellSelected() { return m_pSelectedEdTable ? TRUE : (m_SelectedEdCells.Size() > 0 ? TRUE : FALSE); }
|
||||
|
|
|
@ -1603,7 +1603,8 @@ CEditBuffer::CEditBuffer(MWContext *pContext, XP_Bool bImportText):
|
|||
m_pNonTextSelectedTable(0),
|
||||
m_bImportText(bImportText),
|
||||
m_bFillNewCellWithSpace(FALSE),
|
||||
m_iReplaceCSID(0)
|
||||
m_iReplaceCSID(0),
|
||||
m_pWatchForDeletionElement(0)
|
||||
{
|
||||
INTL_CharSetInfo c = LO_GetDocumentCharacterSetInfo(m_pContext);
|
||||
m_originalWinCSID = INTL_GetCSIWinCSID(c);
|
||||
|
@ -5490,6 +5491,8 @@ EDT_CharacterData* CEditBuffer::GetCharacterDataSelection(EDT_CharacterData *pDa
|
|||
// Get current selection if not supplied
|
||||
if( selection.IsEmpty() )
|
||||
GetSelection( selection );
|
||||
if( selection.IsEmpty() )
|
||||
return 0;
|
||||
|
||||
CEditElement *pElement = selection.m_start.m_pElement;
|
||||
|
||||
|
@ -16927,10 +16930,15 @@ void CEditBuffer::ClearCellSelectionIfNotInside()
|
|||
}
|
||||
}
|
||||
|
||||
void CEditBuffer::ClearTableIfContainsElement(CEditElement *pElement)
|
||||
void CEditBuffer::CleanupForDeletedElement(CEditElement *pElement)
|
||||
{
|
||||
if( pElement )
|
||||
{
|
||||
// Clear the saved pointer for an element we want
|
||||
// to monitor for deletion
|
||||
if(pElement == m_pWatchForDeletionElement)
|
||||
m_pWatchForDeletionElement = 0;
|
||||
|
||||
// Depend on member flag being set correctly
|
||||
if( pElement->IsSelected() )
|
||||
{
|
||||
|
@ -17490,10 +17498,12 @@ CEditBuffer::ReplaceLoop(char *pReplaceText, XP_Bool bReplaceAll,
|
|||
*original_start_ele_loc, *original_end_ele_loc;
|
||||
int32 start_pos, end_pos,
|
||||
original_start_pos, original_end_pos,
|
||||
tlx, tly;
|
||||
tlx, tly;
|
||||
int32 iInsertPointOffset = 0;
|
||||
CL_Layer* layer;/* this will be ignored */
|
||||
CEditLeafElement* origEditElement;//used for replace all to move insertion point back to the proper location
|
||||
|
||||
CEditLeafElement* origEditElement = 0;//used for replace all to move insertion point back to the proper location
|
||||
CEditLeafElement* origBeforeElement = 0;
|
||||
XP_Bool bFirstFind = TRUE;
|
||||
BeginBatchChanges(kGroupOfChangesCommandID);
|
||||
|
||||
|
||||
|
@ -17507,7 +17517,19 @@ CEditBuffer::ReplaceLoop(char *pReplaceText, XP_Bool bReplaceAll,
|
|||
|
||||
if ( bReplaceAll )
|
||||
{
|
||||
origEditElement = m_pCurrent;
|
||||
// Save element at current insert point (m_pCurrent = 0 if there's a selection)
|
||||
CEditInsertPoint ip;
|
||||
GetInsertPoint(ip);
|
||||
origEditElement = ip.m_pElement;
|
||||
if( origEditElement )
|
||||
{
|
||||
// Also save the element before in case origEditElement is deleted
|
||||
// during replacing
|
||||
origBeforeElement = origEditElement->PreviousLeaf();
|
||||
// Set this element to be monitored for deletion
|
||||
m_pWatchForDeletionElement = origEditElement;
|
||||
iInsertPointOffset = ip.m_iPos;
|
||||
}
|
||||
|
||||
NavigateDocument( FALSE, FALSE );
|
||||
LO_GetSelectionEndpoints( m_pContext,
|
||||
|
@ -17524,7 +17546,7 @@ CEditBuffer::ReplaceLoop(char *pReplaceText, XP_Bool bReplaceAll,
|
|||
start_pos = original_start_pos;
|
||||
end_pos = original_end_pos;
|
||||
}
|
||||
|
||||
|
||||
XP_Bool done = FALSE, Wrapped = FALSE;
|
||||
//if we are replacing all, start at top of doc. remember original insertion point.
|
||||
while ( !done )
|
||||
|
@ -17533,11 +17555,10 @@ CEditBuffer::ReplaceLoop(char *pReplaceText, XP_Bool bReplaceAll,
|
|||
&start_pos, &end_ele_loc, &end_pos, !bCaseless, !bBackward);
|
||||
if ( found )
|
||||
{
|
||||
LO_SelectText( m_pContext, start_ele_loc, start_pos,
|
||||
LO_SelectText( m_pContext, start_ele_loc, start_pos,
|
||||
end_ele_loc, end_pos, &tlx, &tly);
|
||||
|
||||
ReplaceOnce( pReplaceText , !bReplaceAll, !bReplaceAll); //do not relayout if we are replacing all!
|
||||
//ReplaceOnce( pReplaceText , TRUE, TRUE);
|
||||
if ( bReplaceAll )
|
||||
{/* We need to reset our starting position to our previous ending position */
|
||||
//do not care to refresh anything now!!
|
||||
|
@ -17569,20 +17590,37 @@ CEditBuffer::ReplaceLoop(char *pReplaceText, XP_Bool bReplaceAll,
|
|||
}
|
||||
if (bReplaceAll) //need to relayout now that we are done.
|
||||
{
|
||||
//set insertion point back to its old location, valid, or not.
|
||||
/*call Reflow( CEditElement* pStartElement,
|
||||
int iEditOffset,
|
||||
CEditElement *pEndElement,
|
||||
intn relayoutFlags ){*/
|
||||
m_bLayoutBackpointersDirty = TRUE;//trust me
|
||||
|
||||
SetInsertPoint(origEditElement, original_start_pos, FALSE);
|
||||
Reduce(this->m_pRoot->GetFirstMostChild());//we must finish what we have begun...
|
||||
|
||||
// Check if original element at insert point was deleted
|
||||
if( m_pWatchForDeletionElement == 0 )
|
||||
{
|
||||
// Get the new replaced element based on the
|
||||
// saved "previous" leaf
|
||||
// (Note: the replaced text may end up appended to origBeforeElement,
|
||||
// so this will position new insert point AFTER that text.
|
||||
// Nothing we can do about that - its close enough to where we started.)
|
||||
if( origBeforeElement )
|
||||
origEditElement = origBeforeElement->NextLeaf();
|
||||
else
|
||||
// This happens when first element in page was replaced,
|
||||
// so just repostion back to the document start
|
||||
origEditElement = m_pRoot->GetFirstMostChild()->Leaf();
|
||||
|
||||
// Assume offset at start of element
|
||||
iInsertPointOffset = 0;
|
||||
}
|
||||
else
|
||||
m_pWatchForDeletionElement = 0;
|
||||
|
||||
SetInsertPoint(origEditElement, iInsertPointOffset, FALSE);
|
||||
|
||||
// (Note: Reduce call was here - moved above in case it deletes anything)
|
||||
// relayout the stream
|
||||
//Relayout(this->m_pRoot->GetFirstMostChild(), 0);
|
||||
// More stable???
|
||||
Relayout(m_pRoot->GetFirstMostChild(), 0, m_pRoot->GetLastMostChild());
|
||||
}
|
||||
EndBatchChanges();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1807,8 +1807,14 @@ XP_Bool CEditElement::DeleteElement(CEditElement* pTellIfKilled){
|
|||
CEditElement *pKill = this;
|
||||
CEditElement *pParent;
|
||||
XP_Bool bKilled = FALSE;
|
||||
// Delete the table/cell sellection if element is in the list
|
||||
GetEditBuffer()->ClearTableIfContainsElement(pKill);
|
||||
CEditBuffer *pBuffer = GetEditBuffer();
|
||||
if( pBuffer )
|
||||
{
|
||||
// Clear the table/cell selection if element is
|
||||
// the selected cell or table, or is contained in a cell or table
|
||||
// Also clears element saved in buffer if = to "this"
|
||||
pBuffer->CleanupForDeletedElement(pKill);
|
||||
}
|
||||
do {
|
||||
pParent = pKill->GetParent();
|
||||
pKill->Unlink();
|
||||
|
|
|
@ -4483,6 +4483,10 @@ void lo_HitLine(MWContext *context, lo_DocState *state, int32 x, int32 y, Bool r
|
|||
/* Last line. We know that the last line only has one element. */
|
||||
end = begin;
|
||||
}
|
||||
/* How can this be? */
|
||||
if( begin == 0 )
|
||||
continue;
|
||||
|
||||
/* Except for cases where the entire line is a line feed, don't select the end line-feed. */
|
||||
if ( begin->type != LO_LINEFEED && end->type == LO_LINEFEED ) {
|
||||
end = end->lo_any.prev;
|
||||
|
|
Загрузка…
Ссылка в новой задаче