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