xref: /trunk/main/sc/source/ui/view/tabvwsh5.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 
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