summaryrefslogtreecommitdiff
path: root/sw/source/core/tox/ToxTabStopTokenHandler.cxx
blob: 8ac6c227c480a730de29304f51010ae13975c467 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
/* -*- 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/.
 */

#include "ToxTabStopTokenHandler.hxx"

#include "editeng/tstpitem.hxx"
#include "editeng/lrspitem.hxx"

#include "cntfrm.hxx"
#include "fmtfsize.hxx"
#include "fmtpdsc.hxx"
#include "frmfmt.hxx"
#include "ndtxt.hxx"
#include "pagedesc.hxx"
#include "pagefrm.hxx"
#include "swrect.hxx"
#include "tox.hxx"

namespace sw {

DefaultToxTabStopTokenHandler::DefaultToxTabStopTokenHandler(sal_uInt32 indexOfSectionNode,
        const SwPageDesc& defaultPageDescription,
        bool tabPositionIsRelativeToParagraphIndent,
        TabStopReferencePolicy referencePolicy)
: mIndexOfSectionNode(indexOfSectionNode),
  mDefaultPageDescription(defaultPageDescription),
  mTabPositionIsRelativeToParagraphIndent(tabPositionIsRelativeToParagraphIndent),
  mTabStopReferencePolicy(referencePolicy)
{
}


ToxTabStopTokenHandler::HandledTabStopToken
DefaultToxTabStopTokenHandler::HandleTabStopToken(
        const SwFormToken& aToken, const SwTextNode& targetNode, const SwRootFrm *currentLayout) const
{
    HandledTabStopToken result;

    if (aToken.bWithTab) { // #i21237#
        result.text = "\t";
    }

    // check whether a tab adjustment has been specified.
    if (SVX_TAB_ADJUST_END > aToken.eTabAlign) {
        const SvxLRSpaceItem& rLR = static_cast<const SvxLRSpaceItem&>( targetNode.SwContentNode::GetAttr(RES_LR_SPACE) );

        long nTabPosition = aToken.nTabStopPosition;
        if (!mTabPositionIsRelativeToParagraphIndent && rLR.GetTextLeft()) {
            nTabPosition -= rLR.GetTextLeft();
        }
        result.tabStop = SvxTabStop(nTabPosition, aToken.eTabAlign, cDfltDecimalChar, aToken.cTabFillChar);
        return result;
    }

    SwRect aNdRect;
    if (CanUseLayoutRectangle(targetNode, currentLayout)) {
        aNdRect = targetNode.FindLayoutRect(true);
    }
    long nRightMargin;
    if (aNdRect.IsEmpty()) {
        nRightMargin = CalculatePageMarginFromPageDescription(targetNode);
    } else {
        nRightMargin = aNdRect.Width();
    }
    //#i24363# tab stops relative to indent
    if (mTabStopReferencePolicy == TABSTOPS_RELATIVE_TO_INDENT) {
        // left margin of paragraph style
        const SvxLRSpaceItem& rLRSpace = targetNode.GetTextColl()->GetLRSpace();
        nRightMargin -= rLRSpace.GetLeft();
        nRightMargin -= rLRSpace.GetTextFirstLineOfst();
    }

    result.tabStop = SvxTabStop(nRightMargin, SVX_TAB_ADJUST_RIGHT, cDfltDecimalChar, aToken.cTabFillChar);
    return result;
}

long
DefaultToxTabStopTokenHandler::CalculatePageMarginFromPageDescription(const SwTextNode& targetNode) const
{
    size_t nPgDescNdIdx = targetNode.GetIndex() + 1;
    const SwPageDesc *pPageDesc = targetNode.FindPageDesc(false, &nPgDescNdIdx);
    if (!pPageDesc || nPgDescNdIdx < mIndexOfSectionNode) {
        // Use default page description, if none is found or the found one is given by a Node before the
        // table-of-content section.
        pPageDesc = &mDefaultPageDescription;
    }
    const SwFrameFormat& rPgDscFormat = pPageDesc->GetMaster();
    long result = rPgDscFormat.GetFrmSize().GetWidth() - rPgDscFormat.GetLRSpace().GetLeft()
            - rPgDscFormat.GetLRSpace().GetRight();
    return result;
}


/*static*/ bool
DefaultToxTabStopTokenHandler::CanUseLayoutRectangle(const SwTextNode& targetNode, const SwRootFrm *currentLayout)
{
    const SwPageDesc* pageDescription =
            static_cast<const SwFormatPageDesc&>( targetNode.SwContentNode::GetAttr(RES_PAGEDESC)).GetPageDesc();

    if (!pageDescription) {
        return false;
    }
    const SwFrm* pFrm = targetNode.getLayoutFrm(currentLayout);
    if (!pFrm) {
        return false;
    }
    pFrm = pFrm->FindPageFrm();
    if (!pFrm) {
        return false;
    }
    const SwPageFrm* pageFrm = static_cast<const SwPageFrm*>(pFrm);
    if (pageDescription != pageFrm->GetPageDesc()) {
        return false;
    }
    return true;
}

}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */