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