/* -*- 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 .
*/
// text direction in boxes
std::unique_ptr<SvxFrameDirectionItem> aBoxDirection(std::make_unique<SvxFrameDirectionItem>(SvxFrameDirection::Environment, RES_FRAMEDIR)); if(rSh.GetBoxDirection( aBoxDirection ))
{
aBoxDirection->SetWhich(FN_TABLE_BOX_TEXTORIENTATION);
rSet.Put(*aBoxDirection);
}
// Table variant: If multiple table cells are selected.
rSh.GetCursor(); //Thus GetCursorCnt() returns the right thing
aBoxInfo.SetTable ((rSh.IsTableMode() && rSh.GetCursorCnt() > 1) ||
!bTableSel); // Always show distance field.
aBoxInfo.SetDist (true); // Set minimum size in tables and paragraphs.
aBoxInfo.SetMinDist( !bTableSel || rSh.IsTableMode() ||
rSh.GetSelectionType() &
(SelectionType::Text | SelectionType::Table)); // Always set the default spacing.
aBoxInfo.SetDefDist (MIN_BORDER_DIST); // Individual lines can have DontCare status only in tables.
aBoxInfo.SetValid( SvxBoxInfoItemValidFlags::DISABLE, !bTableSel || !rSh.IsTableMode() );
pRep->SetWidth(nWidth);
pRep->SetWidthPercent(nPercent); // Are individual rows / cells are selected, the column processing will be changed.
pRep->SetLineSelected(bTableSel && ! rSh.HasWholeTabSelection());
rSet.Put(SwPtrItem(FN_TABLE_REP, pRep.get())); return pRep;
}
sal_Int16 eOrient = pRep->GetAlign();
SwFormatHoriOrient aAttr( 0, eOrient );
aSet.Put( aAttr ); // The item must only be recorded while manual alignment, so that the // alignment is not overwritten by the distances while recording. if(eOrient != text::HoriOrientation::NONE) const_cast<SfxItemSet&>(rSet).ClearItem( SID_ATTR_LRSPACE );
staticbool lcl_BoxesInTrackedRows(const SwWrtShell &rSh, const SwSelBoxes& rBoxes)
{ // cursor and selection are there only in tracked rows bool bRet = true;
SwRedlineTable::size_type nRedlinePos = 0; if ( rBoxes.empty() )
bRet = rSh.GetCursor()->GetPointNode().GetTableBox()->GetUpper()->IsTracked(nRedlinePos); else
{
tools::Long nBoxes = rBoxes.size();
SwTableLine* pPrevLine = nullptr; for ( tools::Long i = 0; i < nBoxes; i++ )
{
SwTableLine* pLine = rBoxes[i]->GetUpper(); if ( pLine != pPrevLine )
bRet &= pLine->IsTracked(nRedlinePos);
pPrevLine = pLine;
}
}
return bRet;
}
staticbool lcl_CursorInDeletedTable(const SwWrtShell &rSh)
{ // cursor and selection are there only in deleted table in Show Changes mode if ( rSh.GetLayout()->IsHideRedlines() ) returnfalse;
// At first the slots which doesn't need a FrameMgr. bool bMore = false; const SfxPoolItem* pItem = nullptr;
sal_uInt16 nSlot = rReq.GetSlot(); if(pArgs)
pArgs->GetItemState(GetPool().GetWhichIDFromSlotID(nSlot), false, &pItem); bool bCallDone = false; switch ( nSlot )
{ case SID_ATTR_BORDER:
{ if(!pArgs) break; // Create items, because we have to rework anyway.
std::shared_ptr<SvxBoxItem> aBox(std::make_shared<SvxBoxItem>(RES_BOX));
SfxItemSetFixed<RES_BOX, RES_BOX,
SID_ATTR_BORDER_INNER, SID_ATTR_BORDER_INNER>
aCoreSet( GetPool() );
SvxBoxInfoItem aCoreInfo( SID_ATTR_BORDER_INNER );
aCoreSet.Put(aCoreInfo);
rSh.GetTabBorders( aCoreSet ); const SvxBoxItem& rCoreBox = aCoreSet.Get(RES_BOX); const SvxBoxItem *pBoxItem = pArgs->GetItemIfSet(RES_BOX); if ( pBoxItem )
{
aBox.reset(pBoxItem->Clone());
sal_Int16 nDefValue = MIN_BORDER_DIST; if ( !rReq.IsAPI() )
nDefValue = 55; if (!rReq.IsAPI() || aBox->GetSmallestDistance() < MIN_BORDER_DIST)
{ for( SvxBoxItemLine k : o3tl::enumrange<SvxBoxItemLine>() )
aBox->SetDistance( std::max(rCoreBox.GetDistance(k), nDefValue) , k );
}
} else
OSL_ENSURE( false, "where is BoxItem?" );
//since the drawing layer also supports borders the which id might be a different one
std::shared_ptr<SvxBoxInfoItem> aInfo(std::make_shared<SvxBoxInfoItem>(SID_ATTR_BORDER_INNER)); if (const SvxBoxInfoItem* pBoxInfoItem = pArgs->GetItemIfSet(SID_ATTR_BORDER_INNER))
{
aInfo.reset(pBoxInfoItem->Clone());
} elseif( const SvxBoxInfoItem* pBoxInfoInnerItem = pArgs->GetItemIfSet(SDRATTR_TABLE_BORDER_INNER))
{
aInfo.reset(pBoxInfoInnerItem->Clone());
aInfo->SetWhich(SID_ATTR_BORDER_INNER);
}
// we must record the "real" values because otherwise the lines can't be reconstructed on playtime // the coding style of the controller (setting lines with width 0) is not transportable via Query/PutValue in // the SvxBoxItem
rReq.AppendItem( *aBox );
rReq.AppendItem( *aInfo );
bCallDone = true; break;
} case FN_INSERT_TABLE:
InsertTable( rReq ); break; case FN_BREAK_ABOVE_TABLE:
{
rSh.MoveTable( GotoCurrTable, fnTableStart );
rSh.SplitNode( false ); break;
} case FN_FORMAT_TABLE_DLG:
{ //#127012# get the bindings before the dialog is called // it might happen that this shell is removed after closing the dialog
SfxBindings& rBindings = GetView().GetViewFrame().GetBindings();
SfxItemSet aCoreSet( GetPool(), aUITableAttrRange);
if (pDlg)
{ if (pItem)
pDlg->SetCurPageId(static_cast<const SfxStringItem *>(pItem)->GetValue());
auto xRequest = std::make_shared<SfxRequest>(rReq);
rReq.Ignore(); // the 'old' request is not relevant any more
constbool bTableMode = rSh.IsTableMode();
SwPaM* pCursor = bTableMode ? rSh.GetTableCrs() : rSh.GetCursor(); // tdf#142165 use table cursor if in table mode auto vCursors = CopyPaMRing(*pCursor); // tdf#135636 make a copy to use at later apply
pDlg->StartExecuteAsync([pDlg, xRequest=std::move(xRequest), xTableRep=std::move(xTableRep),
&rBindings, &rSh, vCursors=std::move(vCursors), bTableMode](sal_Int32 nResult){ if (RET_OK == nResult)
{ if (!bTableMode && rSh.IsTableMode()) // tdf#140977 drop current table-cursor if setting a replacement
rSh.TableCursorToCursor(); // non-table one
// tdf#135636 set the selection at dialog launch as current selection
rSh.SetSelection(*vCursors->front()); // UpdateCursor() will be called which in the case // of a table selection should recreate a // SwShellTableCursor if the selection is more than a single cell
if (bTableMode && !rSh.IsTableMode()) // tdf#142721 ensure the new selection is a SwShellTableCursor in
rSh.SelTableBox(); // the case of a single cell
// tdf#132111: if RES_BOXATR_FORMAT state is DEFAULT (no number format set to cell // explicitly), it's not equal to any specific format (the rules are special, e.g. // it's considered numeric for empty or number text in SwTableBox::HasNumContent). // For multiselection, it's INVALID, also not equal to any single format. if (auto pFormat = aBoxSet.GetItemIfSet(RES_BOXATR_FORMAT))
pCoreSet->Put(SfxUInt32Item(SID_ATTR_NUMBERFORMAT_VALUE, pFormat->GetValue()));
if ( !bMore )
{ if(bCallDone)
rReq.Done(); return;
}
// Now the slots which are working directly on the TableFormat. switch ( nSlot )
{ case SID_ATTR_ULSPACE: if(pItem)
{
SvxULSpaceItem aULSpace( *static_cast<const SvxULSpaceItem*>(pItem) );
aULSpace.SetWhich( RES_UL_SPACE );
::lcl_SetAttr( rSh, aULSpace );
} break;
case SID_ATTR_LRSPACE: if(pItem)
{
SfxItemSetFixed<RES_LR_SPACE, RES_LR_SPACE,
RES_HORI_ORIENT, RES_HORI_ORIENT> aSet( GetPool() );
SvxLRSpaceItem aLRSpace( *static_cast<const SvxLRSpaceItem*>(pItem) );
aLRSpace.SetWhich( RES_LR_SPACE );
aSet.Put( aLRSpace );
rSh.SetTableAttr( aSet );
} break; // The last case branch which needs a table manager!! case FN_TABLE_SET_COL_WIDTH:
{ // Adjust line height (dialogue)
SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
VclPtr<AbstractSwTableWidthDlg> pDlg(pFact->CreateSwTableWidthDlg(GetView().GetFrameWeld(), &rSh));
pDlg->StartExecuteAsync(
[pDlg] (sal_Int32 nResult)->void
{ if (nResult == RET_OK)
pDlg->Apply();
pDlg->disposeOnce();
}
); break;
} case SID_TABLE_VERT_NONE: case SID_TABLE_VERT_CENTER: case SID_TABLE_VERT_BOTTOM:
{ const sal_uInt16 nAlign = nSlot == SID_TABLE_VERT_NONE ?
text::VertOrientation::NONE :
nSlot == SID_TABLE_VERT_CENTER ?
text::VertOrientation::CENTER : text::VertOrientation::BOTTOM;
rSh.SetBoxAlign(nAlign);
bCallDone = true; break;
}
case SID_ATTR_PARA_SPLIT: if ( pItem )
{
SwFormatLayoutSplit aSplit( static_cast<const SvxFormatSplitItem*>(pItem)->GetValue());
SfxItemSetFixed<RES_LAYOUT_SPLIT, RES_LAYOUT_SPLIT> aSet(GetPool());
aSet.Put(aSplit);
rSh.SetTableAttr(aSet);
} break;
void SwTableShell::GetState(SfxItemSet &rSet)
{
SfxWhichIter aIter( rSet );
SwWrtShell &rSh = GetShell();
SwFrameFormat *pFormat = rSh.GetTableFormat(); // os #124829# crash report: in case of an invalid shell selection return immediately if(!pFormat) return;
sal_uInt16 nSlot = aIter.FirstWhich(); while ( nSlot )
{ switch ( nSlot )
{ case FN_TABLE_MERGE_CELLS: if ( !rSh.IsTableMode() )
rSet.DisableItem(FN_TABLE_MERGE_CELLS); break; case SID_TABLE_MINIMAL_COLUMN_WIDTH: case FN_TABLE_ADJUST_CELLS: if ( !rSh.IsAdjustCellWidthAllowed() )
rSet.DisableItem(nSlot); break;
case FN_TABLE_BALANCE_CELLS: if ( !rSh.IsAdjustCellWidthAllowed(true) )
rSet.DisableItem(FN_TABLE_BALANCE_CELLS); break;
case FN_TABLE_OPTIMAL_HEIGHT: case FN_TABLE_BALANCE_ROWS: if ( !rSh.BalanceRowHeight(true) )
rSet.DisableItem(nSlot); break; case FN_OPTIMIZE_TABLE: if ( !rSh.IsTableMode() &&
!rSh.IsAdjustCellWidthAllowed() &&
!rSh.IsAdjustCellWidthAllowed(true) &&
!rSh.BalanceRowHeight(true) )
rSet.DisableItem(FN_OPTIMIZE_TABLE); break; case SID_INSERT_DIAGRAM:
{
SvtModuleOptions aMOpt; if ( !aMOpt.IsMathInstalled() || rSh.IsTableComplexForChart() )
rSet.DisableItem(nSlot);
} break;
case FN_INSERT_TABLE: if ( rSh.CursorInsideInputField() )
{
rSet.DisableItem( nSlot );
} break;
case SID_TABLE_MINIMAL_ROW_HEIGHT:
{ // Disable if auto height already is enabled.
std::unique_ptr<SwFormatFrameSize> pSz = rSh.GetRowHeight(); if ( pSz )
{ if ( SwFrameSize::Variable == pSz->GetHeightSizeType() )
rSet.DisableItem( nSlot );
} break;
} case FN_TABLE_INSERT_COL_BEFORE: case FN_TABLE_INSERT_COL_AFTER:
{
SfxImageItem aImageItem(nSlot); if (pFormat->GetFrameDir().GetValue() == SvxFrameDirection::Environment)
{ // Inherited from superordinate object (page or frame). // If the table spans multiple pages, direction is set by the first page.
SwIterator<SwTabFrame, SwFrameFormat> aIterT(*pFormat); for (SwTabFrame* pFrame = aIterT.First(); pFrame;
pFrame = static_cast<SwTabFrame*>(pFrame->GetPrecede()))
aImageItem.SetMirrored(pFrame->IsRightToLeft());
} else
aImageItem.SetMirrored(pFormat->GetFrameDir().GetValue() == SvxFrameDirection::Horizontal_RL_TB);
rSet.Put(aImageItem); break;
} case FN_TABLE_INSERT_ROW: case FN_TABLE_INSERT_ROW_AFTER: case FN_TABLE_INSERT_ROW_DLG: if ( rSh.IsInRepeatedHeadline() )
rSet.DisableItem( nSlot ); break; case RES_LR_SPACE:
rSet.Put(pFormat->GetLRSpace()); break; case RES_UL_SPACE:
rSet.Put(pFormat->GetULSpace()); break;
case FN_TABLE_MODE_FIX : case FN_TABLE_MODE_FIX_PROP : case FN_TABLE_MODE_VARIABLE :
{
TableChgMode nMode = rSh.GetTableChgMode(); bool bSet = (nSlot == FN_TABLE_MODE_FIX && nMode == TableChgMode::FixedWidthChangeAbs) ||
(nSlot == FN_TABLE_MODE_FIX_PROP && nMode == TableChgMode::FixedWidthChangeProp) ||
(nSlot == FN_TABLE_MODE_VARIABLE && nMode == TableChgMode::VarWidthChangeAbs);
rSet.Put(SfxBoolItem(nSlot, bSet));
} break; case FN_BREAK_ABOVE_TABLE:
{ // exec just moves on top and adds the break, which however makes only sense if the table // is the very first item of the document; the command should be hidden otherwise
SwContentFrame* pCurFrame = rSh.GetCurrFrame();
SwPageFrame* pPageFrame = pCurFrame->FindPageFrame();
SwFrame* pFrame = pPageFrame->Lower();
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.