[Libreoffice-commits] core.git: Branch 'feature/chained-text-boxes' - 15 commits - editeng/Library_editeng.mk editeng/source include/editeng include/svx sd/source svx/inc svx/Library_svxcore.mk svx/source xmloff/source
Thorsten Behrens
Thorsten.Behrens at CIB.de
Sat Sep 19 17:02:46 PDT 2015
Rebased ref, commits from common ancestor:
commit 133498a53c9b639c29eb7c2f90dec6feb8dd476e
Author: Thorsten Behrens <Thorsten.Behrens at CIB.de>
Date: Sun Sep 20 01:42:12 2015 +0200
chained editeng: Convert fprintf to SAL_INFO
Change-Id: I8e0cfedd34d7e0d70a30147a3bbf0f1cd8e6d3cc
diff --git a/editeng/source/editeng/impedit3.cxx b/editeng/source/editeng/impedit3.cxx
index 70072a2..74eb16d 100644
--- a/editeng/source/editeng/impedit3.cxx
+++ b/editeng/source/editeng/impedit3.cxx
@@ -564,18 +564,13 @@ void ImpEditEngine::CheckAutoPageSize()
void ImpEditEngine::CheckPageOverflow()
{
- // FIXME(matteocam)
- /* fprintf( stderr, IsPageOverflow(aPaperSize, aPrevPaperSize)
- ? "YES Overflow!\n" : "NO Overflow!\n" ); */
- // setting overflow status
-
- fprintf(stderr, "[CONTROL_STATUS] AutoPageSize is %s", ( aStatus.GetControlWord() & EEControlBits::AUTOPAGESIZE ) ? "ON\n" : "OFF\n" );
+ SAL_INFO("editeng.chaining", "[CONTROL_STATUS] AutoPageSize is " << (( aStatus.GetControlWord() & EEControlBits::AUTOPAGESIZE ) ? "ON" : "OFF") );
sal_uInt32 nBoxHeight = GetMaxAutoPaperSize().Height();
- fprintf(stderr, "[OVERFLOW-CHECK] Current MaxAutoPaperHeight is %d\n", nBoxHeight);
+ SAL_INFO("editeng.chaining", "[OVERFLOW-CHECK] Current MaxAutoPaperHeight is " << nBoxHeight);
sal_uInt32 nTxtHeight = CalcTextHeight(NULL);
- fprintf(stderr, "[OVERFLOW-CHECK] Current Text Height is %d\n", nTxtHeight);
+ SAL_INFO("editeng.chaining", "[OVERFLOW-CHECK] Current Text Height is " << nTxtHeight);
sal_uInt32 nParaCount = GetParaPortions().Count();
sal_uInt32 nFirstLineCount = GetLineCount(0);
@@ -4636,7 +4631,7 @@ void ImpEditEngine::ImplUpdateOverflowingParaNum(sal_uInt32 nPaperHeight)
if ( nY > nPaperHeight /*nCurTextHeight*/ ) // found first paragraph overflowing
{
mnOverflowingPara = nPara;
- fprintf(stderr, "[CHAINING] Setting first overflowing #Para#: %d\n", nPara);
+ SAL_INFO("editeng.chaining", "[CHAINING] Setting first overflowing #Para#: " << nPara);
ImplUpdateOverflowingLineNum( nPaperHeight, nPara, nY-nPH);
return;
}
@@ -4662,13 +4657,13 @@ void ImpEditEngine::ImplUpdateOverflowingLineNum(sal_uInt32 nPaperHeight,
// Debugging output
if (nLine == 0) {
- fprintf(stderr, "[CHAINING] First line has height %d\n", nLH);
+ SAL_INFO("editeng.chaining", "[CHAINING] First line has height " << nLH);
}
if ( nY > nPaperHeight ) // found first line overflowing
{
mnOverflowingLine = nLine;
- fprintf(stderr, "[CHAINING] Setting first overflowing -Line- to: %d\n", nLine);
+ SAL_INFO("editeng.chaining", "[CHAINING] Setting first overflowing -Line- to: " << nLine);
return;
}
}
diff --git a/editeng/source/outliner/outliner.cxx b/editeng/source/outliner/outliner.cxx
index 77bb66a..040bc6e 100644
--- a/editeng/source/outliner/outliner.cxx
+++ b/editeng/source/outliner/outliner.cxx
@@ -2094,17 +2094,16 @@ NonOverflowingText *Outliner::GetNonOverflowingText() const
// Defensive check: oveflowing para index beyond actual # of paragraphs?
if ( nCount > GetParagraphCount()-1) {
- fprintf(stderr,
- "[Overflowing] Ops, trying to retrieve para %d when max index is %d\n",
- nCount,
- GetParagraphCount()-1);
+ SAL_INFO("editeng.chaining",
+ "[Overflowing] Ops, trying to retrieve para "
+ << nCount << " when max index is " << GetParagraphCount()-1 );
return NULL;
}
if (nCount < 0)
{
- fprintf(stderr,
- "[Overflowing] No Overflowing text but GetNonOverflowinText called?!\n");
+ SAL_INFO("editeng.chaining",
+ "[Overflowing] No Overflowing text but GetNonOverflowinText called?!");
return NULL;
}
@@ -2202,10 +2201,10 @@ OverflowingText *Outliner::GetOverflowingText() const
// Defensive check: oveflowing para index beyond actual # of paragraphs?
if ( pEditEngine->GetOverflowingParaNum() > GetParagraphCount()-1) {
- fprintf(stderr,
- "[Overflowing] Ops, trying to retrieve para %d when max index is %d\n",
- pEditEngine->GetOverflowingParaNum(),
- GetParagraphCount()-1);
+ SAL_INFO("editeng.chaining",
+ "[Overflowing] Ops, trying to retrieve para "
+ << pEditEngine->GetOverflowingParaNum() << " when max index is "
+ << GetParagraphCount()-1 );
return NULL;
}
diff --git a/editeng/source/outliner/overflowingtxt.cxx b/editeng/source/outliner/overflowingtxt.cxx
index bd0f59f..fb5abd0 100644
--- a/editeng/source/outliner/overflowingtxt.cxx
+++ b/editeng/source/outliner/overflowingtxt.cxx
@@ -158,11 +158,9 @@ bool NonOverflowingText::IsLastParaInterrupted() const
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);
+ SAL_INFO("editeng.chaining", "Deleting selection from (Para: " << maContentSel.nStartPara
+ << ", Pos: " << maContentSel.nStartPos << ") to (Para: " << maContentSel.nEndPara
+ << ", Pos: " << maContentSel.nEndPos ")\n");
return pOutliner->CreateParaObject();
}
@@ -213,10 +211,10 @@ OutlinerParaObject *OFlowChainedText::InsertOverflowingText(Outliner *pOutliner,
return NULL;
if (mbIsDeepMerge) {
- fprintf(stderr, "[TEXTCHAINFLOW - OF] Deep merging paras\n" );
+ SAL_INFO("editeng.chaining", "[TEXTCHAINFLOW - OF] Deep merging paras" );
return mpOverflowingTxt->DeeplyMergeParaObject(pOutliner, pTextToBeMerged );
} else {
- fprintf(stderr, "[TEXTCHAINFLOW - OF] Juxtaposing paras\n" );
+ SAL_INFO("editeng.chaining", "[TEXTCHAINFLOW - OF] Juxtaposing paras" );
return mpOverflowingTxt->JuxtaposeParaObject(pOutliner, pTextToBeMerged );
}
}
@@ -249,11 +247,11 @@ OutlinerParaObject *UFlowChainedText::CreateMergedUnderflowParaObject(Outliner *
OutlinerParaObject *pNewText = NULL;
if (mbIsDeepMerge) {
- fprintf(stderr, "[TEXTCHAINFLOW - UF] Deep merging paras\n" );
+ SAL_INFO("editeng.chaining", "[TEXTCHAINFLOW - UF] Deep merging paras" );
pNewText = TextChainingUtils::DeeplyMergeParaObject(mxUnderflowingTxt, pOutl, pNextLinkWholeText);
} else {
// NewTextForCurBox = Txt(CurBox) ++ Txt(NextBox)
- fprintf(stderr, "[TEXTCHAINFLOW - UF] Juxtaposing paras\n" );
+ SAL_INFO("editeng.chaining", "[TEXTCHAINFLOW - UF] Juxtaposing paras" );
pNewText = TextChainingUtils::JuxtaposeParaObject(mxUnderflowingTxt, pOutl, pNextLinkWholeText);
}
commit d8c7e8b68bcd71925d5849e3d8a7cbd999b6980d
Author: matteocam <matteo.campanelli at gmail.com>
Date: Mon Sep 7 20:01:35 2015 +0200
chained editeng: Handle chaining for cutting and pasting
Change-Id: Iec08e339a7f06c5fa56e67b42206b31c766f845b
diff --git a/editeng/source/outliner/outlvw.cxx b/editeng/source/outliner/outlvw.cxx
index 4a0d96e..edf617f 100644
--- a/editeng/source/outliner/outlvw.cxx
+++ b/editeng/source/outliner/outlvw.cxx
@@ -675,8 +675,12 @@ void OutlinerView::InsertText( const OutlinerParaObject& rParaObj )
void OutlinerView::Cut()
{
- if ( !ImpCalcSelectedPages( false ) || pOwner->ImpCanDeleteSelectedPages( this ) )
+ if ( !ImpCalcSelectedPages( false ) || pOwner->ImpCanDeleteSelectedPages( this ) ) {
pEditView->Cut();
+ // Chaining handling
+ if (aEndCutPasteLink.IsSet())
+ aEndCutPasteLink.Call(NULL);
+ }
}
void OutlinerView::Paste()
@@ -705,6 +709,11 @@ void OutlinerView::PasteSpecial()
pEditView->SetEditEngineUpdateMode( true );
pOwner->UndoActionEnd( OLUNDO_INSERT );
pEditView->ShowCursor( true );
+
+ // Chaining handling
+ // NOTE: We need to do this last because it pEditView may be deleted if a switch of box occurs
+ if (aEndCutPasteLink.IsSet())
+ aEndCutPasteLink.Call(NULL);
}
}
commit edd3273fcb8ef1a3efab256722cc8c5ca7283e60
Author: matteocam <matteo.campanelli at gmail.com>
Date: Mon Sep 7 19:58:16 2015 +0200
chained editeng: Handle DEL key for chaining
Change-Id: I124b1adf6df3c42a58d45eaeb0e1e053c0eea4c9
diff --git a/sd/source/ui/view/drviewse.cxx b/sd/source/ui/view/drviewse.cxx
index da65984..d9e0a99 100644
--- a/sd/source/ui/view/drviewse.cxx
+++ b/sd/source/ui/view/drviewse.cxx
@@ -950,7 +950,10 @@ void DrawViewShell::FuSupport(SfxRequest& rReq)
{
vcl::KeyCode aKCode(KEY_DELETE);
KeyEvent aKEvt( 0, aKCode);
- pOLV->PostKeyEvent(aKEvt);
+ //pOLV->PostKeyEvent(aKEvt);
+ // We use SdrObjEditView to handle DEL for underflow handling
+ mpDrawView->KeyInput(aKEvt, NULL);
+
}
}
else
commit ca385fa6de8f72e638880116621b41a0fa216db3
Author: matteocam <matteo.campanelli at gmail.com>
Date: Mon Sep 7 16:37:56 2015 +0200
chained editeng: Enable chaining after a key is pressed
Change-Id: I64351619dd0886f3bb0c080557864c46a17d737d
diff --git a/svx/source/svdraw/svdedxv.cxx b/svx/source/svdraw/svdedxv.cxx
index 288b5e4..19f1b46 100644
--- a/svx/source/svdraw/svdedxv.cxx
+++ b/svx/source/svdraw/svdedxv.cxx
@@ -1325,6 +1325,15 @@ bool SdrObjEditView::KeyInput(const KeyEvent& rKEvt, vcl::Window* pWin)
{
if(pTextEditOutlinerView)
{
+ /* Start special handling of keys within a chain */
+ // We possibly move to another box before any handling
+ bool bHandled = false;
+ TextChainCursorManager *pCursorManager =
+ ImpHandleMotionThroughBoxesKeyInput(rKEvt, pWin, &bHandled);
+ if (bHandled)
+ return true;
+ /* End special handling of keys within a chain */
+
if (pTextEditOutlinerView->PostKeyEvent(rKEvt, pWin))
{
if( mpModel )
@@ -1333,6 +1342,11 @@ bool SdrObjEditView::KeyInput(const KeyEvent& rKEvt, vcl::Window* pWin)
mpModel->SetChanged();
}
+ /* Start chaining processing */
+ ImpChainingEventHdl();
+ ImpMoveCursorAfterChainingEvent(pCursorManager);
+ /* End chaining processing */
+
if (pWin!=NULL && pWin!=pTextEditWin) SetTextEditWin(pWin);
#ifdef DBG_UTIL
if (mpItemBrowser!=nullptr) mpItemBrowser->SetDirty();
commit 6f3bc537f00ff5c8dd6af847b4c9caa8c35569e5
Author: matteocam <matteo.campanelli at gmail.com>
Date: Mon Sep 7 16:33:39 2015 +0200
chained editeng: Add methods and basic setup for editing-mode chaining
Change-Id: I8065bebaf2a54170bc7b3ddbd35740bcca42298d
diff --git a/include/svx/svdedxv.hxx b/include/svx/svdedxv.hxx
index 2aa9f89..c388941 100644
--- a/include/svx/svdedxv.hxx
+++ b/include/svx/svdedxv.hxx
@@ -34,6 +34,7 @@ class EditFieldInfo;
class ImpSdrEditPara;
struct PasteOrDropInfos;
class SdrUndoManager;
+class TextChainCursorManager;
namespace com { namespace sun { namespace star { namespace uno {
class Any;
@@ -101,6 +102,10 @@ protected:
// provide their document UndoManager and derive it from SdrUndoManager.
virtual SdrUndoManager* getSdrUndoManagerForEnhancedTextEdit() const;
+ void ImpMoveCursorAfterChainingEvent(TextChainCursorManager *pCursorManager);
+ TextChainCursorManager *ImpHandleMotionThroughBoxesKeyInput(const KeyEvent& rKEvt, vcl::Window* pWin, bool *bOutHandled);
+
+
OutlinerView* ImpFindOutlinerView(vcl::Window* pWin) const;
// Create a new OutlinerView at the heap and initialize all required parameters.
@@ -109,6 +114,11 @@ protected:
void ImpPaintOutlinerView(OutlinerView& rOutlView, const Rectangle& rRect, OutputDevice& rTargetDevice) const;
void ImpInvalidateOutlinerView(OutlinerView& rOutlView) const;
+ // Chaining
+ void ImpChainingEventHdl();
+ DECL_LINK(ImpAfterCutOrPasteChainingEventHdl,void*);
+
+
// Check if the whole text is selected.
// Still returns sal_True if there is no text present.
bool ImpIsTextEditAllSelected() const;
diff --git a/sd/source/ui/view/outlview.cxx b/sd/source/ui/view/outlview.cxx
index 17fe875..c2687f6 100644
--- a/sd/source/ui/view/outlview.cxx
+++ b/sd/source/ui/view/outlview.cxx
@@ -1375,6 +1375,7 @@ void OutlineView::ResetLinks() const
mrOutliner.SetDrawPortionHdl(Link<DrawPortionInfo*,void>());
mrOutliner.SetBeginPasteOrDropHdl(Link<PasteOrDropInfos*,void>());
mrOutliner.SetEndPasteOrDropHdl(Link<PasteOrDropInfos*,void>());
+ mrOutliner.SetChainingEventHdl(aEmptyLink);
}
sal_Int8 OutlineView::AcceptDrop( const AcceptDropEvent&, DropTargetHelper&, ::sd::Window*, sal_uInt16, sal_uInt16)
diff --git a/sd/source/ui/view/sdview.cxx b/sd/source/ui/view/sdview.cxx
index 18fbf2e..524faba 100644
--- a/sd/source/ui/view/sdview.cxx
+++ b/sd/source/ui/view/sdview.cxx
@@ -1204,6 +1204,7 @@ void View::OnBeginPasteOrDrop( PasteOrDropInfos* /*pInfos*/ )
get the correct style sheet. */
void View::OnEndPasteOrDrop( PasteOrDropInfos* pInfos )
{
+ /* Style Sheet handling */
SdrTextObj* pTextObj = dynamic_cast< SdrTextObj* >( GetTextEditObject() );
SdrOutliner* pOutliner = GetTextEditOutliner();
if( pOutliner && pTextObj && pTextObj->GetPage() )
diff --git a/svx/source/svdraw/svdedxv.cxx b/svx/source/svdraw/svdedxv.cxx
index f38d33f..288b5e4 100644
--- a/svx/source/svdraw/svdedxv.cxx
+++ b/svx/source/svdraw/svdedxv.cxx
@@ -51,6 +51,8 @@
#include "svx/svdstr.hrc"
#include "svdglob.hxx"
#include "svx/globl3d.hxx"
+#include <svx/textchain.hxx>
+#include <svx/textchaincursor.hxx>
#include <editeng/outliner.hxx>
#include <editeng/adjustitem.hxx>
#include <svtools/colorcfg.hxx>
@@ -489,6 +491,102 @@ IMPL_LINK(SdrObjEditView,ImpOutlinerStatusEventHdl,EditStatus*,pEditStat)
return 0;
}
+void SdrObjEditView::ImpChainingEventHdl()
+{
+ if(pTextEditOutliner )
+ {
+ SdrTextObj* pTextObj = dynamic_cast< SdrTextObj * >( mxTextEditObj.get() );
+ OutlinerView* pOLV = GetTextEditOutlinerView();
+ if( pTextObj && pOLV)
+ {
+ TextChain *pTextChain = pTextObj->GetTextChain();
+
+ // XXX: IsChainable and GetNilChainingEvent are a bit mixed up atm
+ if (!pTextObj->IsChainable()) {
+ return;
+ }
+ // This is true during an underflow-caused overflow (with pEdtOutl->SetText())
+ if (pTextChain->GetNilChainingEvent(pTextObj)) {
+ return;
+ }
+
+ // We prevent to trigger further handling of overflow/underflow for pTextObj
+ pTextChain->SetNilChainingEvent(pTextObj, true); // XXX
+
+ // Save previous selection pos // NOTE: It must be done to have the right CursorEvent in KeyInput
+ pTextChain->SetPreChainingSel(pTextObj, pOLV->GetSelection());
+ //maPreChainingSel = new ESelection(pOLV->GetSelection());
+
+ // Handling Undo
+ const int nText = 0; // XXX: hardcoded index (SdrTextObj::getText handles only 0)
+
+ SdrUndoObjSetText *pTxtUndo = dynamic_cast< SdrUndoObjSetText* >
+ ( GetModel()->GetSdrUndoFactory().CreateUndoObjectSetText(*pTextObj, nText ) );
+
+ // trigger actual chaining
+ pTextObj->onChainingEvent();
+
+ if (pTxtUndo!=NULL)
+ {
+ pTxtUndo->AfterSetText();
+ if (!pTxtUndo->IsDifferent())
+ {
+ delete pTxtUndo;
+ pTxtUndo=NULL;
+ }
+ }
+
+ if (pTxtUndo)
+ AddUndo(pTxtUndo);
+
+ //maCursorEvent = new CursorChainingEvent(pTextChain->GetCursorEvent(pTextObj));
+ //SdrTextObj *pNextLink = pTextObj->GetNextLinkInChain();
+
+ // NOTE: Must be called. Don't let the function return if you set it to true and not reset it
+ pTextChain->SetNilChainingEvent(pTextObj, false);
+ } else {
+ // XXX
+ fprintf(stderr, "[OnChaining] No Edit Outliner View\n");
+ }
+ }
+
+}
+
+IMPL_LINK_NOARG(SdrObjEditView,ImpAfterCutOrPasteChainingEventHdl)
+{
+ SdrTextObj* pTextObj = dynamic_cast< SdrTextObj * >( GetTextEditObject());
+ if (!pTextObj)
+ return 0;
+ ImpChainingEventHdl();
+ TextChainCursorManager *pCursorManager = new TextChainCursorManager(this, pTextObj);
+ ImpMoveCursorAfterChainingEvent(pCursorManager);
+ return 0;
+}
+
+void SdrObjEditView::ImpMoveCursorAfterChainingEvent(TextChainCursorManager *pCursorManager)
+{
+ if (!mxTextEditObj.is() || !pCursorManager)
+ return;
+
+ SdrTextObj* pTextObj = dynamic_cast<SdrTextObj*>(mxTextEditObj.get());
+
+ // Check if it has links to move it to
+ if (!pTextObj->IsChainable())
+ return;
+
+ TextChain *pTextChain = pTextObj->GetTextChain();
+ ESelection aNewSel = pTextChain->GetPostChainingSel(pTextObj);
+
+
+ pCursorManager->HandleCursorEventAfterChaining(
+ pTextChain->GetCursorEvent(pTextObj),
+ aNewSel);
+
+ // Reset event
+ pTextChain->SetCursorEvent(pTextObj, CursorChainingEvent::NULL_EVENT);
+}
+
+
IMPL_LINK_TYPED(SdrObjEditView,ImpOutlinerCalcFieldValueHdl,EditFieldInfo*,pFI,void)
{
bool bOk=false;
@@ -728,6 +826,10 @@ bool SdrObjEditView::SdrBeginTextEdit(
pTextEditOutlinerView->ShowCursor();
pTextEditOutliner->SetStatusEventHdl(LINK(this,SdrObjEditView,ImpOutlinerStatusEventHdl));
+ if (pTextObj->IsChainable()) {
+ pTextEditOutlinerView->SetEndCutPasteLinkHdl(LINK(this,SdrObjEditView,ImpAfterCutOrPasteChainingEventHdl) );
+ }
+
#ifdef DBG_UTIL
if (mpItemBrowser!=nullptr) mpItemBrowser->SetDirty();
#endif
@@ -917,6 +1019,8 @@ SdrEndTextEditKind SdrObjEditView::SdrEndTextEdit(bool bDontDeleteReally)
pTEOutliner->SetBeginPasteOrDropHdl(Link<PasteOrDropInfos*,void>());
pTEOutliner->SetEndPasteOrDropHdl(Link<PasteOrDropInfos*,void>());
+ pTEOutliner->SetChainingEventHdl(Link<>());
+
const bool bUndo = IsUndoEnabled();
if( bUndo )
{
@@ -1189,6 +1293,32 @@ bool SdrObjEditView::IsTextEditFrameHit(const Point& rHit) const
return bOk;
}
+TextChainCursorManager *SdrObjEditView::ImpHandleMotionThroughBoxesKeyInput(
+ const KeyEvent& rKEvt,
+ vcl::Window*,
+ bool *bOutHandled)
+{
+ *bOutHandled = false;
+
+ SdrTextObj* pTextObj = NULL;
+ if (mxTextEditObj.is())
+ pTextObj= dynamic_cast<SdrTextObj*>(mxTextEditObj.get());
+ else
+ return NULL;
+
+ if (!pTextObj->GetNextLinkInChain() && !pTextObj->GetPrevLinkInChain())
+ return NULL;
+
+ TextChainCursorManager *pCursorManager = new TextChainCursorManager(this, pTextObj);
+ if( pCursorManager->HandleKeyEvent(rKEvt) ) {
+ // Possibly do other stuff here if necessary...
+ // XXX: Careful with the checks below (in KeyInput) for pWin and co. You should do them here I guess.
+ *bOutHandled = true;
+ }
+
+ return pCursorManager;
+}
+
bool SdrObjEditView::KeyInput(const KeyEvent& rKEvt, vcl::Window* pWin)
commit 225e72233de96b1216e688d35ccc49aaebf61b17
Author: matteocam <matteo.campanelli at gmail.com>
Date: Mon Sep 7 12:44:37 2015 +0200
chained editeng: Change EndTextEdit behavior to support recursive overflow
Change-Id: I14009fa2e91b19a850e45484de7cd234e872689a
diff --git a/svx/source/svdraw/svdotxed.cxx b/svx/source/svdraw/svdotxed.cxx
index c68b085..4e07027 100644
--- a/svx/source/svdraw/svdotxed.cxx
+++ b/svx/source/svdraw/svdotxed.cxx
@@ -23,10 +23,12 @@
#include <svx/svdoutl.hxx>
#include <editeng/editdata.hxx>
#include <editeng/outliner.hxx>
+#include <editeng/overflowingtxt.hxx>
#include <editeng/editstat.hxx>
#include <svl/itemset.hxx>
#include <editeng/eeitem.hxx>
#include <svx/sdtfchim.hxx>
+#include <svx/textchain.hxx>
bool SdrTextObj::HasTextEdit() const
@@ -126,6 +128,19 @@ bool SdrTextObj::BegTextEdit(SdrOutliner& rOutl)
return true;
}
+void ImpUpdateOutlParamsForOverflow(SdrOutliner *pOutl, SdrTextObj *pTextObj)
+{
+ // Code from ImpSetTextEditParams
+ Size aPaperMin;
+ Size aPaperMax;
+ Rectangle aEditArea;
+ pTextObj->TakeTextEditArea(&aPaperMin,&aPaperMax,&aEditArea,NULL);
+
+ pOutl->SetMinAutoPaperSize(aPaperMin);
+ pOutl->SetMaxAutoPaperSize(aPaperMax);
+ pOutl->SetPaperSize(Size());
+}
+
void SdrTextObj::TakeTextEditArea(Size* pPaperMin, Size* pPaperMax, Rectangle* pViewInit, Rectangle* pViewMin) const
{
bool bFitToSize(IsFitToSize());
@@ -263,9 +278,10 @@ void SdrTextObj::TakeTextEditArea(Size* pPaperMin, Size* pPaperMax, Rectangle* p
void SdrTextObj::EndTextEdit(SdrOutliner& rOutl)
{
+ OutlinerParaObject* pNewText = NULL;
+
if(rOutl.IsModified())
{
- OutlinerParaObject* pNewText = NULL;
// to make the gray field background vanish again
rOutl.UpdateFields();
@@ -277,8 +293,39 @@ void SdrTextObj::EndTextEdit(SdrOutliner& rOutl)
// uses GetCurrentBoundRect() which needs to take the text into account
// to work correct
mbInEditMode = false;
- SetOutlinerParaObject(pNewText);
+
+ // We don't want broadcasting if we are merely trying to move to next box (this prevents infinite loops)
+ if (IsChainable() && GetTextChain()->GetSwitchingToNextBox(this)) {
+ GetTextChain()->SetSwitchingToNextBox(this, false);
+ if( getActiveText() )
+ getActiveText()->SetOutlinerParaObject( pNewText);
+ } else { // If we are not doing in-chaining switching just set the ParaObject
+ SetOutlinerParaObject(pNewText);
+ }
+ }
+
+ /* Beginning Chaining-related code */
+ rOutl.ClearOverflowingParaNum();
+
+ /* Flush overflow for next textbox - Necessary for recursive chaining */
+ if (false &&
+ IsChainable() &&
+ GetNextLinkInChain() &&
+ GetTextChain()->GetPendingOverflowCheck(GetNextLinkInChain()) )
+ {
+ GetTextChain()->SetPendingOverflowCheck(GetNextLinkInChain(), false);
+
+ SdrOutliner rDrawOutl = GetNextLinkInChain()->ImpGetDrawOutliner();
+ // Prepare Outliner for overflow check
+ ImpUpdateOutlParamsForOverflow(&rDrawOutl, GetNextLinkInChain());
+ const OutlinerParaObject *pObj = GetNextLinkInChain()->GetOutlinerParaObject();
+ rDrawOutl.SetText(*pObj);
+
+ rDrawOutl.SetUpdateMode(true);
+ // XXX: Change name of method below to impHandleChainingEventsNonEditMode
+ GetNextLinkInChain()->impHandleChainingEventsDuringDecomposition(rDrawOutl);
}
+ /* End Chaining-related code */
pEdtOutl = NULL;
rOutl.Clear();
commit 6f344c67c38611f2914e12cafb8b9719ecf563c4
Author: matteocam <matteo.campanelli at gmail.com>
Date: Mon Sep 7 12:32:14 2015 +0200
chained editeng: Change size settings if box is chainable
Change-Id: I3717324b3be36b9503cae195fd42249d92d2c685
diff --git a/svx/source/svdraw/svdotext.cxx b/svx/source/svdraw/svdotext.cxx
index 8fd7bc2..55948aa 100644
--- a/svx/source/svdraw/svdotext.cxx
+++ b/svx/source/svdraw/svdotext.cxx
@@ -755,14 +755,19 @@ void SdrTextObj::TakeTextRect( SdrOutliner& rOutliner, Rectangle& rTextRect, boo
if (eAniDirection==SDRTEXTANI_UP || eAniDirection==SDRTEXTANI_DOWN) nHgt=1000000;
}
- // #i119885# Do not limit/force height to geometrical frame (vice versa for vertical writing)
- if(IsVerticalWriting())
- {
- nWdt = 1000000;
- }
- else
- {
- nHgt = 1000000;
+ bool bChainedFrame = IsChainable();
+ // Might be required for overflow check working: do limit height to frame if box is chainable.
+ if (!bChainedFrame) {
+ // #i119885# Do not limit/force height to geometrical frame (vice versa for vertical writing)
+
+ if(IsVerticalWriting())
+ {
+ nWdt = 1000000;
+ }
+ else
+ {
+ nHgt = 1000000;
+ }
}
rOutliner.SetMaxAutoPaperSize(Size(nWdt,nHgt));
diff --git a/svx/source/svdraw/svdotxed.cxx b/svx/source/svdraw/svdotxed.cxx
index b0b2ccc..c68b085 100644
--- a/svx/source/svdraw/svdotxed.cxx
+++ b/svx/source/svdraw/svdotxed.cxx
@@ -62,6 +62,14 @@ bool SdrTextObj::BegTextEdit(SdrOutliner& rOutl)
rOutl.SetControlWord(nStat);
}
+ // disable AUTOPAGESIZE if IsChainable (might be required for overflow check)
+ if ( IsChainable() ) {
+ EEControlBits nStat1=rOutl.GetControlWord();
+ nStat1 &=~EEControlBits::AUTOPAGESIZE;
+ rOutl.SetControlWord(nStat1);
+ }
+
+
OutlinerParaObject* pOutlinerParaObject = GetOutlinerParaObject();
if(pOutlinerParaObject!=NULL)
{
@@ -181,14 +189,18 @@ void SdrTextObj::TakeTextEditArea(Size* pPaperMin, Size* pPaperMax, Rectangle* p
if (eAniDirection==SDRTEXTANI_UP || eAniDirection==SDRTEXTANI_DOWN) nMaxHgt=1000000;
}
- // #i119885# Do not limit/force height to geometrical frame (vice versa for vertical writing)
- if(IsVerticalWriting())
- {
- nMaxWdt = 1000000;
- }
- else
- {
- nMaxHgt = 1000000;
+ bool bChainedFrame = IsChainable();
+ // Might be required for overflow check working: do limit height to frame if box is chainable.
+ if (!bChainedFrame) {
+ // #i119885# Do not limit/force height to geometrical frame (vice versa for vertical writing)
+ if(IsVerticalWriting())
+ {
+ nMaxWdt = 1000000;
+ }
+ else
+ {
+ nMaxHgt = 1000000;
+ }
}
aPaperMax.Width()=nMaxWdt;
commit 7c3362c9fb7c053e0e198c1223bb7519fb049644
Author: matteocam <matteo.campanelli at gmail.com>
Date: Mon Sep 7 12:17:30 2015 +0200
chained editeng: Add Chaining-related UNO attribute
Definition and mechanisms for UNO API.
Change-Id: I7fd3969804ca9b04881ced0b1e43ab6236cbefcc
diff --git a/include/editeng/unoprnms.hxx b/include/editeng/unoprnms.hxx
index 0566288..498d417 100644
--- a/include/editeng/unoprnms.hxx
+++ b/include/editeng/unoprnms.hxx
@@ -113,6 +113,7 @@
#define UNO_NAME_TEXT_WRITINGMODE "TextWritingMode"
#define UNO_NAME_TEXT_FONTINDEPENDENTLINESPACING "FontIndependentLineSpacing"
#define UNO_NAME_TEXT_WORDWRAP "TextWordWrap"
+#define UNO_NAME_TEXT_CHAINNEXTNAME "TextChainNextName"
#define UNO_NAME_MEASUREKIND "MeasureKind"
#define UNO_NAME_MEASURETEXTHPOS "MeasureTextHorizontalPosition"
diff --git a/include/svx/svdstr.hrc b/include/svx/svdstr.hrc
index 6663f01..d6bc94b 100644
--- a/include/svx/svdstr.hrc
+++ b/include/svx/svdstr.hrc
@@ -714,5 +714,7 @@
#define STR_TABLE_STYLE_SETTINGS (SIP_Begin + 275)
#define SIP_SA_CROP_MARKERS (SIP_Begin + 276)
#define STR_TABLE_DELETE_CELL_CONTENTS (SIP_Begin + 277)
+#define SIP_SA_CHAINNEXTNAME (SIP_Begin + 278)
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/svx/unoshprp.hxx b/include/svx/unoshprp.hxx
index b7a95be..2f8e35e 100644
--- a/include/svx/unoshprp.hxx
+++ b/include/svx/unoshprp.hxx
@@ -291,6 +291,7 @@
{ OUString(UNO_NAME_TEXT_FONTINDEPENDENTLINESPACING),SDRATTR_TEXT_USEFIXEDCELLHEIGHT,cppu::UnoType<bool>::get(), 0, 0}, \
{ OUString(UNO_NAME_TEXT_VERTADJUST), SDRATTR_TEXT_VERTADJUST, cppu::UnoType<css::drawing::TextVerticalAdjust>::get(), 0, 0},\
{ OUString(UNO_NAME_TEXT_WORDWRAP), SDRATTR_TEXT_WORDWRAP, cppu::UnoType<bool>::get(), 0, 0}, \
+ { OUString(UNO_NAME_TEXT_CHAINNEXTNAME), SDRATTR_TEXT_CHAINNEXTNAME, ::cppu::UnoType<OUString>::get(), 0, 0}, \
SVX_UNOEDIT_CHAR_PROPERTIES, \
SVX_UNOEDIT_PARA_PROPERTIES,
diff --git a/svx/source/svdraw/svdattr.cxx b/svx/source/svdraw/svdattr.cxx
index 69fc2b5..0447ca8 100644
--- a/svx/source/svdraw/svdattr.cxx
+++ b/svx/source/svdraw/svdattr.cxx
@@ -162,6 +162,7 @@ SdrItemPool::SdrItemPool(
mppLocalPoolDefaults[SDRATTR_TEXT_CONTOURFRAME -SDRATTR_START]=new SdrOnOffItem(SDRATTR_TEXT_CONTOURFRAME, false);
mppLocalPoolDefaults[SDRATTR_CUSTOMSHAPE_ADJUSTMENT -SDRATTR_START]=new SdrCustomShapeAdjustmentItem;
mppLocalPoolDefaults[SDRATTR_XMLATTRIBUTES -SDRATTR_START]=new SvXMLAttrContainerItem( SDRATTR_XMLATTRIBUTES );
+ mppLocalPoolDefaults[SDRATTR_TEXT_CHAINNEXTNAME -SDRATTR_START]=new SfxStringItem(SDRATTR_TEXT_CHAINNEXTNAME, "");
mppLocalPoolDefaults[SDRATTR_TEXT_USEFIXEDCELLHEIGHT -SDRATTR_START]=new SdrTextFixedCellHeightItem;
mppLocalPoolDefaults[SDRATTR_TEXT_WORDWRAP -SDRATTR_START]=new SdrOnOffItem(SDRATTR_TEXT_WORDWRAP, true);
mppLocalPoolDefaults[SDRATTR_TEXT_AUTOGROWSIZE -SDRATTR_START]=new SdrOnOffItem(SDRATTR_TEXT_AUTOGROWSIZE, false);
@@ -499,6 +500,7 @@ void SdrItemPool::TakeItemName(sal_uInt16 nWhich, OUString& rItemName)
case SDRATTR_XMLATTRIBUTES : nResId = SIP_SA_XMLATTRIBUTES;break;
case SDRATTR_TEXT_USEFIXEDCELLHEIGHT: nResId = SIP_SA_TEXT_USEFIXEDCELLHEIGHT;break;
case SDRATTR_TEXT_WORDWRAP : nResId = SIP_SA_WORDWRAP;break;
+ case SDRATTR_TEXT_CHAINNEXTNAME : nResId = SIP_SA_CHAINNEXTNAME;break;
case SDRATTR_TEXT_AUTOGROWSIZE : nResId = SIP_SA_AUTOGROWSIZE;break;
case SDRATTR_EDGEKIND : nResId = SIP_SA_EDGEKIND;break;
diff --git a/svx/source/svdraw/svdstr.src b/svx/source/svdraw/svdstr.src
index f790f00..16383f8 100644
--- a/svx/source/svdraw/svdstr.src
+++ b/svx/source/svdraw/svdstr.src
@@ -2114,6 +2114,12 @@ String SIP_SA_WORDWRAP
Text[ en-US ] = "Word wrap text in shape";
};
+String SIP_SA_CHAINNEXTNAME
+{
+ Text[ en-US ] = "Next link in text chain";
+};
+
+
String SIP_SA_AUTOGROWSIZE
{
Text[ en-US ] = "Auto grow shape to fit text";
diff --git a/svx/source/unodraw/unoshap2.cxx b/svx/source/unodraw/unoshap2.cxx
index 63b29ea..103ec4e 100644
--- a/svx/source/unodraw/unoshap2.cxx
+++ b/svx/source/unodraw/unoshap2.cxx
@@ -670,6 +670,7 @@ SvxShapeControlPropertyMapping[] =
{ RTL_CONSTASCII_STRINGPARAM(UNO_NAME_EDIT_CHAR_COLOR), RTL_CONSTASCII_STRINGPARAM("TextColor") },
{ RTL_CONSTASCII_STRINGPARAM("CharBackColor"), RTL_CONSTASCII_STRINGPARAM("CharBackColor") },
{ RTL_CONSTASCII_STRINGPARAM("CharBackTransparent"), RTL_CONSTASCII_STRINGPARAM("CharBackTransparent") },
+ { RTL_CONSTASCII_STRINGPARAM(UNO_NAME_TEXT_CHAINNEXTNAME), RTL_CONSTASCII_STRINGPARAM(UNO_NAME_TEXT_CHAINNEXTNAME) },
{ RTL_CONSTASCII_STRINGPARAM("CharRelief"), RTL_CONSTASCII_STRINGPARAM("FontRelief") },
{ RTL_CONSTASCII_STRINGPARAM("CharUnderlineColor"), RTL_CONSTASCII_STRINGPARAM("TextLineColor") },
{ RTL_CONSTASCII_STRINGPARAM(UNO_NAME_EDIT_PARA_ADJUST), RTL_CONSTASCII_STRINGPARAM("Align") },
diff --git a/xmloff/source/draw/sdpropls.cxx b/xmloff/source/draw/sdpropls.cxx
index 442e5db..5896cc8 100644
--- a/xmloff/source/draw/sdpropls.cxx
+++ b/xmloff/source/draw/sdpropls.cxx
@@ -146,6 +146,7 @@ const XMLPropertyMapEntry aXMLSDProperties[] =
GMAP( "NumberingRules", XML_NAMESPACE_TEXT, XML_LIST_STYLE, XML_SD_TYPE_NUMBULLET|MID_FLAG_ELEMENT_ITEM, CTF_NUMBERINGRULES ),
GMAP( "NumberingRules", XML_NAMESPACE_TEXT, XML_LIST_STYLE_NAME, XML_TYPE_STRING, CTF_SD_NUMBERINGRULES_NAME ),
GMAP( "TextWordWrap", XML_NAMESPACE_FO, XML_WRAP_OPTION, XML_TYPE_WRAP_OPTION, 0 ),
+ GMAP( "TextChainNextName", XML_NAMESPACE_DRAW, XML_CHAIN_NEXT_NAME, XML_TYPE_STRING, 0 ),
// shadow attributes
GMAP( "Shadow", XML_NAMESPACE_DRAW, XML_SHADOW, XML_SD_TYPE_SHADOW, 0 ),
diff --git a/xmloff/source/draw/ximpshap.cxx b/xmloff/source/draw/ximpshap.cxx
index e5eb4a6..8a067f6 100644
--- a/xmloff/source/draw/ximpshap.cxx
+++ b/xmloff/source/draw/ximpshap.cxx
@@ -1600,7 +1600,8 @@ SdXMLTextBoxShapeContext::SdXMLTextBoxShapeContext(
uno::Reference< drawing::XShapes >& rShapes,
bool bTemporaryShape)
: SdXMLShapeContext( rImport, nPrfx, rLocalName, xAttrList, rShapes, bTemporaryShape ),
- mnRadius(0)
+ mnRadius(0),
+ maChainNextName("")
{
}
@@ -1619,6 +1620,13 @@ void SdXMLTextBoxShapeContext::processAttribute( sal_uInt16 nPrefix, const OUStr
mnRadius, rValue);
return;
}
+
+ if( IsXMLToken( rLocalName, XML_CHAIN_NEXT_NAME ) )
+ {
+ maChainNextName = rValue;
+ return;
+ }
+
}
SdXMLShapeContext::processAttribute( nPrefix, rLocalName, rValue );
@@ -1752,6 +1760,23 @@ void SdXMLTextBoxShapeContext::StartElement(const uno::Reference< xml::sax::XAtt
}
}
+ if(maChainNextName != "")
+ {
+ uno::Reference< beans::XPropertySet > xPropSet(mxShape, uno::UNO_QUERY);
+ if(xPropSet.is())
+ {
+ try
+ {
+ xPropSet->setPropertyValue("TextChainNextName",
+ uno::makeAny( maChainNextName ) );
+ }
+ catch(const uno::Exception&)
+ {
+ OSL_FAIL( "exception during setting of name of next chain link!");
+ }
+ }
+ }
+
SdXMLShapeContext::StartElement(mxAttrList);
}
}
diff --git a/xmloff/source/draw/ximpshap.hxx b/xmloff/source/draw/ximpshap.hxx
index 73c9d8c..fdf1e70 100644
--- a/xmloff/source/draw/ximpshap.hxx
+++ b/xmloff/source/draw/ximpshap.hxx
@@ -247,6 +247,7 @@ public:
class SdXMLTextBoxShapeContext : public SdXMLShapeContext
{
sal_Int32 mnRadius;
+ OUString maChainNextName;
public:
TYPEINFO_OVERRIDE();
commit aa5946b1b04aeff5487ea21b4ffd9c3579a8d3e0
Author: matteocam <matteo.campanelli at gmail.com>
Date: Mon Sep 7 11:37:27 2015 +0200
chained editeng: Add chaining attributes and chaining primitive creation logic
Change-Id: I957d5261dd847fe5e950441585e879cfd5ae2fb2
diff --git a/include/svx/sdr/attribute/sdrtextattribute.hxx b/include/svx/sdr/attribute/sdrtextattribute.hxx
index 66e3e7a..7d5de1d 100644
--- a/include/svx/sdr/attribute/sdrtextattribute.hxx
+++ b/include/svx/sdr/attribute/sdrtextattribute.hxx
@@ -76,7 +76,10 @@ namespace drawinglayer
bool bScroll,
bool bInEditMode,
bool bFixedCellHeight,
- bool bWrongSpell);
+ bool bWrongSpell,
+ bool bToBeChained,
+ bool bChainable);
+
SdrTextAttribute();
SdrTextAttribute(const SdrTextAttribute& rCandidate);
SdrTextAttribute& operator=(const SdrTextAttribute& rCandidate);
@@ -107,6 +110,10 @@ namespace drawinglayer
SdrTextHorzAdjust getSdrTextHorzAdjust() const;
SdrTextVertAdjust getSdrTextVertAdjust() const;
+ bool isToBeChained() const;
+ bool isChainable() const;
+
+
// helpers: animation timing generators
void getBlinkTextTiming(
drawinglayer::animation::AnimationEntryList& rAnimList) const;
diff --git a/svx/source/sdr/attribute/sdrtextattribute.cxx b/svx/source/sdr/attribute/sdrtextattribute.cxx
index ddd1ce1..cefefb1 100644
--- a/svx/source/sdr/attribute/sdrtextattribute.cxx
+++ b/svx/source/sdr/attribute/sdrtextattribute.cxx
@@ -67,6 +67,10 @@ namespace drawinglayer
bool mbFixedCellHeight : 1;
bool mbWrongSpell : 1;
+ bool mbToBeChained : 1;
+ bool mbChainable : 1;
+
+
public:
ImpSdrTextAttribute(
const SdrText* pSdrText,
@@ -86,7 +90,9 @@ namespace drawinglayer
bool bScroll,
bool bInEditMode,
bool bFixedCellHeight,
- bool bWrongSpell)
+ bool bWrongSpell,
+ bool bToBeChained,
+ bool bChainable)
: mpSdrText(pSdrText),
mxOutlinerParaObject(new OutlinerParaObject(rOutlinerParaObject)),
maSdrFormTextAttribute(),
@@ -105,7 +111,9 @@ namespace drawinglayer
mbScroll(bScroll),
mbInEditMode(bInEditMode),
mbFixedCellHeight(bFixedCellHeight),
- mbWrongSpell(bWrongSpell)
+ mbWrongSpell(bWrongSpell),
+ mbToBeChained(bToBeChained),
+ mbChainable(bChainable)
{
if(pSdrText)
{
@@ -141,7 +149,9 @@ namespace drawinglayer
mbScroll(false),
mbInEditMode(false),
mbFixedCellHeight(false),
- mbWrongSpell(false)
+ mbWrongSpell(false),
+ mbToBeChained(false),
+ mbChainable(false)
{
}
@@ -167,6 +177,8 @@ namespace drawinglayer
bool isInEditMode() const { return mbInEditMode; }
bool isFixedCellHeight() const { return mbFixedCellHeight; }
bool isWrongSpell() const { return mbWrongSpell; }
+ bool isToBeChained() const { return mbToBeChained; }
+ bool isChainable() const { return mbChainable; }
const SdrFormTextAttribute& getSdrFormTextAttribute() const { return maSdrFormTextAttribute; }
sal_Int32 getTextLeftDistance() const { return maTextLeftDistance; }
sal_Int32 getTextUpperDistance() const { return maTextUpperDistance; }
@@ -225,7 +237,8 @@ namespace drawinglayer
&& isScroll() == rCandidate.isScroll()
&& isInEditMode() == rCandidate.isInEditMode()
&& isFixedCellHeight() == rCandidate.isFixedCellHeight()
- && isWrongSpell() == rCandidate.isWrongSpell());
+ && isWrongSpell() == rCandidate.isWrongSpell()
+ && isToBeChained() == rCandidate.isToBeChained() );
}
};
@@ -253,13 +266,16 @@ namespace drawinglayer
bool bScroll,
bool bInEditMode,
bool bFixedCellHeight,
- bool bWrongSpell)
+ bool bWrongSpell,
+ bool bIsToBeChained,
+ bool bChainable)
: mpSdrTextAttribute(
ImpSdrTextAttribute(
&rSdrText, rOutlinerParaObject, eFormTextStyle, aTextLeftDistance,
aTextUpperDistance, aTextRightDistance, aTextLowerDistance,
aSdrTextHorzAdjust, aSdrTextVertAdjust, bContour, bFitToSize, bAutoFit,
- bHideContour, bBlink, bScroll, bInEditMode, bFixedCellHeight, bWrongSpell))
+ bHideContour, bBlink, bScroll, bInEditMode, bFixedCellHeight, bWrongSpell,
+ bIsToBeChained, bChainable))
{
}
@@ -342,6 +358,17 @@ namespace drawinglayer
return mpSdrTextAttribute->isInEditMode();
}
+ bool SdrTextAttribute::isToBeChained() const
+ {
+ return mpSdrTextAttribute->isToBeChained();
+ }
+
+ bool SdrTextAttribute::isChainable() const
+ {
+ return mpSdrTextAttribute->isChainable();
+ }
+
+
bool SdrTextAttribute::isFixedCellHeight() const
{
return mpSdrTextAttribute->isFixedCellHeight();
diff --git a/svx/source/sdr/primitive2d/sdrattributecreator.cxx b/svx/source/sdr/primitive2d/sdrattributecreator.cxx
index 5222367..2ec29ed 100644
--- a/svx/source/sdr/primitive2d/sdrattributecreator.cxx
+++ b/svx/source/sdr/primitive2d/sdrattributecreator.cxx
@@ -520,6 +520,11 @@ namespace drawinglayer
{
const SdrTextObj& rTextObj = rText.GetObject();
+ // Save chaining attributes
+ bool bToBeChained = rTextObj.IsToBeChained();
+ bool bChainable = rTextObj.IsChainable();
+
+
if(rText.GetOutlinerParaObject() && rText.GetModel())
{
// added TextEdit text suppression
@@ -578,7 +583,9 @@ namespace drawinglayer
SDRTEXTANI_SCROLL == eAniKind || SDRTEXTANI_ALTERNATE == eAniKind || SDRTEXTANI_SLIDE == eAniKind,
bInEditMode,
static_cast<const SdrTextFixedCellHeightItem&>(rSet.Get(SDRATTR_TEXT_USEFIXEDCELLHEIGHT)).GetValue(),
- bWrongSpell);
+ bWrongSpell,
+ bToBeChained,
+ bChainable);
}
return attribute::SdrTextAttribute();
diff --git a/svx/source/sdr/primitive2d/sdrdecompositiontools.cxx b/svx/source/sdr/primitive2d/sdrdecompositiontools.cxx
index ddc6608..390683f 100644
--- a/svx/source/sdr/primitive2d/sdrdecompositiontools.cxx
+++ b/svx/source/sdr/primitive2d/sdrdecompositiontools.cxx
@@ -307,7 +307,18 @@ namespace drawinglayer
else if(rText.isAutoFit())
{
// isotrophically scaled text in range
- pNew = new SdrAutoFitTextPrimitive2D(&rText.getSdrText(), rText.getOutlinerParaObject(), aAnchorTransform, bWordWrap);
+ pNew = new SdrAutoFitTextPrimitive2D(
+ &rText.getSdrText(),
+ rText.getOutlinerParaObject(),
+ aAnchorTransform,
+ bWordWrap);
+ }
+ else if( rText.isChainable() && !rText.isInEditMode() )
+ {
+ pNew = new SdrChainedTextPrimitive2D(
+ &rText.getSdrText(),
+ rText.getOutlinerParaObject(),
+ aAnchorTransform );
}
else // text in range
{
commit fa98c3b4c51d9ea84cd380069b5e5bed8fbce0a3
Author: matteocam <matteo.campanelli at gmail.com>
Date: Sun Sep 6 12:06:47 2015 +0200
chained editeng: Enhance existing svx classes with chaining-related methods
Change-Id: I10829d8f07f8881af6d1a9422cbdae00e83a7ac8
diff --git a/include/svx/sdr/primitive2d/svx_primitivetypes2d.hxx b/include/svx/sdr/primitive2d/svx_primitivetypes2d.hxx
index 0fae52a..1161f2c 100644
--- a/include/svx/sdr/primitive2d/svx_primitivetypes2d.hxx
+++ b/include/svx/sdr/primitive2d/svx_primitivetypes2d.hxx
@@ -48,6 +48,7 @@
#define PRIMITIVE2D_ID_SDRCONTROLPRIMITIVE2D (PRIMITIVE2D_ID_RANGE_SVX| 21)
#define PRIMITIVE2D_ID_SDROLECONTENTPRIMITIVE2D (PRIMITIVE2D_ID_RANGE_SVX| 22)
#define PRIMITIVE2D_ID_SDRAUTOFITTEXTPRIMITIVE2D (PRIMITIVE2D_ID_RANGE_SVX| 23)
+#define PRIMITIVE2D_ID_SDRCHAINEDTEXTPRIMITIVE2D (PRIMITIVE2D_ID_RANGE_SVX| 24)
diff --git a/include/svx/svddef.hxx b/include/svx/svddef.hxx
index 0e92e7f..5b3e5e9 100644
--- a/include/svx/svddef.hxx
+++ b/include/svx/svddef.hxx
@@ -112,7 +112,8 @@
#define SDRATTR_TEXT_USEFIXEDCELLHEIGHT (SDRATTR_MISC_FIRST +24) /* 1121 */ /* 1121 */ /* 1104 */ /* Pool V2 */
#define SDRATTR_TEXT_WORDWRAP (SDRATTR_MISC_FIRST +25) /* 1122 */ /* 1122 */ /* 1105 */ /* Pool V2 */
#define SDRATTR_TEXT_AUTOGROWSIZE (SDRATTR_MISC_FIRST +26) /* 1123 */ /* 1123 */ /* 1106 */ /* Pool V2 */
-#define SDRATTR_MISC_LAST (SDRATTR_TEXT_AUTOGROWSIZE) /* 1125 */ /* 1125 */ /* 1108 */ /* Pool V1: 1056 */
+#define SDRATTR_TEXT_CHAINNEXTNAME (SDRATTR_MISC_FIRST + 27) /* 1124 */ /* 11124 */
+#define SDRATTR_MISC_LAST (SDRATTR_TEXT_CHAINNEXTNAME) /* 1125 */ /* 1125 */ /* 1108 */ /* Pool V1: 1056 */
#define SDRATTR_EDGE_FIRST (SDRATTR_MISC_LAST + 1) /* 1127 */ /* Pool V4 */
#define SDRATTR_EDGEKIND (SDRATTR_EDGE_FIRST + 0) /* 1127 */ /* Pool V4 */
diff --git a/include/svx/svdmodel.hxx b/include/svx/svdmodel.hxx
index 2c9eb47..a296dc6 100644
--- a/include/svx/svdmodel.hxx
+++ b/include/svx/svdmodel.hxx
@@ -76,6 +76,7 @@ class SvNumberFormatter;
class SdrOutlinerCache;
class SdrUndoFactory;
class ImageMap;
+class TextChain;
namespace comphelper
{
class IEmbeddedHelper;
@@ -173,6 +174,7 @@ protected:
m_pEmbeddedHelper; // helper for embedded objects to get rid of the SfxObjectShell
SdrOutliner* pDrawOutliner; // an Outliner for outputting text
SdrOutliner* pHitTestOutliner;// an Outliner for the HitTest
+ SdrOutliner* pChainingOutliner; // an Outliner for chaining overflowing text
sal_uIntPtr nDefTextHgt; // Default text height in logical units
VclPtr<OutputDevice> pRefOutDev; // ReferenceDevice for the EditEngine
/// Set if we are doing tiled rendering.
@@ -216,6 +218,7 @@ protected:
sal_uInt16 nDefaultTabulator;
sal_uInt32 nMaxUndoCount;
+ TextChain* pTextChain;
// sdr::Comment interface
@@ -328,6 +331,10 @@ public:
void SetTextDefaults() const;
static void SetTextDefaults( SfxItemPool* pItemPool, sal_uIntPtr nDefTextHgt );
+ SdrOutliner& GetChainingOutliner(const SdrTextObj* pObj=NULL) const;
+ TextChain *GetTextChain() const;
+ void SetNextLinkInTextChain(SdrTextObj *pPrev, SdrTextObj *pNext);
+
// ReferenceDevice for the EditEngine
void SetRefDevice(OutputDevice* pDev);
OutputDevice* GetRefDevice() const { return pRefOutDev.get(); }
diff --git a/include/svx/svdotext.hxx b/include/svx/svdotext.hxx
index 0b62bab..82950f0f 100644
--- a/include/svx/svdotext.hxx
+++ b/include/svx/svdotext.hxx
@@ -38,12 +38,16 @@
class OutlinerParaObject;
+class OverflowingText;
class SdrOutliner;
class SdrTextObj;
class SdrTextObjTest;
class SvxFieldItem;
class ImpSdrObjTextLink;
class EditStatus;
+class TextChain;
+class TextChainFlow;
+
namespace sdr { namespace properties {
class TextProperties;
@@ -55,6 +59,7 @@ namespace drawinglayer { namespace primitive2d {
class SdrBlockTextPrimitive2D;
class SdrAutoFitTextPrimitive2D;
class SdrStretchTextPrimitive2D;
+ class SdrChainedTextPrimitive2D;
}}
namespace drawinglayer { namespace animation {
@@ -133,6 +138,11 @@ private:
friend class sdr::table::SdrTableRtfExporter;
friend class sdr::table::SdrTableRTFParser;
+ friend class TextChain;
+ friend class TextChainFlow;
+ friend class EditingTextChainFlow;
+
+
// CustomShapeproperties need to access the "bTextFrame" member:
friend class sdr::properties::CustomShapeProperties;
@@ -209,11 +219,24 @@ protected:
// position of the virtual object. This offset is used when setting up
// and maintaining the OutlinerView.
Point maTextEditOffset;
+
+ virtual SdrObject* getFullDragClone() const SAL_OVERRIDE;
+
public:
const Point& GetTextEditOffset() const { return maTextEditOffset; }
void SetTextEditOffset(const Point& rNew) { maTextEditOffset = rNew; }
protected:
+ OverflowingText *mpOverflowingText = NULL;
+ bool mbIsUnchainableClone = false;
+
+ // the successor in a chain
+ SdrTextObj *mpNextInChain = NULL;
+ SdrTextObj *mpPrevInChain = NULL;
+
+ // indicating the for its text to be chained to another text box
+ bool mbToBeChained : 1;
+
// Fuer beschriftete Zeichenobjekte ist bTextFrame=FALSE. Der Textblock
// wird dann hoizontal und vertikal an aRect zentriert. Bei bTextFrame=
// sal_True wird der Text in aRect hineinformatiert. Der eigentliche Textrahmen
@@ -343,6 +366,17 @@ public:
bool IsAutoFit() const;
/// returns true if the old feature for fitting shape content should into shape is enabled. implies IsAutoFit()==false!
bool IsFitToSize() const;
+
+ // Chaining
+ bool IsToBeChained() const;
+ SdrTextObj *GetNextLinkInChain() const;
+ void SetNextLinkInChain(SdrTextObj *);
+ SdrTextObj *GetPrevLinkInChain() const;
+ bool IsChainable() const;
+ void SetPreventChainable();
+ bool GetPreventChainable() const;
+ TextChain *GetTextChain() const;
+
SdrObjKind GetTextKind() const { return eTextKind; }
// #i121917#
@@ -491,6 +525,8 @@ public:
void SetTextEditOutliner(SdrOutliner* pOutl) { pEdtOutl=pOutl; }
+ void SetToBeChained(bool bToBeChained);
+
/** Setup given Outliner equivalently to SdrTextObj::Paint()
To setup an arbitrary Outliner in the same way as the draw
@@ -529,6 +565,10 @@ public:
/** called from the SdrObjEditView during text edit when the status of the edit outliner changes */
virtual void onEditOutlinerStatusEvent( EditStatus* pEditStatus );
+ /** called from the SdrObjEditView during text edit when a chain of boxes is to be updated */
+ virtual void onChainingEvent();
+
+
// transformation interface for StarOfficeAPI. This implements support for
@@ -588,6 +628,11 @@ public:
drawinglayer::primitive2d::Primitive2DSequence& rTarget,
const drawinglayer::primitive2d::SdrStretchTextPrimitive2D& rSdrStretchTextPrimitive,
const drawinglayer::geometry::ViewInformation2D& aViewInformation) const;
+ void impDecomposeChainedTextPrimitive(
+ drawinglayer::primitive2d::Primitive2DSequence& rTarget,
+ const drawinglayer::primitive2d::SdrChainedTextPrimitive2D& rSdrChainedTextPrimitive,
+ const drawinglayer::geometry::ViewInformation2D& aViewInformation) const;
+ void impHandleChainingEventsDuringDecomposition(SdrOutliner &rOutliner) const;
// timing generators
diff --git a/svx/inc/sdr/primitive2d/sdrtextprimitive2d.hxx b/svx/inc/sdr/primitive2d/sdrtextprimitive2d.hxx
index e31bac9..db10e08 100644
--- a/svx/inc/sdr/primitive2d/sdrtextprimitive2d.hxx
+++ b/svx/inc/sdr/primitive2d/sdrtextprimitive2d.hxx
@@ -331,6 +331,43 @@ namespace drawinglayer
} // end of namespace primitive2d
} // end of namespace drawinglayer
+namespace drawinglayer
+{
+ namespace primitive2d
+ {
+ class SdrChainedTextPrimitive2D : public SdrTextPrimitive2D
+ {
+ private:
+ // XXX: might have position of overflowing text
+
+ ::basegfx::B2DHomMatrix maTextRangeTransform; // text range transformation from unit range ([0.0 .. 1.0]) to text range
+ protected:
+ // local decomposition.
+ virtual Primitive2DSequence create2DDecomposition(const geometry::ViewInformation2D& aViewInformation) const SAL_OVERRIDE;
+
+ public:
+ SdrChainedTextPrimitive2D(
+ const SdrText* pSdrText,
+ const OutlinerParaObject& rOutlinerParaObjectPtrs,
+ const ::basegfx::B2DHomMatrix& rTextRangeTransform);
+
+ // get data
+ const basegfx::B2DHomMatrix& getTextRangeTransform() const { return maTextRangeTransform; }
+ //bool getWordWrap() const { return true; } // XXX: Hack! Should have a proper implementation//
+
+ // compare operator
+ virtual bool operator==(const BasePrimitive2D& rPrimitive) const SAL_OVERRIDE;
+
+ // transformed clone operator
+ virtual SdrTextPrimitive2D* createTransformedClone(const basegfx::B2DHomMatrix& rTransform) const SAL_OVERRIDE;
+
+ // provide unique ID
+ DeclPrimitive2DIDBlock()
+ };
+ } // end of namespace primitive2d
+} // end of namespace drawinglayer
+
+
#endif // INCLUDED_SVX_INC_SDR_PRIMITIVE2D_SDRTEXTPRIMITIVE2D_HXX
diff --git a/svx/source/sdr/primitive2d/sdrtextprimitive2d.cxx b/svx/source/sdr/primitive2d/sdrtextprimitive2d.cxx
index 385de99..ac7815d 100644
--- a/svx/source/sdr/primitive2d/sdrtextprimitive2d.cxx
+++ b/svx/source/sdr/primitive2d/sdrtextprimitive2d.cxx
@@ -480,6 +480,48 @@ namespace drawinglayer
} // end of namespace primitive2d
} // end of namespace drawinglayer
+namespace drawinglayer
+{
+ namespace primitive2d
+ {
+
+ SdrChainedTextPrimitive2D::SdrChainedTextPrimitive2D(
+ const SdrText* pSdrText,
+ const OutlinerParaObject& rOutlinerParaObject,
+ const basegfx::B2DHomMatrix& rTextRangeTransform)
+ : SdrTextPrimitive2D(pSdrText, rOutlinerParaObject),
+ maTextRangeTransform(rTextRangeTransform)
+ { }
+
+ Primitive2DSequence SdrChainedTextPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& aViewInformation) const
+ {
+ Primitive2DSequence aRetval;
+ getSdrText()->GetObject().impDecomposeChainedTextPrimitive(aRetval, *this, aViewInformation);
+
+ return encapsulateWithTextHierarchyBlockPrimitive2D(aRetval);
+ }
+
+ bool SdrChainedTextPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
+ {
+ if(SdrTextPrimitive2D::operator==(rPrimitive))
+ {
+ const SdrBlockTextPrimitive2D& rCompare = (SdrBlockTextPrimitive2D&)rPrimitive;
+
+ return (getTextRangeTransform() == rCompare.getTextRangeTransform());
+ }
+
+ return false;
+ }
+
+ SdrTextPrimitive2D* SdrChainedTextPrimitive2D::createTransformedClone(const basegfx::B2DHomMatrix& rTransform) const
+ {
+ return new SdrChainedTextPrimitive2D(getSdrText(), getOutlinerParaObject(), rTransform * getTextRangeTransform());
+ }
+
+ // provide unique ID
+ ImplPrimitive2DIDBlock(SdrChainedTextPrimitive2D, PRIMITIVE2D_ID_SDRCHAINEDTEXTPRIMITIVE2D)
+ } // end of namespace primitive2d
+} // end of namespace drawinglayer
namespace drawinglayer
diff --git a/svx/source/svdraw/svdmodel.cxx b/svx/source/svdraw/svdmodel.cxx
index 5478cdc..942d623 100644
--- a/svx/source/svdraw/svdmodel.cxx
+++ b/svx/source/svdraw/svdmodel.cxx
@@ -56,6 +56,7 @@
#include <svx/svdpool.hxx>
#include <svx/svdobj.hxx>
#include <svx/svdotext.hxx>
+#include <svx/textchain.hxx>
#include <svx/svdetc.hxx>
#include <svx/svdoutl.hxx>
#include <svx/svdoole2.hxx>
@@ -221,6 +222,15 @@ void SdrModel::ImpCtor(SfxItemPool* pPool, ::comphelper::IEmbeddedHelper* _pEmbe
pHitTestOutliner = SdrMakeOutliner(OUTLINERMODE_TEXTOBJECT, *this);
ImpSetOutlinerDefaults(pHitTestOutliner, true);
+ /* Start Text Chaining related code */
+ // Initialize Chaining Outliner
+ pChainingOutliner = SdrMakeOutliner( OUTLINERMODE_TEXTOBJECT, *this );
+ ImpSetOutlinerDefaults(pChainingOutliner, true);
+
+ // Make a TextChain
+ pTextChain = new TextChain;
+ /* End Text Chaining related code */
+
ImpCreateTables();
}
@@ -763,6 +773,12 @@ SdrOutliner& SdrModel::GetDrawOutliner(const SdrTextObj* pObj) const
return *pDrawOutliner;
}
+SdrOutliner& SdrModel::GetChainingOutliner(const SdrTextObj* pObj) const
+{
+ pChainingOutliner->SetTextObj(pObj);
+ return *pChainingOutliner;
+}
+
const SdrTextObj* SdrModel::GetFormattingTextObj() const
{
if (pDrawOutliner!=NULL) {
@@ -1994,6 +2010,17 @@ void SdrModel::PageListChanged()
{
}
+TextChain *SdrModel::GetTextChain() const
+{
+ return pTextChain;
+}
+
+void SdrModel::SetNextLinkInTextChain(SdrTextObj *pPrev, SdrTextObj *pNext)
+{
+ // Delegate to SdrTextObj
+ pPrev->SetNextLinkInChain(pNext);
+}
+
const SdrPage* SdrModel::GetMasterPage(sal_uInt16 nPgNum) const
{
DBG_ASSERT(nPgNum < maMaPag.size(), "SdrModel::GetMasterPage: Access out of range (!)");
diff --git a/svx/source/svdraw/svdotext.cxx b/svx/source/svdraw/svdotext.cxx
index 6feb877..8fd7bc2 100644
--- a/svx/source/svdraw/svdotext.cxx
+++ b/svx/source/svdraw/svdotext.cxx
@@ -38,6 +38,8 @@
#include <editeng/editobj.hxx>
#include <editeng/outliner.hxx>
#include <editeng/fhgtitem.hxx>
+#include <svx/textchain.hxx>
+#include <svx/textchainflow.hxx>
#include <svl/itempool.hxx>
#include <editeng/adjustitem.hxx>
#include <editeng/flditem.hxx>
@@ -102,6 +104,9 @@ SdrTextObj::SdrTextObj()
mbTextAnimationAllowed = true;
maTextEditOffset = Point(0, 0);
+ // chaining
+ mbToBeChained = false;
+
// #i25616#
mbSupportTextIndentingOnLineWidthChange = true;
mbInDownScale = false;
@@ -130,6 +135,9 @@ SdrTextObj::SdrTextObj(const Rectangle& rNewRect)
mbInDownScale = false;
maTextEditOffset = Point(0, 0);
+ // chaining
+ mbToBeChained = false;
+
// #i25616#
mbSupportTextIndentingOnLineWidthChange = true;
}
@@ -155,6 +163,9 @@ SdrTextObj::SdrTextObj(SdrObjKind eNewTextKind)
mbInDownScale = false;
maTextEditOffset = Point(0, 0);
+ // chaining
+ mbToBeChained = false;
+
// #i25616#
mbSupportTextIndentingOnLineWidthChange = true;
}
@@ -176,6 +187,9 @@ SdrTextObj::SdrTextObj(SdrObjKind eNewTextKind, const Rectangle& rNewRect)
bDisableAutoWidthOnDragging=false;
ImpJustifyRect(maRect);
+ // chaining
+ mbToBeChained = false;
+
mbInEditMode = false;
mbTextHidden = false;
mbTextAnimationAllowed = true;
@@ -1520,6 +1534,25 @@ void SdrTextObj::ForceOutlinerParaObject()
}
}
+// chaining
+bool SdrTextObj::IsToBeChained() const
+{
+ return mbToBeChained;
+}
+
+void SdrTextObj::SetToBeChained(bool bToBeChained)
+{
+ mbToBeChained = bToBeChained;
+}
+
+TextChain *SdrTextObj::GetTextChain() const
+{
+ //if (!IsChainable())
+ // return NULL;
+
+ return pModel->GetTextChain();
+}
+
bool SdrTextObj::IsVerticalWriting() const
{
if(pEdtOutl)
@@ -1948,6 +1981,179 @@ void SdrTextObj::onEditOutlinerStatusEvent( EditStatus* pEditStatus )
}
}
+/* Begin chaining code */
+
+// XXX: Make it a method somewhere?
+SdrObject *ImpGetObjByName(SdrObjList *pObjList, OUString aObjName)
+{
+ // scan the whole list
+ size_t nObjCount = pObjList->GetObjCount();
+ for (unsigned i = 0; i < nObjCount; i++) {
+ SdrObject *pCurObj = pObjList->GetObj(i);
+
+ if (pCurObj->GetName() == aObjName) {
+ return pCurObj;
+ }
+ }
+ // not found
+ return NULL;
+}
+
+// XXX: Make it a (private) method of SdrTextObj
+void ImpUpdateChainLinks(SdrTextObj *pTextObj, OUString aNextLinkName)
+{
+ // XXX: Current implementation constraints text boxes to be on the same page
+
+ // No next link
+ if (aNextLinkName == "") {
+ pTextObj->SetNextLinkInChain(NULL);
+ return;
+ }
+
+ SdrPage *pPage = pTextObj->GetPage();
+ assert(pPage);
+ SdrTextObj *pNextTextObj = dynamic_cast< SdrTextObj * >
+ (ImpGetObjByName(pPage, aNextLinkName));
+ if (!pNextTextObj) {
+ fprintf(stderr, "[CHAINING] Can't find object as next link.\n");
+ return;
+ }
+
+ pTextObj->SetNextLinkInChain(pNextTextObj);
+}
+
+bool SdrTextObj::IsChainable() const
+{
+ // Read it as item
+ const SfxItemSet& rSet = GetObjectItemSet();
+ OUString aNextLinkName = static_cast<const SfxStringItem&>(rSet.Get(SDRATTR_TEXT_CHAINNEXTNAME)).GetValue();
+
+ // Update links if any inconsistency is found
+ bool bNextLinkUnsetYet = (aNextLinkName != "") && !mpNextInChain;
+ bool bInconsistentNextLink = mpNextInChain && mpNextInChain->GetName() != aNextLinkName;
+ // if the link is not set despite there should be one OR if it has changed
+ if (bNextLinkUnsetYet || bInconsistentNextLink) {
+ ImpUpdateChainLinks(const_cast<SdrTextObj *>(this), aNextLinkName);
+ }
+
+ return aNextLinkName != ""; // XXX: Should we also check for GetNilChainingEvent? (see old code below)
+
+/*
+ // Check that no overflow is going on
+ if (!GetTextChain() || GetTextChain()->GetNilChainingEvent(this))
+ return false;
+*/
+}
+
+void SdrTextObj::onChainingEvent()
+{
+ if (!pEdtOutl)
+ return;
+
+ // Outliner for text transfer
+ SdrOutliner &aDrawOutliner = ImpGetDrawOutliner();
+
+ EditingTextChainFlow aTxtChainFlow(this);
+ aTxtChainFlow.CheckForFlowEvents(pEdtOutl);
+
+
+ if (aTxtChainFlow.IsOverflow()) {
+ fprintf(stderr, "[CHAINING] Overflow going on\n");
+ // One outliner is for non-overflowing text, the other for overflowing text
+ // We remove text directly from the editing outliner
+ aTxtChainFlow.ExecuteOverflow(pEdtOutl, &aDrawOutliner);
+ } else if (aTxtChainFlow.IsUnderflow()) {
+ fprintf(stderr, "[CHAINING] Underflow going on\n");
+ // underflow-induced overflow
+ aTxtChainFlow.ExecuteUnderflow(&aDrawOutliner);
+ bool bIsOverflowFromUnderflow = aTxtChainFlow.IsOverflow();
+ // handle overflow
+ if (bIsOverflowFromUnderflow) {
+ fprintf(stderr, "[CHAINING] Overflow going on (underflow induced)\n");
+ // prevents infinite loops when setting text for editing outliner
+
+
+ aTxtChainFlow.ExecuteOverflow(&aDrawOutliner, &aDrawOutliner);
+
+ }
+ }
+}
+
+SdrTextObj* SdrTextObj::GetNextLinkInChain() const
+{
+ /*
+ if (GetTextChain())
+ return GetTextChain()->GetNextLink(this);
+
+ return NULL;
+ */
+
+ return mpNextInChain;
+}
+
+void SdrTextObj::SetNextLinkInChain(SdrTextObj *pNextObj)
+{
+ // Basically a doubly linked list implementation
+
+ SdrTextObj *pOldNextObj = mpNextInChain;
+
+ // Replace next link
+ mpNextInChain = pNextObj;
+ // Deal with old next link's prev link
+ if (pOldNextObj) {
+ pOldNextObj->mpPrevInChain = NULL;
+ }
+
+ // Deal with new next link's prev link
+ if (mpNextInChain) {
+ // If there is a prev already at all and this is not already the current object
+ if (mpNextInChain->mpPrevInChain &&
+ mpNextInChain->mpPrevInChain != this)
+ mpNextInChain->mpPrevInChain->mpNextInChain = NULL;
+ mpNextInChain->mpPrevInChain = this;
+ }
+
+ // TODO: Introduce check for circular chains
+
+}
+
+SdrTextObj* SdrTextObj::GetPrevLinkInChain() const
+{
+ /*
+ if (GetTextChain())
+ return GetTextChain()->GetPrevLink(this);
+
+ return NULL;
+ */
+
+ return mpPrevInChain;
+}
+
+void SdrTextObj::SetPreventChainable()
+{
+ mbIsUnchainableClone = true;
+}
+
+bool SdrTextObj::GetPreventChainable() const
+{
+ // Prevent chaining it 1) during dragging && 2) when we are editing next link
+ return mbIsUnchainableClone || (GetNextLinkInChain() && GetNextLinkInChain()->IsInEditMode());
+}
+
+ SdrObject* SdrTextObj::getFullDragClone() const
+ {
+ SdrObject *pClone = SdrAttrObj::getFullDragClone();
+ SdrTextObj *pTextObjClone = dynamic_cast<SdrTextObj *>(pClone);
+ if (pTextObjClone != NULL) {
+ // Avoid transferring of text for chainable object during dragging
+ pTextObjClone->SetPreventChainable();
+ }
+
+ return pClone;
+ }
+
+/* End chaining code */
+
/** returns the currently active text. */
SdrText* SdrTextObj::getActiveText() const
{
diff --git a/svx/source/svdraw/svdotextdecomposition.cxx b/svx/source/svdraw/svdotextdecomposition.cxx
index 74eebf0..be19e39 100644
--- a/svx/source/svdraw/svdotextdecomposition.cxx
+++ b/svx/source/svdraw/svdotextdecomposition.cxx
@@ -22,6 +22,9 @@
#include <svx/svdoutl.hxx>
#include <svx/svdpage.hxx>
#include <svx/svdotext.hxx>
+#include <svx/svdmodel.hxx>
+#include <svx/textchain.hxx>
+#include <svx/textchainflow.hxx>
#include <basegfx/vector/b2dvector.hxx>
#include <sdr/primitive2d/sdrtextprimitive2d.hxx>
#include <drawinglayer/primitive2d/textprimitive2d.hxx>
@@ -48,6 +51,8 @@
#include <svx/unoapi.hxx>
#include <drawinglayer/geometry/viewinformation2d.hxx>
#include <editeng/outlobj.hxx>
+#include <editeng/editobj.hxx>
+#include <editeng/overflowingtxt.hxx>
#include <basegfx/matrix/b2dhommatrixtools.hxx>
using namespace com::sun::star;
@@ -1404,5 +1409,194 @@ void SdrTextObj::impGetScrollTextTiming(drawinglayer::animation::AnimationEntryL
}
}
+void SdrTextObj::impHandleChainingEventsDuringDecomposition(SdrOutliner &rOutliner) const
+{
+ if (GetTextChain()->GetNilChainingEvent(this))
+ return;
+
+ GetTextChain()->SetNilChainingEvent(this, true);
+
+ TextChainFlow aTxtChainFlow(const_cast<SdrTextObj*>(this));
+ bool bIsOverflow;
+
+ // Some debug output
+ size_t nObjCount = pPage->GetObjCount();
+ for (unsigned i = 0; i < nObjCount; i++) {
+ SdrTextObj *pCurObj = (SdrTextObj *) pPage->GetObj(i);
+
+ if (pCurObj == this) {
+ fprintf(stderr, "Working on TextBox %d\n", i);
+ break;
+ }
+ }
+
+ aTxtChainFlow.CheckForFlowEvents(&rOutliner);
+
+ if (aTxtChainFlow.IsUnderflow() && !IsInEditMode())
+ {
+ // underflow-induced overflow
+ aTxtChainFlow.ExecuteUnderflow(&rOutliner);
+ bIsOverflow = aTxtChainFlow.IsOverflow();
+ } else {
+ // standard overflow (no underlow before)
+ bIsOverflow = aTxtChainFlow.IsOverflow();
+ }
+
+ if (bIsOverflow && !IsInEditMode()) {
+ // Initialize Chaining Outliner
+ SdrOutliner &rChainingOutl = pModel->GetChainingOutliner(this);
+ ImpInitDrawOutliner( rChainingOutl );
+ rChainingOutl.SetUpdateMode(true);
+ // We must pass the chaining outliner otherwise we would mess up decomposition
+ aTxtChainFlow.ExecuteOverflow(&rOutliner, &rChainingOutl);
+ }
+
+ GetTextChain()->SetNilChainingEvent(this, false);
+}
+
+void SdrTextObj::impDecomposeChainedTextPrimitive(
+ drawinglayer::primitive2d::Primitive2DSequence& rTarget,
+ const drawinglayer::primitive2d::SdrChainedTextPrimitive2D& rSdrChainedTextPrimitive,
+ const drawinglayer::geometry::ViewInformation2D& aViewInformation) const
+{
+ // decompose matrix to have position and size of text
+ basegfx::B2DVector aScale, aTranslate;
+ double fRotate, fShearX;
+ rSdrChainedTextPrimitive.getTextRangeTransform().decompose(aScale, aTranslate, fRotate, fShearX);
+
+ // use B2DRange aAnchorTextRange for calculations
+ basegfx::B2DRange aAnchorTextRange(aTranslate);
+ aAnchorTextRange.expand(aTranslate + aScale);
+
+ // prepare outliner
+ const SfxItemSet& rTextItemSet = rSdrChainedTextPrimitive.getSdrText()->GetItemSet();
+ SdrOutliner& rOutliner = ImpGetDrawOutliner();
+
+ SdrTextVertAdjust eVAdj = GetTextVerticalAdjust(rTextItemSet);
+ SdrTextHorzAdjust eHAdj = GetTextHorizontalAdjust(rTextItemSet);
+ const EEControlBits nOriginalControlWord(rOutliner.GetControlWord());
+ const Size aNullSize;
+
+ // set visualizing page at Outliner; needed e.g. for PageNumberField decomposition
+ rOutliner.setVisualizedPage(GetSdrPageFromXDrawPage(aViewInformation.getVisualizedPage()));
+
+ rOutliner.SetControlWord(nOriginalControlWord|EEControlBits::AUTOPAGESIZE|EEControlBits::STRETCHING);
+ rOutliner.SetMinAutoPaperSize(aNullSize);
+ rOutliner.SetMaxAutoPaperSize(Size(1000000,1000000));
+
+ // add one to rage sizes to get back to the old Rectangle and outliner measurements
+ const sal_uInt32 nAnchorTextWidth(FRound(aAnchorTextRange.getWidth() + 1L));
+ const sal_uInt32 nAnchorTextHeight(FRound(aAnchorTextRange.getHeight() + 1L));
+
+ // Text
+ const OutlinerParaObject* pOutlinerParaObject = rSdrChainedTextPrimitive.getSdrText()->GetOutlinerParaObject();
+ OSL_ENSURE(pOutlinerParaObject, "impDecomposeBlockTextPrimitive used with no OutlinerParaObject (!)");
+
+ const bool bVerticalWritintg(pOutlinerParaObject->IsVertical());
+ const Size aAnchorTextSize(Size(nAnchorTextWidth, nAnchorTextHeight));
+
+ if(IsTextFrame())
+ {
+ rOutliner.SetMaxAutoPaperSize(aAnchorTextSize);
+ }
+
+ if(SDRTEXTHORZADJUST_BLOCK == eHAdj && !bVerticalWritintg)
+ {
+ rOutliner.SetMinAutoPaperSize(Size(nAnchorTextWidth, 0));
+ }
+
+ if(SDRTEXTVERTADJUST_BLOCK == eVAdj && bVerticalWritintg)
+ {
+ rOutliner.SetMinAutoPaperSize(Size(0, nAnchorTextHeight));
+ }
+
+ rOutliner.SetPaperSize(aNullSize);
+ rOutliner.SetUpdateMode(true);
+ // Sets original text
+ rOutliner.SetText(*pOutlinerParaObject);
+
+ /* Begin overflow/underflow handling */
+
+ impHandleChainingEventsDuringDecomposition(rOutliner);
+
+ /* End overflow/underflow handling */
+
+ // set visualizing page at Outliner; needed e.g. for PageNumberField decomposition
+ rOutliner.setVisualizedPage(GetSdrPageFromXDrawPage(aViewInformation.getVisualizedPage()));
+
+ // now get back the layouted text size from outliner
+ const Size aOutlinerTextSize(rOutliner.GetPaperSize());
+ const basegfx::B2DVector aOutlinerScale(aOutlinerTextSize.Width(), aOutlinerTextSize.Height());
+ basegfx::B2DVector aAdjustTranslate(0.0, 0.0);
+
+ // correct horizontal translation using the now known text size
+ if(SDRTEXTHORZADJUST_CENTER == eHAdj || SDRTEXTHORZADJUST_RIGHT == eHAdj)
+ {
+ const double fFree(aAnchorTextRange.getWidth() - aOutlinerScale.getX());
+
+ if(SDRTEXTHORZADJUST_CENTER == eHAdj)
+ {
+ aAdjustTranslate.setX(fFree / 2.0);
+ }
+
+ if(SDRTEXTHORZADJUST_RIGHT == eHAdj)
+ {
+ aAdjustTranslate.setX(fFree);
+ }
+ }
+
+ // correct vertical translation using the now known text size
+ if(SDRTEXTVERTADJUST_CENTER == eVAdj || SDRTEXTVERTADJUST_BOTTOM == eVAdj)
+ {
+ const double fFree(aAnchorTextRange.getHeight() - aOutlinerScale.getY());
+
+ if(SDRTEXTVERTADJUST_CENTER == eVAdj)
+ {
+ aAdjustTranslate.setY(fFree / 2.0);
+ }
+
+ if(SDRTEXTVERTADJUST_BOTTOM == eVAdj)
+ {
+ aAdjustTranslate.setY(fFree);
+ }
+ }
+
+ // prepare matrices to apply to newly created primitives. aNewTransformA
+ // will get coordinates in aOutlinerScale size and positive in X, Y.
+ basegfx::B2DHomMatrix aNewTransformA;
+ basegfx::B2DHomMatrix aNewTransformB;
+
+ // translate relative to given primitive to get same rotation and shear
+ // as the master shape we are working on. For vertical, use the top-right
+ // corner
+ const double fStartInX(bVerticalWritintg ? aAdjustTranslate.getX() + aOutlinerScale.getX() : aAdjustTranslate.getX());
+ aNewTransformA.translate(fStartInX, aAdjustTranslate.getY());
+
+ // mirroring. We are now in aAnchorTextRange sizes. When mirroring in X and Y,
+ // move the null point which was top left to bottom right.
+ const bool bMirrorX(basegfx::fTools::less(aScale.getX(), 0.0));
+ const bool bMirrorY(basegfx::fTools::less(aScale.getY(), 0.0));
+ aNewTransformB.scale(bMirrorX ? -1.0 : 1.0, bMirrorY ? -1.0 : 1.0);
+
+ // in-between the translations of the single primitives will take place. Afterwards,
+ // the object's transformations need to be applied
+ aNewTransformB.shearX(fShearX);
+ aNewTransformB.rotate(fRotate);
+ aNewTransformB.translate(aTranslate.getX(), aTranslate.getY());
+
+ basegfx::B2DRange aClipRange;
+
+ // now break up text primitives.
+ impTextBreakupHandler aConverter(rOutliner);
+ aConverter.decomposeBlockTextPrimitive(aNewTransformA, aNewTransformB, aClipRange);
+
+ // cleanup outliner
+ rOutliner.Clear();
+ rOutliner.setVisualizedPage(0);
+ rOutliner.SetControlWord(nOriginalControlWord);
+
+ rTarget = aConverter.getPrimitive2DSequence();
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svx/source/svdraw/textchainflow.cxx b/svx/source/svdraw/textchainflow.cxx
index 922cfb3..3286b86 100644
--- a/svx/source/svdraw/textchainflow.cxx
+++ b/svx/source/svdraw/textchainflow.cxx
@@ -170,14 +170,14 @@ void TextChainFlow::ExecuteUnderflow(SdrOutliner *pOutl)
mpNextLink->NbcSetOutlinerParaObject(pOutl->GetEmptyParaObject());
// We store the size since NbcSetOutlinerParaObject can change it
- Size aOldSize = pOutl->GetMaxAutoPaperSize();
+ //Size aOldSize = pOutl->GetMaxAutoPaperSize();
// This should not be done in editing mode!! //XXX
if (!mpTargetLink->IsInEditMode())
mpTargetLink->NbcSetOutlinerParaObject(pNewText);
// Restore size and set new text
- //pOutl->SetMaxAutoPaperSize(aOldSize); // XXX
+ //pOutl->SetMaxAutoPaperSize(aOldSize); // XXX (it seems to be working anyway without this)
pOutl->SetText(*pNewText);
//GetTextChain()->SetNilChainingEvent(mpTargetLink, false);
commit f5f0a20b720d341ca14fc013ccb642ec430cacd4
Author: matteocam <matteo.campanelli at gmail.com>
Date: Sun Sep 6 11:30:31 2015 +0200
chained editeng: Add TextChainCursor related files
Change-Id: I6c98a28ae800197d58df8791e72a00b6490a2e2e
diff --git a/include/svx/textchaincursor.hxx b/include/svx/textchaincursor.hxx
new file mode 100644
index 0000000..61e6939
--- /dev/null
+++ b/include/svx/textchaincursor.hxx
@@ -0,0 +1,64 @@
+/* -*- 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_SVX_TEXTCHAINCURSOR_HXX
+#define INCLUDED_SVX_TEXTCHAINCURSOR_HXX
+
+#include <svx/svxdllapi.h>
+
+class SdrObjEditView;
+class SdrTextObj;
+class KeyEvent;
+class SdrOutliner;
+
+
+class SVX_DLLPUBLIC TextChainCursorManager
+{
+public:
+ TextChainCursorManager(SdrObjEditView *pEditView, const SdrTextObj *pTextObj);
+
+ bool HandleKeyEvent( const KeyEvent& rKEvt );
+
+ // Used by HandledKeyEvent and basic building block for handling cursor event
+ void HandleCursorEvent(const CursorChainingEvent aCurEvt,
+ const ESelection aNewSel);
+
+ // To be used after chaining event to deal with some nuisances
+ void HandleCursorEventAfterChaining(const CursorChainingEvent aCurEvt,
+ const ESelection aNewSel);
+
+private:
+ SdrObjEditView *mpEditView;
+ const SdrTextObj *mpTextObj;
+
+ // flag for handling of CANC which is kind of an exceptional case
+ bool mbHandlingDel;
+
+ void impChangeEditingTextObj(SdrTextObj *pTargetTextObj, ESelection aNewSel);
+ void impDetectEvent(const KeyEvent& rKEvt,
+ CursorChainingEvent *pOutCursorEvt,
+ ESelection *pOutSel,
+ bool *bOutHandled);
+};
+
+
+#endif // INCLUDED_SVX_TEXTCHAINCURSOR_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
+
diff --git a/svx/Library_svxcore.mk b/svx/Library_svxcore.mk
index ffbcf01..ca9e5c5 100644
--- a/svx/Library_svxcore.mk
+++ b/svx/Library_svxcore.mk
@@ -341,6 +341,7 @@ $(eval $(call gb_Library_add_exception_objects,svxcore,\
svx/source/svdraw/svdxcgv \
svx/source/svdraw/textchain \
svx/source/svdraw/textchainflow \
+ svx/source/svdraw/textchaincursor \
svx/source/styles/CommonStylePreviewRenderer \
svx/source/styles/CommonStyleManager \
svx/source/styles/ColorSets \
diff --git a/svx/source/svdraw/textchaincursor.cxx b/svx/source/svdraw/textchaincursor.cxx
new file mode 100644
index 0000000..23bd8f5
--- /dev/null
+++ b/svx/source/svdraw/textchaincursor.cxx
@@ -0,0 +1,210 @@
+/* -*- 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 <svx/textchain.hxx>
+#include <svx/textchaincursor.hxx>
+#include <svx/svdedxv.hxx>
+#include <svx/svdoutl.hxx>
+
+// XXX: Possible duplication of code in behavior with stuff in ImpEditView (or ImpEditEngine) and OutlinerView
+
+// XXX: We violate Demeter's Law several times here, I'm afraid
+
+TextChainCursorManager::TextChainCursorManager(SdrObjEditView *pEditView, const SdrTextObj *pTextObj) :
+ mpEditView(pEditView),
+ mpTextObj(pTextObj),
+ mbHandlingDel(false)
+{
+ assert(mpEditView);
+ assert(mpTextObj);
+
+}
+
+bool TextChainCursorManager::HandleKeyEvent( const KeyEvent& rKEvt )
+{
+ ESelection aNewSel;
+ CursorChainingEvent aCursorEvent;
+
+ // check what the cursor/event situation looks like
+ bool bCompletelyHandled = false;
+ impDetectEvent(rKEvt, &aCursorEvent, &aNewSel, &bCompletelyHandled);
+
+ if (aCursorEvent == CursorChainingEvent::NULL_EVENT)
+ return false;
+ else {
+ HandleCursorEvent(aCursorEvent, aNewSel);
+ // return value depends on the situation we are in
+ return bCompletelyHandled;
+ }
+}
+
+void TextChainCursorManager::impDetectEvent(const KeyEvent& rKEvt,
+ CursorChainingEvent *pOutCursorEvt,
+ ESelection *pOutSel,
+ bool *bOutHandled)
+{
+ SdrOutliner *pOutl = mpEditView->GetTextEditOutliner();
+ OutlinerView *pOLV = mpEditView->GetTextEditOutlinerView();
+
+ SdrTextObj *pNextLink = mpTextObj->GetNextLinkInChain();
+ SdrTextObj *pPrevLink = mpTextObj->GetPrevLinkInChain();
+
+ KeyFuncType eFunc = rKEvt.GetKeyCode().GetFunction();
+
+ // We need to have this KeyFuncType
+ if (eFunc != KeyFuncType::DONTKNOW && eFunc != KeyFuncType::DELETE)
+ {
+ *pOutCursorEvt = CursorChainingEvent::NULL_EVENT;
+ return;
+ }
+
+ sal_uInt16 nCode = rKEvt.GetKeyCode().GetCode();
+ ESelection aCurSel = pOLV->GetSelection();
+
+ ESelection aEndSelPrevBox(100000, 100000);
+
+ sal_Int32 nLastPara = pOutl->GetParagraphCount()-1;
+ OUString aLastParaText = pOutl->GetText(pOutl->GetParagraph(nLastPara));
+ sal_Int32 nLastParaLen = aLastParaText.getLength();
+
+ ESelection aEndSel = ESelection(nLastPara, nLastParaLen);
+ bool bAtEndOfTextContent = aCurSel.IsEqual(aEndSel);
+
+ // Possibility: Are we "pushing" at the end of the object?
+ if (nCode == KEY_RIGHT && bAtEndOfTextContent && pNextLink)
+ {
+ *pOutCursorEvt = CursorChainingEvent::TO_NEXT_LINK;
+ // Selection unchanged: we are at the beginning of the box
+ *bOutHandled = true; // Nothing more to do than move cursor
+ return;
+ }
+
+ // Possibility: Are we "pushing" at the end of the object?
+ if (eFunc == KeyFuncType::DELETE && bAtEndOfTextContent && pNextLink)
+ {
+ *pOutCursorEvt = CursorChainingEvent::TO_NEXT_LINK;
+ // Selection unchanged: we are at the beginning of the box
+ *bOutHandled = false; // We still need to delete the characters
+ mbHandlingDel = true;
+ return;
+ }
+
+ ESelection aStartSel = ESelection(0, 0);
+ bool bAtStartOfTextContent = aCurSel.IsEqual(aStartSel);
+
+ // Possibility: Are we "pushing" at the start of the object?
+ if (nCode == KEY_LEFT && bAtStartOfTextContent && pPrevLink)
+ {
+ *pOutCursorEvt = CursorChainingEvent::TO_PREV_LINK;
+ *pOutSel = aEndSelPrevBox; // Set at end of selection
+ *bOutHandled = true; // Nothing more to do than move cursor
+ return;
+ }
+
+ // Possibility: Are we "pushing" at the start of the object and deleting left?
+ if (nCode == KEY_BACKSPACE && bAtStartOfTextContent && pPrevLink)
+ {
+ *pOutCursorEvt = CursorChainingEvent::TO_PREV_LINK;
+ *pOutSel = aEndSelPrevBox; // Set at end of selection
+ *bOutHandled = false; // We need to delete characters after moving cursor
+ return;
+ }
+
+ // If arrived here there is no event detected
+ *pOutCursorEvt = CursorChainingEvent::NULL_EVENT;
+
+}
+
+void TextChainCursorManager::HandleCursorEventAfterChaining(
+ const CursorChainingEvent aCurEvt,
+ const ESelection aNewSel)
+
+{
+ // Special case for DELETE handling: we need to get back at the end of the prev box
+ if (mbHandlingDel) {
+ // reset flag
+ mbHandlingDel = false;
+
+ // Move to end of prev box
+ SdrTextObj *pPrevLink = mpTextObj->GetPrevLinkInChain();
+ ESelection aEndSel(100000, 100000);
+ impChangeEditingTextObj(pPrevLink, aEndSel);
+ return;
+ }
+
+ // Standard handling
+ HandleCursorEvent(aCurEvt, aNewSel);
+}
+
+
+void TextChainCursorManager::HandleCursorEvent(
+ const CursorChainingEvent aCurEvt,
+ const ESelection aNewSel)
+
+{
+
+ OutlinerView* pOLV = mpEditView->GetTextEditOutlinerView();
+ SdrTextObj *pNextLink = mpTextObj->GetNextLinkInChain();
+ SdrTextObj *pPrevLink = mpTextObj->GetPrevLinkInChain();
+
+
+
+ switch ( aCurEvt ) {
+ case CursorChainingEvent::UNCHANGED:
+ // Set same selection as before the chaining (which is saved as PostChainingSel)
+ // We need an explicit set because the Outliner is messed up
+ // after text transfer and otherwise it brings us at arbitrary positions.
+ pOLV->SetSelection(aNewSel);
+ break;
+ case CursorChainingEvent::TO_NEXT_LINK:
+ mpTextObj->GetTextChain()->SetSwitchingToNextBox(mpTextObj, true);
+ impChangeEditingTextObj(pNextLink, aNewSel);
+ break;
+ case CursorChainingEvent::TO_PREV_LINK:
+ impChangeEditingTextObj(pPrevLink, aNewSel);
+ break;
+ case CursorChainingEvent::NULL_EVENT:
+ // Do nothing here
+ break;
+ }
+
+}
+
+void TextChainCursorManager::impChangeEditingTextObj(SdrTextObj *pTargetTextObj, ESelection aNewSel)
+{
+ assert(pTargetTextObj);
+
+ // To ensure that we check for overflow in the next box // This is handled in SdrTextObj::EndTextEdit
+ SdrTextObj *pNextLink = mpTextObj->GetNextLinkInChain();
+ TextChain *pTextChain = mpTextObj->GetTextChain();
+ // If we are moving forward
+ if (pNextLink && pTargetTextObj == pNextLink)
+ pTextChain->SetPendingOverflowCheck(pNextLink, true);
+
+ mpEditView->SdrEndTextEdit();
+ mpEditView->SdrBeginTextEdit(pTargetTextObj);
+ // OutlinerView has changed, so we update the pointer
+ OutlinerView *pOLV = mpEditView->GetTextEditOutlinerView();
+ pOLV->SetSelection(aNewSel);
+
+ // Update reference text obj
+ mpTextObj = pTargetTextObj;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit 68346af9ad9f3c88cc6c6335b80f916849054f29
Author: matteocam <matteo.campanelli at gmail.com>
Date: Sun Sep 6 11:29:03 2015 +0200
chained editeng: Add TextChainFlow related files
Change-Id: I0e4155391fff29dc4484c7aedd4e62f02c4afd25
diff --git a/include/svx/textchainflow.hxx b/include/svx/textchainflow.hxx
new file mode 100644
index 0000000..60afe75
--- /dev/null
+++ b/include/svx/textchainflow.hxx
@@ -0,0 +1,134 @@
+/* -*- 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_SVX_TEXTCHAINFLOW_HXX
+#define INCLUDED_SVX_TEXTCHAINFLOW_HXX
+
+
+#include <svx/textchain.hxx>
+
+class SdrTextObj;
+class SdrOutliner;
+class NonOverflowingText;
+class OverflowingText;
+class TextChain;
+class OutlinerParaObject;
+class OFlowChainedText;
+class UFlowChainedText;
+
+// XXX: const qualifiers?
+
+class TextChainFlow {
+
+ // -- Public Members --
+ public:
+ TextChainFlow(SdrTextObj *pChainTarget);
+ virtual ~TextChainFlow();
+
+ // Check for flow events in Outliner
+ virtual void CheckForFlowEvents(SdrOutliner *);
+
+ virtual void ExecuteUnderflow(SdrOutliner *);
+
+ // Uses two outliners: one for the non-overfl text and one for overflowing (might be the same)
+ virtual void ExecuteOverflow(SdrOutliner *, SdrOutliner *);
+
+ // Getters
+
+ bool IsOverflow() const;
+ bool IsUnderflow() const;
+
+ SdrTextObj *GetLinkTarget() const;
+ SdrTextObj *GetNextLink() const;
+
+ OFlowChainedText *GetOverflowChainedText() const;
+ UFlowChainedText *GetUnderflowChainedText() const;
+
+ // -- Protected Members --
+ protected:
+
+ // Cursor related
+ bool mbPossiblyCursorOut;
+ CursorChainingEvent maCursorEvent;
+ ESelection maOverflowPosSel;
+ ESelection maPostChainingSel;
+
+ OFlowChainedText *mpOverflChText;
+ UFlowChainedText *mpUnderflChText;
+
+
+
+ void impCheckForFlowEvents(SdrOutliner *, SdrOutliner *);
+
+ TextChain *GetTextChain() const;
+
+ virtual void impLeaveOnlyNonOverflowingText(SdrOutliner *);
+ virtual void impMoveChainedTextToNextLink(SdrOutliner *);
+
+ virtual void impSetFlowOutlinerParams(SdrOutliner *, SdrOutliner *);
+
+ OutlinerParaObject *impGetOverflowingParaObject(SdrOutliner *pOutliner);
+ // impGetMergedUnderflowingParaObject merges underflowing text with the one in the next box
+ OutlinerParaObject *impGetMergedUnderflowParaObject(SdrOutliner *pOutliner);
+
+ // -- Private Members --
+ private:
+ // XXX: It would be nice to get rid of this
+ bool mbOFisUFinduced;
+
+ void impUpdateCursorInfo();
+
+ SdrTextObj *mpTargetLink;
+ SdrTextObj *mpNextLink;
+
+ TextChain *mpTextChain;
+
+ bool bCheckedFlowEvents;
+
+ bool bUnderflow;
+ bool bOverflow;
+
+};
+
+
+// NOTE: EditingTextChainFlow might be strongly coupled with behavior in SdrTextObj::onChainingEvent
+class EditingTextChainFlow : public TextChainFlow
+{
+public:
+ EditingTextChainFlow(SdrTextObj *);
+ virtual void CheckForFlowEvents(SdrOutliner *) SAL_OVERRIDE;
+
+ //virtual void ExecuteOverflow(SdrOutliner *, SdrOutliner *) SAL_OVERRIDE;
+
+protected:
+ virtual void impLeaveOnlyNonOverflowingText(SdrOutliner *) SAL_OVERRIDE;
+
+ virtual void impSetTextForEditingOutliner(OutlinerParaObject *);
+
+ virtual void impSetFlowOutlinerParams(SdrOutliner *, SdrOutliner *) SAL_OVERRIDE;
+
+private:
+ void impBroadcastCursorInfo() const;
+
+};
+
+#endif // INCLUDED_SVX_TEXTCHAINFLOW_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
+
diff --git a/svx/Library_svxcore.mk b/svx/Library_svxcore.mk
index 9c22634..ffbcf01 100644
--- a/svx/Library_svxcore.mk
+++ b/svx/Library_svxcore.mk
@@ -340,6 +340,7 @@ $(eval $(call gb_Library_add_exception_objects,svxcore,\
svx/source/svdraw/svdviter \
svx/source/svdraw/svdxcgv \
svx/source/svdraw/textchain \
+ svx/source/svdraw/textchainflow \
svx/source/styles/CommonStylePreviewRenderer \
svx/source/styles/CommonStyleManager \
svx/source/styles/ColorSets \
diff --git a/svx/source/svdraw/textchainflow.cxx b/svx/source/svdraw/textchainflow.cxx
new file mode 100644
index 0000000..922cfb3
--- /dev/null
+++ b/svx/source/svdraw/textchainflow.cxx
@@ -0,0 +1,353 @@
+/* -*- 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 <svx/svdotext.hxx>
+#include <svx/svdoutl.hxx>
+#include <editeng/outlobj.hxx>
+#include <editeng/editobj.hxx>
+#include <editeng/overflowingtxt.hxx>
+#include <svx/textchainflow.hxx>
+
+TextChainFlow::TextChainFlow(SdrTextObj *pChainTarget)
+ : mpTargetLink(pChainTarget)
+{
+ fprintf(stderr, "\n[TEXTCHAINFLOW] Creating a new TextChainFlow\n");
+
+ mpTextChain = mpTargetLink->GetTextChain();
+ mpNextLink = mpTargetLink->GetNextLinkInChain();
+ bCheckedFlowEvents = false;
+
+ bUnderflow = bOverflow = false;
+
+ mbOFisUFinduced = false;
+
+ mpOverflChText = NULL;
+ mpUnderflChText = NULL;
+
+ maCursorEvent = CursorChainingEvent::NULL_EVENT;
+ mbPossiblyCursorOut = false;
+
+}
+
+
+TextChainFlow::~TextChainFlow()
+{
+ if (mpOverflChText)
+ delete mpOverflChText;
+ if (mpUnderflChText)
+ delete mpUnderflChText;
+}
+
+void TextChainFlow::impSetFlowOutlinerParams(SdrOutliner *, SdrOutliner *)
+{
+ // Nothing to do if not in editing mode
+}
+
+/*
+ * Check for overflow in the state of pFlowOutl.
+ * If pParamOutl is not NULL sets some parameters from there.
+ * This is useful in case the outliner is not set for overflow
+ * (e.g. in editing mode we check for overflow in drawing outl but
+ * parameters come from editing outliner)
+*/
+void TextChainFlow::impCheckForFlowEvents(SdrOutliner *pFlowOutl, SdrOutliner *pParamOutl)
+{
+ bool bOldUpdateMode = pFlowOutl->GetUpdateMode();
+
+ // XXX: This could be reorganized moving most of this stuff inside EditingTextChainFlow
+ if (pParamOutl != NULL)
+ {
+ // We need this since it's required to check overflow
+ pFlowOutl->SetUpdateMode(true);
+
+ // XXX: does this work if you do it before setting the text? Seems so.
+ impSetFlowOutlinerParams(pFlowOutl, pParamOutl);
+ }
+
+ bool bIsPageOverflow = pFlowOutl->IsPageOverflow();
+
+ // NOTE: overflow and underflow cannot be both true
+ bOverflow = bIsPageOverflow && mpNextLink;
+ bUnderflow = !bIsPageOverflow && mpNextLink && mpNextLink->HasText();
+
+ // Get old state on whether to merge para-s or not
+ // NOTE: We handle UF/OF using the _old_ state. The new one is simply saved
+ bool bMustMergeParaAmongLinks = GetTextChain()->GetIsPartOfLastParaInNextLink(mpTargetLink);
+
+ // Set (Non)OverflowingTxt here (if any)
+
+ // If we had an underflow before we have to deep merge paras anyway
+ bool bMustMergeParaOF = bMustMergeParaAmongLinks || mbOFisUFinduced;
+
+ // XXX
+ bMustMergeParaOF = true; // XXX: Experiment: no deep merging.
+
+ mpOverflChText = bOverflow ?
+ new OFlowChainedText(pFlowOutl, bMustMergeParaOF) :
+ NULL;
+
+ // Set current underflowing text (if any)
+ mpUnderflChText = bUnderflow ?
+ new UFlowChainedText(pFlowOutl, bMustMergeParaAmongLinks) :
+ NULL;
+
+ // Reset update mode // Reset it here because we use WriteRTF (needing updatemode = true) in the two constructors above
+ if (!bOldUpdateMode) // Reset only if the old value was false
+ pFlowOutl->SetUpdateMode(bOldUpdateMode);
+
+ // NOTE: Must be called after mp*ChText abd b*flow have been set but before mbOFisUFinduced is reset
+ impUpdateCursorInfo();
+
+ // To check whether an overflow is underflow induced or not (useful in cursor checking)
+ mbOFisUFinduced = bUnderflow;
+}
+
+void TextChainFlow::impUpdateCursorInfo()
+{
+ // XXX: Maybe we can get rid of mbOFisUFinduced by not allowing handling of more than one event by the same TextChainFlow
+ // if this is not an OF triggered during an UF
+
+ mbPossiblyCursorOut = bOverflow;
+
+ if(mbPossiblyCursorOut ) {
+ maOverflowPosSel = ESelection(mpOverflChText->GetOverflowPointSel());
+ ESelection aSelAtUFTime = GetTextChain()->GetPreChainingSel(GetLinkTarget());
+ // Might be an invalid selection if the cursor at UF time was before
+ // the (possibly UF-induced) Overflowing point but we don't use it in that case
+ maPostChainingSel = ESelection(aSelAtUFTime.nStartPara-maOverflowPosSel.nStartPara,
+ aSelAtUFTime.nStartPos-maOverflowPosSel.nStartPos );
+ }
+
+ // XXX: It may not be necessary anymore to keep this method separated from EditingTextChainFlow::impBroadcastCursorInfo
+}
+
+void TextChainFlow::CheckForFlowEvents(SdrOutliner *pFlowOutl)
+{
+ impCheckForFlowEvents(pFlowOutl, NULL);
+}
+
+
+bool TextChainFlow::IsOverflow() const
+{
+ return bOverflow;
+}
+
+bool TextChainFlow::IsUnderflow() const
+{
+ return bUnderflow;
+}
+
+
+// XXX: In editing mode you need to get "underflowing" text from editing outliner, so it's kinda separate from the drawing one!
+
+// XXX:Would it be possible to unify undeflow and its possibly following overrflow?
+void TextChainFlow::ExecuteUnderflow(SdrOutliner *pOutl)
+{
+
+ //GetTextChain()->SetNilChainingEvent(mpTargetLink, true);
+ // making whole text
+ OutlinerParaObject *pNewText = impGetMergedUnderflowParaObject(pOutl);
+
+ // Set the other box empty; it will be replaced by the rest of the text if overflow occurs
+ if (!mpTargetLink->GetPreventChainable())
+ mpNextLink->NbcSetOutlinerParaObject(pOutl->GetEmptyParaObject());
+
+ // We store the size since NbcSetOutlinerParaObject can change it
+ Size aOldSize = pOutl->GetMaxAutoPaperSize();
+
+ // This should not be done in editing mode!! //XXX
+ if (!mpTargetLink->IsInEditMode())
+ mpTargetLink->NbcSetOutlinerParaObject(pNewText);
+
+ // Restore size and set new text
+ //pOutl->SetMaxAutoPaperSize(aOldSize); // XXX
+ pOutl->SetText(*pNewText);
+
+ //GetTextChain()->SetNilChainingEvent(mpTargetLink, false);
+
+ // Check for new overflow
+ CheckForFlowEvents(pOutl);
+}
+
+void TextChainFlow::ExecuteOverflow(SdrOutliner *pNonOverflOutl, SdrOutliner *pOverflOutl)
+{
+ //GetTextChain()->SetNilChainingEvent(mpTargetLink, true);
+ // Leave only non overflowing text
+ impLeaveOnlyNonOverflowingText(pNonOverflOutl);
+
+ // Transfer of text to next link
+ if (!mpTargetLink->GetPreventChainable() ) // we don't transfer text while dragging because of resizing
+ {
+ impMoveChainedTextToNextLink(pOverflOutl);
+ }
+
+ //GetTextChain()->SetNilChainingEvent(mpTargetLink, false);
+}
+
+void TextChainFlow::impLeaveOnlyNonOverflowingText(SdrOutliner *pNonOverflOutl)
+{
+ OutlinerParaObject *pNewText = mpOverflChText->RemoveOverflowingText(pNonOverflOutl);
+
+ fprintf(stderr, "[TEXTCHAINFLOW - OF] SOURCE box set to %d paras \n", pNewText->GetTextObject().GetParagraphCount());
+
+ // adds it to current outliner anyway (useful in static decomposition)
+ pNonOverflOutl->SetText(*pNewText);
+
+ mpTargetLink->NbcSetOutlinerParaObject(pNewText);
+ // For some reason the paper size is lost after last instruction, so we set it.
+ pNonOverflOutl->SetPaperSize(Size(pNonOverflOutl->GetPaperSize().Width(),
+ pNonOverflOutl->GetTextHeight()));
+
+}
+
+void TextChainFlow::impMoveChainedTextToNextLink(SdrOutliner *pOverflOutl)
+{
+ // prevent copying text in same box
+ if ( mpNextLink == mpTargetLink ) {
+ fprintf(stderr, "[CHAINING] Trying to copy text for next link in same object\n");
+ return;
+ }
+
+ OutlinerParaObject *pNewText =
+ mpOverflChText->InsertOverflowingText(pOverflOutl,
+ mpNextLink->GetOutlinerParaObject());
+ fprintf(stderr, "[TEXTCHAINFLOW - OF] DEST box set to %d paras \n", pNewText->GetTextObject().GetParagraphCount());
+
+ if (pNewText)
+ mpNextLink->NbcSetOutlinerParaObject(pNewText);
+
+ // Set Deep Merge status
+ fprintf(stderr, "[DEEPMERGE] Setting deepMerge to %d\n", mpOverflChText->IsLastParaInterrupted());
+ GetTextChain()->SetIsPartOfLastParaInNextLink(
+ mpTargetLink,
+ mpOverflChText->IsLastParaInterrupted());
+}
+
+SdrTextObj *TextChainFlow::GetLinkTarget() const
+{
+ return mpTargetLink;
+}
+
+SdrTextObj *TextChainFlow::GetNextLink() const
+{
+ return mpNextLink;
+}
+
+OutlinerParaObject *TextChainFlow::impGetOverflowingParaObject(SdrOutliner *)
+{ // XXX: Should never be called (to be deleted)
+ assert(0);
+ return NULL;
+ //return mpOverflChText->CreateOverflowingParaObject(pOutliner,
+// mpNextLink->GetOutlinerParaObject());
+}
+
+OutlinerParaObject *TextChainFlow::impGetMergedUnderflowParaObject(SdrOutliner *pOutliner)
+{
... etc. - the rest is truncated
More information about the Libreoffice-commits
mailing list