xref: /trunk/main/sc/source/ui/drawfunc/futext3.cxx (revision a840a559)
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 
StopEditMode(sal_Bool)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         SdrUndoGroup* pCalcUndo = pDrawLayer->GetCalcUndo();
91 
92         if(pCalcUndo)
93         {
94             const String aUndoStr = ScGlobal::GetRscString( STR_UNDO_EDITNOTE );
95             pUndoMgr->EnterListAction( aUndoStr, aUndoStr );
96 
97             /*  Note has been created before editing, if first undo action is
98                 an insert action. Needed below to decide whether to drop the
99                 undo if editing a new note has been cancelled. */
100             bNewNote = (pCalcUndo->GetActionCount() > 0) && pCalcUndo->GetAction( 0 )->ISA( SdrUndoNewObj );
101 
102             // create a "insert note" undo action if needed
103             if( bNewNote )
104                 pUndoMgr->AddUndoAction( new ScUndoReplaceNote( *pDocShell, aNotePos, pNote->GetNoteData(), true, pCalcUndo ) );
105             else
106                 pUndoMgr->AddUndoAction( pCalcUndo );
107         }
108     }
109 
110     if( pNote )
111         rDoc.LockStreamValid(true);     // only the affected sheet is invalidated below
112 
113     /*  SdrObjEditView::SdrEndTextEdit() may try to delete the entire drawing
114         object, if it does not contain text and has invisible border and fill.
115         This must not happen for note caption objects. They will be removed
116         below together with the cell note if the text is empty (independent of
117         border and area formatting). It is possible to prevent automatic
118         deletion by passing sal_True to this function. The return value changes
119         from SDRENDTEXTEDIT_DELETED to SDRENDTEXTEDIT_SHOULDBEDELETED in this
120         case. */
121     /*SdrEndTextEditKind eResult =*/ pView->SdrEndTextEdit( pNote != 0 );
122 
123     // or ScEndTextEdit (with drawview.hxx)
124     pViewShell->SetDrawTextUndo( 0 );
125 
126     Cursor* pCur = pWindow->GetCursor();
127     if( pCur && pCur->IsVisible() )
128         pCur->Hide();
129 
130     if( pNote )
131     {
132         // hide the caption object if it is in hidden state
133         pNote->ShowCaptionTemp( aNotePos, false );
134 
135         // update author and date
136         pNote->AutoStamp();
137 
138         /*  If the entire text has been cleared, the cell note and its caption
139             object have to be removed. */
140         SdrTextObj* pTextObject = dynamic_cast< SdrTextObj* >( pObject );
141         bool bDeleteNote = !pTextObject || !pTextObject->HasText();
142         if( bDeleteNote )
143         {
144             if( pUndoMgr )
145             {
146                 // collect the "remove object" drawing undo action created by DeleteNote()
147                 pDrawLayer->BeginCalcUndo(false);
148                 // rescue note data before deletion
149                 ScNoteData aNoteData( pNote->GetNoteData() );
150                 // delete note from document (removes caption, but does not delete it)
151                 rDoc.DeleteNote( aNotePos );
152                 // create undo action for removed note
153                 pUndoMgr->AddUndoAction( new ScUndoReplaceNote( *pDocShell, aNotePos, aNoteData, false, pDrawLayer->GetCalcUndo() ) );
154             }
155             else
156             {
157                 rDoc.DeleteNote( aNotePos );
158             }
159             // ScDocument::DeleteNote has deleted the note that pNote points to
160             pNote = 0;
161         }
162 
163         // finalize the undo list action
164         if( pUndoMgr )
165         {
166             pUndoMgr->LeaveListAction();
167 
168             /*  #i94039# Update the default name "Edit Note" of the undo action
169                 if the note has been created before editing or is deleted due
170                 to deleted text. If the note has been created *and* is deleted,
171                 the last undo action can be removed completely. Note: The
172                 function LeaveListAction() removes the last action by itself,
173                 if it is empty (when result is SDRENDTEXTEDIT_UNCHANGED). */
174             if( bNewNote && bDeleteNote )
175             {
176                 pUndoMgr->RemoveLastUndoAction();
177             }
178             else if( bNewNote || bDeleteNote )
179             {
180                 SfxListUndoAction* pAction = dynamic_cast< SfxListUndoAction* >( pUndoMgr->GetUndoAction() );
181                 DBG_ASSERT( pAction, "FuText::StopEditMode - list undo action expected" );
182                 if( pAction )
183                     pAction->SetComment( ScGlobal::GetRscString( bNewNote ? STR_UNDO_INSERTNOTE : STR_UNDO_DELETENOTE ) );
184             }
185         }
186 
187         // invalidate stream positions only for the affected sheet
188         rDoc.LockStreamValid(false);
189         if (rDoc.IsStreamValid(aNotePos.Tab()))
190             rDoc.SetStreamValid(aNotePos.Tab(), sal_False);
191     }
192 }
193 
194 // Called following an EndDragObj() to update the new note rectangle position
StopDragMode(SdrObject *)195 void FuText::StopDragMode(SdrObject* /*pObject*/)
196 {
197 #if 0 // DR
198     ScViewData& rViewData = *pViewShell->GetViewData();
199     if( ScDrawObjData* pData = ScDrawLayer::GetNoteCaptionData( pObject, rViewData.GetTabNo() ) )
200     {
201         ScDocument& rDoc = *rViewData.GetDocument();
202         const ScAddress& rPos = pData->maStart;
203         ScPostIt* pNote = rDoc.GetNote( rPos );
204         DBG_ASSERT( pNote && (pNote->GetCaption() == pObject), "FuText::StopDragMode - missing or invalid cell note" );
205         if( pNote )
206         {
207             Rectangle aOldRect = pNote->CalcRectangle( rDoc, rPos );
208             Rectangle aNewRect = pObject->GetLogicRect();
209             if( aOldRect != aNewRect )
210             {
211                 pNote->UpdateFromRectangle( rDoc, rPos, aNewRect );
212                 OutlinerParaObject* pPObj = pCaption->GetOutlinerParaObject();
213                 bool bVertical = (pPObj && pPObj->IsVertical());
214                 // The new height/width is honoured if property item is reset.
215                 if(!bVertical && aNewRect.Bottom() - aNewRect.Top() > aOldRect.Bottom() - aOldRect.Top())
216                 {
217                     if(pCaption->IsAutoGrowHeight() && !bVertical)
218                     {
219                         pCaption->SetMergedItem( SdrTextAutoGrowHeightItem( false ) );
220                         aNote.SetItemSet( *pDoc, pCaption->GetMergedItemSet() );
221                     }
222                 }
223                 else if(bVertical && aNewRect.Right() - aNewRect.Left() > aOldRect.Right() - aOldRect.Left())
224                 {
225                     if(pCaption->IsAutoGrowWidth() && bVertical)
226                     {
227                         pCaption->SetMergedItem( SdrTextAutoGrowWidthItem( false ) );
228                         aNote.SetItemSet( *pDoc, pCaption->GetMergedItemSet() );
229                     }
230                 }
231                 pViewShell->SetNote( aTabPos.Col(), aTabPos.Row(), aTabPos.Tab(), aNote );
232 
233                 // This repaint should not be necessary but it cleans
234                 // up the 'marks' left behind  by the note handles
235                 // now that notes can simultaineously have handles and edit active.
236                 ScRange aDrawRange = rDoc.GetRange( rPos.Tab(), aOldRect );
237                 // Set Start/End Row to previous/next row to allow for handles.
238                 if( aDrawRange.aStart.Row() > 0 )
239                     aDrawRange.aStart.IncRow( -1 );
240                 if( aDrawRange.aEnd.Row() < MAXROW )
241                     aDrawRange.aEnd.IncRow( 1 );
242                 ScDocShell* pDocSh = rViewData.GetDocShell();
243                 pDocSh->PostPaint( aDrawRange, PAINT_GRID| PAINT_EXTRAS);
244             }
245         }
246     }
247 #endif
248 }
249 
250