blob: 09d012cb655fb38161c08529dac25d148cd0f4cd [file] [log] [blame]
/**************************************************************
*
* 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 )
}
//------------------------------------------------------------------