/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * 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 .
*/
ScCellShell::~ScCellShell()
{ if ( pImpl->m_xClipEvtLstnr.is() )
{
pImpl->m_xClipEvtLstnr->RemoveListener( GetViewData().GetActiveWin() );
// 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_xClipEvtLstnr->ClearCallbackLink();
SfxWhichIter aIter(rSet);
sal_uInt16 nWhich = aIter.FirstWhich(); while ( nWhich )
{ bool bDisable = false; bool bNeedEdit = true; // need selection be editable? switch ( nWhich )
{ case FID_FILL_TO_BOTTOM: // fill to top / bottom
{
bDisable = !bSimpleArea || (nRow1 == 0 && nRow2 == 0); if (!bDisable && GetViewData().SelectionForbidsCellFill())
bDisable = true; if ( !bDisable && bEditable )
{ // do not damage matrix
bDisable = rDoc.HasSelectedBlockMatrixFragment(
nCol1, nRow1, nCol2, nRow1, rMark ); // first row
}
} break; case FID_FILL_TO_TOP:
{
bDisable = (!bSimpleArea) || (nRow1 == rDoc.MaxRow() && nRow2 == rDoc.MaxRow()); if (!bDisable && GetViewData().SelectionForbidsCellFill())
bDisable = true; if ( !bDisable && bEditable )
{ // do not damage matrix
bDisable = rDoc.HasSelectedBlockMatrixFragment(
nCol1, nRow2, nCol2, nRow2, rMark ); // last row
}
} break; case FID_FILL_TO_RIGHT: // fill to left / right
{
bDisable = !bSimpleArea || (nCol1 == 0 && nCol2 == 0); if (!bDisable && GetViewData().SelectionForbidsCellFill())
bDisable = true; if ( !bDisable && bEditable )
{ // do not damage matrix
bDisable = rDoc.HasSelectedBlockMatrixFragment(
nCol1, nRow1, nCol1, nRow2, rMark ); // first column
}
} break; case FID_FILL_TO_LEFT:
{
bDisable = (!bSimpleArea) || (nCol1 == rDoc.MaxCol() && nCol2 == rDoc.MaxCol()); if (!bDisable && GetViewData().SelectionForbidsCellFill())
bDisable = true; if ( !bDisable && bEditable )
{ // do not damage matrix
bDisable = rDoc.HasSelectedBlockMatrixFragment(
nCol2, nRow1, nCol2, nRow2, rMark ); // last column
}
} break;
case SID_RANDOM_NUMBER_GENERATOR_DIALOG:
bDisable = !bSimpleArea || GetViewData().SelectionForbidsCellFill(); break; case SID_SAMPLING_DIALOG: case SID_DESCRIPTIVE_STATISTICS_DIALOG: case SID_ANALYSIS_OF_VARIANCE_DIALOG: case SID_CORRELATION_DIALOG: case SID_COVARIANCE_DIALOG: case SID_INSERT_SPARKLINE:
{
bDisable = !bSimpleArea;
} break; case SID_GROUP_SPARKLINES: case SID_UNGROUP_SPARKLINES:
{
bDisable = !bSimpleArea;
} break;
case SID_EDIT_SPARKLINE:
{
bDisable = !rDoc.HasSparkline(GetViewData().GetCurPos());
} break;
case SID_DELETE_SPARKLINE: case SID_EDIT_SPARKLINE_GROUP: case SID_DELETE_SPARKLINE_GROUP:
{
bDisable = !rDoc.HasOneSparklineGroup(ScRange(nCol1, nRow1, nTab, nCol2, nRow2, nTab));
} break;
case FID_FILL_SERIES: // fill block case SID_OPENDLG_TABOP: // multiple-cell operations, are at least 2 cells marked? if (rDoc.GetChangeTrack()!=nullptr &&nWhich ==SID_OPENDLG_TABOP)
bDisable = true; else
bDisable = (!bSimpleArea) || (nCol1 == nCol2 && nRow1 == nRow2);
if (!bDisable && GetViewData().SelectionForbidsCellFill())
bDisable = true;
if ( !bDisable && bEditable && nWhich == FID_FILL_SERIES )
{ // do not damage matrix
bDisable = rDoc.HasSelectedBlockMatrixFragment(
nCol1, nRow1, nCol2, nRow1, rMark ) // first row
|| rDoc.HasSelectedBlockMatrixFragment(
nCol1, nRow2, nCol2, nRow2, rMark ) // last row
|| rDoc.HasSelectedBlockMatrixFragment(
nCol1, nRow1, nCol1, nRow2, rMark ) // first column
|| rDoc.HasSelectedBlockMatrixFragment(
nCol2, nRow1, nCol2, nRow2, rMark ); // last column
} break; case FID_FILL_SINGLE_EDIT:
bDisable = false; break; case SID_CUT: // cut case SID_COPYDELETE:
bDisable = !bSimpleArea || GetObjectShell()->isContentExtractionLocked(); break; case FID_INS_CELL: // insert cells, just simple selection
bDisable = (!bSimpleArea); break;
case SID_PASTE: case SID_PASTE_SPECIAL: case SID_PASTE_UNFORMATTED: case SID_PASTE_ONLY_VALUE: case SID_PASTE_ONLY_TEXT: case SID_PASTE_ONLY_FORMULA: case SID_PASTE_TRANSPOSED: case SID_PASTE_AS_LINK: case SID_PASTE_TEXTIMPORT_DIALOG:
bDisable = GetViewData().SelectionForbidsPaste(); break;
case FID_INS_ROW: case FID_INS_ROWS_BEFORE: // insert rows case FID_INS_ROWS_AFTER:
{
sc::EditAction eAction = sc::EditAction::InsertRowsBefore; if (nWhich == FID_INS_ROWS_AFTER)
eAction = sc::EditAction::InsertRowsAfter;
bDisable = (!bSimpleArea) || GetViewData().SimpleColMarked(); if (!bEditable && nCol1 == 0 && nCol2 == rDoc.MaxCol())
{ // See if row insertions are allowed.
bEditable = rDoc.IsEditActionAllowed(eAction, rMark, nCol1, nRow1, nCol2, nRow2);
} break;
} case FID_INS_CELLSDOWN:
bDisable = (!bSimpleArea) || GetViewData().SimpleColMarked(); break;
case FID_INS_COLUMN: case FID_INS_COLUMNS_BEFORE: // insert columns case FID_INS_COLUMNS_AFTER:
{
sc::EditAction eAction = sc::EditAction::InsertColumnsBefore; if (nWhich == FID_INS_COLUMNS_AFTER)
eAction = sc::EditAction::InsertColumnsAfter;
bDisable = (!bSimpleArea && eMarkType != SC_MARK_SIMPLE_FILTERED)
|| GetViewData().SimpleRowMarked(); if (!bEditable && nRow1 == 0 && nRow2 == rDoc.MaxRow())
{ // See if row insertions are allowed.
bEditable = rDoc.IsEditActionAllowed(eAction, rMark, nCol1, nRow1, nCol2, nRow2);
} break;
} case FID_INS_CELLSRIGHT:
bDisable = (!bSimpleArea) || GetViewData().SimpleRowMarked(); break;
case SID_COPY: // copy case SID_COPY_HYPERLINK_LOCATION: // not editable because of matrix only? Do not damage matrix //! is not called, when protected AND matrix, we will have //! to live with this... is caught in Copy-Routine, otherwise //! work is to be done once more if ( bEditable || !bOnlyNotBecauseOfMatrix )
bNeedEdit = false; // allowed when protected/ReadOnly
bDisable = GetObjectShell()->isContentExtractionLocked(); break;
case SID_AUTOFORMAT: // Autoformat, at least 3x3 selected
bDisable = (!bSimpleArea)
|| ((nCol2 - nCol1) < 2) || ((nRow2 - nRow1) < 2); break;
case SID_CELL_FORMAT_RESET : case FID_CELL_FORMAT : case SID_ENABLE_HYPHENATION : // not editable because of matrix only? Attribute ok nonetheless if ( !bEditable && bOnlyNotBecauseOfMatrix )
bNeedEdit = false; break;
case FID_CURRENTVALIDATION: case FID_VALIDATION:
{ if ( rDocShell.IsDocShared() )
{
bDisable = true;
}
} break; case SID_TRANSLITERATE_HALFWIDTH: case SID_TRANSLITERATE_FULLWIDTH: case SID_TRANSLITERATE_HIRAGANA: case SID_TRANSLITERATE_KATAKANA:
ScViewUtil::HideDisabledSlot( rSet, GetViewData().GetBindings(), nWhich ); break; case SID_CONVERT_FORMULA_TO_VALUE:
{ // Check and see if the marked range has at least one formula cell.
bDisable = !rDoc.HasFormulaCell(aMarkRange);
} break;
} if (!bDisable && bNeedEdit && !bEditable)
bDisable = true;
if (bDisable)
rSet.DisableItem(nWhich); elseif (nWhich == SID_ENABLE_HYPHENATION)
{ // toggle slots need a bool item
rSet.Put( SfxBoolItem( nWhich, false ) );
}
nWhich = aIter.NextWhich();
}
}
// functions, disabled depending on cursor position // Default: // SID_INSERT_POSTIT, SID_CHARMAP, SID_OPENDLG_FUNCTION
void ScCellShell::GetCellState( SfxItemSet& rSet )
{
ScDocShell& rDocShell = GetViewData().GetDocShell();
ScDocument& rDoc = GetViewData().GetDocShell().GetDocument();
ScAddress aCursor( GetViewData().GetCurX(), GetViewData().GetCurY(),
GetViewData().GetTabNo() );
SfxWhichIter aIter(rSet);
sal_uInt16 nWhich = aIter.FirstWhich(); while ( nWhich )
{ bool bDisable = false; bool bNeedEdit = true; // need cursor position be editable? switch ( nWhich )
{ case SID_THESAURUS:
{
CellType eType = rDoc.GetCellType( aCursor );
bDisable = ( eType != CELLTYPE_STRING && eType != CELLTYPE_EDIT); if (!bDisable)
{ // test for available languages
LanguageType nLang = ScViewUtil::GetEffLanguage( rDoc, aCursor );
bDisable = !ScModule::HasThesaurusLanguage( nLang );
}
} break; case SID_OPENDLG_FUNCTION:
{
ScMarkData aMarkData = GetViewData().GetMarkData();
aMarkData.MarkToSimple(); const ScRange& aRange = aMarkData.GetMarkArea(); if(aMarkData.IsMarked())
{ if (!rDoc.IsBlockEditable( aCursor.Tab(), aRange.aStart.Col(),aRange.aStart.Row(),
aRange.aEnd.Col(),aRange.aEnd.Row() ))
{
bDisable = true;
}
bNeedEdit=false;
}
bool checkDestRanges(ScViewData& rViewData)
{
ScRange aDummy;
ScMarkType eMarkType = rViewData.GetSimpleArea( aDummy); if (eMarkType != SC_MARK_MULTI)
{ // Single destination range. if (eMarkType != SC_MARK_SIMPLE && eMarkType != SC_MARK_SIMPLE_FILTERED) returnfalse;
}
// Multiple destination ranges.
// Same as ScViewData::SelectionForbidsPaste() in // sc/source/ui/view/viewdata.cxx but different return details.
vcl::Window* pWin = rViewData.GetActiveWin(); if (!pWin) returnfalse;
const ScTransferObj* pOwnClip = ScTransferObj::GetOwnClipboard(ScTabViewShell::GetClipData(pWin)); if (!pOwnClip) // If it's not a Calc document, we won't be picky. returntrue;
ScDocument* pClipDoc = pOwnClip->GetDocument(); if (!pClipDoc) returnfalse;
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
if ((nRanges == 1 && (nCol2 != nCol1 || nRow1 != nRow2)) || nRanges > 1)
{ bool bSameRows = true; bool bSameCols = true;
SCROW nRowsSum = 0;
SCCOL nColsSum = 0; for (size_t i = 0; i < nRanges; ++i)
{ const ScRange& rRange = (*aMarkRanges)[i]; const SCCOL nRangeCol1 = rRange.aStart.Col(); const SCROW nRangeRow1 = rRange.aStart.Row(); const SCCOL nRangeCol2 = rRange.aEnd.Col(); const SCROW nRangeRow2 = rRange.aEnd.Row();
bSameRows &= (nRow1 == nRangeRow1 && nRow2 == nRangeRow2);
bSameCols &= (nCol1 == nRangeCol1 && nCol2 == nRangeCol2); // Sum rows if the number of cols is the same or // sum columns if the number of rows is the same, // otherwise do not show any count of selected cells. if (bSameRows || bSameCols)
{ constauto nCols = nRangeCol2 - nRangeCol1 + 1; constauto nRows = (bSameCols || nRowsSum == 0) ?
rDoc.CountNonFilteredRows( nRangeRow1, nRangeRow2, rRange.aStart.Tab()) :
nRowsSum; if (bSameRows)
{
nRowsSum = nRows;
nColsSum += nCols;
} elseif (bSameCols)
{
nRowsSum += nRows;
nColsSum = nCols;
}
} else break;
} // Either the rows or columns are the same among selections if (bSameRows || bSameCols)
{ const LocaleDataWrapper& rLocaleData
= Application::GetSettings().GetUILocaleDataWrapper();
OUString aRowArg
= ScResId(STR_SELCOUNT_ROWARG, nRowsSum)
.replaceAll("%d", rLocaleData.getNum(nRowsSum, 0));
OUString aColArg
= ScResId(STR_SELCOUNT_COLARG, nColsSum)
.replaceAll("%d", rLocaleData.getNum(nColsSum, 0));
OUString aStr = ScResId(STR_SELCOUNT);
aStr = aStr.replaceAll("%1", aRowArg);
aStr = aStr.replaceAll("%2", aColArg);
rSet.Put(SfxStringItem(nWhich, aStr));
}
} else
{
SCSIZE nSelected, nTotal;
rDoc.GetFilterSelCount( nPosX, nPosY, nTab, nSelected, nTotal ); if( nTotal && nSelected != SCSIZE_MAX )
{
OUString aStr = ScResId( STR_FILTER_SELCOUNT );
aStr = aStr.replaceAll( "%1", OUString::number( nSelected ) );
aStr = aStr.replaceAll( "%2", OUString::number( nTotal ) );
rSet.Put( SfxStringItem( nWhich, aStr ) );
}
}
} break;
// calculations etc. with date/time/Fail/position&size together
// #i34458# The SvxStatusItem 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:
{ // Test, if error under cursor // (not rDoc.GetErrCode, to avoid erasing circular references)
// In interpreter may happen via rescheduled Basic if ( rDoc.IsInInterpreter() )
rSet.Put( SvxStatusItem( SID_TABLE_CELL, u"..."_ustr, StatusCategory::Formula ) ); else
{
FormulaError nErrCode = FormulaError::NONE;
ScFormulaCell* pCell = rDoc.GetFormulaCell(ScAddress(nPosX, nPosY, nTab)); if (pCell && !pCell->IsRunning())
nErrCode = pCell->GetErrCode();
case SID_DATA_SELECT: // HasSelectionData includes column content and validity, // page fields have to be checked separately. if ( !rDoc.HasSelectionData( nPosX, nPosY, nTab ) &&
!pTabViewShell->HasPageFieldDataAtCursor() )
rSet.DisableItem( nWhich ); break;
case FID_CURRENTVALIDATION: if ( !rDoc.HasValidationData( nPosX, nPosY, nTab ))
rSet.DisableItem( nWhich ); break;
case SID_STATUS_SUM:
{
OUString aFuncStr; if ( pTabViewShell->GetFunction( aFuncStr, FormulaError::NONE ) )
rSet.Put( SfxStringItem( nWhich, aFuncStr ) );
} break;
case FID_MERGE_ON: if ( rDoc.GetChangeTrack() || !pTabViewShell->TestMergeCells() )
rSet.DisableItem( nWhich ); break;
case FID_MERGE_OFF: if ( rDoc.GetChangeTrack() || !pTabViewShell->TestRemoveMerge() )
rSet.DisableItem( nWhich ); 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 ( rDoc.IsTabProtected(nTab) || rDocSh.IsReadOnly())
rSet.DisableItem( nWhich ); break;
case SID_OUTLINE_MAKE:
{ if ( GetViewData().GetDocument().GetDPAtCursor( GetViewData().GetCurX(),
GetViewData().GetCurY(), GetViewData().GetTabNo() ) )
{ //! test for data pilot operation
} elseif (rDoc.GetChangeTrack()!=nullptr || 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
} elseif (!pTabViewShell->OutlinePossible(false))
rSet.DisableItem( nWhich ); break;
case SID_OUTLINE_HIDE: if ( GetViewData().GetDocument().GetDPAtCursor( GetViewData().GetCurX(),
GetViewData().GetCurY(), GetViewData().GetTabNo() ) )
{ //! test for data pilot operation
} elseif (!pTabViewShell->OutlinePossible(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
{ bool bCol, bRow;
pTabViewShell->TestRemoveOutline( bCol, bRow ); if ( !bCol && !bRow )
rSet.DisableItem( nWhich );
}
} break;
case FID_COL_WIDTH:
{
SfxUInt16Item aWidthItem( FID_COL_WIDTH, rDoc.GetColWidth( nPosX , nTab) );
rSet.Put( aWidthItem ); if ( rDocSh.IsReadOnly())
rSet.DisableItem( nWhich );
//XXX disable if not conclusive
} break;
case FID_ROW_HEIGHT:
{
SfxUInt16Item aHeightItem( FID_ROW_HEIGHT, rDoc.GetRowHeight( nPosY , nTab) );
rSet.Put( aHeightItem ); //XXX disable if not conclusive if ( rDocSh.IsReadOnly())
rSet.DisableItem( nWhich );
} break;
case SID_DETECTIVE_FILLMODE:
rSet.Put(SfxBoolItem( nWhich, pTabViewShell->IsAuditShell() )); break;
case FID_INPUTLINE_STATUS:
OSL_FAIL( "Old update method. Use ScTabViewShell::UpdateInputHandler()." ); break;
case SID_SCENARIOS: // scenarios: if (!(rMark.IsMarked() || rMark.IsMultiMarked())) // only, if something selected
rSet.DisableItem( nWhich ); break;
case SID_DELETE_NOTE:
{ bool bEnable = false; if ( rMark.IsMarked() || rMark.IsMultiMarked() )
{ if ( rDoc.IsSelectionEditable( rMark ) )
{ // look for at least one note in selection
ScRangeList aRanges;
rMark.FillRangeListWithMarks( &aRanges, false );
bEnable = rDoc.ContainsNotesInRange( aRanges );
}
} else
{
bEnable = rDoc.IsBlockEditable( nTab, nPosX,nPosY, nPosX,nPosY ) &&
rDoc.GetNote(nPosX, nPosY, nTab);
} if ( !bEnable )
rSet.DisableItem( nWhich );
} break;
case SID_OPENDLG_CONSOLIDATE: case SCITEM_CONSOLIDATEDATA:
{ if (rDoc.GetChangeTrack()!=nullptr)
rSet.DisableItem( nWhich);
} break;
case SID_CHINESE_CONVERSION: case SID_HANGUL_HANJA_CONVERSION:
ScViewUtil::HideDisabledSlot( rSet, rData.GetBindings(), nWhich ); break;
case FID_USE_NAME:
{ if ( rDocSh.IsDocShared() )
rSet.DisableItem( nWhich ); else
{
ScRange aRange; if ( rData.GetSimpleArea( aRange ) != SC_MARK_SIMPLE )
rSet.DisableItem( nWhich );
}
} break;
case FID_DEFINE_NAME: case FID_INSERT_NAME: case FID_ADD_NAME: case SID_DEFINE_COLROWNAMERANGES:
{ if ( rDocSh.IsDocShared() )
{
rSet.DisableItem( nWhich );
}
} break;
case FID_DEFINE_CURRENT_NAME:
{
ScAddress aCurrentAddress( nPosX, nPosY, nTab );
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.