xref: /aoo41x/main/sc/source/ui/view/cellsh.cxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_sc.hxx"
30 
31 //------------------------------------------------------------------
32 
33 #include "scitems.hxx"
34 
35 #include <svl/slstitm.hxx>
36 #include <svl/stritem.hxx>
37 #include <svl/whiter.hxx>
38 #include <unotools/moduleoptions.hxx>
39 #include <svtools/cliplistener.hxx>
40 #include <svtools/insdlg.hxx>
41 #include <sot/formats.hxx>
42 #include <svx/hlnkitem.hxx>
43 #include <sfx2/app.hxx>
44 #include <sfx2/bindings.hxx>
45 #include <sfx2/childwin.hxx>
46 #include <sfx2/objface.hxx>
47 #include <sfx2/request.hxx>
48 #include <sfx2/viewfrm.hxx>
49 #include <svx/clipfmtitem.hxx>
50 #include <editeng/langitem.hxx>
51 
52 #include "cellsh.hxx"
53 #include "sc.hrc"
54 #include "docsh.hxx"
55 #include "attrib.hxx"
56 #include "scresid.hxx"
57 #include "tabvwsh.hxx"
58 #include "impex.hxx"
59 #include "cell.hxx"
60 #include "scmod.hxx"
61 #include "globstr.hrc"
62 #include "transobj.hxx"
63 #include "drwtrans.hxx"
64 #include "scabstdlg.hxx"
65 #include "dociter.hxx"
66 #include "postit.hxx"
67 
68 //------------------------------------------------------------------
69 
70 #define ScCellShell
71 #define	CellMovement
72 #include "scslots.hxx"
73 
74 TYPEINIT1( ScCellShell, ScFormatShell );
75 
76 SFX_IMPL_INTERFACE(ScCellShell, ScFormatShell , ScResId(SCSTR_CELLSHELL) )
77 {
78 	SFX_OBJECTBAR_REGISTRATION( SFX_OBJECTBAR_OBJECT | SFX_VISIBILITY_STANDARD |
79 								SFX_VISIBILITY_SERVER,
80 								ScResId(RID_OBJECTBAR_FORMAT));
81 	SFX_POPUPMENU_REGISTRATION(ScResId(RID_POPUP_CELLS));
82 }
83 
84 
85 ScCellShell::ScCellShell(ScViewData* pData) :
86 	ScFormatShell(pData),
87     pImpl( new CellShell_Impl() ),
88 	bPastePossible(sal_False)
89 {
90 	SetHelpId(HID_SCSHELL_CELLSH);
91 	SetName(String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("Cell")));
92 }
93 
94 ScCellShell::~ScCellShell()
95 {
96     if ( pImpl->m_pClipEvtLstnr )
97 	{
98         pImpl->m_pClipEvtLstnr->AddRemoveListener( GetViewData()->GetActiveWin(), sal_False );
99 
100 		//  #103849# The listener may just now be waiting for the SolarMutex and call the link
101 		//  afterwards, in spite of RemoveListener. So the link has to be reset, too.
102         pImpl->m_pClipEvtLstnr->ClearCallbackLink();
103 
104         pImpl->m_pClipEvtLstnr->release();
105 	}
106 
107     delete pImpl->m_pLinkedDlg;
108     delete pImpl->m_pRequest;
109     delete pImpl;
110 }
111 
112 //------------------------------------------------------------------
113 
114 void ScCellShell::GetBlockState( SfxItemSet& rSet )
115 {
116 	ScTabViewShell*	pTabViewShell  	= GetViewData()->GetViewShell();
117 	ScRange aMarkRange;
118     ScMarkType eMarkType = GetViewData()->GetSimpleArea( aMarkRange );
119 	sal_Bool bSimpleArea = (eMarkType == SC_MARK_SIMPLE);
120 	sal_Bool bOnlyNotBecauseOfMatrix;
121 	sal_Bool bEditable = pTabViewShell->SelectionEditable( &bOnlyNotBecauseOfMatrix );
122 	ScDocument* pDoc = GetViewData()->GetDocument();
123     ScDocShell* pDocShell = GetViewData()->GetDocShell();
124     ScMarkData& rMark = GetViewData()->GetMarkData();
125 	SCCOL nCol1, nCol2;
126 	SCROW nRow1, nRow2;
127 	nCol1 = aMarkRange.aStart.Col();
128 	nRow1 = aMarkRange.aStart.Row();
129 	nCol2 = aMarkRange.aEnd.Col();
130 	nRow2 = aMarkRange.aEnd.Row();
131 
132 	SfxWhichIter aIter(rSet);
133 	sal_uInt16 nWhich = aIter.FirstWhich();
134 	while ( nWhich )
135 	{
136 		sal_Bool bDisable = sal_False;
137 		sal_Bool bNeedEdit = sal_True;		// muss Selektion editierbar sein?
138 		switch ( nWhich )
139 		{
140 			case FID_FILL_TO_BOTTOM:	// Fuellen oben/unten
141 			case FID_FILL_TO_TOP:		// mind. 2 Zeilen markiert?
142 				bDisable = (!bSimpleArea) || (nRow1 == nRow2);
143 				if ( !bDisable && bEditable )
144 				{	// Matrix nicht zerreissen
145 					if ( nWhich == FID_FILL_TO_BOTTOM )
146 						bDisable = pDoc->HasSelectedBlockMatrixFragment(
147 							nCol1, nRow1, nCol2, nRow1, rMark );	// erste Zeile
148 					else
149 						bDisable = pDoc->HasSelectedBlockMatrixFragment(
150 							nCol1, nRow2, nCol2, nRow2, rMark );	// letzte Zeile
151 				}
152 				break;
153 
154 			case FID_FILL_TO_RIGHT:		// Fuellen links/rechts
155 			case FID_FILL_TO_LEFT:		// mind. 2 Spalten markiert?
156 				bDisable = (!bSimpleArea) || (nCol1 == nCol2);
157 				if ( !bDisable && bEditable )
158 				{	// Matrix nicht zerreissen
159 					if ( nWhich == FID_FILL_TO_RIGHT )
160 						bDisable = pDoc->HasSelectedBlockMatrixFragment(
161 							nCol1, nRow1, nCol1, nRow2, rMark );	// erste Spalte
162 					else
163 						bDisable = pDoc->HasSelectedBlockMatrixFragment(
164 							nCol2, nRow1, nCol2, nRow2, rMark );	// letzte Spalte
165 				}
166 				break;
167 
168 			case FID_FILL_SERIES:		// Block fuellen
169 			case SID_OPENDLG_TABOP:		// Mehrfachoperationen, mind. 2 Zellen markiert?
170 				if (pDoc->GetChangeTrack()!=NULL &&nWhich ==SID_OPENDLG_TABOP)
171 					bDisable = sal_True;
172 				else
173 					bDisable = (!bSimpleArea) || (nCol1 == nCol2 && nRow1 == nRow2);
174 
175 				if ( !bDisable && bEditable && nWhich == FID_FILL_SERIES )
176 				{	// Matrix nicht zerreissen
177 					bDisable = pDoc->HasSelectedBlockMatrixFragment(
178 							nCol1, nRow1, nCol2, nRow1, rMark )	// erste Zeile
179 						||	pDoc->HasSelectedBlockMatrixFragment(
180 							nCol1, nRow2, nCol2, nRow2, rMark )	// letzte Zeile
181 						||	pDoc->HasSelectedBlockMatrixFragment(
182 							nCol1, nRow1, nCol1, nRow2, rMark )	// erste Spalte
183 						||	pDoc->HasSelectedBlockMatrixFragment(
184 							nCol2, nRow1, nCol2, nRow2, rMark );	// letzte Spalte
185 				}
186 				break;
187 
188 			case SID_CUT:				// Ausschneiden,
189 			case FID_INS_CELL:			// Zellen einfuegen, nur einf. Selektion
190 				bDisable = (!bSimpleArea);
191 				break;
192 
193             case FID_INS_ROW:           // insert rows
194             case FID_INS_CELLSDOWN:
195                 bDisable = (!bSimpleArea) || GetViewData()->SimpleColMarked();
196                 break;
197 
198             case FID_INS_COLUMN:        // insert columns
199             case FID_INS_CELLSRIGHT:
200                 bDisable = (!bSimpleArea) || GetViewData()->SimpleRowMarked();
201                 break;
202 
203 			case SID_COPY:						// Kopieren
204 				// nur wegen Matrix nicht editierbar? Matrix nicht zerreissen
205 				//! schlaegt nicht zu, wenn geschuetzt UND Matrix, aber damit
206 				//! muss man leben.. wird in Copy-Routine abgefangen, sonst
207 				//! muesste hier nochmal Aufwand getrieben werden
208 				if ( !(!bEditable && bOnlyNotBecauseOfMatrix) )
209 					bNeedEdit = sal_False;			// erlaubt, wenn geschuetzt/ReadOnly
210 				break;
211 
212 			case SID_AUTOFORMAT:		// Autoformat, mind. 3x3 selektiert
213 				bDisable =    (!bSimpleArea)
214 						   || ((nCol2 - nCol1) < 2) || ((nRow2 - nRow1) < 2);
215 				break;
216 
217 			case SID_OPENDLG_CONDFRMT :
218                 {
219                     if ( !bEditable && bOnlyNotBecauseOfMatrix )
220                     {
221                         bNeedEdit = sal_False;
222                     }
223                     if ( pDocShell && pDocShell->IsDocShared() )
224                     {
225                         bDisable = sal_True;
226                     }
227                 }
228                 break;
229 
230 			case FID_CONDITIONAL_FORMAT :
231 			case SID_CELL_FORMAT_RESET :
232 			case FID_CELL_FORMAT :
233 			case SID_ENABLE_HYPHENATION :
234 				// nur wegen Matrix nicht editierbar? Attribute trotzdem ok
235 				if ( !bEditable && bOnlyNotBecauseOfMatrix )
236 					bNeedEdit = sal_False;
237 				break;
238 
239             case FID_VALIDATION:
240                 {
241                     if ( pDocShell && pDocShell->IsDocShared() )
242                     {
243                         bDisable = sal_True;
244                     }
245                 }
246                 break;
247 
248 			case SID_TRANSLITERATE_HALFWIDTH:
249 			case SID_TRANSLITERATE_FULLWIDTH:
250 			case SID_TRANSLITERATE_HIRAGANA:
251 			case SID_TRANSLITERATE_KATAGANA:
252                 ScViewUtil::HideDisabledSlot( rSet, GetViewData()->GetBindings(), nWhich );
253             break;
254 		}
255 		if (!bDisable && bNeedEdit && !bEditable)
256 			bDisable = sal_True;
257 
258 		if (bDisable)
259 			rSet.DisableItem(nWhich);
260 		else if (nWhich == SID_ENABLE_HYPHENATION)
261 		{
262 			// toggle slots need a bool item
263 			rSet.Put( SfxBoolItem( nWhich, sal_False ) );
264 		}
265 		nWhich = aIter.NextWhich();
266 	}
267 }
268 
269 //	Funktionen, die je nach Cursorposition disabled sind
270 //	Default:
271 //		SID_INSERT_POSTIT, SID_CHARMAP, SID_OPENDLG_FUNCTION
272 
273 void ScCellShell::GetCellState( SfxItemSet& rSet )
274 {
275     ScDocShell* pDocShell = GetViewData()->GetDocShell();
276 	ScDocument* pDoc = GetViewData()->GetDocShell()->GetDocument();
277 	ScAddress aCursor( GetViewData()->GetCurX(), GetViewData()->GetCurY(),
278 						GetViewData()->GetTabNo() );
279 
280 	SfxWhichIter aIter(rSet);
281 	sal_uInt16 nWhich = aIter.FirstWhich();
282 	while ( nWhich )
283 	{
284 		sal_Bool bDisable = sal_False;
285 		sal_Bool bNeedEdit = sal_True;		// muss Cursorposition editierbar sein?
286 		switch ( nWhich )
287 		{
288             case SID_THESAURUS:
289 				{
290 					CellType eType = pDoc->GetCellType( aCursor );
291 					bDisable = ( eType != CELLTYPE_STRING && eType != CELLTYPE_EDIT);
292 					if (!bDisable)
293 					{
294 						//	test for available languages
295 						sal_uInt16 nLang = ScViewUtil::GetEffLanguage( pDoc, aCursor );
296 						bDisable = !ScModule::HasThesaurusLanguage( nLang );
297 					}
298 				}
299 				break;
300 			case SID_OPENDLG_FUNCTION:
301 				{
302 					ScMarkData aMarkData=GetViewData()->GetMarkData();
303 					aMarkData.MarkToSimple();
304 					ScRange aRange;
305 					aMarkData.GetMarkArea(aRange);
306 					if(aMarkData.IsMarked())
307 					{
308 						if (!pDoc->IsBlockEditable( aCursor.Tab(), aRange.aStart.Col(),aRange.aStart.Row(),
309 											aRange.aEnd.Col(),aRange.aEnd.Row() ))
310 						{
311 							bDisable = sal_True;
312 						}
313 						bNeedEdit=sal_False;
314 					}
315 
316 				}
317 				break;
318             case SID_INSERT_POSTIT:
319                 {
320                     if ( pDocShell && pDocShell->IsDocShared() )
321                     {
322                         bDisable = sal_True;
323                     }
324                 }
325                 break;
326 		}
327 		if (!bDisable && bNeedEdit)
328 			if (!pDoc->IsBlockEditable( aCursor.Tab(), aCursor.Col(),aCursor.Row(),
329 										aCursor.Col(),aCursor.Row() ))
330 				bDisable = sal_True;
331 		if (bDisable)
332 			rSet.DisableItem(nWhich);
333 		nWhich = aIter.NextWhich();
334 	}
335 }
336 
337 sal_Bool lcl_TestFormat( SvxClipboardFmtItem& rFormats, const TransferableDataHelper& rDataHelper,
338 						SotFormatStringId nFormatId )
339 {
340 	if ( rDataHelper.HasFormat( nFormatId ) )
341 	{
342 		//	#90675# translated format name strings are no longer inserted here,
343 		//	handled by "paste special" dialog / toolbox controller instead.
344 		//	Only the object type name has to be set here:
345 		String aStrVal;
346 		if ( nFormatId == SOT_FORMATSTR_ID_EMBED_SOURCE )
347 		{
348 			TransferableObjectDescriptor aDesc;
349 			if ( ((TransferableDataHelper&)rDataHelper).GetTransferableObjectDescriptor(
350 										SOT_FORMATSTR_ID_OBJECTDESCRIPTOR, aDesc ) )
351 				aStrVal = aDesc.maTypeName;
352 		}
353 		else if ( nFormatId == SOT_FORMATSTR_ID_EMBED_SOURCE_OLE
354 		  || nFormatId == SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE )
355 		{
356 			String aSource;
357             SvPasteObjectHelper::GetEmbeddedName( rDataHelper, aStrVal, aSource, nFormatId );
358 		}
359 
360 		if ( aStrVal.Len() )
361 			rFormats.AddClipbrdFormat( nFormatId, aStrVal );
362 		else
363 			rFormats.AddClipbrdFormat( nFormatId );
364 
365 		return sal_True;
366 	}
367 
368 	return sal_False;
369 }
370 
371 void ScCellShell::GetPossibleClipboardFormats( SvxClipboardFmtItem& rFormats )
372 {
373 	Window* pWin = GetViewData()->GetActiveWin();
374 	sal_Bool bDraw = ( ScDrawTransferObj::GetOwnClipboard( pWin ) != NULL );
375 
376 	TransferableDataHelper aDataHelper( TransferableDataHelper::CreateFromSystemClipboard( pWin ) );
377 
378 	lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_DRAWING );
379 	lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_SVXB );
380 	lcl_TestFormat( rFormats, aDataHelper, SOT_FORMAT_GDIMETAFILE );
381 	lcl_TestFormat( rFormats, aDataHelper, SOT_FORMAT_BITMAP );
382 	lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_EMBED_SOURCE );
383 
384 	if ( !bDraw )
385 	{
386 		lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_LINK );
387 		lcl_TestFormat( rFormats, aDataHelper, SOT_FORMAT_STRING );
388 		lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_DIF );
389 		lcl_TestFormat( rFormats, aDataHelper, SOT_FORMAT_RTF );
390 		lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_HTML );
391 		lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_HTML_SIMPLE );
392         lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_BIFF_8 );
393 		lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_BIFF_5 );
394 	}
395 
396 	if ( !lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_EMBED_SOURCE_OLE ) )
397 		lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE );
398 }
399 
400 //	Einfuegen, Inhalte einfuegen
401 
402 sal_Bool lcl_IsCellPastePossible( const TransferableDataHelper& rData )
403 {
404 	sal_Bool bPossible = sal_False;
405 	if ( ScTransferObj::GetOwnClipboard( NULL ) || ScDrawTransferObj::GetOwnClipboard( NULL ) )
406 		bPossible = sal_True;
407 	else
408 	{
409 		if ( rData.HasFormat( SOT_FORMAT_BITMAP ) ||
410 			 rData.HasFormat( SOT_FORMAT_GDIMETAFILE ) ||
411 			 rData.HasFormat( SOT_FORMATSTR_ID_SVXB ) ||
412 			 rData.HasFormat( FORMAT_PRIVATE ) ||
413 			 rData.HasFormat( SOT_FORMAT_RTF ) ||
414 			 rData.HasFormat( SOT_FORMATSTR_ID_EMBED_SOURCE ) ||
415 			 rData.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE ) ||
416 			 rData.HasFormat( SOT_FORMATSTR_ID_EMBED_SOURCE_OLE ) ||
417 			 rData.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE_OLE ) ||
418 			 rData.HasFormat( SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE ) ||
419 			 rData.HasFormat( SOT_FORMAT_STRING ) ||
420 			 rData.HasFormat( SOT_FORMATSTR_ID_SYLK ) ||
421 			 rData.HasFormat( SOT_FORMATSTR_ID_LINK ) ||
422 			 rData.HasFormat( SOT_FORMATSTR_ID_HTML ) ||
423 			 rData.HasFormat( SOT_FORMATSTR_ID_HTML_SIMPLE ) ||
424 			 rData.HasFormat( SOT_FORMATSTR_ID_DIF ) )
425 		{
426 			bPossible = sal_True;
427 		}
428 	}
429 	return bPossible;
430 }
431 
432 IMPL_LINK( ScCellShell, ClipboardChanged, TransferableDataHelper*, pDataHelper )
433 {
434 	if ( pDataHelper )
435 	{
436 		bPastePossible = lcl_IsCellPastePossible( *pDataHelper );
437 
438 		SfxBindings& rBindings = GetViewData()->GetBindings();
439 		rBindings.Invalidate( SID_PASTE );
440         rBindings.Invalidate( SID_PASTE_SPECIAL );
441 		rBindings.Invalidate( SID_CLIPBOARD_FORMAT_ITEMS );
442 	}
443 	return 0;
444 }
445 
446 
447 void __EXPORT ScCellShell::GetClipState( SfxItemSet& rSet )
448 {
449 // SID_PASTE
450 // SID_PASTE_SPECIAL
451 // SID_CLIPBOARD_FORMAT_ITEMS
452 
453     if ( !pImpl->m_pClipEvtLstnr )
454 	{
455 		// create listener
456         pImpl->m_pClipEvtLstnr = new TransferableClipboardListener( LINK( this, ScCellShell, ClipboardChanged ) );
457         pImpl->m_pClipEvtLstnr->acquire();
458 		Window* pWin = GetViewData()->GetActiveWin();
459         pImpl->m_pClipEvtLstnr->AddRemoveListener( pWin, sal_True );
460 
461 		// get initial state
462 		TransferableDataHelper aDataHelper( TransferableDataHelper::CreateFromSystemClipboard( pWin ) );
463 		bPastePossible = lcl_IsCellPastePossible( aDataHelper );
464 	}
465 
466 	sal_Bool bDisable = !bPastePossible;
467 
468 	//	Zellschutz / Multiselektion
469 
470 	if (!bDisable)
471 	{
472 		SCCOL nCol = GetViewData()->GetCurX();
473 		SCROW nRow = GetViewData()->GetCurY();
474 		SCTAB nTab = GetViewData()->GetTabNo();
475 		ScDocument* pDoc = GetViewData()->GetDocShell()->GetDocument();
476 		if (!pDoc->IsBlockEditable( nTab, nCol,nRow, nCol,nRow ))
477 			bDisable = sal_True;
478         ScRange aDummy;
479         ScMarkType eMarkType = GetViewData()->GetSimpleArea( aDummy);
480         if (eMarkType != SC_MARK_SIMPLE && eMarkType != SC_MARK_SIMPLE_FILTERED)
481 			bDisable = sal_True;
482 	}
483 
484 	if (bDisable)
485 	{
486 		rSet.DisableItem( SID_PASTE );
487         rSet.DisableItem( SID_PASTE_SPECIAL );
488 		rSet.DisableItem( SID_CLIPBOARD_FORMAT_ITEMS );
489 	}
490 	else if ( rSet.GetItemState( SID_CLIPBOARD_FORMAT_ITEMS ) != SFX_ITEM_UNKNOWN )
491 	{
492 		SvxClipboardFmtItem aFormats( SID_CLIPBOARD_FORMAT_ITEMS );
493 		GetPossibleClipboardFormats( aFormats );
494 		rSet.Put( aFormats );
495 	}
496 }
497 
498 //	only SID_HYPERLINK_GETLINK:
499 
500 void ScCellShell::GetHLinkState( SfxItemSet& rSet )
501 {
502 	//	always return an item (or inserting will be disabled)
503 	//	if the cell at the cursor contains only a link, return that link
504 
505 	SvxHyperlinkItem aHLinkItem;
506 	if ( !GetViewData()->GetView()->HasBookmarkAtCursor( &aHLinkItem ) )
507 	{
508 		//!	put selected text into item?
509 	}
510 
511 	rSet.Put(aHLinkItem);
512 }
513 
514 void ScCellShell::GetState(SfxItemSet &rSet)
515 {
516 	// removed: SID_BORDER_OBJECT (old Basic)
517 
518 	ScTabViewShell*	pTabViewShell  	= GetViewData()->GetViewShell();
519 //     sal_Bool bOle = pTabViewShell->GetViewFrame()->GetFrame().IsInPlace();
520 // 	sal_Bool bTabProt = GetViewData()->GetDocument()->IsTabProtected(GetViewData()->GetTabNo());
521 	ScDocShell* pDocSh = GetViewData()->GetDocShell();
522     ScViewData* pData       = GetViewData();
523 	ScDocument* pDoc		= pData->GetDocument();
524 	ScMarkData& rMark		= pData->GetMarkData();
525 	SCCOL		nPosX		= pData->GetCurX();
526 	SCROW		nPosY		= pData->GetCurY();
527 	SCTAB		nTab		= pData->GetTabNo();
528 
529 	SCTAB nTabCount = pDoc->GetTableCount();
530 	SCTAB nTabSelCount = rMark.GetSelectCount();
531 
532 
533 
534 	SfxWhichIter aIter(rSet);
535 	sal_uInt16 nWhich = aIter.FirstWhich();
536 	while ( nWhich )
537 	{
538 		switch ( nWhich )
539 		{
540 			case SID_DETECTIVE_REFRESH:
541 				if (!pDoc->HasDetectiveOperations())
542 					rSet.DisableItem( nWhich );
543 				break;
544 
545 			case SID_RANGE_ADDRESS:
546 				{
547 					ScRange aRange;
548 					if ( pData->GetSimpleArea( aRange ) == SC_MARK_SIMPLE )
549 					{
550 						String aStr;
551 						sal_uInt16 nFlags = SCA_VALID | SCA_TAB_3D;
552 						aRange.Format(aStr,nFlags,pDoc);
553 						rSet.Put( SfxStringItem( nWhich, aStr ) );
554 					}
555 				}
556 				break;
557 
558 			case SID_RANGE_NOTETEXT:
559 				{
560 					//	#43343# always take cursor position, do not use top-left cell of selection
561 					ScAddress aPos( nPosX, nPosY, nTab );
562 					String aNoteText;
563 					if ( const ScPostIt* pNote = pDoc->GetNote( aPos ) )
564                         aNoteText = pNote->GetText();
565 					rSet.Put( SfxStringItem( nWhich, aNoteText ) );
566 				}
567 				break;
568 
569 			case SID_RANGE_ROW:
570 				rSet.Put( SfxInt32Item( nWhich, nPosY+1 ) );
571 				break;
572 
573 			case SID_RANGE_COL:
574 				rSet.Put( SfxInt16Item( nWhich, nPosX+1 ) );
575 				break;
576 
577 			case SID_RANGE_TABLE:
578 				rSet.Put( SfxInt16Item( nWhich, nTab+1 ) );
579 				break;
580 
581 			case SID_RANGE_VALUE:
582 				{
583 					double nValue;
584 					pDoc->GetValue( nPosX, nPosY, nTab, nValue );
585 					rSet.Put( ScDoubleItem( nWhich, nValue ) );
586 				}
587 				break;
588 
589 			case SID_RANGE_FORMULA:
590 				{
591 					String aString;
592 					pDoc->GetFormula( nPosX, nPosY, nTab, aString );
593 					if( aString.Len() == 0 )
594 					{
595 						pDoc->GetInputString( nPosX, nPosY, nTab, aString );
596 					}
597 					rSet.Put( SfxStringItem( nWhich, aString ) );
598 				}
599 				break;
600 
601 			case SID_RANGE_TEXTVALUE:
602 				{
603 					String aString;
604 					pDoc->GetString( nPosX, nPosY, nTab, aString );
605 					rSet.Put( SfxStringItem( nWhich, aString ) );
606 				}
607 				break;
608 
609 			case SID_STATUS_SELMODE:
610 				{
611 					/* 0: STD	Click hebt Sel auf
612 					 * 1: ER	Click erweitert Selektion
613 					 * 2: ERG	Click definiert weitere Selektion
614 					 */
615 					sal_uInt16 nMode = pTabViewShell->GetLockedModifiers();
616 
617 					switch ( nMode )
618 					{
619 						case KEY_SHIFT: nMode = 1;	break;
620 						case KEY_MOD1:	nMode = 2;	break; // Control-Taste
621 						case 0:
622 						default:
623 							nMode = 0;
624 					}
625 
626 					rSet.Put( SfxUInt16Item( nWhich, nMode ) );
627 				}
628 				break;
629 
630 			case SID_STATUS_DOCPOS:
631 				{
632 					String	aStr( ScGlobal::GetRscString( STR_TABLE ) );
633 
634 					aStr += ' ';
635 					aStr += String::CreateFromInt32( nTab + 1 );
636 					aStr.AppendAscii(RTL_CONSTASCII_STRINGPARAM( " / " ));
637 					aStr += String::CreateFromInt32( nTabCount );
638 					rSet.Put( SfxStringItem( nWhich, aStr ) );
639 				}
640 				break;
641 
642 			//	Summe etc. mit Datum/Zeit/Fehler/Pos&Groesse zusammengefasst
643 
644             // #i34458# The SfxStringItem belongs only into SID_TABLE_CELL. It no longer has to be
645             // duplicated in SID_ATTR_POSITION or SID_ATTR_SIZE for SvxPosSizeStatusBarControl.
646 			case SID_TABLE_CELL:
647 				{
648 					//	Testen, ob Fehler unter Cursor
649 					//	(nicht pDoc->GetErrCode, um keine zirkulaeren Referenzen auszuloesen)
650 
651 					// In interpreter may happen via rescheduled Basic
652 					if ( pDoc->IsInInterpreter() )
653 						rSet.Put( SfxStringItem( nWhich,
654 							String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("...")) ) );
655 					else
656 					{
657 						sal_uInt16 nErrCode = 0;
658 						ScBaseCell* pCell;
659 						pDoc->GetCell( nPosX, nPosY, nTab, pCell );
660 						if ( pCell && pCell->GetCellType() == CELLTYPE_FORMULA )
661 						{
662 							ScFormulaCell* pFCell = (ScFormulaCell*) pCell;
663 							if (!pFCell->IsRunning())
664 								nErrCode = pFCell->GetErrCode();
665 						}
666 
667                         String aFuncStr;
668                         if ( pTabViewShell->GetFunction( aFuncStr, nErrCode ) )
669                             rSet.Put( SfxStringItem( nWhich, aFuncStr ) );
670 					}
671 				}
672 				break;
673 
674 			case SID_DATA_SELECT:
675                 // HasSelectionData includes column content and validity,
676                 // page fields have to be checked separately.
677                 if ( !pDoc->HasSelectionData( nPosX, nPosY, nTab ) &&
678                      !pTabViewShell->HasPageFieldDataAtCursor() )
679 					rSet.DisableItem( nWhich );
680 				break;
681 
682 			case SID_STATUS_SUM:
683 				{
684 					String aFuncStr;
685 					if ( pTabViewShell->GetFunction( aFuncStr ) )
686 						rSet.Put( SfxStringItem( nWhich, aFuncStr ) );
687 				}
688 				break;
689 
690 			case FID_MERGE_ON:
691 				if ( pDoc->GetChangeTrack() || !pTabViewShell->TestMergeCells() )
692 					rSet.DisableItem( nWhich );
693 				break;
694 
695 			case FID_MERGE_OFF:
696 				if ( pDoc->GetChangeTrack() || !pTabViewShell->TestRemoveMerge() )
697 					rSet.DisableItem( nWhich );
698 				break;
699 
700             case FID_MERGE_TOGGLE:
701                 if ( pDoc->GetChangeTrack() )
702                     rSet.DisableItem( nWhich );
703                 else
704                 {
705                     bool bCanMerge = pTabViewShell->TestMergeCells();
706                     bool bCanSplit = pTabViewShell->TestRemoveMerge();
707                     if( !bCanMerge && !bCanSplit )
708                         rSet.DisableItem( nWhich );
709                     else
710                         rSet.Put( SfxBoolItem( nWhich, bCanSplit ) );
711                 }
712                 break;
713 
714 			case FID_INS_ROWBRK:
715                 if ( nPosY==0 || (pDoc->HasRowBreak(nPosY, nTab) & BREAK_MANUAL) )
716 					rSet.DisableItem( nWhich );
717 				break;
718 
719 			case FID_INS_COLBRK:
720                 if ( nPosX==0 || (pDoc->HasColBreak(nPosX, nTab) & BREAK_MANUAL) )
721 					rSet.DisableItem( nWhich );
722 				break;
723 
724 			case FID_DEL_ROWBRK:
725                 if ( nPosY==0 || (pDoc->HasRowBreak(nPosY, nTab) & BREAK_MANUAL) == 0 )
726 					rSet.DisableItem( nWhich );
727 				break;
728 
729 			case FID_DEL_COLBRK:
730                 if ( nPosX==0 || (pDoc->HasColBreak(nPosX, nTab) & BREAK_MANUAL) == 0 )
731 					rSet.DisableItem( nWhich );
732 				break;
733 
734 			case FID_FILL_TAB:
735 				if ( nTabSelCount < 2 )
736 					rSet.DisableItem( nWhich );
737 				break;
738 
739 			case SID_SELECT_SCENARIO:
740 				{
741                     // ScDocument* pDoc = GetViewData()->GetDocument();
742                     // SCTAB       nTab = GetViewData()->GetTabNo();
743 					List		aList;
744 
745 					Color	aDummyCol;
746 
747 					if ( !pDoc->IsScenario(nTab) )
748 					{
749 						String aStr;
750 						sal_uInt16 nFlags;
751 						SCTAB nScTab = nTab + 1;
752 						String aProtect;
753 						bool bSheetProtected = pDoc->IsTabProtected(nTab);
754 
755 						while ( pDoc->IsScenario(nScTab) )
756 						{
757 							pDoc->GetName( nScTab, aStr );
758 							aList.Insert( new String( aStr ), LIST_APPEND );
759 							pDoc->GetScenarioData( nScTab, aStr, aDummyCol, nFlags );
760 							aList.Insert( new String( aStr ), LIST_APPEND );
761 							// Protection is sal_True if both Sheet and Scenario are protected
762 							aProtect = (bSheetProtected && (nFlags & SC_SCENARIO_PROTECT)) ? '1' : '0';
763 							aList.Insert( new String( aProtect), LIST_APPEND );
764 							++nScTab;
765 						}
766 					}
767 					else
768 					{
769 						String	aComment;
770 						sal_uInt16	nDummyFlags;
771 						pDoc->GetScenarioData( nTab, aComment, aDummyCol, nDummyFlags );
772 						DBG_ASSERT( aList.Count() == 0, "List not empty!" );
773 						aList.Insert( new String( aComment ) );
774 					}
775 
776 					rSet.Put( SfxStringListItem( nWhich, &aList ) );
777 
778 					sal_uLong nCount = aList.Count();
779 					for ( sal_uLong i=0; i<nCount; i++ )
780 						delete (String*) aList.GetObject(i);
781 				}
782 				break;
783 
784 			case FID_ROW_HIDE:
785 			case FID_ROW_SHOW:
786 			case FID_COL_HIDE:
787 			case FID_COL_SHOW:
788 			case FID_COL_OPT_WIDTH:
789 			case FID_ROW_OPT_HEIGHT:
790 			case FID_DELETE_CELL:
791 				if ( pDoc->IsTabProtected(nTab) || pDocSh->IsReadOnly())
792 					rSet.DisableItem( nWhich );
793 				break;
794 
795 /*	Zellschutz bei selektierten Zellen wird bei anderen Funktionen auch nicht abgefragt...
796 			case SID_DELETE:
797 				{
798 					if ( pDoc->IsTabProtected(nTab) )
799 					{
800 						const SfxItemSet&		rAttrSet  = GetSelectionPattern()->GetItemSet();
801 						const ScProtectionAttr& rProtAttr = (const ScProtectionAttr&)rAttrSet.Get( ATTR_PROTECTION, sal_True );
802 						if ( rProtAttr.GetProtection() )
803 							rSet.DisableItem( nWhich );
804 					}
805 				}
806 				break;
807 */
808 			case SID_OUTLINE_MAKE:
809 				{
810     				if ( GetViewData()->GetDocument()->GetDPAtCursor( GetViewData()->GetCurX(),
811                 							GetViewData()->GetCurY(), GetViewData()->GetTabNo() ) )
812                     {
813                         //! test for data pilot operation
814                     }
815 					else if (pDoc->GetChangeTrack()!=NULL || GetViewData()->IsMultiMarked())
816 					{
817 						rSet.DisableItem( nWhich );
818 					}
819 				}
820 				break;
821 			case SID_OUTLINE_SHOW:
822 				if ( GetViewData()->GetDocument()->GetDPAtCursor( GetViewData()->GetCurX(),
823             							GetViewData()->GetCurY(), GetViewData()->GetTabNo() ) )
824                 {
825                     //! test for data pilot operation
826                 }
827 				else if (!pTabViewShell->OutlinePossible(sal_False))
828 					rSet.DisableItem( nWhich );
829 				break;
830 
831 			case SID_OUTLINE_HIDE:
832 				if ( GetViewData()->GetDocument()->GetDPAtCursor( GetViewData()->GetCurX(),
833             							GetViewData()->GetCurY(), GetViewData()->GetTabNo() ) )
834                 {
835                     //! test for data pilot operation
836                 }
837 				else if (!pTabViewShell->OutlinePossible(sal_True))
838 					rSet.DisableItem( nWhich );
839 				break;
840 
841 			case SID_OUTLINE_REMOVE:
842 				{
843     				if ( GetViewData()->GetDocument()->GetDPAtCursor( GetViewData()->GetCurX(),
844                 							GetViewData()->GetCurY(), GetViewData()->GetTabNo() ) )
845                     {
846                         //! test for data pilot operation
847                     }
848                     else
849                     {
850     					sal_Bool bCol, bRow;
851     					pTabViewShell->TestRemoveOutline( bCol, bRow );
852     					if ( !bCol && !bRow )
853     						rSet.DisableItem( nWhich );
854                     }
855 				}
856 				break;
857 
858 			case FID_COL_WIDTH:
859 				{
860 					//GetViewData()->GetCurX();
861 					SfxUInt16Item aWidthItem( FID_COL_WIDTH, pDoc->GetColWidth( nPosX , nTab) );
862 					rSet.Put( aWidthItem );
863 					if ( pDocSh->IsReadOnly())
864 						rSet.DisableItem( nWhich );
865 
866 					//XXX Disablen wenn nicht eindeutig
867 				}
868 				break;
869 
870 			case FID_ROW_HEIGHT:
871 				{
872 					//GetViewData()->GetCurY();
873 					SfxUInt16Item aHeightItem( FID_ROW_HEIGHT, pDoc->GetRowHeight( nPosY , nTab) );
874 					rSet.Put( aHeightItem );
875 					//XXX Disablen wenn nicht eindeutig
876 					if ( pDocSh->IsReadOnly())
877 						rSet.DisableItem( nWhich );
878 				}
879 				break;
880 
881 			case SID_DETECTIVE_FILLMODE:
882 				rSet.Put(SfxBoolItem( nWhich, pTabViewShell->IsAuditShell() ));
883 				break;
884 
885 			case FID_INPUTLINE_STATUS:
886 				DBG_ERROR( "Old update method. Use ScTabViewShell::UpdateInputHandler()." );
887 				break;
888 
889 			case SID_SCENARIOS:										// Szenarios:
890 				if (!(rMark.IsMarked() || rMark.IsMultiMarked()))	// nur, wenn etwas selektiert
891 					rSet.DisableItem( nWhich );
892 				break;
893 
894 			case FID_NOTE_VISIBLE:
895 				{
896                     const ScPostIt* pNote = pDoc->GetNote( ScAddress( nPosX, nPosY, nTab ) );
897 					if ( pNote && pDoc->IsBlockEditable( nTab, nPosX,nPosY, nPosX,nPosY ) )
898 						rSet.Put( SfxBoolItem( nWhich, pNote->IsCaptionShown() ) );
899 					else
900 						rSet.DisableItem( nWhich );
901 				}
902 				break;
903 
904             case SID_DELETE_NOTE:
905                 {
906                     sal_Bool bEnable = sal_False;
907                     if ( rMark.IsMarked() || rMark.IsMultiMarked() )
908                     {
909                         if ( pDoc->IsSelectionEditable( rMark ) )
910                         {
911                             // look for at least one note in selection
912                             ScRangeList aRanges;
913                             rMark.FillRangeListWithMarks( &aRanges, sal_False );
914                             sal_uLong nCount = aRanges.Count();
915                             for (sal_uLong nPos=0; nPos<nCount && !bEnable; nPos++)
916                             {
917                                 ScCellIterator aCellIter( pDoc, *aRanges.GetObject(nPos) );
918                                 for( ScBaseCell* pCell = aCellIter.GetFirst(); pCell && !bEnable; pCell = aCellIter.GetNext() )
919                                     if ( pCell->HasNote() )
920                                         bEnable = sal_True;             // note found
921                             }
922                         }
923                     }
924                     else
925                     {
926                         bEnable = pDoc->IsBlockEditable( nTab, nPosX,nPosY, nPosX,nPosY ) &&
927                                   pDoc->GetNote( ScAddress( nPosX, nPosY, nTab ) );
928                     }
929                     if ( !bEnable )
930                         rSet.DisableItem( nWhich );
931                 }
932                 break;
933 
934 			case SID_OPENDLG_CONSOLIDATE:
935 			case SCITEM_CONSOLIDATEDATA:
936 				{
937 					if(pDoc->GetChangeTrack()!=NULL)
938 								rSet.DisableItem( nWhich);
939 				}
940 				break;
941 
942             case SID_CHINESE_CONVERSION:
943             case SID_HANGUL_HANJA_CONVERSION:
944                 ScViewUtil::HideDisabledSlot( rSet, pData->GetBindings(), nWhich );
945             break;
946 
947             case FID_USE_NAME:
948                 {
949                     if ( pDocSh && pDocSh->IsDocShared() )
950                         rSet.DisableItem( nWhich );
951                     else
952                     {
953                         ScRange aRange;
954                         if ( pData->GetSimpleArea( aRange ) != SC_MARK_SIMPLE )
955                             rSet.DisableItem( nWhich );
956                     }
957                 }
958                 break;
959 
960             case FID_DEFINE_NAME:
961             case FID_INSERT_NAME:
962             case SID_DEFINE_COLROWNAMERANGES:
963                 {
964                     if ( pDocSh && pDocSh->IsDocShared() )
965                     {
966                         rSet.DisableItem( nWhich );
967                     }
968                 }
969                 break;
970 
971             case SID_SPELL_DIALOG:
972                 {
973                     if ( pDoc && pData && pDoc->IsTabProtected( pData->GetTabNo() ) )
974                     {
975                         bool bVisible = false;
976                         SfxViewFrame* pViewFrame = ( pTabViewShell ? pTabViewShell->GetViewFrame() : NULL );
977                         if ( pViewFrame && pViewFrame->HasChildWindow( nWhich ) )
978                         {
979                             SfxChildWindow* pChild = pViewFrame->GetChildWindow( nWhich );
980                             Window* pWin = ( pChild ? pChild->GetWindow() : NULL );
981                             if ( pWin && pWin->IsVisible() )
982                             {
983                                 bVisible = true;
984                             }
985                         }
986                         if ( !bVisible )
987                         {
988                             rSet.DisableItem( nWhich );
989                         }
990                     }
991                 }
992                 break;
993 
994 		} // switch ( nWitch )
995 		nWhich = aIter.NextWhich();
996 	} // while ( nWitch )
997 }
998 
999 //------------------------------------------------------------------
1000 
1001 
1002 
1003