/**************************************************************
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
 *************************************************************/



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sc.hxx"

//------------------------------------------------------------------

#include "scitems.hxx"

#include <svl/slstitm.hxx>
#include <svl/stritem.hxx>
#include <svl/whiter.hxx>
#include <unotools/moduleoptions.hxx>
#include <svtools/cliplistener.hxx>
#include <svtools/insdlg.hxx>
#include <sot/formats.hxx>
#include <svx/hlnkitem.hxx>
#include <sfx2/app.hxx>
#include <sfx2/bindings.hxx>
#include <sfx2/childwin.hxx>
#include <sfx2/objface.hxx>
#include <sfx2/request.hxx>
#include <sfx2/viewfrm.hxx>
#include <sfx2/sidebar/EnumContext.hxx>
#include <svx/clipfmtitem.hxx>
#include <svx/sidebar/ContextChangeEventMultiplexer.hxx>
#include <editeng/langitem.hxx>

#include "cellsh.hxx"
#include "sc.hrc"
#include "docsh.hxx"
#include "attrib.hxx"
#include "scresid.hxx"
#include "tabvwsh.hxx"
#include "impex.hxx"
#include "cell.hxx"
#include "scmod.hxx"
#include "globstr.hrc"
#include "transobj.hxx"
#include "drwtrans.hxx"
#include "scabstdlg.hxx"
#include "dociter.hxx"
#include "postit.hxx"

//------------------------------------------------------------------

#define ScCellShell
#define	CellMovement
#include "scslots.hxx"

TYPEINIT1( ScCellShell, ScFormatShell );

SFX_IMPL_INTERFACE(ScCellShell, ScFormatShell , ScResId(SCSTR_CELLSHELL) )
{
	SFX_OBJECTBAR_REGISTRATION( SFX_OBJECTBAR_OBJECT | SFX_VISIBILITY_STANDARD |
								SFX_VISIBILITY_SERVER,
								ScResId(RID_OBJECTBAR_FORMAT));
	SFX_POPUPMENU_REGISTRATION(ScResId(RID_POPUP_CELLS));
}


ScCellShell::ScCellShell(ScViewData* pData) :
	ScFormatShell(pData),
    pImpl( new CellShell_Impl() ),
	bPastePossible(sal_False)
{
	SetHelpId(HID_SCSHELL_CELLSH);
	SetName(String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("Cell")));
    SfxShell::SetContextName(sfx2::sidebar::EnumContext::GetContextName(sfx2::sidebar::EnumContext::Context_Cell));
}

ScCellShell::~ScCellShell()
{
    if ( pImpl->m_pClipEvtLstnr )
	{
        pImpl->m_pClipEvtLstnr->AddRemoveListener( GetViewData()->GetActiveWin(), sal_False );

		//  #103849# The listener may just now be waiting for the SolarMutex and call the link
		//  afterwards, in spite of RemoveListener. So the link has to be reset, too.
        pImpl->m_pClipEvtLstnr->ClearCallbackLink();

        pImpl->m_pClipEvtLstnr->release();
	}

    delete pImpl->m_pLinkedDlg;
    delete pImpl->m_pRequest;
    delete pImpl;
}

//------------------------------------------------------------------

void ScCellShell::GetBlockState( SfxItemSet& rSet )
{
	ScTabViewShell*	pTabViewShell  	= GetViewData()->GetViewShell();
	ScRange aMarkRange;
    ScMarkType eMarkType = GetViewData()->GetSimpleArea( aMarkRange );
	sal_Bool bSimpleArea = (eMarkType == SC_MARK_SIMPLE);
	sal_Bool bOnlyNotBecauseOfMatrix;
	sal_Bool bEditable = pTabViewShell->SelectionEditable( &bOnlyNotBecauseOfMatrix );
	ScDocument* pDoc = GetViewData()->GetDocument();
    ScDocShell* pDocShell = GetViewData()->GetDocShell();
    ScMarkData& rMark = GetViewData()->GetMarkData();
	SCCOL nCol1, nCol2;
	SCROW nRow1, nRow2;
	nCol1 = aMarkRange.aStart.Col();
	nRow1 = aMarkRange.aStart.Row();
	nCol2 = aMarkRange.aEnd.Col();
	nRow2 = aMarkRange.aEnd.Row();

	SfxWhichIter aIter(rSet);
	sal_uInt16 nWhich = aIter.FirstWhich();
	while ( nWhich )
	{
		sal_Bool bDisable = sal_False;
		sal_Bool bNeedEdit = sal_True;		// muss Selektion editierbar sein?
		switch ( nWhich )
		{
			case FID_FILL_TO_BOTTOM:	// Fuellen oben/unten
			case FID_FILL_TO_TOP:		// mind. 2 Zeilen markiert?
				bDisable = (!bSimpleArea) || (nRow1 == nRow2);
				if ( !bDisable && bEditable )
				{	// Matrix nicht zerreissen
					if ( nWhich == FID_FILL_TO_BOTTOM )
						bDisable = pDoc->HasSelectedBlockMatrixFragment(
							nCol1, nRow1, nCol2, nRow1, rMark );	// erste Zeile
					else
						bDisable = pDoc->HasSelectedBlockMatrixFragment(
							nCol1, nRow2, nCol2, nRow2, rMark );	// letzte Zeile
				}
				break;

			case FID_FILL_TO_RIGHT:		// Fuellen links/rechts
			case FID_FILL_TO_LEFT:		// mind. 2 Spalten markiert?
				bDisable = (!bSimpleArea) || (nCol1 == nCol2);
				if ( !bDisable && bEditable )
				{	// Matrix nicht zerreissen
					if ( nWhich == FID_FILL_TO_RIGHT )
						bDisable = pDoc->HasSelectedBlockMatrixFragment(
							nCol1, nRow1, nCol1, nRow2, rMark );	// erste Spalte
					else
						bDisable = pDoc->HasSelectedBlockMatrixFragment(
							nCol2, nRow1, nCol2, nRow2, rMark );	// letzte Spalte
				}
				break;

			case FID_FILL_SERIES:		// Block fuellen
			case SID_OPENDLG_TABOP:		// Mehrfachoperationen, mind. 2 Zellen markiert?
				if (pDoc->GetChangeTrack()!=NULL &&nWhich ==SID_OPENDLG_TABOP)
					bDisable = sal_True;
				else
					bDisable = (!bSimpleArea) || (nCol1 == nCol2 && nRow1 == nRow2);

				if ( !bDisable && bEditable && nWhich == FID_FILL_SERIES )
				{	// Matrix nicht zerreissen
					bDisable = pDoc->HasSelectedBlockMatrixFragment(
							nCol1, nRow1, nCol2, nRow1, rMark )	// erste Zeile
						||	pDoc->HasSelectedBlockMatrixFragment(
							nCol1, nRow2, nCol2, nRow2, rMark )	// letzte Zeile
						||	pDoc->HasSelectedBlockMatrixFragment(
							nCol1, nRow1, nCol1, nRow2, rMark )	// erste Spalte
						||	pDoc->HasSelectedBlockMatrixFragment(
							nCol2, nRow1, nCol2, nRow2, rMark );	// letzte Spalte
				}
				break;

			case SID_CUT:				// Ausschneiden,
			case FID_INS_CELL:			// Zellen einfuegen, nur einf. Selektion
				bDisable = (!bSimpleArea);
				break;

            case FID_INS_ROW:           // insert rows
            case FID_INS_CELLSDOWN:
                bDisable = (!bSimpleArea) || GetViewData()->SimpleColMarked();
                break;

            case FID_INS_COLUMN:        // insert columns
            case FID_INS_CELLSRIGHT:
                bDisable = (!bSimpleArea) || GetViewData()->SimpleRowMarked();
                break;

			case SID_COPY:						// Kopieren
				// nur wegen Matrix nicht editierbar? Matrix nicht zerreissen
				//! schlaegt nicht zu, wenn geschuetzt UND Matrix, aber damit
				//! muss man leben.. wird in Copy-Routine abgefangen, sonst
				//! muesste hier nochmal Aufwand getrieben werden
				if ( !(!bEditable && bOnlyNotBecauseOfMatrix) )
					bNeedEdit = sal_False;			// erlaubt, wenn geschuetzt/ReadOnly
				break;

			case SID_AUTOFORMAT:		// Autoformat, mind. 3x3 selektiert
				bDisable =    (!bSimpleArea)
						   || ((nCol2 - nCol1) < 2) || ((nRow2 - nRow1) < 2);
				break;

			case SID_OPENDLG_CONDFRMT :
                {
                    if ( !bEditable && bOnlyNotBecauseOfMatrix )
                    {
                        bNeedEdit = sal_False;
                    }
                    if ( pDocShell && pDocShell->IsDocShared() )
                    {
                        bDisable = sal_True;
                    }
                }
                break;

			case FID_CONDITIONAL_FORMAT :
			case SID_CELL_FORMAT_RESET :
			case FID_CELL_FORMAT :
			case SID_ENABLE_HYPHENATION :
				// nur wegen Matrix nicht editierbar? Attribute trotzdem ok
				if ( !bEditable && bOnlyNotBecauseOfMatrix )
					bNeedEdit = sal_False;
				break;

            case FID_VALIDATION:
                {
                    if ( pDocShell && pDocShell->IsDocShared() )
                    {
                        bDisable = sal_True;
                    }
                }
                break;

			case SID_TRANSLITERATE_HALFWIDTH:
			case SID_TRANSLITERATE_FULLWIDTH:
			case SID_TRANSLITERATE_HIRAGANA:
			case SID_TRANSLITERATE_KATAGANA:
                ScViewUtil::HideDisabledSlot( rSet, GetViewData()->GetBindings(), nWhich );
            break;
		}
		if (!bDisable && bNeedEdit && !bEditable)
			bDisable = sal_True;

		if (bDisable)
			rSet.DisableItem(nWhich);
		else if (nWhich == SID_ENABLE_HYPHENATION)
		{
			// toggle slots need a bool item
			rSet.Put( SfxBoolItem( nWhich, sal_False ) );
		}
		nWhich = aIter.NextWhich();
	}
}

//	Funktionen, die je nach Cursorposition disabled sind
//	Default:
//		SID_INSERT_POSTIT, SID_CHARMAP, SID_OPENDLG_FUNCTION

void ScCellShell::GetCellState( SfxItemSet& rSet )
{
    ScDocShell* pDocShell = GetViewData()->GetDocShell();
	ScDocument* pDoc = GetViewData()->GetDocShell()->GetDocument();
	ScAddress aCursor( GetViewData()->GetCurX(), GetViewData()->GetCurY(),
						GetViewData()->GetTabNo() );

	SfxWhichIter aIter(rSet);
	sal_uInt16 nWhich = aIter.FirstWhich();
	while ( nWhich )
	{
		sal_Bool bDisable = sal_False;
		sal_Bool bNeedEdit = sal_True;		// muss Cursorposition editierbar sein?
		switch ( nWhich )
		{
            case SID_THESAURUS:
				{
					CellType eType = pDoc->GetCellType( aCursor );
					bDisable = ( eType != CELLTYPE_STRING && eType != CELLTYPE_EDIT);
					if (!bDisable)
					{
						//	test for available languages
						sal_uInt16 nLang = ScViewUtil::GetEffLanguage( pDoc, aCursor );
						bDisable = !ScModule::HasThesaurusLanguage( nLang );
					}
				}
				break;
			case SID_OPENDLG_FUNCTION:
				{
					ScMarkData aMarkData=GetViewData()->GetMarkData();
					aMarkData.MarkToSimple();
					ScRange aRange;
					aMarkData.GetMarkArea(aRange);
					if(aMarkData.IsMarked())
					{
						if (!pDoc->IsBlockEditable( aCursor.Tab(), aRange.aStart.Col(),aRange.aStart.Row(),
											aRange.aEnd.Col(),aRange.aEnd.Row() ))
						{
							bDisable = sal_True;
						}
						bNeedEdit=sal_False;
					}

				}
				break;
            case SID_INSERT_POSTIT:
                {
                    if ( pDocShell && pDocShell->IsDocShared() )
                    {
                        bDisable = sal_True;
                    }
                }
                break;
		}
		if (!bDisable && bNeedEdit)
			if (!pDoc->IsBlockEditable( aCursor.Tab(), aCursor.Col(),aCursor.Row(),
										aCursor.Col(),aCursor.Row() ))
				bDisable = sal_True;
		if (bDisable)
			rSet.DisableItem(nWhich);
		nWhich = aIter.NextWhich();
	}
}

sal_Bool lcl_TestFormat( SvxClipboardFmtItem& rFormats, const TransferableDataHelper& rDataHelper,
						SotFormatStringId nFormatId )
{
	if ( rDataHelper.HasFormat( nFormatId ) )
	{
		//	#90675# translated format name strings are no longer inserted here,
		//	handled by "paste special" dialog / toolbox controller instead.
		//	Only the object type name has to be set here:
		String aStrVal;
		if ( nFormatId == SOT_FORMATSTR_ID_EMBED_SOURCE )
		{
			TransferableObjectDescriptor aDesc;
			if ( ((TransferableDataHelper&)rDataHelper).GetTransferableObjectDescriptor(
										SOT_FORMATSTR_ID_OBJECTDESCRIPTOR, aDesc ) )
				aStrVal = aDesc.maTypeName;
		}
		else if ( nFormatId == SOT_FORMATSTR_ID_EMBED_SOURCE_OLE
		  || nFormatId == SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE )
		{
			String aSource;
            SvPasteObjectHelper::GetEmbeddedName( rDataHelper, aStrVal, aSource, nFormatId );
		}

		if ( aStrVal.Len() )
			rFormats.AddClipbrdFormat( nFormatId, aStrVal );
		else
			rFormats.AddClipbrdFormat( nFormatId );

		return sal_True;
	}

	return sal_False;
}

void ScCellShell::GetPossibleClipboardFormats( SvxClipboardFmtItem& rFormats )
{
	Window* pWin = GetViewData()->GetActiveWin();
	sal_Bool bDraw = ( ScDrawTransferObj::GetOwnClipboard( pWin ) != NULL );

	TransferableDataHelper aDataHelper( TransferableDataHelper::CreateFromSystemClipboard( pWin ) );

	lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_DRAWING );
	lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_SVXB );
	lcl_TestFormat( rFormats, aDataHelper, SOT_FORMAT_GDIMETAFILE );
	lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_PNG );
	lcl_TestFormat( rFormats, aDataHelper, SOT_FORMAT_BITMAP );
	lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_EMBED_SOURCE );

	if ( !bDraw )
	{
		lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_LINK );
		lcl_TestFormat( rFormats, aDataHelper, SOT_FORMAT_STRING );
		lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_DIF );
		lcl_TestFormat( rFormats, aDataHelper, SOT_FORMAT_RTF );
		lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_HTML );
		lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_HTML_SIMPLE );
        lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_BIFF_8 );
		lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_BIFF_5 );
	}

	if ( !lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_EMBED_SOURCE_OLE ) )
		lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE );
}

//	Einfuegen, Inhalte einfuegen

sal_Bool lcl_IsCellPastePossible( const TransferableDataHelper& rData )
{
	sal_Bool bPossible = sal_False;
	if ( ScTransferObj::GetOwnClipboard( NULL ) || ScDrawTransferObj::GetOwnClipboard( NULL ) )
		bPossible = sal_True;
	else
	{
		if ( rData.HasFormat( SOT_FORMATSTR_ID_PNG ) ||
             rData.HasFormat( SOT_FORMAT_BITMAP ) ||
			 rData.HasFormat( SOT_FORMAT_GDIMETAFILE ) ||
			 rData.HasFormat( SOT_FORMATSTR_ID_SVXB ) ||
			 rData.HasFormat( FORMAT_PRIVATE ) ||
			 rData.HasFormat( SOT_FORMAT_RTF ) ||
			 rData.HasFormat( SOT_FORMATSTR_ID_EMBED_SOURCE ) ||
			 rData.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE ) ||
			 rData.HasFormat( SOT_FORMATSTR_ID_EMBED_SOURCE_OLE ) ||
			 rData.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE_OLE ) ||
			 rData.HasFormat( SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE ) ||
			 rData.HasFormat( SOT_FORMAT_STRING ) ||
			 rData.HasFormat( SOT_FORMATSTR_ID_SYLK ) ||
			 rData.HasFormat( SOT_FORMATSTR_ID_LINK ) ||
			 rData.HasFormat( SOT_FORMATSTR_ID_HTML ) ||
			 rData.HasFormat( SOT_FORMATSTR_ID_HTML_SIMPLE ) ||
			 rData.HasFormat( SOT_FORMATSTR_ID_DIF ) )
		{
			bPossible = sal_True;
		}
	}
	return bPossible;
}

IMPL_LINK( ScCellShell, ClipboardChanged, TransferableDataHelper*, pDataHelper )
{
	if ( pDataHelper )
	{
		bPastePossible = lcl_IsCellPastePossible( *pDataHelper );

		SfxBindings& rBindings = GetViewData()->GetBindings();
		rBindings.Invalidate( SID_PASTE );
        rBindings.Invalidate( SID_PASTE_SPECIAL );
		rBindings.Invalidate( SID_CLIPBOARD_FORMAT_ITEMS );
	}
	return 0;
}


void __EXPORT ScCellShell::GetClipState( SfxItemSet& rSet )
{
// SID_PASTE
// SID_PASTE_SPECIAL
// SID_CLIPBOARD_FORMAT_ITEMS

    if ( !pImpl->m_pClipEvtLstnr )
	{
		// create listener
        pImpl->m_pClipEvtLstnr = new TransferableClipboardListener( LINK( this, ScCellShell, ClipboardChanged ) );
        pImpl->m_pClipEvtLstnr->acquire();
		Window* pWin = GetViewData()->GetActiveWin();
        pImpl->m_pClipEvtLstnr->AddRemoveListener( pWin, sal_True );

		// get initial state
		TransferableDataHelper aDataHelper( TransferableDataHelper::CreateFromSystemClipboard( pWin ) );
		bPastePossible = lcl_IsCellPastePossible( aDataHelper );
	}

	sal_Bool bDisable = !bPastePossible;

	//	Zellschutz / Multiselektion

	if (!bDisable)
	{
		SCCOL nCol = GetViewData()->GetCurX();
		SCROW nRow = GetViewData()->GetCurY();
		SCTAB nTab = GetViewData()->GetTabNo();
		ScDocument* pDoc = GetViewData()->GetDocShell()->GetDocument();
		if (!pDoc->IsBlockEditable( nTab, nCol,nRow, nCol,nRow ))
			bDisable = sal_True;
        ScRange aDummy;
        ScMarkType eMarkType = GetViewData()->GetSimpleArea( aDummy);
        if (eMarkType != SC_MARK_SIMPLE && eMarkType != SC_MARK_SIMPLE_FILTERED)
			bDisable = sal_True;
	}

	if (bDisable)
	{
		rSet.DisableItem( SID_PASTE );
        rSet.DisableItem( SID_PASTE_SPECIAL );
		rSet.DisableItem( SID_CLIPBOARD_FORMAT_ITEMS );
	}
	else if ( rSet.GetItemState( SID_CLIPBOARD_FORMAT_ITEMS ) != SFX_ITEM_UNKNOWN )
	{
		SvxClipboardFmtItem aFormats( SID_CLIPBOARD_FORMAT_ITEMS );
		GetPossibleClipboardFormats( aFormats );
		rSet.Put( aFormats );
	}
}

//	only SID_HYPERLINK_GETLINK:

void ScCellShell::GetHLinkState( SfxItemSet& rSet )
{
	//	always return an item (or inserting will be disabled)
	//	if the cell at the cursor contains only a link, return that link

	SvxHyperlinkItem aHLinkItem;
	if ( !GetViewData()->GetView()->HasBookmarkAtCursor( &aHLinkItem ) )
	{
		//!	put selected text into item?
	}

	rSet.Put(aHLinkItem);
}

void ScCellShell::GetState(SfxItemSet &rSet)
{
	// removed: SID_BORDER_OBJECT (old Basic)

	ScTabViewShell*	pTabViewShell  	= GetViewData()->GetViewShell();
//     sal_Bool bOle = pTabViewShell->GetViewFrame()->GetFrame().IsInPlace();
// 	sal_Bool bTabProt = GetViewData()->GetDocument()->IsTabProtected(GetViewData()->GetTabNo());
	ScDocShell* pDocSh = GetViewData()->GetDocShell();
    ScViewData* pData       = GetViewData();
	ScDocument* pDoc		= pData->GetDocument();
	ScMarkData& rMark		= pData->GetMarkData();
	SCCOL		nPosX		= pData->GetCurX();
	SCROW		nPosY		= pData->GetCurY();
	SCTAB		nTab		= pData->GetTabNo();

	SCTAB nTabCount = pDoc->GetTableCount();
	SCTAB nTabSelCount = rMark.GetSelectCount();



	SfxWhichIter aIter(rSet);
	sal_uInt16 nWhich = aIter.FirstWhich();
	while ( nWhich )
	{
		switch ( nWhich )
		{
			case SID_DETECTIVE_REFRESH:
				if (!pDoc->HasDetectiveOperations())
					rSet.DisableItem( nWhich );
				break;

			case SID_RANGE_ADDRESS:
				{
					ScRange aRange;
					if ( pData->GetSimpleArea( aRange ) == SC_MARK_SIMPLE )
					{
						String aStr;
						sal_uInt16 nFlags = SCA_VALID | SCA_TAB_3D;
						aRange.Format(aStr,nFlags,pDoc);
						rSet.Put( SfxStringItem( nWhich, aStr ) );
					}
				}
				break;

			case SID_RANGE_NOTETEXT:
				{
					//	#43343# always take cursor position, do not use top-left cell of selection
					ScAddress aPos( nPosX, nPosY, nTab );
					String aNoteText;
					if ( const ScPostIt* pNote = pDoc->GetNote( aPos ) )
                        aNoteText = pNote->GetText();
					rSet.Put( SfxStringItem( nWhich, aNoteText ) );
				}
				break;

			case SID_RANGE_ROW:
				rSet.Put( SfxInt32Item( nWhich, nPosY+1 ) );
				break;

			case SID_RANGE_COL:
				rSet.Put( SfxInt16Item( nWhich, nPosX+1 ) );
				break;

			case SID_RANGE_TABLE:
				rSet.Put( SfxInt16Item( nWhich, nTab+1 ) );
				break;

			case SID_RANGE_VALUE:
				{
					double nValue;
					pDoc->GetValue( nPosX, nPosY, nTab, nValue );
					rSet.Put( ScDoubleItem( nWhich, nValue ) );
				}
				break;

			case SID_RANGE_FORMULA:
				{
					String aString;
					pDoc->GetFormula( nPosX, nPosY, nTab, aString );
					if( aString.Len() == 0 )
					{
						pDoc->GetInputString( nPosX, nPosY, nTab, aString );
					}
					rSet.Put( SfxStringItem( nWhich, aString ) );
				}
				break;

			case SID_RANGE_TEXTVALUE:
				{
					String aString;
					pDoc->GetString( nPosX, nPosY, nTab, aString );
					rSet.Put( SfxStringItem( nWhich, aString ) );
				}
				break;

			case SID_STATUS_SELMODE:
				{
					/* 0: STD	Click hebt Sel auf
					 * 1: ER	Click erweitert Selektion
					 * 2: ERG	Click definiert weitere Selektion
					 */
					sal_uInt16 nMode = pTabViewShell->GetLockedModifiers();

					switch ( nMode )
					{
						case KEY_SHIFT: nMode = 1;	break;
						case KEY_MOD1:	nMode = 2;	break; // Control-Taste
						case 0:
						default:
							nMode = 0;
					}

					rSet.Put( SfxUInt16Item( nWhich, nMode ) );
				}
				break;

			case SID_STATUS_DOCPOS:
				{
					String	aStr( ScGlobal::GetRscString( STR_TABLE ) );

					aStr += ' ';
					aStr += String::CreateFromInt32( nTab + 1 );
					aStr.AppendAscii(RTL_CONSTASCII_STRINGPARAM( " / " ));
					aStr += String::CreateFromInt32( nTabCount );
					rSet.Put( SfxStringItem( nWhich, aStr ) );
				}
				break;

			//	Summe etc. mit Datum/Zeit/Fehler/Pos&Groesse zusammengefasst

            // #i34458# The SfxStringItem belongs only into SID_TABLE_CELL. It no longer has to be
            // duplicated in SID_ATTR_POSITION or SID_ATTR_SIZE for SvxPosSizeStatusBarControl.
			case SID_TABLE_CELL:
				{
					//	Testen, ob Fehler unter Cursor
					//	(nicht pDoc->GetErrCode, um keine zirkulaeren Referenzen auszuloesen)

					// In interpreter may happen via rescheduled Basic
					if ( pDoc->IsInInterpreter() )
						rSet.Put( SfxStringItem( nWhich,
							String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("...")) ) );
					else
					{
						sal_uInt16 nErrCode = 0;
						ScBaseCell* pCell;
						pDoc->GetCell( nPosX, nPosY, nTab, pCell );
						if ( pCell && pCell->GetCellType() == CELLTYPE_FORMULA )
						{
							ScFormulaCell* pFCell = (ScFormulaCell*) pCell;
							if (!pFCell->IsRunning())
								nErrCode = pFCell->GetErrCode();
						}

                        String aFuncStr;
                        if ( pTabViewShell->GetFunction( aFuncStr, nErrCode ) )
                            rSet.Put( SfxStringItem( nWhich, aFuncStr ) );
					}
				}
				break;

			case SID_DATA_SELECT:
                // HasSelectionData includes column content and validity,
                // page fields have to be checked separately.
                if ( !pDoc->HasSelectionData( nPosX, nPosY, nTab ) &&
                     !pTabViewShell->HasPageFieldDataAtCursor() )
					rSet.DisableItem( nWhich );
				break;

			case SID_STATUS_SUM:
				{
					String aFuncStr;
					if ( pTabViewShell->GetFunction( aFuncStr ) )
						rSet.Put( SfxStringItem( nWhich, aFuncStr ) );
				}
				break;

			case FID_MERGE_ON:
				if ( pDoc->GetChangeTrack() || !pTabViewShell->TestMergeCells() )
					rSet.DisableItem( nWhich );
				break;

			case FID_MERGE_OFF:
				if ( pDoc->GetChangeTrack() || !pTabViewShell->TestRemoveMerge() )
					rSet.DisableItem( nWhich );
				break;

            case FID_MERGE_TOGGLE:
                if ( pDoc->GetChangeTrack() )
                    rSet.DisableItem( nWhich );
                else
                {
                    bool bCanMerge = pTabViewShell->TestMergeCells();
                    bool bCanSplit = pTabViewShell->TestRemoveMerge();
                    if( !bCanMerge && !bCanSplit )
                        rSet.DisableItem( nWhich );
                    else
                        rSet.Put( SfxBoolItem( nWhich, bCanSplit ) );
                }
                break;

			case FID_INS_ROWBRK:
                if ( nPosY==0 || (pDoc->HasRowBreak(nPosY, nTab) & BREAK_MANUAL) )
					rSet.DisableItem( nWhich );
				break;

			case FID_INS_COLBRK:
                if ( nPosX==0 || (pDoc->HasColBreak(nPosX, nTab) & BREAK_MANUAL) )
					rSet.DisableItem( nWhich );
				break;

			case FID_DEL_ROWBRK:
                if ( nPosY==0 || (pDoc->HasRowBreak(nPosY, nTab) & BREAK_MANUAL) == 0 )
					rSet.DisableItem( nWhich );
				break;

			case FID_DEL_COLBRK:
                if ( nPosX==0 || (pDoc->HasColBreak(nPosX, nTab) & BREAK_MANUAL) == 0 )
					rSet.DisableItem( nWhich );
				break;

			case FID_FILL_TAB:
				if ( nTabSelCount < 2 )
					rSet.DisableItem( nWhich );
				break;

			case SID_SELECT_SCENARIO:
				{
                    // ScDocument* pDoc = GetViewData()->GetDocument();
                    // SCTAB       nTab = GetViewData()->GetTabNo();
					List		aList;

					Color	aDummyCol;

					if ( !pDoc->IsScenario(nTab) )
					{
						String aStr;
						sal_uInt16 nFlags;
						SCTAB nScTab = nTab + 1;
						String aProtect;
						bool bSheetProtected = pDoc->IsTabProtected(nTab);

						while ( pDoc->IsScenario(nScTab) )
						{
							pDoc->GetName( nScTab, aStr );
							aList.Insert( new String( aStr ), LIST_APPEND );
							pDoc->GetScenarioData( nScTab, aStr, aDummyCol, nFlags );
							aList.Insert( new String( aStr ), LIST_APPEND );
							// Protection is sal_True if both Sheet and Scenario are protected
							aProtect = (bSheetProtected && (nFlags & SC_SCENARIO_PROTECT)) ? '1' : '0';
							aList.Insert( new String( aProtect), LIST_APPEND );
							++nScTab;
						}
					}
					else
					{
						String	aComment;
						sal_uInt16	nDummyFlags;
						pDoc->GetScenarioData( nTab, aComment, aDummyCol, nDummyFlags );
						DBG_ASSERT( aList.Count() == 0, "List not empty!" );
						aList.Insert( new String( aComment ) );
					}

					rSet.Put( SfxStringListItem( nWhich, &aList ) );

					sal_uLong nCount = aList.Count();
					for ( sal_uLong i=0; i<nCount; i++ )
						delete (String*) aList.GetObject(i);
				}
				break;

			case FID_ROW_HIDE:
			case FID_ROW_SHOW:
			case FID_COL_HIDE:
			case FID_COL_SHOW:
			case FID_COL_OPT_WIDTH:
			case FID_ROW_OPT_HEIGHT:
			case FID_DELETE_CELL:
				if ( pDoc->IsTabProtected(nTab) || pDocSh->IsReadOnly())
					rSet.DisableItem( nWhich );
				break;

/*	Zellschutz bei selektierten Zellen wird bei anderen Funktionen auch nicht abgefragt...
			case SID_DELETE:
				{
					if ( pDoc->IsTabProtected(nTab) )
					{
						const SfxItemSet&		rAttrSet  = GetSelectionPattern()->GetItemSet();
						const ScProtectionAttr& rProtAttr = (const ScProtectionAttr&)rAttrSet.Get( ATTR_PROTECTION, sal_True );
						if ( rProtAttr.GetProtection() )
							rSet.DisableItem( nWhich );
					}
				}
				break;
*/
			case SID_OUTLINE_MAKE:
				{
    				if ( GetViewData()->GetDocument()->GetDPAtCursor( GetViewData()->GetCurX(),
                							GetViewData()->GetCurY(), GetViewData()->GetTabNo() ) )
                    {
                        //! test for data pilot operation
                    }
					else if (pDoc->GetChangeTrack()!=NULL || GetViewData()->IsMultiMarked())
					{
						rSet.DisableItem( nWhich );
					}
				}
				break;
			case SID_OUTLINE_SHOW:
				if ( GetViewData()->GetDocument()->GetDPAtCursor( GetViewData()->GetCurX(),
            							GetViewData()->GetCurY(), GetViewData()->GetTabNo() ) )
                {
                    //! test for data pilot operation
                }
				else if (!pTabViewShell->OutlinePossible(sal_False))
					rSet.DisableItem( nWhich );
				break;

			case SID_OUTLINE_HIDE:
				if ( GetViewData()->GetDocument()->GetDPAtCursor( GetViewData()->GetCurX(),
            							GetViewData()->GetCurY(), GetViewData()->GetTabNo() ) )
                {
                    //! test for data pilot operation
                }
				else if (!pTabViewShell->OutlinePossible(sal_True))
					rSet.DisableItem( nWhich );
				break;

			case SID_OUTLINE_REMOVE:
				{
    				if ( GetViewData()->GetDocument()->GetDPAtCursor( GetViewData()->GetCurX(),
                							GetViewData()->GetCurY(), GetViewData()->GetTabNo() ) )
                    {
                        //! test for data pilot operation
                    }
                    else
                    {
    					sal_Bool bCol, bRow;
    					pTabViewShell->TestRemoveOutline( bCol, bRow );
    					if ( !bCol && !bRow )
    						rSet.DisableItem( nWhich );
                    }
				}
				break;

			case FID_COL_WIDTH:
				{
					//GetViewData()->GetCurX();
					SfxUInt16Item aWidthItem( FID_COL_WIDTH, pDoc->GetColWidth( nPosX , nTab) );
					rSet.Put( aWidthItem );
					if ( pDocSh->IsReadOnly())
						rSet.DisableItem( nWhich );

					//XXX Disablen wenn nicht eindeutig
				}
				break;

			case FID_ROW_HEIGHT:
				{
					//GetViewData()->GetCurY();
					SfxUInt16Item aHeightItem( FID_ROW_HEIGHT, pDoc->GetRowHeight( nPosY , nTab) );
					rSet.Put( aHeightItem );
					//XXX Disablen wenn nicht eindeutig
					if ( pDocSh->IsReadOnly())
						rSet.DisableItem( nWhich );
				}
				break;

			case SID_DETECTIVE_FILLMODE:
				rSet.Put(SfxBoolItem( nWhich, pTabViewShell->IsAuditShell() ));
				break;

			case FID_INPUTLINE_STATUS:
				DBG_ERROR( "Old update method. Use ScTabViewShell::UpdateInputHandler()." );
				break;

			case SID_SCENARIOS:										// Szenarios:
				if (!(rMark.IsMarked() || rMark.IsMultiMarked()))	// nur, wenn etwas selektiert
					rSet.DisableItem( nWhich );
				break;

			case FID_NOTE_VISIBLE:
				{
                    const ScPostIt* pNote = pDoc->GetNote( ScAddress( nPosX, nPosY, nTab ) );
					if ( pNote && pDoc->IsBlockEditable( nTab, nPosX,nPosY, nPosX,nPosY ) )
						rSet.Put( SfxBoolItem( nWhich, pNote->IsCaptionShown() ) );
					else
						rSet.DisableItem( nWhich );
				}
				break;

            case SID_DELETE_NOTE:
                {
                    sal_Bool bEnable = sal_False;
                    if ( rMark.IsMarked() || rMark.IsMultiMarked() )
                    {
                        if ( pDoc->IsSelectionEditable( rMark ) )
                        {
                            // look for at least one note in selection
                            ScRangeList aRanges;
                            rMark.FillRangeListWithMarks( &aRanges, sal_False );
                            sal_uLong nCount = aRanges.Count();
                            for (sal_uLong nPos=0; nPos<nCount && !bEnable; nPos++)
                            {
                                ScCellIterator aCellIter( pDoc, *aRanges.GetObject(nPos) );
                                for( ScBaseCell* pCell = aCellIter.GetFirst(); pCell && !bEnable; pCell = aCellIter.GetNext() )
                                    if ( pCell->HasNote() )
                                        bEnable = sal_True;             // note found
                            }
                        }
                    }
                    else
                    {
                        bEnable = pDoc->IsBlockEditable( nTab, nPosX,nPosY, nPosX,nPosY ) &&
                                  pDoc->GetNote( ScAddress( nPosX, nPosY, nTab ) );
                    }
                    if ( !bEnable )
                        rSet.DisableItem( nWhich );
                }
                break;

			case SID_OPENDLG_CONSOLIDATE:
			case SCITEM_CONSOLIDATEDATA:
				{
					if(pDoc->GetChangeTrack()!=NULL)
								rSet.DisableItem( nWhich);
				}
				break;

            case SID_CHINESE_CONVERSION:
            case SID_HANGUL_HANJA_CONVERSION:
                ScViewUtil::HideDisabledSlot( rSet, pData->GetBindings(), nWhich );
            break;

            case FID_USE_NAME:
                {
                    if ( pDocSh && pDocSh->IsDocShared() )
                        rSet.DisableItem( nWhich );
                    else
                    {
                        ScRange aRange;
                        if ( pData->GetSimpleArea( aRange ) != SC_MARK_SIMPLE )
                            rSet.DisableItem( nWhich );
                    }
                }
                break;

            case FID_DEFINE_NAME:
            case FID_INSERT_NAME:
            case SID_DEFINE_COLROWNAMERANGES:
                {
                    if ( pDocSh && pDocSh->IsDocShared() )
                    {
                        rSet.DisableItem( nWhich );
                    }
                }
                break;

            case SID_SPELL_DIALOG:
                {
                    if ( pDoc && pData && pDoc->IsTabProtected( pData->GetTabNo() ) )
                    {
                        bool bVisible = false;
                        SfxViewFrame* pViewFrame = ( pTabViewShell ? pTabViewShell->GetViewFrame() : NULL );
                        if ( pViewFrame && pViewFrame->HasChildWindow( nWhich ) )
                        {
                            SfxChildWindow* pChild = pViewFrame->GetChildWindow( nWhich );
                            Window* pWin = ( pChild ? pChild->GetWindow() : NULL );
                            if ( pWin && pWin->IsVisible() )
                            {
                                bVisible = true;
                            }
                        }
                        if ( !bVisible )
                        {
                            rSet.DisableItem( nWhich );
                        }
                    }
                }
                break;

		} // switch ( nWitch )
		nWhich = aIter.NextWhich();
	} // while ( nWitch )
}

//------------------------------------------------------------------
