1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <rtl/ustring.hxx>
21 #include <sal/log.hxx>
23 #include <editeng/overflowingtxt.hxx>
24 #include <editeng/outliner.hxx>
25 #include <editeng/outlobj.hxx>
26 #include <editeng/editeng.hxx>
27 #include <editeng/editobj.hxx>
28 #include <editeng/editdata.hxx>
30 #include <editdoc.hxx>
34 std::optional
<OutlinerParaObject
> TextChainingUtils::JuxtaposeParaObject(
35 css::uno::Reference
< css::datatransfer::XTransferable
> const & xOverflowingContent
,
37 OutlinerParaObject
const *pNextPObj
)
40 pOutl
->SetToEmptyText();
42 pOutl
->SetText(*pNextPObj
);
45 // Special case: if only empty text remove it at the end
46 bool bOnlyOneEmptyPara
= !pNextPObj
||
47 (pOutl
->GetParagraphCount() == 1 &&
48 pNextPObj
->GetTextObject().GetText(0).isEmpty());
50 EditEngine
&rEditEngine
= const_cast<EditEngine
&>(pOutl
->GetEditEngine());
52 // XXX: this code should be moved in Outliner directly
53 // creating Outliner::InsertText(...transferable...)
54 EditSelection
aStartSel(rEditEngine
.CreateSelection(ESelection(0,0)));
55 EditSelection aNewSel
= rEditEngine
.InsertText(xOverflowingContent
,
60 if (!bOnlyOneEmptyPara
) {
61 // Separate Paragraphs
62 rEditEngine
.InsertParaBreak(aNewSel
);
66 return pOutl
->CreateParaObject();
69 std::optional
<OutlinerParaObject
> TextChainingUtils::DeeplyMergeParaObject(
70 css::uno::Reference
< css::datatransfer::XTransferable
> const & xOverflowingContent
,
72 OutlinerParaObject
const *pNextPObj
)
75 pOutl
->SetToEmptyText();
77 pOutl
->SetText(*pNextPObj
);
80 EditEngine
&rEditEngine
= const_cast<EditEngine
&>(pOutl
->GetEditEngine());
82 // XXX: this code should be moved in Outliner directly
83 // creating Outliner::InsertText(...transferable...)
84 EditSelection
aStartSel(rEditEngine
.CreateSelection(ESelection(0,0)));
85 // We don't need to mark the selection
86 // EditSelection aNewSel =
87 rEditEngine
.InsertText(xOverflowingContent
,
92 return pOutl
->CreateParaObject();
95 css::uno::Reference
< css::datatransfer::XTransferable
> TextChainingUtils::CreateTransferableFromText(Outliner
const *pOutl
)
97 const EditEngine
&rEditEngine
= pOutl
->GetEditEngine();
98 sal_Int32 nLastPara
= pOutl
->GetParagraphCount()-1;
99 ESelection
aWholeTextSel(0, 0, nLastPara
, rEditEngine
.GetTextLen(nLastPara
));
101 return rEditEngine
.CreateTransferable(aWholeTextSel
);
106 OverflowingText::OverflowingText(css::uno::Reference
< css::datatransfer::XTransferable
> xOverflowingContent
) :
107 mxOverflowingContent(std::move(xOverflowingContent
))
114 NonOverflowingText::NonOverflowingText(const ESelection
&aSel
, bool bLastParaInterrupted
)
116 , mbLastParaInterrupted(bLastParaInterrupted
)
120 bool NonOverflowingText::IsLastParaInterrupted() const
122 return mbLastParaInterrupted
;
126 std::optional
<OutlinerParaObject
> NonOverflowingText::RemoveOverflowingText(Outliner
*pOutliner
) const
128 pOutliner
->QuickDelete(maContentSel
);
129 SAL_INFO("editeng.chaining", "Deleting selection from (Para: " << maContentSel
.nStartPara
130 << ", Pos: " << maContentSel
.nStartPos
<< ") to (Para: " << maContentSel
.nEndPara
131 << ", Pos: " << maContentSel
.nEndPos
<< ")");
132 return pOutliner
->CreateParaObject();
135 ESelection
NonOverflowingText::GetOverflowPointSel() const
137 //return getLastPositionSel(mpContentTextObj);
139 // return the starting point of the selection we are removing
140 return ESelection(maContentSel
.nStartPara
, maContentSel
.nStartPos
); //XXX
143 // The equivalent of ToParaObject for OverflowingText. Here we are prepending the overflowing text to the old dest box's text
144 // XXX: In a sense a better name for OverflowingText and NonOverflowingText are respectively DestLinkText and SourceLinkText
145 std::optional
<OutlinerParaObject
> OverflowingText::JuxtaposeParaObject(Outliner
*pOutl
, OutlinerParaObject
const *pNextPObj
)
147 return TextChainingUtils::JuxtaposeParaObject(mxOverflowingContent
, pOutl
, pNextPObj
);
150 std::optional
<OutlinerParaObject
> OverflowingText::DeeplyMergeParaObject(Outliner
*pOutl
, OutlinerParaObject
const *pNextPObj
)
152 return TextChainingUtils::DeeplyMergeParaObject(mxOverflowingContent
, pOutl
, pNextPObj
);
156 OFlowChainedText::OFlowChainedText(Outliner
const *pOutl
, bool bIsDeepMerge
)
158 mpOverflowingTxt
= pOutl
->GetOverflowingText();
159 mpNonOverflowingTxt
= pOutl
->GetNonOverflowingText();
161 mbIsDeepMerge
= bIsDeepMerge
;
164 OFlowChainedText::~OFlowChainedText()
169 ESelection
OFlowChainedText::GetOverflowPointSel() const
171 return mpNonOverflowingTxt
->GetOverflowPointSel();
174 std::optional
<OutlinerParaObject
> OFlowChainedText::InsertOverflowingText(Outliner
*pOutliner
, OutlinerParaObject
const *pTextToBeMerged
)
176 // Just return the roughly merged paras for now
177 if (!mpOverflowingTxt
)
181 SAL_INFO("editeng.chaining", "[TEXTCHAINFLOW - OF] Deep merging paras" );
182 return mpOverflowingTxt
->DeeplyMergeParaObject(pOutliner
, pTextToBeMerged
);
184 SAL_INFO("editeng.chaining", "[TEXTCHAINFLOW - OF] Juxtaposing paras" );
185 return mpOverflowingTxt
->JuxtaposeParaObject(pOutliner
, pTextToBeMerged
);
190 std::optional
<OutlinerParaObject
> OFlowChainedText::RemoveOverflowingText(Outliner
*pOutliner
)
192 if (!mpNonOverflowingTxt
)
195 return mpNonOverflowingTxt
->RemoveOverflowingText(pOutliner
);
198 bool OFlowChainedText::IsLastParaInterrupted() const
200 return mpNonOverflowingTxt
->IsLastParaInterrupted();
205 UFlowChainedText::UFlowChainedText(Outliner
const *pOutl
, bool bIsDeepMerge
)
207 mxUnderflowingTxt
= TextChainingUtils::CreateTransferableFromText(pOutl
);
208 mbIsDeepMerge
= bIsDeepMerge
;
211 std::optional
<OutlinerParaObject
> UFlowChainedText::CreateMergedUnderflowParaObject(Outliner
*pOutl
, OutlinerParaObject
const *pNextLinkWholeText
)
213 std::optional
<OutlinerParaObject
> pNewText
;
216 SAL_INFO("editeng.chaining", "[TEXTCHAINFLOW - UF] Deep merging paras" );
217 pNewText
= TextChainingUtils::DeeplyMergeParaObject(mxUnderflowingTxt
, pOutl
, pNextLinkWholeText
);
219 // NewTextForCurBox = Txt(CurBox) ++ Txt(NextBox)
220 SAL_INFO("editeng.chaining", "[TEXTCHAINFLOW - UF] Juxtaposing paras" );
221 pNewText
= TextChainingUtils::JuxtaposeParaObject(mxUnderflowingTxt
, pOutl
, pNextLinkWholeText
);
227 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */