1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir 28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 29*cdf0e10cSrcweir #include "precompiled_sc.hxx" 30*cdf0e10cSrcweir 31*cdf0e10cSrcweir #include <editeng/editeng.hxx> 32*cdf0e10cSrcweir #include <editeng/outlobj.hxx> 33*cdf0e10cSrcweir #include <svx/svdocapt.hxx> 34*cdf0e10cSrcweir #include <svx/svdpage.hxx> 35*cdf0e10cSrcweir #include <svx/svdundo.hxx> 36*cdf0e10cSrcweir #include <svx/svdview.hxx> 37*cdf0e10cSrcweir #include <editeng/editobj.hxx> 38*cdf0e10cSrcweir #include <vcl/cursor.hxx> 39*cdf0e10cSrcweir #include <sfx2/objsh.hxx> 40*cdf0e10cSrcweir #include <editeng/writingmodeitem.hxx> 41*cdf0e10cSrcweir 42*cdf0e10cSrcweir #include "global.hxx" 43*cdf0e10cSrcweir #include "drwlayer.hxx" 44*cdf0e10cSrcweir #include "userdat.hxx" 45*cdf0e10cSrcweir #include "tabvwsh.hxx" // oder GetDocument irgendwo 46*cdf0e10cSrcweir #include "document.hxx" 47*cdf0e10cSrcweir #include "editutil.hxx" 48*cdf0e10cSrcweir #include "futext.hxx" 49*cdf0e10cSrcweir #include "docsh.hxx" 50*cdf0e10cSrcweir #include "postit.hxx" 51*cdf0e10cSrcweir #include "globstr.hrc" 52*cdf0e10cSrcweir #include "attrib.hxx" 53*cdf0e10cSrcweir #include "scitems.hxx" 54*cdf0e10cSrcweir #include "drawview.hxx" 55*cdf0e10cSrcweir #include "undocell.hxx" 56*cdf0e10cSrcweir 57*cdf0e10cSrcweir // ------------------------------------------------------------------------------------ 58*cdf0e10cSrcweir // Editieren von Notiz-Legendenobjekten muss immer ueber StopEditMode beendet werden, 59*cdf0e10cSrcweir // damit die Aenderungen ins Dokument uebernommen werden! 60*cdf0e10cSrcweir // (Fontwork-Execute in drawsh und drtxtob passiert nicht fuer Legendenobjekte) 61*cdf0e10cSrcweir // bTextDirection=sal_True means that this function is called from SID_TEXTDIRECTION_XXX(drtxtob.cxx). 62*cdf0e10cSrcweir // ------------------------------------------------------------------------------------ 63*cdf0e10cSrcweir 64*cdf0e10cSrcweir void FuText::StopEditMode(sal_Bool /*bTextDirection*/) 65*cdf0e10cSrcweir { 66*cdf0e10cSrcweir SdrObject* pObject = pView->GetTextEditObject(); 67*cdf0e10cSrcweir if( !pObject ) return; 68*cdf0e10cSrcweir 69*cdf0e10cSrcweir // relock the internal layer that has been unlocked in FuText::SetInEditMode() 70*cdf0e10cSrcweir if ( pObject->GetLayer() == SC_LAYER_INTERN ) 71*cdf0e10cSrcweir pView->LockInternalLayer(); 72*cdf0e10cSrcweir 73*cdf0e10cSrcweir ScViewData& rViewData = *pViewShell->GetViewData(); 74*cdf0e10cSrcweir ScDocument& rDoc = *rViewData.GetDocument(); 75*cdf0e10cSrcweir ScDrawLayer* pDrawLayer = rDoc.GetDrawLayer(); 76*cdf0e10cSrcweir DBG_ASSERT( pDrawLayer && (pDrawLayer == pDrDoc), "FuText::StopEditMode - missing or different drawing layers" ); 77*cdf0e10cSrcweir 78*cdf0e10cSrcweir ScAddress aNotePos; 79*cdf0e10cSrcweir ScPostIt* pNote = 0; 80*cdf0e10cSrcweir if( const ScDrawObjData* pCaptData = ScDrawLayer::GetNoteCaptionData( pObject, rViewData.GetTabNo() ) ) 81*cdf0e10cSrcweir { 82*cdf0e10cSrcweir aNotePos = pCaptData->maStart; 83*cdf0e10cSrcweir pNote = rDoc.GetNote( aNotePos ); 84*cdf0e10cSrcweir DBG_ASSERT( pNote && (pNote->GetCaption() == pObject), "FuText::StopEditMode - missing or invalid cell note" ); 85*cdf0e10cSrcweir } 86*cdf0e10cSrcweir 87*cdf0e10cSrcweir ScDocShell* pDocShell = rViewData.GetDocShell(); 88*cdf0e10cSrcweir ::svl::IUndoManager* pUndoMgr = rDoc.IsUndoEnabled() ? pDocShell->GetUndoManager() : 0; 89*cdf0e10cSrcweir bool bNewNote = false; 90*cdf0e10cSrcweir if( pNote && pUndoMgr ) 91*cdf0e10cSrcweir { 92*cdf0e10cSrcweir /* Put all undo actions already collected (e.g. create caption object) 93*cdf0e10cSrcweir and all following undo actions (text changed) together into a ListAction. */ 94*cdf0e10cSrcweir String aUndoStr = ScGlobal::GetRscString( STR_UNDO_EDITNOTE ); 95*cdf0e10cSrcweir pUndoMgr->EnterListAction( aUndoStr, aUndoStr ); 96*cdf0e10cSrcweir if( SdrUndoGroup* pCalcUndo = pDrawLayer->GetCalcUndo() ) 97*cdf0e10cSrcweir { 98*cdf0e10cSrcweir /* Note has been created before editing, if first undo action is 99*cdf0e10cSrcweir an insert action. Needed below to decide whether to drop the 100*cdf0e10cSrcweir undo if editing a new note has been cancelled. */ 101*cdf0e10cSrcweir bNewNote = (pCalcUndo->GetActionCount() > 0) && pCalcUndo->GetAction( 0 )->ISA( SdrUndoNewObj ); 102*cdf0e10cSrcweir // create a "insert note" undo action if needed 103*cdf0e10cSrcweir if( bNewNote ) 104*cdf0e10cSrcweir pUndoMgr->AddUndoAction( new ScUndoReplaceNote( *pDocShell, aNotePos, pNote->GetNoteData(), true, pCalcUndo ) ); 105*cdf0e10cSrcweir else 106*cdf0e10cSrcweir pUndoMgr->AddUndoAction( pCalcUndo ); 107*cdf0e10cSrcweir } 108*cdf0e10cSrcweir } 109*cdf0e10cSrcweir 110*cdf0e10cSrcweir if( pNote ) 111*cdf0e10cSrcweir rDoc.LockStreamValid(true); // only the affected sheet is invalidated below 112*cdf0e10cSrcweir 113*cdf0e10cSrcweir /* SdrObjEditView::SdrEndTextEdit() may try to delete the entire drawing 114*cdf0e10cSrcweir object, if it does not contain text and has invisible border and fill. 115*cdf0e10cSrcweir This must not happen for note caption objects. They will be removed 116*cdf0e10cSrcweir below together with the cell note if the text is empty (independent of 117*cdf0e10cSrcweir border and area formatting). It is possible to prevent automatic 118*cdf0e10cSrcweir deletion by passing sal_True to this function. The return value changes 119*cdf0e10cSrcweir from SDRENDTEXTEDIT_DELETED to SDRENDTEXTEDIT_SHOULDBEDELETED in this 120*cdf0e10cSrcweir case. */ 121*cdf0e10cSrcweir /*SdrEndTextEditKind eResult =*/ pView->SdrEndTextEdit( pNote != 0 ); 122*cdf0e10cSrcweir 123*cdf0e10cSrcweir // or ScEndTextEdit (with drawview.hxx) 124*cdf0e10cSrcweir pViewShell->SetDrawTextUndo( 0 ); 125*cdf0e10cSrcweir 126*cdf0e10cSrcweir Cursor* pCur = pWindow->GetCursor(); 127*cdf0e10cSrcweir if( pCur && pCur->IsVisible() ) 128*cdf0e10cSrcweir pCur->Hide(); 129*cdf0e10cSrcweir 130*cdf0e10cSrcweir if( pNote ) 131*cdf0e10cSrcweir { 132*cdf0e10cSrcweir // hide the caption object if it is in hidden state 133*cdf0e10cSrcweir pNote->ShowCaptionTemp( aNotePos, false ); 134*cdf0e10cSrcweir 135*cdf0e10cSrcweir // update author and date 136*cdf0e10cSrcweir pNote->AutoStamp(); 137*cdf0e10cSrcweir 138*cdf0e10cSrcweir /* If the entire text has been cleared, the cell note and its caption 139*cdf0e10cSrcweir object have to be removed. */ 140*cdf0e10cSrcweir SdrTextObj* pTextObject = dynamic_cast< SdrTextObj* >( pObject ); 141*cdf0e10cSrcweir bool bDeleteNote = !pTextObject || !pTextObject->HasText(); 142*cdf0e10cSrcweir if( bDeleteNote ) 143*cdf0e10cSrcweir { 144*cdf0e10cSrcweir if( pUndoMgr ) 145*cdf0e10cSrcweir { 146*cdf0e10cSrcweir // collect the "remove object" drawing undo action created by DeleteNote() 147*cdf0e10cSrcweir pDrawLayer->BeginCalcUndo(); 148*cdf0e10cSrcweir // rescue note data before deletion 149*cdf0e10cSrcweir ScNoteData aNoteData( pNote->GetNoteData() ); 150*cdf0e10cSrcweir // delete note from document (removes caption, but does not delete it) 151*cdf0e10cSrcweir rDoc.DeleteNote( aNotePos ); 152*cdf0e10cSrcweir // create undo action for removed note 153*cdf0e10cSrcweir pUndoMgr->AddUndoAction( new ScUndoReplaceNote( *pDocShell, aNotePos, aNoteData, false, pDrawLayer->GetCalcUndo() ) ); 154*cdf0e10cSrcweir } 155*cdf0e10cSrcweir else 156*cdf0e10cSrcweir { 157*cdf0e10cSrcweir rDoc.DeleteNote( aNotePos ); 158*cdf0e10cSrcweir } 159*cdf0e10cSrcweir // ScDocument::DeleteNote has deleted the note that pNote points to 160*cdf0e10cSrcweir pNote = 0; 161*cdf0e10cSrcweir } 162*cdf0e10cSrcweir 163*cdf0e10cSrcweir // finalize the undo list action 164*cdf0e10cSrcweir if( pUndoMgr ) 165*cdf0e10cSrcweir { 166*cdf0e10cSrcweir pUndoMgr->LeaveListAction(); 167*cdf0e10cSrcweir 168*cdf0e10cSrcweir /* #i94039# Update the default name "Edit Note" of the undo action 169*cdf0e10cSrcweir if the note has been created before editing or is deleted due 170*cdf0e10cSrcweir to deleted text. If the note has been created *and* is deleted, 171*cdf0e10cSrcweir the last undo action can be removed completely. Note: The 172*cdf0e10cSrcweir function LeaveListAction() removes the last action by itself, 173*cdf0e10cSrcweir if it is empty (when result is SDRENDTEXTEDIT_UNCHANGED). */ 174*cdf0e10cSrcweir if( bNewNote && bDeleteNote ) 175*cdf0e10cSrcweir { 176*cdf0e10cSrcweir pUndoMgr->RemoveLastUndoAction(); 177*cdf0e10cSrcweir } 178*cdf0e10cSrcweir else if( bNewNote || bDeleteNote ) 179*cdf0e10cSrcweir { 180*cdf0e10cSrcweir SfxListUndoAction* pAction = dynamic_cast< SfxListUndoAction* >( pUndoMgr->GetUndoAction() ); 181*cdf0e10cSrcweir DBG_ASSERT( pAction, "FuText::StopEditMode - list undo action expected" ); 182*cdf0e10cSrcweir if( pAction ) 183*cdf0e10cSrcweir pAction->SetComment( ScGlobal::GetRscString( bNewNote ? STR_UNDO_INSERTNOTE : STR_UNDO_DELETENOTE ) ); 184*cdf0e10cSrcweir } 185*cdf0e10cSrcweir } 186*cdf0e10cSrcweir 187*cdf0e10cSrcweir // invalidate stream positions only for the affected sheet 188*cdf0e10cSrcweir rDoc.LockStreamValid(false); 189*cdf0e10cSrcweir if (rDoc.IsStreamValid(aNotePos.Tab())) 190*cdf0e10cSrcweir rDoc.SetStreamValid(aNotePos.Tab(), sal_False); 191*cdf0e10cSrcweir } 192*cdf0e10cSrcweir } 193*cdf0e10cSrcweir 194*cdf0e10cSrcweir // Called following an EndDragObj() to update the new note rectangle position 195*cdf0e10cSrcweir void FuText::StopDragMode(SdrObject* /*pObject*/) 196*cdf0e10cSrcweir { 197*cdf0e10cSrcweir #if 0 // DR 198*cdf0e10cSrcweir ScViewData& rViewData = *pViewShell->GetViewData(); 199*cdf0e10cSrcweir if( ScDrawObjData* pData = ScDrawLayer::GetNoteCaptionData( pObject, rViewData.GetTabNo() ) ) 200*cdf0e10cSrcweir { 201*cdf0e10cSrcweir ScDocument& rDoc = *rViewData.GetDocument(); 202*cdf0e10cSrcweir const ScAddress& rPos = pData->maStart; 203*cdf0e10cSrcweir ScPostIt* pNote = rDoc.GetNote( rPos ); 204*cdf0e10cSrcweir DBG_ASSERT( pNote && (pNote->GetCaption() == pObject), "FuText::StopDragMode - missing or invalid cell note" ); 205*cdf0e10cSrcweir if( pNote ) 206*cdf0e10cSrcweir { 207*cdf0e10cSrcweir Rectangle aOldRect = pNote->CalcRectangle( rDoc, rPos ); 208*cdf0e10cSrcweir Rectangle aNewRect = pObject->GetLogicRect(); 209*cdf0e10cSrcweir if( aOldRect != aNewRect ) 210*cdf0e10cSrcweir { 211*cdf0e10cSrcweir pNote->UpdateFromRectangle( rDoc, rPos, aNewRect ); 212*cdf0e10cSrcweir OutlinerParaObject* pPObj = pCaption->GetOutlinerParaObject(); 213*cdf0e10cSrcweir bool bVertical = (pPObj && pPObj->IsVertical()); 214*cdf0e10cSrcweir // The new height/width is honoured if property item is reset. 215*cdf0e10cSrcweir if(!bVertical && aNewRect.Bottom() - aNewRect.Top() > aOldRect.Bottom() - aOldRect.Top()) 216*cdf0e10cSrcweir { 217*cdf0e10cSrcweir if(pCaption->IsAutoGrowHeight() && !bVertical) 218*cdf0e10cSrcweir { 219*cdf0e10cSrcweir pCaption->SetMergedItem( SdrTextAutoGrowHeightItem( false ) ); 220*cdf0e10cSrcweir aNote.SetItemSet( *pDoc, pCaption->GetMergedItemSet() ); 221*cdf0e10cSrcweir } 222*cdf0e10cSrcweir } 223*cdf0e10cSrcweir else if(bVertical && aNewRect.Right() - aNewRect.Left() > aOldRect.Right() - aOldRect.Left()) 224*cdf0e10cSrcweir { 225*cdf0e10cSrcweir if(pCaption->IsAutoGrowWidth() && bVertical) 226*cdf0e10cSrcweir { 227*cdf0e10cSrcweir pCaption->SetMergedItem( SdrTextAutoGrowWidthItem( false ) ); 228*cdf0e10cSrcweir aNote.SetItemSet( *pDoc, pCaption->GetMergedItemSet() ); 229*cdf0e10cSrcweir } 230*cdf0e10cSrcweir } 231*cdf0e10cSrcweir pViewShell->SetNote( aTabPos.Col(), aTabPos.Row(), aTabPos.Tab(), aNote ); 232*cdf0e10cSrcweir 233*cdf0e10cSrcweir // This repaint should not be necessary but it cleans 234*cdf0e10cSrcweir // up the 'marks' left behind by the note handles 235*cdf0e10cSrcweir // now that notes can simultaineously have handles and edit active. 236*cdf0e10cSrcweir ScRange aDrawRange = rDoc.GetRange( rPos.Tab(), aOldRect ); 237*cdf0e10cSrcweir // Set Start/End Row to previous/next row to allow for handles. 238*cdf0e10cSrcweir if( aDrawRange.aStart.Row() > 0 ) 239*cdf0e10cSrcweir aDrawRange.aStart.IncRow( -1 ); 240*cdf0e10cSrcweir if( aDrawRange.aEnd.Row() < MAXROW ) 241*cdf0e10cSrcweir aDrawRange.aEnd.IncRow( 1 ); 242*cdf0e10cSrcweir ScDocShell* pDocSh = rViewData.GetDocShell(); 243*cdf0e10cSrcweir pDocSh->PostPaint( aDrawRange, PAINT_GRID| PAINT_EXTRAS); 244*cdf0e10cSrcweir } 245*cdf0e10cSrcweir } 246*cdf0e10cSrcweir } 247*cdf0e10cSrcweir #endif 248*cdf0e10cSrcweir } 249*cdf0e10cSrcweir 250