From 98608e57f21820ec1d2c6cd77f433b6963e249a6 Mon Sep 17 00:00:00 2001 From: Tomaž Vajngerl Date: Tue, 23 Jul 2013 20:43:29 +0200 Subject: fdo#38144 In ruler snap to markers for tab stops, margins, etc. Change-Id: Ie7f829b0ec36af79a2a97d9de7b6e37034c22e61 --- include/svtools/ruler.hxx | 14 +++ include/svx/ruler.hxx | 5 +- svtools/source/control/ruler.cxx | 20 ++--- svx/source/dialog/svxruler.cxx | 181 ++++++++++++++++++++++++--------------- 4 files changed, 134 insertions(+), 86 deletions(-) diff --git a/include/svtools/ruler.hxx b/include/svtools/ruler.hxx index bee6f05d91b5..4c08745d2c21 100644 --- a/include/svtools/ruler.hxx +++ b/include/svtools/ruler.hxx @@ -586,6 +586,18 @@ struct RulerLine sal_uInt16 nStyle; }; +struct RulerUnitData +{ + MapUnit eMapUnit; // MAP_UNIT for calculaion + long nTickUnit; // Unit divider + long nTick1; // Minimal step + long nTick2; // Tick half unit + long nTick3; // Tick whole unit + long n100THMM; // 100mm Unit divider + sal_uInt16 nUnitDigits; // Number of digits + sal_Char aUnitStr[8]; // Unit string +}; + class ImplRulerData; // --------- // - Ruler - @@ -681,6 +693,8 @@ private: protected: long GetRulerVirHeight() const; + MapMode GetMapMode() const { return maMapMode; } + RulerUnitData GetCurrentRulerUnit() const; public: Ruler( Window* pParent, WinBits nWinStyle = WB_STDRULER ); diff --git a/include/svx/ruler.hxx b/include/svx/ruler.hxx index aa18893ec3cc..a6faad748bc8 100644 --- a/include/svx/ruler.hxx +++ b/include/svx/ruler.hxx @@ -22,7 +22,7 @@ #include #include #include -#include "svx/svxdllapi.h" +#include class SvxProtectItem; class SvxRulerItem; @@ -124,6 +124,9 @@ class SVX_DLLPUBLIC SvxRuler: public Ruler, public SfxListener void UpdateColumns(); void UpdateObject(); + // Normalize position to the ruler's tick value + void NormalizePosition(long& rValue) const; + long PixelHAdjust(long lPos, long lPos2) const; long PixelVAdjust(long lPos, long lPos2) const; long PixelAdjust(long lPos, long lPos2) const; diff --git a/svtools/source/control/ruler.cxx b/svtools/source/control/ruler.cxx index 0a683692be2a..d1289756cf36 100644 --- a/svtools/source/control/ruler.cxx +++ b/svtools/source/control/ruler.cxx @@ -105,20 +105,7 @@ public: ImplRulerData& operator=( const ImplRulerData& rData ); }; - -struct ImplRulerUnitData -{ - MapUnit eMapUnit; // MAP_UNIT zum Umrechnen - long nTickUnit; // Teiler fuer Einheit - long nTick1; // Schrittweite - long nTick2; // Tick fuer halbe Werte - long nTick3; // Tick fuer Zahlenausgabe - long n100THMM; // Teiler fuer Einheit - sal_uInt16 nUnitDigits; // Anzahl Nachkommastellen - sal_Char aUnitStr[8]; // Einheiten-String -}; - -static ImplRulerUnitData aImplRulerUnitTab[RULER_UNIT_COUNT] = +static RulerUnitData aImplRulerUnitTab[RULER_UNIT_COUNT] = { { MAP_100TH_MM, 100, 25, 50, 100, 100, 3, " mm" }, // MM { MAP_100TH_MM, 1000, 250, 500, 1000, 1000, 3, " cm" }, // CM @@ -2776,6 +2763,11 @@ long Ruler::GetMargin1() const { return mpData->nMargin1; } long Ruler::GetMargin2() const { return mpData->nMargin2; } long Ruler::GetRulerVirHeight() const { return mnVirHeight; } +RulerUnitData Ruler::GetCurrentRulerUnit() const +{ + return aImplRulerUnitTab[mnUnitIndex]; +} + void Ruler::DrawTicks() { mbFormat = sal_True; diff --git a/svx/source/dialog/svxruler.cxx b/svx/source/dialog/svxruler.cxx index fe648c279b61..ff87c51a213d 100644 --- a/svx/source/dialog/svxruler.cxx +++ b/svx/source/dialog/svxruler.cxx @@ -19,23 +19,24 @@ #include #include + #include #include +#include #include #include -#include - #include - +#include #include #include #include -#include "rlrcitem.hxx" -#include "svx/rulritem.hxx" +#include #include #include -#include "editeng/protitem.hxx" -#include +#include + +#include "rlrcitem.hxx" + #ifndef RULER_TAB_RTL #define RULER_TAB_RTL ((sal_uInt16)0x0010) #endif @@ -269,7 +270,6 @@ void SvxRuler_Impl::SetPercSize(sal_uInt16 nSize) // expects: something like SwTabCols // Ruler: SetBorders - SvxRuler::SvxRuler( Window* pParent, // StarView Parent Window* pWin, // Output window: is used for conversion @@ -433,6 +433,15 @@ SvxRuler::~SvxRuler() } /* Internal conversion routines */ + +void SvxRuler::NormalizePosition(long& rValue) const +{ + long aNewPositionLogic = pEditWin->PixelToLogic(Size(0, rValue), GetMapMode()).Height(); + long aTickDivider = GetCurrentRulerUnit().nTick1; + aNewPositionLogic = (aNewPositionLogic / aTickDivider) * aTickDivider; + rValue = pEditWin->LogicToPixel(Size(0, aNewPositionLogic), GetMapMode()).Height(); +} + long SvxRuler::ConvertHPosPixel(long nVal) const { return pEditWin->LogicToPixel(Size(nVal, 0)).Width(); @@ -1360,10 +1369,15 @@ void ModifyTabs_Impl( sal_uInt16 nCount, // Number of Tabs void SvxRuler::DragMargin1() { /* Dragging the left edge of frame */ - const long lDragPos = GetCorrectedDragPos( !TAB_FLAG || !NEG_FLAG, sal_True ); + long lDragPos = GetCorrectedDragPos( !TAB_FLAG || !NEG_FLAG, sal_True ); + NormalizePosition(lDragPos); + + // Check if position changed + if (lDragPos == 0) + return; + DrawLine_Impl(lTabPos, ( TAB_FLAG && NEG_FLAG ) ? 3 : 7, bHorz); - if(pColumnItem&& - (nDragType & DRAG_OBJECT_SIZE_PROPORTIONAL)) + if(pColumnItem && (nDragType & DRAG_OBJECT_SIZE_PROPORTIONAL)) DragBorders(); AdjustMargin1(lDragPos); } @@ -1486,13 +1500,19 @@ void SvxRuler::AdjustMargin1(long lDiff) void SvxRuler::DragMargin2() { /* Dragging the right edge of frame */ - const long lDragPos = GetCorrectedDragPos( sal_True, !TAB_FLAG || !NEG_FLAG); - DrawLine_Impl(lTabPos, ( TAB_FLAG && NEG_FLAG ) ? 5 : 7, bHorz); + long lDragPos = GetCorrectedDragPos( sal_True, !TAB_FLAG || !NEG_FLAG); + NormalizePosition(lDragPos); long lDiff = lDragPos - GetMargin2(); - if(pRuler_Imp->bIsTableRows && !bHorz && pColumnItem&& + // Check if position changed + if (lDiff == 0) + return; + + if(pRuler_Imp->bIsTableRows && !bHorz && pColumnItem && (nDragType & DRAG_OBJECT_SIZE_PROPORTIONAL)) + { DragBorders(); + } sal_Bool bProtectColumns = pRuler_Imp->aProtectItem.IsSizeProtected() || @@ -1507,76 +1527,86 @@ void SvxRuler::DragMargin2() pIndents[INDENT_FIRST_LINE].nPos += lDiff; SetIndents(INDENT_COUNT, pIndents+INDENT_GAP); } + + DrawLine_Impl(lTabPos, ( TAB_FLAG && NEG_FLAG ) ? 5 : 7, bHorz); } void SvxRuler::DragIndents() { /* Dragging the paragraph indents */ - const long lDragPos = NEG_FLAG ? GetDragPos() : GetCorrectedDragPos(); - const sal_uInt16 nIdx = GetDragAryPos()+INDENT_GAP; - const long lDiff = pIndents[nIdx].nPos - lDragPos; - - if((nIdx == INDENT_FIRST_LINE || - nIdx == INDENT_LEFT_MARGIN ) && - (nDragType & DRAG_OBJECT_LEFT_INDENT_ONLY) != - DRAG_OBJECT_LEFT_INDENT_ONLY) + long lDragPos = NEG_FLAG ? GetDragPos() : GetCorrectedDragPos(); + const sal_uInt16 nIndex = GetDragAryPos() + INDENT_GAP; + NormalizePosition(lDragPos); + const long lDiff = pIndents[nIndex].nPos - lDragPos; + + // Check if position changed + if (lDiff == 0) + return; + + if((nIndex == INDENT_FIRST_LINE || nIndex == INDENT_LEFT_MARGIN ) && + (nDragType & DRAG_OBJECT_LEFT_INDENT_ONLY) != DRAG_OBJECT_LEFT_INDENT_ONLY) + { pIndents[INDENT_FIRST_LINE].nPos -= lDiff; + } - pIndents[nIdx].nPos = lDragPos; + pIndents[nIndex].nPos = lDragPos; SetIndents(INDENT_COUNT, pIndents + INDENT_GAP); DrawLine_Impl(lTabPos, 1, bHorz); } -void SvxRuler::DrawLine_Impl(long &_lTabPos, int nNew, sal_Bool Hori) +void SvxRuler::DrawLine_Impl(long& lTabPosition, int nNew, sal_Bool bHorizontal) { /* Output routine for the ledger line when moving tabs, tables and other columns */ - if(Hori) + if(bHorizontal) { const long nHeight = pEditWin->GetOutputSize().Height(); - Point aZero=pEditWin->GetMapMode().GetOrigin(); - if(_lTabPos!=-1) + Point aZero = pEditWin->GetMapMode().GetOrigin(); + if(lTabPosition != -1) + { pEditWin->InvertTracking( - Rectangle( Point(_lTabPos, -aZero.Y()), - Point(_lTabPos, -aZero.Y()+nHeight)), + Rectangle( Point(lTabPosition, -aZero.Y()), + Point(lTabPosition, -aZero.Y() + nHeight)), SHOWTRACK_SPLIT | SHOWTRACK_CLIP ); + } if( nNew & 1 ) { - - _lTabPos = ConvertHSizeLogic( - GetCorrectedDragPos( ( nNew&4 ) != 0, ( nNew&2 ) != 0 ) + - GetNullOffset() ); + long nDrapPosition = GetCorrectedDragPos( ( nNew & 4 ) != 0, ( nNew & 2 ) != 0 ); + NormalizePosition(nDrapPosition); + lTabPosition = ConvertHSizeLogic( nDrapPosition + GetNullOffset() ); if(pPagePosItem) - _lTabPos += pPagePosItem->GetPos().X(); + lTabPosition += pPagePosItem->GetPos().X(); pEditWin->InvertTracking( - Rectangle(Point(_lTabPos, -aZero.Y()), - Point(_lTabPos, -aZero.Y()+nHeight)), + Rectangle( Point(lTabPosition, -aZero.Y()), + Point(lTabPosition, -aZero.Y() + nHeight) ), SHOWTRACK_CLIP | SHOWTRACK_SPLIT ); } } else { const long nWidth = pEditWin->GetOutputSize().Width(); - Point aZero=pEditWin->GetMapMode().GetOrigin(); - if(_lTabPos != -1) + Point aZero = pEditWin->GetMapMode().GetOrigin(); + if(lTabPosition != -1) { pEditWin->InvertTracking( - Rectangle( Point(-aZero.X(), _lTabPos), - Point(-aZero.X()+nWidth, _lTabPos)), + Rectangle( Point(-aZero.X(), lTabPosition), + Point(-aZero.X() + nWidth, lTabPosition)), SHOWTRACK_SPLIT | SHOWTRACK_CLIP ); } if(nNew & 1) { - _lTabPos = ConvertVSizeLogic(GetCorrectedDragPos()+GetNullOffset()); + long nDrapPosition = GetCorrectedDragPos(); + NormalizePosition(nDrapPosition); + lTabPosition = ConvertVSizeLogic(nDrapPosition + GetNullOffset()); if(pPagePosItem) - _lTabPos += pPagePosItem->GetPos().Y(); + lTabPosition += pPagePosItem->GetPos().Y(); pEditWin->InvertTracking( - Rectangle( Point(-aZero.X(), _lTabPos), - Point(-aZero.X()+nWidth, _lTabPos)), + Rectangle( Point(-aZero.X(), lTabPosition), + Point(-aZero.X()+nWidth, lTabPosition)), SHOWTRACK_CLIP | SHOWTRACK_SPLIT ); } } @@ -1586,12 +1616,14 @@ void SvxRuler::DragTabs() { /* Dragging of Tabs */ long lDragPos = GetCorrectedDragPos(sal_True, sal_False); + NormalizePosition(lDragPos); + sal_uInt16 nIdx = GetDragAryPos() + TAB_GAP; + long nDiff = lDragPos - pTabs[nIdx].nPos; + if (nDiff == 0) + return; - sal_uInt16 nIdx = GetDragAryPos()+TAB_GAP; DrawLine_Impl(lTabPos, 7, bHorz); - long nDiff = lDragPos - pTabs[nIdx].nPos; - if(nDragType & DRAG_OBJECT_SIZE_LINEAR) { @@ -1624,7 +1656,10 @@ void SvxRuler::DragTabs() } } else + { pTabs[nIdx].nPos = lDragPos; + } + if(IsDragDelete()) pTabs[nIdx].nStyle |= RULER_STYLE_INVISIBLE; @@ -1686,7 +1721,8 @@ void SvxRuler::UpdateParaContents_Impl( void SvxRuler::DragBorders() { /* Dragging of Borders (Tables and other columns) */ - sal_Bool bLeftIndentsCorrected = sal_False, bRightIndentsCorrected = sal_False; + sal_Bool bLeftIndentsCorrected = sal_False; + sal_Bool bRightIndentsCorrected = sal_False; int nIdx; if(GetDragType()==RULER_TYPE_BORDER) @@ -1695,7 +1731,9 @@ void SvxRuler::DragBorders() nIdx = GetDragAryPos(); } else + { nIdx=0; + } sal_uInt16 nDragSize = GetDragSize(); long lDiff = 0; @@ -1703,7 +1741,6 @@ void SvxRuler::DragBorders() // the drag position has to be corrected to be able to prevent borders from passing each other long lPos = GetCorrectedDragPos(); - switch(nDragSize) { case RULER_DRAGSIZE_MOVE: @@ -1973,7 +2010,7 @@ void SvxRuler::ApplyIndents() { /* Applying paragraph settings; changed by dragging. */ long nNewTxtLeft; - if(pColumnItem&&!IsActFirstColumn( sal_True )) + if(pColumnItem && !IsActFirstColumn( sal_True )) { long nLeftCol=GetActLeftColumn( sal_True ); nNewTxtLeft = @@ -1985,10 +2022,11 @@ void SvxRuler::ApplyIndents() lAppNullOffset,pParaItem->GetTxtLeft()); } else - nNewTxtLeft = - PixelHAdjust( - ConvertHPosLogic(pIndents[INDENT_LEFT_MARGIN].nPos), - pParaItem->GetTxtLeft()); + { + nNewTxtLeft = PixelHAdjust( + ConvertHPosLogic(pIndents[INDENT_LEFT_MARGIN].nPos), + pParaItem->GetTxtLeft()); + } sal_Bool bRTL = pRuler_Imp->pTextRTLItem && pRuler_Imp->pTextRTLItem->GetValue(); @@ -1996,18 +2034,20 @@ void SvxRuler::ApplyIndents() if(bRTL) { long nRightFrameMargin = GetRightFrameMargin(); - nNewFirstLineOffset = PixelHAdjust(nRightFrameMargin - - ConvertHPosLogic(pIndents[INDENT_FIRST_LINE].nPos ) - - lAppNullOffset, - pParaItem->GetTxtFirstLineOfst()); + nNewFirstLineOffset = PixelHAdjust( + nRightFrameMargin - + ConvertHPosLogic(pIndents[INDENT_FIRST_LINE].nPos ) - + lAppNullOffset, + pParaItem->GetTxtFirstLineOfst()); } else - nNewFirstLineOffset= - PixelHAdjust( - ConvertHPosLogic(pIndents[INDENT_FIRST_LINE].nPos - - pIndents[INDENT_LEFT_MARGIN].nPos) - - lAppNullOffset, - pParaItem->GetTxtFirstLineOfst()); + { + nNewFirstLineOffset = PixelHAdjust( + ConvertHPosLogic(pIndents[INDENT_FIRST_LINE].nPos - + pIndents[INDENT_LEFT_MARGIN].nPos) - + lAppNullOffset, + pParaItem->GetTxtFirstLineOfst()); + } // If the new TxtLeft is smaller than the old FirstLineIndent, then the // difference is lost and the paragraph is in total indented too far, @@ -2025,11 +2065,10 @@ void SvxRuler::ApplyIndents() nNewFirstLineOffset -= pParaBorderItem->GetRight(); } } - pParaItem->SetTxtFirstLineOfst( - sal::static_int_cast< short >(nNewFirstLineOffset)); + pParaItem->SetTxtFirstLineOfst(sal::static_int_cast< short >(nNewFirstLineOffset)); pParaItem->SetTxtLeft(nNewTxtLeft); - if(pColumnItem && ((!bRTL && !IsActLastColumn( sal_True ))|| (bRTL && !IsActFirstColumn()))) + if(pColumnItem && ((!bRTL && !IsActLastColumn( sal_True )) || (bRTL && !IsActFirstColumn()))) { if(bRTL) { @@ -2044,9 +2083,9 @@ void SvxRuler::ApplyIndents() PixelHAdjust( ConvertHPosLogic( pBorders[GetActRightColumn( sal_True )].nPos - - pIndents[INDENT_RIGHT_MARGIN].nPos) - - lAppNullOffset, - pParaItem->GetRight())); + pIndents[INDENT_RIGHT_MARGIN].nPos) - + lAppNullOffset, + pParaItem->GetRight())); } } @@ -3091,7 +3130,7 @@ void SvxRuler::Drag() switch(GetDragType()) { case RULER_TYPE_MARGIN1: // left edge of the surrounding Frame DragMargin1(); - pRuler_Imp->lLastLMargin=GetMargin1(); + pRuler_Imp->lLastLMargin = GetMargin1(); break; case RULER_TYPE_MARGIN2: // right edge of the surrounding Frame DragMargin2(); -- cgit v1.2.3