summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--editeng/source/editeng/editeng.cxx5
-rw-r--r--editeng/source/editeng/impedit3.cxx1
-rw-r--r--editeng/source/outliner/outliner.cxx13
-rw-r--r--include/editeng/editeng.hxx2
-rw-r--r--include/editeng/outliner.hxx2
-rw-r--r--include/svx/svdedtv.hxx4
-rw-r--r--officecfg/registry/data/org/openoffice/Office/UI/DrawImpressCommands.xcu11
-rw-r--r--sd/inc/app.hrc1
-rw-r--r--sd/sdi/_drvwsh.sdi5
-rw-r--r--sd/sdi/sdraw.sdi17
-rw-r--r--sd/source/ui/view/drviews2.cxx23
-rw-r--r--sd/source/ui/view/drviewsj.cxx2
-rw-r--r--sd/uiconfig/sdraw/menubar/menubar.xml2
-rw-r--r--sd/uiconfig/sdraw/popupmenu/multiselect.xml1
-rw-r--r--svx/source/svdraw/svdedtv2.cxx67
15 files changed, 150 insertions, 6 deletions
diff --git a/editeng/source/editeng/editeng.cxx b/editeng/source/editeng/editeng.cxx
index cae8822cd48e..84b2f39df32d 100644
--- a/editeng/source/editeng/editeng.cxx
+++ b/editeng/source/editeng/editeng.cxx
@@ -1666,7 +1666,7 @@ bool EditEngine::IsInSelectionMode() const
pImpEditEngine->GetSelEngine().IsInSelection() );
}
-void EditEngine::InsertParagraph( sal_Int32 nPara, const EditTextObject& rTxtObj )
+void EditEngine::InsertParagraph( sal_Int32 nPara, const EditTextObject& rTxtObj, bool bAppend )
{
if ( nPara > GetParagraphCount() )
{
@@ -1683,6 +1683,9 @@ void EditEngine::InsertParagraph( sal_Int32 nPara, const EditTextObject& rTxtObj
pImpEditEngine->RemoveCharAttribs( nPara );
pImpEditEngine->InsertText( rTxtObj, EditSelection( aPaM, aPaM ) );
+ if ( bAppend && nPara )
+ pImpEditEngine->ConnectContents( nPara-1, /*bBackwards=*/false );
+
pImpEditEngine->UndoActionEnd();
pImpEditEngine->FormatAndUpdate();
diff --git a/editeng/source/editeng/impedit3.cxx b/editeng/source/editeng/impedit3.cxx
index 976a94ea2f1a..99603db06493 100644
--- a/editeng/source/editeng/impedit3.cxx
+++ b/editeng/source/editeng/impedit3.cxx
@@ -3921,7 +3921,6 @@ EditPaM ImpEditEngine::ConnectContents( sal_Int32 nLeftNode, bool bBackward )
ContentNode* pRightNode = aEditDoc.GetObject( nLeftNode+1 );
DBG_ASSERT( pLeftNode, "Invalid left node in ConnectContents ");
DBG_ASSERT( pRightNode, "Invalid right node in ConnectContents ");
- DBG_ASSERT( IsInUndo(), "ConnectContent only for Undo()!" );
return ImpConnectParagraphs( pLeftNode, pRightNode, bBackward );
}
diff --git a/editeng/source/outliner/outliner.cxx b/editeng/source/outliner/outliner.cxx
index 2d757fb23c9d..320dc6958355 100644
--- a/editeng/source/outliner/outliner.cxx
+++ b/editeng/source/outliner/outliner.cxx
@@ -602,7 +602,7 @@ void Outliner::SetText( const OutlinerParaObject& rPObj )
DBG_ASSERT( pEditEngine->GetParagraphCount()==rPObj.Count(),"SetText failed");
}
-void Outliner::AddText( const OutlinerParaObject& rPObj )
+void Outliner::AddText( const OutlinerParaObject& rPObj, bool bAppend )
{
bool bUpdate = pEditEngine->GetUpdateMode();
@@ -615,16 +615,25 @@ void Outliner::AddText( const OutlinerParaObject& rPObj )
pParaList->Clear();
pEditEngine->SetText(rPObj.GetTextObject());
nPara = 0;
+ bAppend = false;
}
else
{
nPara = pParaList->GetParagraphCount();
- pEditEngine->InsertParagraph( EE_PARA_APPEND, rPObj.GetTextObject() );
+ pEditEngine->InsertParagraph( EE_PARA_APPEND, rPObj.GetTextObject(), bAppend );
}
bFirstParaIsEmpty = false;
for( sal_Int32 n = 0; n < rPObj.Count(); n++ )
{
+ if ( n == 0 && bAppend )
+ {
+ // This first "paragraph" was just appended to an existing (incomplete) paragraph.
+ // Since no new paragraph will be added, the assumed increase-by-1 also won't happen.
+ --nPara;
+ continue;
+ }
+
Paragraph* pPara = new Paragraph( rPObj.GetParagraphData(n) );
pParaList->Append(std::unique_ptr<Paragraph>(pPara));
sal_Int32 nP = nPara+n;
diff --git a/include/editeng/editeng.hxx b/include/editeng/editeng.hxx
index e531b6c8d9f5..64581f930aab 100644
--- a/include/editeng/editeng.hxx
+++ b/include/editeng/editeng.hxx
@@ -299,7 +299,7 @@ public:
void SetText( const EditTextObject& rTextObject );
void RemoveParagraph(sal_Int32 nPara);
- void InsertParagraph(sal_Int32 nPara, const EditTextObject& rTxtObj);
+ void InsertParagraph(sal_Int32 nPara, const EditTextObject& rTxtObj, const bool bAppend = false);
void InsertParagraph(sal_Int32 nPara, const OUString& rText);
void SetText(sal_Int32 nPara, const OUString& rText);
diff --git a/include/editeng/outliner.hxx b/include/editeng/outliner.hxx
index cc2505202e66..9d4037d6885c 100644
--- a/include/editeng/outliner.hxx
+++ b/include/editeng/outliner.hxx
@@ -676,7 +676,7 @@ public:
Paragraph* Insert( const OUString& rText, sal_Int32 nAbsPos = EE_PARA_APPEND, sal_Int16 nDepth = 0 );
void SetText( const OutlinerParaObject& );
- void AddText( const OutlinerParaObject& );
+ void AddText( const OutlinerParaObject&, bool bAppend = false );
void SetText( const OUString& rText, Paragraph* pParagraph );
OUString GetText( Paragraph const * pPara, sal_Int32 nParaCount=1 ) const;
diff --git a/include/svx/svdedtv.hxx b/include/svx/svdedtv.hxx
index 320d082d6b3a..1b662cde29c5 100644
--- a/include/svx/svdedtv.hxx
+++ b/include/svx/svdedtv.hxx
@@ -244,6 +244,10 @@ public:
bool IsCropAllowed() const;
bool IsDistortAllowed(bool bNoContortion=false) const;
+ // Consolidate the text from multiple, selected TextObjects,
+ // attempting to identify paragraph fragments and join them together
+ void CombineMarkedTextObjects();
+
// Unite several objects to a polygon:
// - rectangles/circles/text... are implicitly converted.
// - polygones are closed automatically
diff --git a/officecfg/registry/data/org/openoffice/Office/UI/DrawImpressCommands.xcu b/officecfg/registry/data/org/openoffice/Office/UI/DrawImpressCommands.xcu
index 2facd9bee872..abe7e7162e06 100644
--- a/officecfg/registry/data/org/openoffice/Office/UI/DrawImpressCommands.xcu
+++ b/officecfg/registry/data/org/openoffice/Office/UI/DrawImpressCommands.xcu
@@ -856,6 +856,17 @@
<value>1</value>
</prop>
</node>
+ <node oor:name=".uno:TextCombine" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="en-US">Consolidate Text</value>
+ </prop>
+ <prop oor:name="TooltipLabel" oor:type="xs:string">
+ <value xml:lang="en-US">Merges text fragments from selected objects into one new textbox</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
<node oor:name=".uno:Combine" oor:op="replace">
<prop oor:name="Label" oor:type="xs:string">
<value xml:lang="en-US">Comb~ine</value>
diff --git a/sd/inc/app.hrc b/sd/inc/app.hrc
index 2738085f0ae5..9445f47cd0a7 100644
--- a/sd/inc/app.hrc
+++ b/sd/inc/app.hrc
@@ -94,6 +94,7 @@
// FREE
#define SID_POSITION (SID_SD_START+22)
// FREE
+#define SID_TEXT_COMBINE (SID_SD_START+25)
#define SID_COMBINE (SID_SD_START+26)
#define SID_NAME_GROUP (SID_SD_START+27)
#define SID_DRAWTBX_CONNECTORS (SID_SD_START+28)
diff --git a/sd/sdi/_drvwsh.sdi b/sd/sdi/_drvwsh.sdi
index 8dfdf71023de..3c98b281347f 100644
--- a/sd/sdi/_drvwsh.sdi
+++ b/sd/sdi/_drvwsh.sdi
@@ -469,6 +469,11 @@ interface DrawView
StateMethod = GetMenuState ;
FastCall = FALSE ;
]
+ SID_TEXT_COMBINE // ole : no, status : ?
+ [
+ ExecMethod = FuTemporary ;
+ StateMethod = GetMenuState ;
+ ]
SID_COMBINE // ole : no, status : ?
[
ExecMethod = FuTemporary ;
diff --git a/sd/sdi/sdraw.sdi b/sd/sdi/sdraw.sdi
index b1760f31bb3b..ad88ee8a09ab 100644
--- a/sd/sdi/sdraw.sdi
+++ b/sd/sdi/sdraw.sdi
@@ -330,6 +330,23 @@ SfxBoolItem ColorView SID_COLORVIEW
GroupId = SfxGroupId::View;
]
+SfxVoidItem TextCombine SID_TEXT_COMBINE
+()
+[
+ AutoUpdate = FALSE,
+ FastCall = FALSE,
+ ReadOnlyDoc = FALSE,
+ Toggle = FALSE,
+ Container = FALSE,
+ RecordAbsolute = FALSE,
+ RecordPerSet;
+
+ AccelConfig = TRUE,
+ MenuConfig = TRUE,
+ ToolBoxConfig = TRUE,
+ GroupId = SfxGroupId::Modify;
+]
+
SfxVoidItem Combine SID_COMBINE
()
[
diff --git a/sd/source/ui/view/drviews2.cxx b/sd/source/ui/view/drviews2.cxx
index a812d3be34f4..11025537247f 100644
--- a/sd/source/ui/view/drviews2.cxx
+++ b/sd/source/ui/view/drviews2.cxx
@@ -2598,6 +2598,29 @@ void DrawViewShell::FuTemporary(SfxRequest& rReq)
}
break;
+ case SID_TEXT_COMBINE: // BASIC
+ {
+ // End text edit to avoid conflicts
+ if(mpDrawView->IsTextEdit())
+ mpDrawView->SdrEndTextEdit();
+
+ if ( mpDrawView->IsPresObjSelected() )
+ {
+ std::unique_ptr<weld::MessageDialog> xInfoBox(Application::CreateMessageDialog(GetFrameWeld(),
+ VclMessageType::Info, VclButtonsType::Ok,
+ SdResId(STR_ACTION_NOTPOSSIBLE)));
+ xInfoBox->run();
+ }
+ else
+ {
+ WaitObject aWait( GetActiveWindow() );
+ mpDrawView->CombineMarkedTextObjects();
+ }
+ Cancel();
+ rReq.Done ();
+ }
+ break;
+
case SID_COMBINE: // BASIC
{
// End text edit to avoid conflicts
diff --git a/sd/source/ui/view/drviewsj.cxx b/sd/source/ui/view/drviewsj.cxx
index 32e05aefa4da..92917a72bf67 100644
--- a/sd/source/ui/view/drviewsj.cxx
+++ b/sd/source/ui/view/drviewsj.cxx
@@ -285,6 +285,7 @@ void DrawViewShell::GetMenuStateSel( SfxItemSet &rSet )
}
rSet.DisableItem(SID_GROUP);
+ rSet.DisableItem(SID_TEXT_COMBINE);
rSet.DisableItem(SID_COMBINE);
rSet.DisableItem(SID_DISTRIBUTE_DLG);
rSet.DisableItem(SID_POLY_MERGE);
@@ -493,6 +494,7 @@ void DrawViewShell::GetMenuStateSel( SfxItemSet &rSet )
rSet.DisableItem( SID_DISMANTLE );
rSet.DisableItem( SID_BREAK );
+ rSet.DisableItem( SID_TEXT_COMBINE );
rSet.DisableItem( SID_COMBINE );
rSet.DisableItem(SID_DISTRIBUTE_DLG);
rSet.DisableItem(SID_POLY_MERGE);
diff --git a/sd/uiconfig/sdraw/menubar/menubar.xml b/sd/uiconfig/sdraw/menubar/menubar.xml
index e8f139cb900a..579869a296b4 100644
--- a/sd/uiconfig/sdraw/menubar/menubar.xml
+++ b/sd/uiconfig/sdraw/menubar/menubar.xml
@@ -548,6 +548,8 @@
<menu:menuitem menu:id=".uno:Substract"/>
<menu:menuitem menu:id=".uno:Intersect"/>
<menu:menuseparator/>
+ <menu:menuitem menu:id=".uno:TextCombine"/>
+ <menu:menuseparator/>
<menu:menuitem menu:id=".uno:CopyObjects"/>
<menu:menuitem menu:id=".uno:Morphing"/>
<menu:menuseparator/>
diff --git a/sd/uiconfig/sdraw/popupmenu/multiselect.xml b/sd/uiconfig/sdraw/popupmenu/multiselect.xml
index cb88b0d81eae..86639b8ea309 100644
--- a/sd/uiconfig/sdraw/popupmenu/multiselect.xml
+++ b/sd/uiconfig/sdraw/popupmenu/multiselect.xml
@@ -73,6 +73,7 @@
<menu:menuitem menu:id=".uno:EqualizeHeight"/>
</menu:menupopup>
</menu:menu>
+ <menu:menuitem menu:id=".uno:TextCombine"/>
<menu:menuseparator/>
<menu:menuitem menu:id=".uno:FormatGroup"/>
<menu:menuitem menu:id=".uno:FormatUngroup"/>
diff --git a/svx/source/svdraw/svdedtv2.cxx b/svx/source/svdraw/svdedtv2.cxx
index 47dd34025de2..5a7bf23d64f4 100644
--- a/svx/source/svdraw/svdedtv2.cxx
+++ b/svx/source/svdraw/svdedtv2.cxx
@@ -21,6 +21,7 @@
#include <editeng/outliner.hxx>
#include <svx/svdundo.hxx>
#include <svx/svdogrp.hxx>
+#include <svx/svdoutl.hxx>
#include <svx/svdovirt.hxx>
#include <svx/svdopath.hxx>
#include <svx/svdpage.hxx>
@@ -33,6 +34,7 @@
#include <svx/sdshitm.hxx>
#include <svx/xfillit0.hxx>
#include <svx/xlineit0.hxx>
+#include <svx/xtextit0.hxx>
#include "svdfmtf.hxx"
#include "svdpdf.hxx"
#include <svx/svdetc.hxx>
@@ -45,6 +47,7 @@
#include <svx/strings.hrc>
#include <svx/svdoashp.hxx>
#include <basegfx/polygon/b2dpolypolygoncutter.hxx>
+#include <i18nutil/unicode.hxx>
#include <sal/log.hxx>
#include <tools/debug.hxx>
#include <memory>
@@ -1213,6 +1216,70 @@ void SdrEditView::EqualizeMarkedObjects(bool bWidth)
EndUndo();
}
+void SdrEditView::CombineMarkedTextObjects()
+{
+ SdrPageView* pPageView = GetSdrPageView();
+ if ( !pPageView || pPageView->IsLayerLocked( GetActiveLayer() ) )
+ return;
+
+ bool bUndo = IsUndoEnabled();
+
+ // Undo-String will be set later
+ if ( bUndo )
+ BegUndo();
+
+ SdrOutliner& rDrawOutliner = getSdrModelFromSdrView().GetDrawOutliner();
+
+ SdrObjListIter aIter( GetMarkedObjectList(), SdrIterMode::Flat);
+ while ( aIter.IsMore() )
+ {
+ SdrObject* pObj = aIter.Next();
+ SdrTextObj* pTextObj = dynamic_cast<SdrTextObj*>( pObj );
+ const OutlinerParaObject* pOPO = pTextObj ? pTextObj->GetOutlinerParaObject() : nullptr;
+ if ( pOPO && pTextObj->IsTextFrame()
+ && pTextObj->GetObjIdentifier() == OBJ_TEXT // not callouts (OBJ_CAPTION)
+ && !pTextObj->IsOutlText() // not impress presentation objects
+ && pTextObj->GetMergedItem(XATTR_FORMTXTSTYLE).GetValue() == XFormTextStyle::NONE // not Fontwork
+ )
+ {
+ // if the last paragraph does not end in paragraph-end punctuation (ignoring whitespace),
+ // assume this text should be added to the end of the last paragraph, instead of starting a new paragraph.
+ const sal_Int32 nPara = rDrawOutliner.GetParagraphCount();
+ const OUString sLastPara = nPara ? rDrawOutliner.GetText( rDrawOutliner.GetParagraph( nPara - 1 ) ) : "";
+ sal_Int32 n = sLastPara.getLength();
+ while ( n && unicode::isWhiteSpace( sLastPara[--n] ) )
+ ;
+ //TODO: find way to use Locale to identify sentence final punctuation. Copied IsSentenceAtEnd() from autofmt.cxx
+ const bool bAppend = !n || ( sLastPara[n] != '.' && sLastPara[n] != '?' && sLastPara[n] != '!' );
+ rDrawOutliner.AddText( *pOPO, bAppend );
+ }
+ else
+ {
+ // Unmark non-textboxes, because all marked objects are deleted at the end. AdjustMarkHdl later.
+ MarkObj(pObj, pPageView, /*bUnmark=*/true, /*bImpNoSetMarkHdl=*/true);
+ }
+ }
+
+ MarkListHasChanged();
+ AdjustMarkHdl();
+
+ if ( GetMarkedObjectCount() > 1 )
+ {
+ SdrRectObj* pReplacement = new SdrRectObj( getSdrModelFromSdrView(), OBJ_TEXT );
+ pReplacement->SetOutlinerParaObject( rDrawOutliner.CreateParaObject() );
+ pReplacement->SetSnapRect( GetMarkedObjRect() );
+
+ const SdrInsertFlags nFlags = SdrInsertFlags::DONTMARK | SdrInsertFlags::SETDEFLAYER;
+ if ( InsertObjectAtView( pReplacement, *pPageView, nFlags ) )
+ DeleteMarkedObj();
+ }
+
+ if ( bUndo )
+ EndUndo();
+
+ return;
+}
+
void SdrEditView::CombineMarkedObjects(bool bNoPolyPoly)
{
// #105899# Start of Combine-Undo put to front, else ConvertMarkedToPolyObj would