chained editeng: Add interface and implementations for text chaining
Change-Id: I378b96581c2b006eb880ca0f11e7ca76b686846e
This commit is contained in:
parent
95182ff010
commit
e705b13b9b
@ -22,6 +22,7 @@ $(eval $(call gb_Library_Library,editeng))
|
|||||||
$(eval $(call gb_Library_set_include,editeng,\
|
$(eval $(call gb_Library_set_include,editeng,\
|
||||||
$$(INCLUDE) \
|
$$(INCLUDE) \
|
||||||
-I$(SRCDIR)/editeng/inc \
|
-I$(SRCDIR)/editeng/inc \
|
||||||
|
-I$(SRCDIR)/editeng/source/editeng \
|
||||||
))
|
))
|
||||||
|
|
||||||
$(eval $(call gb_Library_use_custom_headers,editeng,editeng/generated))
|
$(eval $(call gb_Library_use_custom_headers,editeng,editeng/generated))
|
||||||
@ -101,6 +102,7 @@ $(eval $(call gb_Library_add_exception_objects,editeng,\
|
|||||||
editeng/source/outliner/outlobj \
|
editeng/source/outliner/outlobj \
|
||||||
editeng/source/outliner/outlundo \
|
editeng/source/outliner/outlundo \
|
||||||
editeng/source/outliner/outlvw \
|
editeng/source/outliner/outlvw \
|
||||||
|
editeng/source/outliner/overflowingtxt \
|
||||||
editeng/source/outliner/paralist \
|
editeng/source/outliner/paralist \
|
||||||
editeng/source/rtf/rtfitem \
|
editeng/source/rtf/rtfitem \
|
||||||
editeng/source/rtf/svxrtf \
|
editeng/source/rtf/svxrtf \
|
||||||
|
263
editeng/source/outliner/overflowingtxt.cxx
Normal file
263
editeng/source/outliner/overflowingtxt.cxx
Normal file
@ -0,0 +1,263 @@
|
|||||||
|
/* -*- 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/.
|
||||||
|
*
|
||||||
|
* 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 .
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "rtl/ustring.hxx"
|
||||||
|
#include "tools/debug.hxx"
|
||||||
|
#include "sal/info.hxx"
|
||||||
|
|
||||||
|
#include "editeng/overflowingtxt.hxx"
|
||||||
|
#include "editeng/outliner.hxx"
|
||||||
|
#include "editeng/outlobj.hxx"
|
||||||
|
#include "editeng/editobj.hxx"
|
||||||
|
#include "editeng/editdata.hxx"
|
||||||
|
|
||||||
|
#include "outleeng.hxx"
|
||||||
|
#include "editdoc.hxx"
|
||||||
|
|
||||||
|
#include <com/sun/star/datatransfer/clipboard/XClipboard.hpp>
|
||||||
|
|
||||||
|
|
||||||
|
OutlinerParaObject *TextChainingUtils::JuxtaposeParaObject(
|
||||||
|
TranferableText xOverflowingContent,
|
||||||
|
Outliner *pOutl,
|
||||||
|
OutlinerParaObject *pNextPObj)
|
||||||
|
{
|
||||||
|
if (!pNextPObj) {
|
||||||
|
pOutl->SetToEmptyText();
|
||||||
|
} else {
|
||||||
|
pOutl->SetText(*pNextPObj);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Special case: if only empty text remove it at the end
|
||||||
|
bool bOnlyOneEmptyPara = !pNextPObj ||
|
||||||
|
(pOutl->GetParagraphCount() == 1 &&
|
||||||
|
pNextPObj->GetTextObject().GetText(0) == "");
|
||||||
|
|
||||||
|
EditEngine &rEditEngine = const_cast<EditEngine &>(pOutl->GetEditEngine());
|
||||||
|
|
||||||
|
// XXX: this code should be moved in Outliner directly
|
||||||
|
// creating Outliner::InsertText(...transferable...)
|
||||||
|
EditSelection aStartSel(rEditEngine.CreateSelection(ESelection(0,0)));
|
||||||
|
EditSelection aNewSel = rEditEngine.InsertText(xOverflowingContent,
|
||||||
|
OUString(),
|
||||||
|
aStartSel.Min(),
|
||||||
|
true);
|
||||||
|
|
||||||
|
if (!bOnlyOneEmptyPara) {
|
||||||
|
// Separate Paragraphs
|
||||||
|
rEditEngine.InsertParaBreak(aNewSel);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return pOutl->CreateParaObject();
|
||||||
|
}
|
||||||
|
|
||||||
|
OutlinerParaObject *TextChainingUtils::DeeplyMergeParaObject(
|
||||||
|
TranferableText xOverflowingContent,
|
||||||
|
Outliner *pOutl,
|
||||||
|
OutlinerParaObject *pNextPObj)
|
||||||
|
{
|
||||||
|
if (!pNextPObj) {
|
||||||
|
pOutl->SetToEmptyText();
|
||||||
|
} else {
|
||||||
|
pOutl->SetText(*pNextPObj);
|
||||||
|
}
|
||||||
|
|
||||||
|
EditEngine &rEditEngine = const_cast<EditEngine &>(pOutl->GetEditEngine());
|
||||||
|
|
||||||
|
// XXX: this code should be moved in Outliner directly
|
||||||
|
// creating Outliner::InsertText(...transferable...)
|
||||||
|
EditSelection aStartSel(rEditEngine.CreateSelection(ESelection(0,0)));
|
||||||
|
// We don't need to mark the selection
|
||||||
|
// EditSelection aNewSel =
|
||||||
|
rEditEngine.InsertText(xOverflowingContent,
|
||||||
|
OUString(),
|
||||||
|
aStartSel.Min(),
|
||||||
|
true);
|
||||||
|
|
||||||
|
return pOutl->CreateParaObject();
|
||||||
|
}
|
||||||
|
|
||||||
|
TranferableText TextChainingUtils::CreateTransferableFromText(Outliner *pOutl)
|
||||||
|
{
|
||||||
|
const EditEngine &rEditEngine = pOutl->GetEditEngine();
|
||||||
|
sal_Int32 nLastPara = pOutl->GetParagraphCount()-1;
|
||||||
|
ESelection aWholeTextSel(0, 0, nLastPara, rEditEngine.GetTextLen(nLastPara));
|
||||||
|
|
||||||
|
return rEditEngine.CreateTransferable(aWholeTextSel);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Helper functions for *OverflowingText classes */
|
||||||
|
|
||||||
|
ESelection getLastPositionSel(const EditTextObject *pTObj)
|
||||||
|
{
|
||||||
|
sal_Int32 nLastPara = pTObj->GetParagraphCount()-1;
|
||||||
|
// If text is empty
|
||||||
|
if (nLastPara < 0 )
|
||||||
|
nLastPara = 0;
|
||||||
|
sal_Int32 nLen = pTObj->GetText(nLastPara).getLength();
|
||||||
|
ESelection aEndPos(nLastPara, nLen, nLastPara, nLen);
|
||||||
|
|
||||||
|
return aEndPos;
|
||||||
|
}
|
||||||
|
|
||||||
|
// class OverflowingText
|
||||||
|
|
||||||
|
OverflowingText::OverflowingText(TranferableText xOverflowingContent) :
|
||||||
|
mxOverflowingContent(xOverflowingContent)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ESelection OverflowingText::GetInsertionPointSel() const
|
||||||
|
{
|
||||||
|
assert(0);
|
||||||
|
return getLastPositionSel(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
// class NonOverflowingText
|
||||||
|
|
||||||
|
NonOverflowingText::NonOverflowingText(const EditTextObject *pTObj, bool bLastParaInterrupted)
|
||||||
|
: mpContentTextObj(pTObj->Clone()),
|
||||||
|
mbLastParaInterrupted(bLastParaInterrupted)
|
||||||
|
{
|
||||||
|
// XXX: may have to delete pTObj
|
||||||
|
}
|
||||||
|
|
||||||
|
NonOverflowingText::NonOverflowingText(const ESelection &aSel, bool bLastParaInterrupted)
|
||||||
|
: maContentSel(aSel),
|
||||||
|
mbLastParaInterrupted(bLastParaInterrupted)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NonOverflowingText::IsLastParaInterrupted() const
|
||||||
|
{
|
||||||
|
return mbLastParaInterrupted;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
OutlinerParaObject *NonOverflowingText::RemoveOverflowingText(Outliner *pOutliner) const
|
||||||
|
{
|
||||||
|
pOutliner->QuickDelete(maContentSel);
|
||||||
|
fprintf(stderr, "Deleting selection from (Para: %d, Pos: %d) to (Para: %d, Pos: %d)\n",
|
||||||
|
maContentSel.nStartPara,
|
||||||
|
maContentSel.nStartPos,
|
||||||
|
maContentSel.nEndPara,
|
||||||
|
maContentSel.nEndPos);
|
||||||
|
return pOutliner->CreateParaObject();
|
||||||
|
}
|
||||||
|
|
||||||
|
ESelection NonOverflowingText::GetOverflowPointSel() const
|
||||||
|
{
|
||||||
|
//return getLastPositionSel(mpContentTextObj);
|
||||||
|
|
||||||
|
// return the starting point of the selection we are removing
|
||||||
|
return ESelection(maContentSel.nStartPara, maContentSel.nStartPos); //XXX
|
||||||
|
}
|
||||||
|
|
||||||
|
// The equivalent of ToParaObject for OverflowingText. Here we are prepending the overflowing text to the old dest box's text
|
||||||
|
// XXX: In a sense a better name for OverflowingText and NonOverflowingText are respectively DestLinkText and SourceLinkText
|
||||||
|
OutlinerParaObject *OverflowingText::JuxtaposeParaObject(Outliner *pOutl, OutlinerParaObject *pNextPObj)
|
||||||
|
{
|
||||||
|
return TextChainingUtils::JuxtaposeParaObject(mxOverflowingContent, pOutl, pNextPObj);
|
||||||
|
}
|
||||||
|
|
||||||
|
OutlinerParaObject *OverflowingText::DeeplyMergeParaObject(Outliner *pOutl, OutlinerParaObject *pNextPObj)
|
||||||
|
{
|
||||||
|
return TextChainingUtils::DeeplyMergeParaObject(mxOverflowingContent, pOutl, pNextPObj);
|
||||||
|
}
|
||||||
|
|
||||||
|
// class OFlowChainedText
|
||||||
|
|
||||||
|
OFlowChainedText::OFlowChainedText(Outliner *pOutl, bool bIsDeepMerge)
|
||||||
|
{
|
||||||
|
mpOverflowingTxt = pOutl->GetOverflowingText();
|
||||||
|
mpNonOverflowingTxt = pOutl->GetNonOverflowingText();
|
||||||
|
|
||||||
|
mbIsDeepMerge = bIsDeepMerge;
|
||||||
|
}
|
||||||
|
|
||||||
|
ESelection OFlowChainedText::GetInsertionPointSel() const
|
||||||
|
{
|
||||||
|
return mpOverflowingTxt->GetInsertionPointSel();
|
||||||
|
}
|
||||||
|
|
||||||
|
ESelection OFlowChainedText::GetOverflowPointSel() const
|
||||||
|
{
|
||||||
|
return mpNonOverflowingTxt->GetOverflowPointSel();
|
||||||
|
}
|
||||||
|
|
||||||
|
OutlinerParaObject *OFlowChainedText::InsertOverflowingText(Outliner *pOutliner, OutlinerParaObject *pTextToBeMerged)
|
||||||
|
{
|
||||||
|
// Just return the roughly merged paras for now
|
||||||
|
if (mpOverflowingTxt == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (mbIsDeepMerge) {
|
||||||
|
fprintf(stderr, "[TEXTCHAINFLOW - OF] Deep merging paras\n" );
|
||||||
|
return mpOverflowingTxt->DeeplyMergeParaObject(pOutliner, pTextToBeMerged );
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "[TEXTCHAINFLOW - OF] Juxtaposing paras\n" );
|
||||||
|
return mpOverflowingTxt->JuxtaposeParaObject(pOutliner, pTextToBeMerged );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
OutlinerParaObject *OFlowChainedText::RemoveOverflowingText(Outliner *pOutliner)
|
||||||
|
{
|
||||||
|
if (mpNonOverflowingTxt == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return mpNonOverflowingTxt->RemoveOverflowingText(pOutliner);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool OFlowChainedText::IsLastParaInterrupted() const
|
||||||
|
{
|
||||||
|
return mpNonOverflowingTxt->IsLastParaInterrupted();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// classes UFlowChainedText
|
||||||
|
|
||||||
|
UFlowChainedText::UFlowChainedText(Outliner *pOutl, bool bIsDeepMerge)
|
||||||
|
{
|
||||||
|
mxUnderflowingTxt = TextChainingUtils::CreateTransferableFromText(pOutl);
|
||||||
|
mbIsDeepMerge = bIsDeepMerge;
|
||||||
|
}
|
||||||
|
|
||||||
|
OutlinerParaObject *UFlowChainedText::CreateMergedUnderflowParaObject(Outliner *pOutl, OutlinerParaObject *pNextLinkWholeText)
|
||||||
|
{
|
||||||
|
OutlinerParaObject *pNewText = NULL;
|
||||||
|
|
||||||
|
if (mbIsDeepMerge) {
|
||||||
|
fprintf(stderr, "[TEXTCHAINFLOW - UF] Deep merging paras\n" );
|
||||||
|
pNewText = TextChainingUtils::DeeplyMergeParaObject(mxUnderflowingTxt, pOutl, pNextLinkWholeText);
|
||||||
|
} else {
|
||||||
|
// NewTextForCurBox = Txt(CurBox) ++ Txt(NextBox)
|
||||||
|
fprintf(stderr, "[TEXTCHAINFLOW - UF] Juxtaposing paras\n" );
|
||||||
|
pNewText = TextChainingUtils::JuxtaposeParaObject(mxUnderflowingTxt, pOutl, pNextLinkWholeText);
|
||||||
|
}
|
||||||
|
|
||||||
|
return pNewText;
|
||||||
|
|
||||||
|
}
|
||||||
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
149
include/editeng/overflowingtxt.hxx
Normal file
149
include/editeng/overflowingtxt.hxx
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
/* -*- 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/.
|
||||||
|
*
|
||||||
|
* 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 .
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef INCLUDED_EDITENG_OVERFLOWINGTXT_HXX
|
||||||
|
#define INCLUDED_EDITENG_OVERFLOWINGTXT_HXX
|
||||||
|
|
||||||
|
#include <editeng/macros.hxx>
|
||||||
|
#include <editeng/editengdllapi.h>
|
||||||
|
#include <editeng/editdata.hxx>
|
||||||
|
|
||||||
|
#include <com/sun/star/uno/Reference.h>
|
||||||
|
|
||||||
|
namespace com { namespace sun { namespace star {
|
||||||
|
namespace datatransfer {
|
||||||
|
class XTransferable;
|
||||||
|
} } } }
|
||||||
|
|
||||||
|
typedef com::sun::star::uno::Reference<
|
||||||
|
com::sun::star::datatransfer::XTransferable> TranferableText;
|
||||||
|
|
||||||
|
namespace rtl {
|
||||||
|
class OUString;
|
||||||
|
};
|
||||||
|
using ::rtl::OUString;
|
||||||
|
|
||||||
|
|
||||||
|
class OutlinerParaObject;
|
||||||
|
class EditTextObject;
|
||||||
|
class Outliner;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* A collection of static methods for attaching text.
|
||||||
|
* Strongly coupled with some of the classes in this file.
|
||||||
|
*/
|
||||||
|
class TextChainingUtils
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static TranferableText CreateTransferableFromText(Outliner *);
|
||||||
|
|
||||||
|
static OutlinerParaObject *JuxtaposeParaObject(
|
||||||
|
TranferableText xOverflowingContent,
|
||||||
|
Outliner *,
|
||||||
|
OutlinerParaObject *);
|
||||||
|
static OutlinerParaObject *DeeplyMergeParaObject(
|
||||||
|
TranferableText xOverflowingContent,
|
||||||
|
Outliner *,
|
||||||
|
OutlinerParaObject *);
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The classes OverflowingText and NonOverflowingText handle the
|
||||||
|
* actual preparation of the OutlinerParaObjects to be used in destination
|
||||||
|
* and source box respectively.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class OverflowingText
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
OutlinerParaObject *JuxtaposeParaObject(Outliner *, OutlinerParaObject *);
|
||||||
|
OutlinerParaObject *DeeplyMergeParaObject(Outliner *, OutlinerParaObject *);
|
||||||
|
ESelection GetInsertionPointSel() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
friend class Outliner;
|
||||||
|
OverflowingText(TranferableText xOverflowingContent);
|
||||||
|
|
||||||
|
TranferableText mxOverflowingContent;
|
||||||
|
};
|
||||||
|
|
||||||
|
class NonOverflowingText
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
OutlinerParaObject *RemoveOverflowingText(Outliner *) const;
|
||||||
|
ESelection GetOverflowPointSel() const;
|
||||||
|
bool IsLastParaInterrupted() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
NonOverflowingText(const EditTextObject *pTObj, bool bLastParaInterrupted);
|
||||||
|
NonOverflowingText(const ESelection &aSel, bool bLastParaInterrupted);
|
||||||
|
|
||||||
|
friend class Outliner;
|
||||||
|
const EditTextObject *mpContentTextObj;
|
||||||
|
const ESelection maContentSel;
|
||||||
|
const bool mbLastParaInterrupted;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* classes OFlowChainedText and UFlowChainedText:
|
||||||
|
* contain and handle the state of a broken up text _after_ a flow event
|
||||||
|
* (respectively after Overflow and Underflow).
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class EDITENG_DLLPUBLIC OFlowChainedText
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
OFlowChainedText(Outliner *, bool );
|
||||||
|
|
||||||
|
OutlinerParaObject *InsertOverflowingText(Outliner *, OutlinerParaObject *);
|
||||||
|
OutlinerParaObject *RemoveOverflowingText(Outliner *);
|
||||||
|
|
||||||
|
ESelection GetInsertionPointSel() const;
|
||||||
|
ESelection GetOverflowPointSel() const;
|
||||||
|
|
||||||
|
bool IsLastParaInterrupted() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void impSetOutlinerToEmptyTxt(Outliner *);
|
||||||
|
|
||||||
|
private:
|
||||||
|
NonOverflowingText *mpNonOverflowingTxt;
|
||||||
|
OverflowingText *mpOverflowingTxt;
|
||||||
|
|
||||||
|
bool mbIsDeepMerge;
|
||||||
|
};
|
||||||
|
|
||||||
|
// UFlowChainedText is a simpler class than OFlowChainedText: it almost only joins para-objects
|
||||||
|
class EDITENG_DLLPUBLIC UFlowChainedText
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
UFlowChainedText(Outliner *, bool);
|
||||||
|
OutlinerParaObject *CreateMergedUnderflowParaObject(Outliner *, OutlinerParaObject *);
|
||||||
|
|
||||||
|
private:
|
||||||
|
TranferableText mxUnderflowingTxt;
|
||||||
|
|
||||||
|
bool mbIsDeepMerge;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
Loading…
x
Reference in New Issue
Block a user