/* -*- 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/. * * 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 .
*/
// evaluate the table right edge of the table if(mxColumnItem && mxColumnItem->IsTable())
lRight = mxColumnItem->GetRight(); else
lRight = mxLRSpaceItem->GetRight();
void SvxRuler::UpdateFrame(const SvxLongLRSpaceItem *pItem) // new value LRSpace
{ /* Store new value LRSpace; delete old ones if possible */ if(bActive)
{ if(pItem)
mxLRSpaceItem.reset(new SvxLongLRSpaceItem(*pItem)); else
mxLRSpaceItem.reset();
StartListening_Impl();
}
}
void SvxRuler::UpdateFrameMinMax(const SfxRectangleItem *pItem) // value for MinMax
{ /* Set new value for MinMax; delete old ones if possible */ if(bActive)
{ if(pItem)
mxMinMaxItem.reset(new SfxRectangleItem(*pItem)); else
mxMinMaxItem.reset();
}
}
void SvxRuler::Update( const SvxColumnItem *pItem, // new value
sal_uInt16 nSID) //Slot Id to identify NULL items
{ /* Set new value for column view */ if(!bActive) return;
if(pItem)
{
mxColumnItem.reset(new SvxColumnItem(*pItem));
mxRulerImpl->bIsTableRows = (pItem->Which() == SID_RULER_ROWS || pItem->Which() == SID_RULER_ROWS_VERTICAL); if(!bHorz && !mxRulerImpl->bIsTableRows)
mxColumnItem->SetWhich(SID_RULER_BORDERS_VERTICAL);
} elseif(mxColumnItem && mxColumnItem->Which() == nSID) //there are two groups of column items table/frame columns and table rows //both can occur in vertical or horizontal mode //the horizontal ruler handles the SID_RULER_BORDERS and SID_RULER_ROWS_VERTICAL //and the vertical handles SID_RULER_BORDERS_VERTICAL and SID_RULER_ROWS //if mxColumnItem is already set with one of the ids then a NULL pItem argument //must not delete it
{
mxColumnItem.reset();
mxRulerImpl->bIsTableRows = false;
}
StartListening_Impl();
}
if(mxColumnItem->Count() == i + 1)
{ //with table rows the end of the table is contained in the //column item but it has no width!
mpBorders[i].nWidth = 0;
} else
{
mpBorders[i].nWidth = ConvertSizePixel(mxColumnItem->At(i + 1).nStart - mxColumnItem->At(i).nEnd);
}
mpBorders[i].nMinPos = ConvertPosPixel(mxColumnItem->At(i).nEndMin + lAppNullOffset);
mpBorders[i].nMaxPos = ConvertPosPixel(mxColumnItem->At(i).nEndMax + lAppNullOffset);
}
SetBorders(mxColumnItem->Count() - 1, mpBorders.data());
} else
{
SetBorders();
}
}
/* Update the view for paragraph indents: Left margin, first line indent, right margin paragraph update mpIndents[0] = Buffer for old intent mpIndents[1] = Buffer for old intent mpIndents[INDENT_FIRST_LINE] = first line indent mpIndents[INDENT_LEFT_MARGIN] = left margin mpIndents[INDENT_RIGHT_MARGIN] = right margin
*/
// Dependence on PagePosItem if (mxParaItem && mxPagePosItem && !mxObjectItem)
{ bool bRTLText = mxRulerImpl->pTextRTLItem && mxRulerImpl->pTextRTLItem->GetValue(); // First-line indent is negative to the left paragraph margin
tools::Long nLeftFrameMargin = GetLeftFrameMargin();
tools::Long nRightFrameMargin = GetRightFrameMargin();
SetLeftFrameMargin(ConvertHPosPixel(nLeftFrameMargin));
SetRightFrameMargin(ConvertHPosPixel(nRightFrameMargin));
void SvxRuler::UpdatePara(const SvxLRSpaceItem *pItem) // new value of paragraph indents
{ /* Store new value of paragraph indents */ if(bActive)
{ if(pItem)
mxParaItem.reset(new SvxLRSpaceItem(*pItem)); else
mxParaItem.reset();
StartListening_Impl();
}
}
void SvxRuler::UpdatePage()
{ /* Update view of position and width of page */ if (mxPagePosItem)
{ // all objects are automatically adjusted if(bHorz)
{
SetPagePos(
pEditWin->LogicToPixel(mxPagePosItem->GetPos()).X(),
pEditWin->LogicToPixel(Size(mxPagePosItem->GetWidth(), 0)).
Width());
} else
{
SetPagePos(
pEditWin->LogicToPixel(mxPagePosItem->GetPos()).Y(),
pEditWin->LogicToPixel(Size(0, mxPagePosItem->GetHeight())).
Height());
} if(bAppSetNullOffset)
SetNullOffset(ConvertSizePixel(-lAppNullOffset + lLogicNullOffset));
} else
{
SetPagePos();
}
tools::Long lPos = 0;
Point aOwnPos = GetPosPixel();
Point aEdtWinPos = pEditWin->GetPosPixel(); if( AllSettings::GetLayoutRTL() && bHorz )
{ //#i73321# in RTL the window and the ruler is not mirrored but the // influence of the vertical ruler is inverted
Size aOwnSize = GetSizePixel();
Size aEdtWinSize = pEditWin->GetSizePixel();
lPos = aOwnSize.Width() - aEdtWinSize.Width();
lPos -= (aEdtWinPos - aOwnPos).X();
} else
{
Point aPos(aEdtWinPos - aOwnPos);
lPos = bHorz ? aPos.X() : aPos.Y();
}
// Unfortunately, we get the offset of the edit window to the ruler never // through a status message. So we set it ourselves if necessary. if(lPos != mxRulerImpl->lOldWinPos)
{
mxRulerImpl->lOldWinPos=lPos;
SetWinPos(lPos);
}
}
void SvxRuler::Update(const SvxPagePosSizeItem *pItem) // new value of page attributes
{ /* Store new value of page attributes */ if(bActive)
{ if(pItem)
mxPagePosItem.reset(new SvxPagePosSizeItem(*pItem)); else
mxPagePosItem.reset();
StartListening_Impl();
}
}
void SvxRuler::SetDefTabDist(tools::Long inDefTabDist) // New distance for DefaultTabs in App-Metrics
{ if (lAppNullOffset == LONG_MAX)
UpdateFrame(); // hack: try to get lAppNullOffset initialized /* New distance is set for DefaultTabs */
lDefTabDist = inDefTabDist; if( !lDefTabDist )
lDefTabDist = 1;
UpdateTabs();
}
static sal_uInt16 ToSvTab_Impl(SvxTabAdjust eAdj)
{ /* Internal conversion routine between SV-Tab.-Enum and Svx */ switch(eAdj) { case SvxTabAdjust::Left: return RULER_TAB_LEFT; case SvxTabAdjust::Right: return RULER_TAB_RIGHT; case SvxTabAdjust::Decimal: return RULER_TAB_DECIMAL; case SvxTabAdjust::Center: return RULER_TAB_CENTER; case SvxTabAdjust::Default: return RULER_TAB_DEFAULT; default: ; //prevent warning
} return 0;
}
static SvxTabAdjust ToAttrTab_Impl(sal_uInt16 eAdj)
{ switch(eAdj) { case RULER_TAB_LEFT: return SvxTabAdjust::Left ; case RULER_TAB_RIGHT: return SvxTabAdjust::Right ; case RULER_TAB_DECIMAL: return SvxTabAdjust::Decimal ; case RULER_TAB_CENTER: return SvxTabAdjust::Center ; case RULER_TAB_DEFAULT: return SvxTabAdjust::Default ;
} return SvxTabAdjust::Left;
}
void SvxRuler::Update(const SvxTabStopItem *pItem) // new value for tabs
{ /* Store new value for tabs; delete old ones if possible */ if(!bActive) return;
void SvxRuler::Update(const SvxObjectItem *pItem) // new value for objects
{ /* Store new value for objects */ if(bActive)
{ if(pItem)
mxObjectItem.reset(new SvxObjectItem(*pItem)); else
mxObjectItem.reset();
StartListening_Impl();
}
}
// Determine if we are a Ruler for Writer or not if (SfxViewFrame* pFrame = SfxViewFrame::Current())
{
uno::Reference<frame::XFrame> xFrame = pFrame->GetFrame().GetFrameInterface();
uno::Reference<frame::XModel> xModel = xFrame->getController()->getModel();
uno::Reference<lang::XServiceInfo> xSI(xModel, uno::UNO_QUERY); if (xSI.is())
{
bWriter = xSI->supportsService("com.sun.star.text.TextDocument")
|| xSI->supportsService("com.sun.star.text.WebDocument")
|| xSI->supportsService("com.sun.star.text.GlobalDocument");
}
}
if (bWriter)
{ // In Writer the ruler values need to be converted first from pixel to twips (default logical unit) and then to 100thmm
nMargin1 = convertTwipToMm100(ConvertPosLogic(GetMargin1()));
nMargin2 = convertTwipToMm100(ConvertPosLogic(GetMargin2()));
nNullOffset = convertTwipToMm100(ConvertPosLogic(GetNullOffset()));
nPageOffset = convertTwipToMm100(ConvertPosLogic(GetPageOffset()));
nPageWidthHeight = convertTwipToMm100(GetPageWidth());
} else
{ // Only convert from pixel to default logical unit, which is 100thmm for Impress
nMargin1 = ConvertPosLogic(GetMargin1());
nMargin2 = ConvertPosLogic(GetMargin2());
nPageOffset = ConvertPosLogic(GetPageOffset());
// In LOKit API we expect the ruler 0,0 coordinate is where the document starts. // In Impress and Draw the ruler 0,0 is where the canvas starts, not where the document starts. // The margin to the document is 1 document width (on the left and right) and 0.5 document height // (on the top and bottom). // So the canvas width = 3 * document width, canvas height = 2 * document height if (isHorizontal())
{
nPageWidthHeight = GetPageWidth() / 3;
nNullOffset = ConvertPosLogic(GetNullOffset()) - nPageWidthHeight;
} else
{
nPageWidthHeight = GetPageWidth() / 2;
nNullOffset = ConvertPosLogic(GetNullOffset()) - (nPageWidthHeight / 2);
}
}
// The RulerTab array elements that GetTabs() returns have their nPos field in twips. So these // too are actual mm100. for (autoconst& tab : GetTabs())
{ auto tabNode = rJsonWriter.startNode("");
rJsonWriter.put("position", convertTwipToMm100(tab.nPos));
rJsonWriter.put("style", tab.nStyle);
}
}
inline tools::Long SvxRuler::GetFrameLeft() const
{ /* Get Left margin in Pixels */ return bAppSetNullOffset ?
GetMargin1() + ConvertSizePixel(lLogicNullOffset) :
Ruler::GetNullOffset();
}
tools::Long SvxRuler::GetFirstLineIndent() const
{ /* Get First-line indent in pixels */ return mxParaItem ? mpIndents[INDENT_FIRST_LINE].nPos : GetMargin1();
}
tools::Long SvxRuler::GetLeftIndent() const
{ /* Get Left paragraph margin in Pixels */ return mxParaItem ? mpIndents[INDENT_LEFT_MARGIN].nPos : GetMargin1();
}
tools::Long SvxRuler::GetRightIndent() const
{ /* Get Right paragraph margin in Pixels */ return mxParaItem ? mpIndents[INDENT_RIGHT_MARGIN].nPos : GetMargin2();
}
tools::Long SvxRuler::GetLogicRightIndent() const
{ /* Get Right paragraph margin in Logic */ return mxParaItem ? GetRightFrameMargin() - mxParaItem->ResolveRight({})
: GetRightFrameMargin();
}
// Left margin in App values, is either the margin (= 0) or the left edge of // the column that is set in the column attribute as current column.
tools::Long SvxRuler::GetLeftFrameMargin() const
{ // #126721# for some unknown reason the current column is set to 0xffff
DBG_ASSERT(!mxColumnItem || mxColumnItem->GetActColumn() < mxColumnItem->Count(), "issue #126721# - invalid current column!");
tools::Long nLeft = 0; if (mxColumnItem &&
mxColumnItem->Count() &&
mxColumnItem->IsConsistent())
{
nLeft = mxColumnItem->GetActiveColumnDescription().nStart;
}
if (mxBorderItem && (!mxColumnItem || mxColumnItem->IsTable()))
nLeft += mxBorderItem->ResolveLeft({});
return nLeft;
}
inline tools::Long SvxRuler::GetLeftMin() const
{
DBG_ASSERT(mxMinMaxItem, "no MinMax value set"); if (mxMinMaxItem)
{ if (bHorz) return mxMinMaxItem->GetValue().Left(); else return mxMinMaxItem->GetValue().Top();
} return 0;
}
inline tools::Long SvxRuler::GetRightMax() const
{
DBG_ASSERT(mxMinMaxItem, "no MinMax value set"); if (mxMinMaxItem)
{ if (bHorz) return mxMinMaxItem->GetValue().Right(); else return mxMinMaxItem->GetValue().Bottom();
} return 0;
}
tools::Long SvxRuler::GetRightFrameMargin() const
{ /* Get right frame margin (in logical units) */ if (mxColumnItem)
{ if (!IsActLastColumn(true))
{ return mxColumnItem->At(GetActRightColumn(true)).nEnd;
}
}
tools::Long lResult = lLogicNullOffset;
// If possible deduct right table entry if(mxColumnItem && mxColumnItem->IsTable())
lResult += mxColumnItem->GetRight(); elseif(bHorz && mxLRSpaceItem)
lResult += mxLRSpaceItem->GetRight(); elseif(!bHorz && mxULSpaceItem)
lResult += mxULSpaceItem->GetLower();
tools::Long SvxRuler::GetCorrectedDragPos( bool bLeft, bool bRight )
{ /* Corrects the position within the calculated limits. The limit values are in pixels relative to the page edge.
*/
staticvoid ModifyTabs_Impl( sal_uInt16 nCount, // Number of Tabs
RulerTab* pTabs, // Tab buffer
tools::Long lDiff) // difference to be added
{ /* Helper function, move all the tabs by a fixed value */ if( pTabs )
{ for(sal_uInt16 i = 0; i < nCount; ++i)
{
pTabs[i].nPos += lDiff;
}
}
}
void SvxRuler::DragMargin1()
{ /* Dragging the left edge of frame */
tools::Long aDragPosition = GetCorrectedDragPos( !TAB_FLAG || !NEG_FLAG );
if (!mxColumnItem && !mxObjectItem && mxParaItem)
{ // Right indent of the old position
mpIndents[INDENT_RIGHT_MARGIN].nPos -= lDiff;
SetIndents(INDENT_COUNT, mpIndents.data() + INDENT_GAP);
} if (mxObjectItem)
{
mpObjectBorders[GetObjectBordersOff(0)].nPos -= lDiff;
mpObjectBorders[GetObjectBordersOff(1)].nPos -= lDiff;
SetBorders(2, mpObjectBorders.data() + GetObjectBordersOff(0));
} if (mxColumnItem)
{ for(sal_uInt16 i = 0; i < mxColumnItem->Count()-1; ++i)
mpBorders[i].nPos -= lDiff;
SetBorders(mxColumnItem->Count()-1, mpBorders.data()); if(mxColumnItem->IsFirstAct())
{ // Right indent of the old position if (mxParaItem)
{
mpIndents[INDENT_RIGHT_MARGIN].nPos -= lDiff;
SetIndents(INDENT_COUNT, mpIndents.data() + INDENT_GAP);
}
} else
{ if (mxParaItem)
{
mpIndents[INDENT_FIRST_LINE].nPos -= lDiff;
mpIndents[INDENT_LEFT_MARGIN].nPos -= lDiff;
mpIndents[INDENT_RIGHT_MARGIN].nPos -= lDiff;
SetIndents(INDENT_COUNT, mpIndents.data() + INDENT_GAP);
}
} if(mxTabStopItem && (nDragType & SvxRulerDragFlags::OBJECT_SIZE_PROPORTIONAL)
&&!IsActFirstColumn())
{
ModifyTabs_Impl(nTabCount + TAB_GAP, mpTabs.data(), -lDiff);
SetTabs(nTabCount, mpTabs.data() + TAB_GAP);
}
}
}
} else
{
tools::Long lDiff = lDragPos - nOld;
SetMargin1(nOld + lDiff, nMarginStyle);
if (!mxColumnItem
|| !(nDragType
& (SvxRulerDragFlags::OBJECT_SIZE_LINEAR
| SvxRulerDragFlags::OBJECT_SIZE_PROPORTIONAL)))
{ if (!mxColumnItem && !mxObjectItem && mxParaItem)
{ // Left indent of the old position
mpIndents[INDENT_FIRST_LINE].nPos += lDiff;
mpIndents[INDENT_LEFT_MARGIN].nPos += lDiff;
SetIndents(INDENT_COUNT, mpIndents.data() + INDENT_GAP);
}
if (mxColumnItem)
{ for(sal_uInt16 i = 0; i < mxColumnItem->Count() - 1; ++i)
mpBorders[i].nPos += lDiff;
SetBorders(mxColumnItem->Count() - 1, mpBorders.data()); if (mxColumnItem->IsFirstAct())
{ // Left indent of the old position if (mxParaItem)
{
mpIndents[INDENT_FIRST_LINE].nPos += lDiff;
mpIndents[INDENT_LEFT_MARGIN].nPos += lDiff;
SetIndents(INDENT_COUNT, mpIndents.data() + INDENT_GAP);
}
} else
{ if (mxParaItem)
{
mpIndents[INDENT_FIRST_LINE].nPos += lDiff;
mpIndents[INDENT_LEFT_MARGIN].nPos += lDiff;
mpIndents[INDENT_RIGHT_MARGIN].nPos += lDiff;
SetIndents(INDENT_COUNT, mpIndents.data() + INDENT_GAP);
}
}
} if (mxTabStopItem)
{
ModifyTabs_Impl(nTabCount + TAB_GAP, mpTabs.data(), lDiff);
SetTabs(nTabCount, mpTabs.data() + TAB_GAP);
}
}
}
}
void SvxRuler::DragMargin2()
{ /* Dragging the right edge of frame */
tools::Long aDragPosition = GetCorrectedDragPos( true, !TAB_FLAG || !NEG_FLAG);
aDragPosition = MakePositionSticky(aDragPosition, GetLeftFrameMargin(), false);
tools::Long lDiff = aDragPosition - GetMargin2();
// Check if position changed if (lDiff == 0) return;
// Right indent of the old position if ((!mxColumnItem || IsActLastColumn()) && mxParaItem)
{
mpIndents[INDENT_FIRST_LINE].nPos += lDiff;
SetIndents(INDENT_COUNT, mpIndents.data() + INDENT_GAP);
}
// the drag position has to be corrected to be able to prevent borders from passing each other
tools::Long lPos = MakePositionSticky(GetCorrectedDragPos(), GetLeftFrameMargin());
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.