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