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