summaryrefslogtreecommitdiff
path: root/svx/source
diff options
context:
space:
mode:
Diffstat (limited to 'svx/source')
-rw-r--r--svx/source/sdr/contact/viewcontact.cxx23
-rw-r--r--svx/source/sdr/contact/viewobjectcontact.cxx11
-rw-r--r--svx/source/svdraw/svdedxv.cxx87
-rw-r--r--svx/source/unodraw/unoshtxt.cxx8
4 files changed, 128 insertions, 1 deletions
diff --git a/svx/source/sdr/contact/viewcontact.cxx b/svx/source/sdr/contact/viewcontact.cxx
index 99106d0d6ed0..fcc9a6975380 100644
--- a/svx/source/sdr/contact/viewcontact.cxx
+++ b/svx/source/sdr/contact/viewcontact.cxx
@@ -203,6 +203,29 @@ void ViewContact::ActionChanged()
}
}
+// IASS: helper for IASS invalidates
+void ViewContact::ActionChangedIfDifferentPageView(SdrPageView& rSdrPageView)
+{
+ const sal_uInt32 nCount(maViewObjectContactVector.size());
+
+ for (sal_uInt32 a(0); a < nCount; a++)
+ {
+ ViewObjectContact* pCandidate = maViewObjectContactVector[a];
+ DBG_ASSERT(pCandidate,
+ "ViewContact::GetViewObjectContact() invalid ViewObjectContactList (!)");
+
+ if (pCandidate)
+ {
+ pCandidate->ActionChangedIfDifferentPageView(rSdrPageView);
+ }
+ }
+}
+
+bool ViewContact::hasMultipleViewObjectContacts() const
+{
+ return maViewObjectContactVector.size() > 1;
+}
+
// access to SdrObject and/or SdrPage. May return 0L like the default
// implementations do. Override as needed.
SdrObject* ViewContact::TryToGetSdrObject() const { return nullptr; }
diff --git a/svx/source/sdr/contact/viewobjectcontact.cxx b/svx/source/sdr/contact/viewobjectcontact.cxx
index 2e3ebfd8d3f9..03d6eb4bd10c 100644
--- a/svx/source/sdr/contact/viewobjectcontact.cxx
+++ b/svx/source/sdr/contact/viewobjectcontact.cxx
@@ -250,6 +250,17 @@ void ViewObjectContact::ActionChanged()
GetObjectContact().setLazyInvalidate(*this);
}
+// IASS: helper for IASS invalidates
+void ViewObjectContact::ActionChangedIfDifferentPageView(SdrPageView& rSdrPageView)
+{
+ SdrPageView* pSdrPageView(GetObjectContact().TryToGetSdrPageView());
+
+ // if there is no SdrPageView or different from given one, force
+ // invalidate/repaint
+ if (nullptr == pSdrPageView || pSdrPageView != &rSdrPageView)
+ ActionChanged();
+}
+
void ViewObjectContact::triggerLazyInvalidate()
{
if(!mbLazyInvalidate)
diff --git a/svx/source/svdraw/svdedxv.cxx b/svx/source/svdraw/svdedxv.cxx
index f3f5d4818f20..3685cd55a8ef 100644
--- a/svx/source/svdraw/svdedxv.cxx
+++ b/svx/source/svdraw/svdedxv.cxx
@@ -68,11 +68,15 @@
#include <textchaincursor.hxx>
#include <tools/debug.hxx>
#include <vcl/svapp.hxx>
+#include <svx/sdr/contact/viewcontact.hxx>
#include <memory>
SdrObjEditView::SdrObjEditView(SdrModel& rSdrModel, OutputDevice* pOut)
: SdrGlueEditView(rSdrModel, pOut)
+ , maTEOverlayGroup()
+ , maTextEditUpdateTimer("TextEditUpdateTimer")
+ , mxWeakTextEditObj()
, mpTextEditPV(nullptr)
, mpTextEditOutlinerView(nullptr)
, mpTextEditWin(nullptr)
@@ -80,18 +84,89 @@ SdrObjEditView::SdrObjEditView(SdrModel& rSdrModel, OutputDevice* pOut)
, pMacroObj(nullptr)
, pMacroPV(nullptr)
, pMacroWin(nullptr)
+ , aTextEditArea()
+ , aMinTextEditArea()
+ , aOldCalcFieldValueLink()
+ , aMacroDownPos()
, nMacroTol(0)
, mbTextEditDontDelete(false)
, mbTextEditOnlyOneView(false)
, mbTextEditNewObj(false)
, mbQuickTextEditMode(true)
, mbMacroDown(false)
+ , mbInteractiveSlideShow(false)
+ , mxSelectionController()
+ , mxLastSelectionController()
, mpOldTextEditUndoManager(nullptr)
+ , mpLocalTextEditUndoManager()
{
+ // init some timer settings (not starting it of course)
+ maTextEditUpdateTimer.SetTimeout(EDIT_UPDATEDATA_TIMEOUT);
+ maTextEditUpdateTimer.SetInvokeHandler(LINK(this, SdrObjEditView, TextEditUpdate));
+}
+
+IMPL_LINK_NOARG(SdrObjEditView, ImpModifyHdl, LinkParamNone*, void)
+{
+ // IASS: active TextEdit had a model change. Check and react.
+ if (nullptr == mpTextEditOutliner)
+ // no Outliner, no TextEdit
+ return;
+
+ if (!mxWeakTextEditObj.get().is())
+ // no TextObject, no TextEdit
+ return;
+
+ // reset & restart the timer
+ maTextEditUpdateTimer.SetTimeout(EDIT_UPDATEDATA_TIMEOUT);
+ maTextEditUpdateTimer.Start();
+}
+
+IMPL_LINK_NOARG(SdrObjEditView, TextEditUpdate, Timer*, void)
+{
+ // IASS: text was changed and EDIT_UPDATEDATA_TIMEOUT has passed
+ // since last user input
+ maTextEditUpdateTimer.Stop();
+
+ // be safe: still in TextEdit?
+ if (nullptr == mpTextEditOutliner)
+ // no Outliner, no TextEdit
+ return;
+
+ if (!mxWeakTextEditObj.get().is())
+ // no TextObject, no TextEdit
+ return;
+
+ // lauch an ObjectChange: This is the straightforward method
+ // to get this broadcasted. We do not risk to set the model
+ // unwantedly to changed, we had a text edit going on already.
+ // This is needed for SlideShow since it is not (yet) using the
+ // standard schema with VC/VOC/OC
+ if (isInteractiveSlideShow())
+ mxWeakTextEditObj.get()->BroadcastObjectChange();
+
+ // force repaint for objects with changed text in all views
+ // that are VC/VOC/OC based (SlideShow is not yet)
+ sdr::contact::ViewContact& rVC(mxWeakTextEditObj.get()->GetViewContact());
+
+ if (!rVC.hasMultipleViewObjectContacts())
+ // only one VOC -> this is us
+ return;
+
+ if (nullptr == mpTextEditPV)
+ // should not happen, just invalidate all visualizations
+ rVC.ActionChanged();
+ else
+ // invalidate only visualizations in different views:
+ // this is important to not cause evtl. high repaint costs
+ // in the EditView -> we avoid this by running the TextEdit
+ // on the overlay. NOTE: This is only for better performance,
+ // any repaint will just work fine and do the right thing
+ rVC.ActionChangedIfDifferentPageView(*mpTextEditPV);
}
SdrObjEditView::~SdrObjEditView()
{
+ maTextEditUpdateTimer.Stop();
mpTextEditWin = nullptr; // so there's no ShowCursor in SdrEndTextEdit
assert(!IsTextEdit());
if (IsTextEdit())
@@ -1481,6 +1556,12 @@ bool SdrObjEditView::SdrBeginTextEdit(SdrObject* pObj_, SdrPageView* pPV, vcl::W
mpTextEditOutlinerView->ShowCursor();
mpTextEditOutliner->SetStatusEventHdl(
LINK(this, SdrObjEditView, ImpOutlinerStatusEventHdl));
+
+ // IASS: start listening to ModelChanges of TextEdit
+ if (isInteractiveSlideShow()
+ || pTextObj->GetViewContact().hasMultipleViewObjectContacts())
+ mpTextEditOutliner->SetModifyHdl(LINK(this, SdrObjEditView, ImpModifyHdl));
+
if (pTextObj->IsChainable())
{
mpTextEditOutlinerView->SetEndCutPasteLinkHdl(
@@ -1564,6 +1645,9 @@ bool SdrObjEditView::SdrBeginTextEdit(SdrObject* pObj_, SdrPageView* pPV, vcl::W
SdrEndTextEditKind SdrObjEditView::SdrEndTextEdit(bool bDontDeleteReally)
{
+ // IASS: stop evtl. running timer immediately
+ maTextEditUpdateTimer.Stop();
+
SdrEndTextEditKind eRet = SdrEndTextEditKind::Unchanged;
rtl::Reference<SdrTextObj> pTEObj = mxWeakTextEditObj.get();
vcl::Window* pTEWin = mpTextEditWin;
@@ -1682,6 +1766,9 @@ SdrEndTextEditKind SdrObjEditView::SdrEndTextEdit(bool bDontDeleteReally)
pTEOutliner->SetBeginPasteOrDropHdl(Link<PasteOrDropInfos*, void>());
pTEOutliner->SetEndPasteOrDropHdl(Link<PasteOrDropInfos*, void>());
+ // IASS: stop listening to ModelChanges of TextEdit
+ pTEOutliner->SetModifyHdl(Link<LinkParamNone*, void>());
+
const bool bUndo = IsUndoEnabled();
if (bUndo)
{
diff --git a/svx/source/unodraw/unoshtxt.cxx b/svx/source/unodraw/unoshtxt.cxx
index e6b958ce4dc0..e445978d98bb 100644
--- a/svx/source/unodraw/unoshtxt.cxx
+++ b/svx/source/unodraw/unoshtxt.cxx
@@ -641,7 +641,13 @@ SvxTextForwarder* SvxTextEditSourceImpl::GetTextForwarder()
// distinguish the cases
// a) connected to view, maybe edit mode is active, can work directly on the EditOutliner
// b) background Outliner, reflect changes into ParaOutlinerObject (this is exactly the old UNO code)
- if( HasView() )
+
+ // IASS: testing for HasView() is *not* sufficient - there may be more views of one document
+ // open and TextEdit is only active in one of them, or - as with IASS - it may even be the view
+ // of the running SlideShow itself which also will have no active TextEdit and thus no Outliner.
+ // Thus, to identify the view which indeed does have an outliner (and is in TextEdit mode),
+ // also check if it has an active Outliner by using GetTextEditOutliner()
+ if( HasView() && nullptr != mpView->GetTextEditOutliner() )
{
if( IsEditMode() != mbForwarderIsEditMode )
{