xref: /AOO41X/main/sc/source/ui/view/tabvwsh5.cxx (revision b3f79822e811ac3493b185030a72c3c5a51f32d8)
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 
28 
29 // INCLUDE ---------------------------------------------------------------
30 #define _ZFORLIST_DECLARE_TABLE
31 #include "scitems.hxx"
32 #include <svl/smplhint.hxx>
33 #include <svl/zforlist.hxx>
34 #include <svx/numfmtsh.hxx>
35 #include <svx/numinf.hxx>
36 #include <svx/svxids.hrc>
37 #include <sfx2/dispatch.hxx>
38 #include <sfx2/objsh.hxx>
39 
40 #include "tabvwsh.hxx"
41 #include "sc.hrc"
42 #include "global.hxx"
43 #include "docsh.hxx"
44 #include "document.hxx"
45 #include "cell.hxx"
46 #include "globstr.hrc"
47 #include "scmod.hxx"
48 #include "uiitems.hxx"
49 #include "editsh.hxx"
50 #include "hints.hxx"
51 
52 
53 //==================================================================
54 
Notify(SfxBroadcaster & rBC,const SfxHint & rHint)55 void __EXPORT ScTabViewShell::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
56 {
57     if (rHint.ISA(SfxSimpleHint))                       // ohne Parameter
58     {
59         sal_uLong nSlot = ((SfxSimpleHint&)rHint).GetId();
60         switch ( nSlot )
61         {
62             case FID_DATACHANGED:
63                 UpdateFormulas();
64                 break;
65 
66             case FID_REFMODECHANGED:
67                 {
68                     sal_Bool bRefMode = SC_MOD()->IsFormulaMode();
69                     if (!bRefMode)
70                         StopRefMode();
71                     else
72                     {
73                         GetSelEngine()->Reset();
74                         GetFunctionSet()->SetAnchorFlag(sal_True);
75                         //  AnchorFlag, damit gleich mit Control angehaengt werden kann
76                     }
77                 }
78                 break;
79 
80             case FID_KILLEDITVIEW:
81             case FID_KILLEDITVIEW_NOPAINT:
82                 StopEditShell();
83                 KillEditView( nSlot == FID_KILLEDITVIEW_NOPAINT );
84                 break;
85 
86             case SFX_HINT_DOCCHANGED:
87                 {
88                     ScDocument* pDoc = GetViewData()->GetDocument();
89                     if (!pDoc->HasTable( GetViewData()->GetTabNo() ))
90                     {
91                         SetTabNo(0);
92                     }
93                 }
94                 break;
95 
96             case SC_HINT_DRWLAYER_NEW:
97                 MakeDrawView();
98                 break;
99 
100             case SC_HINT_DOC_SAVED:
101                 {
102                     //  beim "Save as" kann ein vorher schreibgeschuetztes Dokument
103                     //  bearbeitbar werden, deshalb die Layer-Locks neu (#39884#)
104                     //  (Invalidate etc. passiert schon vom Sfx her)
105                     //  #42091# bei SID_EDITDOC kommt kein SFX_HINT_TITLECHANGED, darum
106                     //  der eigene Hint aus DoSaveCompleted
107                     //! was ist mit SFX_HINT_SAVECOMPLETED ?
108 
109                     UpdateLayerLocks();
110 
111                     //  #54891# Design-Modus bei jedem Speichern anzupassen, waere zuviel
112                     //  (beim Speichern unter gleichem Namen soll er unveraendert bleiben)
113                     //  Darum nur bei SFX_HINT_MODECHANGED (vom ViewFrame)
114                 }
115                 break;
116 
117             case SFX_HINT_MODECHANGED:
118                 //  #54891#/#58510# Da man sich nicht mehr darauf verlassen kann, woher
119                 //  dieser Hint kommt, den Design-Modus immer dann umschalten, wenn der
120                 //  ReadOnly-Status sich wirklich geaendert hat:
121 
122                 if ( GetViewData()->GetSfxDocShell()->IsReadOnly() != bReadOnly )
123                 {
124                     bReadOnly = GetViewData()->GetSfxDocShell()->IsReadOnly();
125 
126                     SfxBoolItem aItem( SID_FM_DESIGN_MODE, !bReadOnly);
127                     GetViewData()->GetDispatcher().Execute( SID_FM_DESIGN_MODE, SFX_CALLMODE_ASYNCHRON,
128                                                 &aItem, 0L );
129 
130                     UpdateInputContext();
131                 }
132                 break;
133 
134             case SC_HINT_SHOWRANGEFINDER:
135                 PaintRangeFinder();
136                 break;
137 
138             case SC_HINT_FORCESETTAB:
139                 SetTabNo( GetViewData()->GetTabNo(), sal_True );
140                 break;
141 
142             default:
143                 break;
144         }
145     }
146     else if (rHint.ISA(ScPaintHint))                    // neu zeichnen
147     {
148         ScPaintHint* pHint = (ScPaintHint*) &rHint;
149         sal_uInt16 nParts = pHint->GetParts();
150         SCTAB nTab = GetViewData()->GetTabNo();
151         if (pHint->GetStartTab() <= nTab && pHint->GetEndTab() >= nTab)
152         {
153             if (nParts & PAINT_EXTRAS)          // zuerst, falls Tabelle weg ist !!!
154                 if (PaintExtras())
155                     nParts = PAINT_ALL;
156 
157             // if the current sheet has pending row height updates (sheet links refreshed),
158             // execute them before invalidating the window
159             GetViewData()->GetDocShell()->UpdatePendingRowHeights( GetViewData()->GetTabNo() );
160 
161             if (nParts & PAINT_SIZE)
162                 RepeatResize();                     //! InvalidateBorder ???
163             if (nParts & PAINT_GRID)
164                 PaintArea( pHint->GetStartCol(), pHint->GetStartRow(),
165                            pHint->GetEndCol(), pHint->GetEndRow() );
166             if (nParts & PAINT_MARKS)
167                 PaintArea( pHint->GetStartCol(), pHint->GetStartRow(),
168                            pHint->GetEndCol(), pHint->GetEndRow(), SC_UPDATE_MARKS );
169             if (nParts & PAINT_LEFT)
170                 PaintLeftArea( pHint->GetStartRow(), pHint->GetEndRow() );
171             if (nParts & PAINT_TOP)
172                 PaintTopArea( pHint->GetStartCol(), pHint->GetEndCol() );
173             if (nParts & PAINT_INVERT)
174                 InvertBlockMark( pHint->GetStartCol(), pHint->GetStartRow(),
175                                  pHint->GetEndCol(), pHint->GetEndRow() );
176 
177             // #i84689# call UpdateAllOverlays here instead of in ScTabView::PaintArea
178             if (nParts & ( PAINT_LEFT | PAINT_TOP ))    // only if widths or heights changed
179                 UpdateAllOverlays();
180 
181             HideNoteMarker();
182         }
183     }
184     else if (rHint.ISA(ScEditViewHint))                 // Edit-View anlegen
185     {
186         //  ScEditViewHint kommt nur an aktiver View an
187 
188         ScEditViewHint* pHint = (ScEditViewHint*) &rHint;
189         SCTAB nTab = GetViewData()->GetTabNo();
190         if ( pHint->GetTab() == nTab )
191         {
192             SCCOL nCol = pHint->GetCol();
193             SCROW nRow = pHint->GetRow();
194             {
195                 HideNoteMarker();
196 
197                 MakeEditView( pHint->GetEngine(), nCol, nRow );
198 
199                 StopEditShell();                    // sollte nicht gesetzt sein
200 
201                 ScSplitPos eActive = GetViewData()->GetActivePart();
202                 if ( GetViewData()->HasEditView(eActive) )
203                 {
204                     //  MakeEditView geht schief, wenn der Cursor ausserhalb des
205                     //  Bildschirms steht. GetEditView gibt dann eine nicht aktive
206                     //  View zurueck, darum die Abfrage HasEditView.
207 
208                     EditView* pView = GetViewData()->GetEditView(eActive);  // ist nicht 0
209 
210                     SetEditShell(pView ,sal_True);
211                 }
212             }
213         }
214     }
215     else if (rHint.ISA(ScTablesHint))               // Tabelle eingefuegt / geloescht
216     {
217             //  aktuelle Tabelle zuerst holen (kann bei DeleteTab an ViewData geaendert werden)
218         SCTAB nActiveTab = GetViewData()->GetTabNo();
219 
220         const ScTablesHint& rTabHint = (const ScTablesHint&)rHint;
221         SCTAB nTab1 = rTabHint.GetTab1();
222         SCTAB nTab2 = rTabHint.GetTab2();
223         sal_uInt16 nId  = rTabHint.GetId();
224         switch (nId)
225         {
226             case SC_TAB_INSERTED:
227                 GetViewData()->InsertTab( nTab1 );
228                 break;
229             case SC_TAB_DELETED:
230                 GetViewData()->DeleteTab( nTab1 );
231                 break;
232             case SC_TAB_MOVED:
233                 GetViewData()->MoveTab( nTab1, nTab2 );
234                 break;
235             case SC_TAB_COPIED:
236                 GetViewData()->CopyTab( nTab1, nTab2 );
237                 break;
238             case SC_TAB_HIDDEN:
239                 break;
240             default:
241                 DBG_ERROR("unbekannter ScTablesHint");
242         }
243 
244         //  hier keine Abfrage auf IsActive() mehr, weil die Aktion von Basic ausgehen
245         //  kann und dann auch die aktive View umgeschaltet werden muss.
246 
247         SCTAB nNewTab = nActiveTab;
248         bool bStayOnActiveTab = true;
249         switch (nId)
250         {
251             case SC_TAB_INSERTED:
252                 if ( nTab1 <= nNewTab )             // vorher eingefuegt
253                     ++nNewTab;
254                 break;
255             case SC_TAB_DELETED:
256                 if ( nTab1 < nNewTab )              // vorher geloescht
257                     --nNewTab;
258                 else if ( nTab1 == nNewTab )        // aktuelle geloescht
259                     bStayOnActiveTab = false;
260                 break;
261             case SC_TAB_MOVED:
262                 if ( nNewTab == nTab1 )             // verschobene Tabelle
263                     nNewTab = nTab2;
264                 else if ( nTab1 < nTab2 )           // nach hinten verschoben
265                 {
266                     if ( nNewTab > nTab1 && nNewTab <= nTab2 )      // nachrueckender Bereich
267                         --nNewTab;
268                 }
269                 else                                // nach vorne verschoben
270                 {
271                     if ( nNewTab >= nTab2 && nNewTab < nTab1 )      // nachrueckender Bereich
272                         ++nNewTab;
273                 }
274                 break;
275             case SC_TAB_COPIED:
276                 if ( nNewTab >= nTab2 )             // vorher eingefuegt
277                     ++nNewTab;
278                 break;
279             case SC_TAB_HIDDEN:
280                 if ( nTab1 == nNewTab )             // aktuelle ausgeblendet
281                     bStayOnActiveTab = false;
282                 break;
283         }
284 
285         ScDocument* pDoc = GetViewData()->GetDocument();
286         if ( nNewTab >= pDoc->GetTableCount() )
287             nNewTab = pDoc->GetTableCount() - 1;
288 
289         sal_Bool bForce = !bStayOnActiveTab;
290         SetTabNo( nNewTab, bForce, sal_False, bStayOnActiveTab );
291     }
292     else if (rHint.ISA(ScIndexHint))
293     {
294         const ScIndexHint& rIndexHint = (const ScIndexHint&)rHint;
295         sal_uInt16 nId = rIndexHint.GetId();
296         sal_uInt16 nIndex = rIndexHint.GetIndex();
297         switch (nId)
298         {
299             case SC_HINT_SHOWRANGEFINDER:
300                 PaintRangeFinder( nIndex );
301                 break;
302         }
303     }
304 
305     SfxViewShell::Notify( rBC, rHint );
306 }
307 
308 //------------------------------------------------------------------
309 
MakeNumberInfoItem(ScDocument * pDoc,ScViewData * pViewData,SvxNumberInfoItem ** ppItem)310 void ScTabViewShell::MakeNumberInfoItem( ScDocument*         pDoc,
311                                          ScViewData*         pViewData,
312                                          SvxNumberInfoItem** ppItem )
313 {
314     //------------------------------
315     // NumberInfo-Item konstruieren:
316     //------------------------------
317     ScBaseCell*         pCell = NULL;
318     SvxNumberValueType  eValType        = SVX_VALUE_TYPE_UNDEFINED;
319     double              nCellValue      = 0;
320     String              aCellString;
321 
322     pDoc->GetCell( pViewData->GetCurX(),
323                    pViewData->GetCurY(),
324                    pViewData->GetTabNo(),
325                    pCell );
326 
327     if ( pCell )
328     {
329         switch ( pCell->GetCellType() )
330         {
331             case CELLTYPE_VALUE:
332                 {
333                     nCellValue = ((ScValueCell*)pCell)->GetValue();
334                     eValType = SVX_VALUE_TYPE_NUMBER;
335                     aCellString.Erase();
336                 }
337                 break;
338 
339             case CELLTYPE_STRING:
340                 {
341                     ((ScStringCell*)pCell)->GetString( aCellString );
342                     eValType = SVX_VALUE_TYPE_STRING;
343                 }
344                 break;
345 
346             case CELLTYPE_FORMULA:
347                 {
348                     if ( ((ScFormulaCell*)pCell)->IsValue() )
349                     {
350                         nCellValue = ((ScFormulaCell*)pCell)->GetValue();
351                         eValType = SVX_VALUE_TYPE_NUMBER;
352                     }
353                     else
354                     {
355                         nCellValue = 0;
356                         eValType   = SVX_VALUE_TYPE_UNDEFINED;
357                     }
358                     aCellString.Erase();
359                 }
360                 break;
361 
362             default:
363                 nCellValue = 0;
364                 eValType   = SVX_VALUE_TYPE_UNDEFINED;
365                 aCellString.Erase();
366         }
367     }
368     else // Zelle noch leer (== nicht erzeugt)
369     {
370         nCellValue = 0;
371         eValType   = SVX_VALUE_TYPE_UNDEFINED;
372         aCellString.Erase();
373     }
374 
375     switch ( eValType )
376     {
377         case SVX_VALUE_TYPE_STRING:
378             *ppItem = new SvxNumberInfoItem(
379                                 pDoc->GetFormatTable(),
380                                 aCellString,
381                                 SID_ATTR_NUMBERFORMAT_INFO );
382             break;
383 
384         case SVX_VALUE_TYPE_NUMBER:
385             *ppItem = new SvxNumberInfoItem(
386                                 pDoc->GetFormatTable(),
387                                 nCellValue,
388                                 SID_ATTR_NUMBERFORMAT_INFO );
389             break;
390 
391         case SVX_VALUE_TYPE_UNDEFINED:
392         default:
393             *ppItem = new SvxNumberInfoItem(
394                                 pDoc->GetFormatTable(),
395                                 (const sal_uInt16)
396                                 SID_ATTR_NUMBERFORMAT_INFO );
397     }
398 }
399 
400 //------------------------------------------------------------------
401 
UpdateNumberFormatter(ScDocument * pDoc,const SvxNumberInfoItem & rInfoItem)402 void ScTabViewShell::UpdateNumberFormatter(
403                         ScDocument*              pDoc,
404                         const SvxNumberInfoItem& rInfoItem )
405 {
406     const sal_uInt32 nDelCount = rInfoItem.GetDelCount();
407 
408     if ( nDelCount > 0 )
409     {
410         const sal_uInt32* pDelArr = rInfoItem.GetDelArray();
411 
412         for ( sal_uInt16 i=0; i<nDelCount; i++ )
413             rInfoItem.GetNumberFormatter()->DeleteEntry( pDelArr[i] );
414     }
415 
416     // sollte besser UpdateNumberFormats() heissen ?
417     pDoc->DeleteNumberFormat( rInfoItem.GetDelArray(),
418                               rInfoItem.GetDelCount() );
419 }
420 
421 
422 
423 
424 
425 
426