/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ /* * 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/.
*/
void UnfloatTableButton::SetOffset(Point aTopRightPixel)
{ // Compute the text size and get the box position & size from it
tools::Rectangle aTextRect;
m_xVirDev->GetTextBoundRect(aTextRect, m_sLabel);
tools::Rectangle aTextPxRect = m_xVirDev->LogicToPixel(aTextRect);
FontMetric aFontMetric = m_xVirDev->GetFontMetric(m_xVirDev->GetFont());
Size aBoxSize(aTextPxRect.GetWidth() + BUTTON_WIDTH + TEXT_PADDING * 2,
aFontMetric.GetLineHeight() + TEXT_PADDING * 2);
Point aBoxPos(aTopRightPixel.X() - aBoxSize.Width() - BOX_DISTANCE, aTopRightPixel.Y());
if (AllSettings::GetLayoutRTL())
{
aBoxPos.setX(aTopRightPixel.X() + BOX_DISTANCE);
}
// Set the position & Size of the window
SetPosSizePixel(aBoxPos, aBoxSize);
m_xVirDev->SetOutputSizePixel(aBoxSize);
PaintButton();
}
IMPL_LINK_NOARG(UnfloatTableButton, ClickHdl, weld::Button&, void)
{
assert(GetFrame()->IsFlyFrame()); // const_cast is needed because of bad design of ISwFrameControl and derived classes
SwFlyFrame* pFlyFrame = const_cast<SwFlyFrame*>(static_cast<const SwFlyFrame*>(GetFrame()));
// Find the table inside the text frame
SwTabFrame* pTableFrame = nullptr;
SwFrame* pLower = pFlyFrame->GetLower(); while (pLower)
{ if (pLower->IsTabFrame())
{
pTableFrame = static_cast<SwTabFrame*>(pLower); break;
}
pLower = pLower->GetNext();
}
if (pTableFrame == nullptr) return;
// Insert the table at the position of the text node which has the frame anchored to
SwFrame* pAnchoreFrame = pFlyFrame->AnchorFrame(); if (pAnchoreFrame == nullptr || !pAnchoreFrame->IsTextFrame()) return;
SwTextFrame* pTextFrame = static_cast<SwTextFrame*>(pAnchoreFrame); if (pTextFrame->GetTextNodeFirst() == nullptr) return;
SwTableNode* pTableNode = pTableFrame->GetTable()->GetTableNode(); if (pTableNode == nullptr) return;
SwDoc& rDoc = pTextFrame->GetDoc();
// tdf#129176: clear "TablePosition" grab bag, since we explicitly change the position here // See DomainMapperTableHandler::endTableGetTableStyle, where the grab bag is filled, and // DocxAttributeOutput::TableDefinition that uses it on export
SwFrameFormat* pTableFormat = pTableFrame->GetTable()->GetFrameFormat();
assert(pTableFormat); if (const SfxGrabBagItem* pGrabBagItem = pTableFormat->GetAttrSet().GetItem(RES_FRMATR_GRABBAG))
{
std::map<OUString, css::uno::Any> aGrabBagMap = pGrabBagItem->GetGrabBag(); // Editable copy if (aGrabBagMap.erase(u"TablePosition"_ustr))
{
SfxGrabBagItem aNewGrabBagItem(RES_FRMATR_GRABBAG, std::move(aGrabBagMap));
css::uno::Any aVal;
aNewGrabBagItem.QueryValue(aVal);
pTableFormat->SetFormatAttr(aNewGrabBagItem); const rtl::Reference<SwXTextTable> xTable
= SwXTextTable::CreateXTextTable(pTableFormat);
xTable->setPropertyValue(UNO_NAME_TABLE_INTEROP_GRAB_BAG, aVal);
}
}
// When we move the table before the first text node, we need to clear RES_PAGEDESC attribute // of the text node otherwise LO will create a page break after the table if (pTextFrame->GetTextNodeFirst())
{ const SwPageDesc* pPageDesc
= pTextFrame->GetPageDescItem().GetPageDesc(); // First text node of the page has this if (pPageDesc)
{ // First set the existing page desc for the table node
SfxItemSetFixed<RES_PAGEDESC, RES_PAGEDESC> aSet(
GetEditWin()->GetView().GetWrtShell().GetAttrPool());
aSet.Put(SwFormatPageDesc(pPageDesc));
SwPaM aPaMTable(*pTableNode);
rDoc.getIDocumentContentOperations().InsertItemSet(
aPaMTable, aSet, SetAttrMode::DEFAULT, GetPageFrame()->getRootFrame());
// Then remove pagedesc from the attributes of the text node
aSet.Put(SwFormatPageDesc(nullptr));
SwPaM aPaMTextNode(*pTextFrame->GetTextNodeFirst());
rDoc.getIDocumentContentOperations().InsertItemSet(
aPaMTextNode, aSet, SetAttrMode::DEFAULT, GetPageFrame()->getRootFrame());
}
}
// Undoing MoveNodeRange() is not working correctly in case of tables, it crashes sometimes // So don't allow to undo after unfloating (similar to MakeFlyAndMove() method) if (rDoc.GetIDocumentUndoRedo().DoesUndo())
{
rDoc.GetIDocumentUndoRedo().DelAllUndoObj();
}
}
void UnfloatTableButton::PaintButton()
{ if (!m_xVirDev) return;
// Create the processor and process the primitives const drawinglayer::geometry::ViewInformation2D aNewViewInfos;
std::unique_ptr<drawinglayer::processor2d::BaseProcessor2D> pProcessor(
drawinglayer::processor2d::createProcessor2DFromOutputDevice(*m_xVirDev, aNewViewInfos));
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.