summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/svx/sdr/contact/viewcontact.hxx5
-rw-r--r--include/svx/sdr/contact/viewobjectcontact.hxx5
-rw-r--r--include/svx/svdedxv.hxx14
-rw-r--r--sd/source/ui/view/sdview.cxx6
-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
8 files changed, 157 insertions, 2 deletions
diff --git a/include/svx/sdr/contact/viewcontact.hxx b/include/svx/sdr/contact/viewcontact.hxx
index 7b6d0f3ab2c1..00b7f6253eae 100644
--- a/include/svx/sdr/contact/viewcontact.hxx
+++ b/include/svx/sdr/contact/viewcontact.hxx
@@ -27,6 +27,7 @@
class SdrLayerIDSet;
class SdrPage;
class SdrObject;
+class SdrPageView;
namespace sdr::contact
{
@@ -122,6 +123,10 @@ public:
// React on changes of the object of this ViewContact
virtual void ActionChanged();
+ // IASS: helpers for IASS invalidates
+ void ActionChangedIfDifferentPageView(SdrPageView& rSdrPageView);
+ bool hasMultipleViewObjectContacts() const;
+
// access to the local primitive. This will ensure that the primitive is
// current in comparing the local one with a fresh created incarnation
void getViewIndependentPrimitive2DContainer(
diff --git a/include/svx/sdr/contact/viewobjectcontact.hxx b/include/svx/sdr/contact/viewobjectcontact.hxx
index 12195a0faa34..8f903d93e04b 100644
--- a/include/svx/sdr/contact/viewobjectcontact.hxx
+++ b/include/svx/sdr/contact/viewobjectcontact.hxx
@@ -24,6 +24,8 @@
#include <svx/svxdllapi.h>
#include <drawinglayer/primitive2d/Primitive2DContainer.hxx>
+class SdrPageView;
+
namespace vcl { class Region; }
namespace sdr::animation {
@@ -101,6 +103,9 @@ public:
// React on changes of the object of this ViewContact
virtual void ActionChanged();
+ // IASS: helper for IASS invalidates
+ void ActionChangedIfDifferentPageView(SdrPageView& rSdrPageView);
+
// LazyInvalidate handling
void triggerLazyInvalidate();
diff --git a/include/svx/svdedxv.hxx b/include/svx/svdedxv.hxx
index 8ad7f048b682..6c6a37f108a7 100644
--- a/include/svx/svdedxv.hxx
+++ b/include/svx/svdedxv.hxx
@@ -76,8 +76,15 @@ class SVXCORE_DLLPUBLIC SdrObjEditView : public SdrGlueEditView, public EditView
virtual void EditViewCursorRect(const tools::Rectangle& rRect, int nExtTextInputWidth) override;
// The OverlayObjects used for visualizing active TextEdit (currently
- // using TextEditOverlayObject, but not limited to it
+ // using TextEditOverlayObject, but not limited to it)
sdr::overlay::OverlayObjectList maTEOverlayGroup;
+ Timer maTextEditUpdateTimer;
+
+ // IASS: allow reaction to active TextEdit changes
+ DECL_DLLPRIVATE_LINK(ImpModifyHdl, LinkParamNone*, void);
+
+ // IASS: timer-based reaction on TextEdit changes
+ DECL_DLLPRIVATE_LINK(TextEditUpdate, Timer*, void);
protected:
// TextEdit
@@ -104,10 +111,15 @@ protected:
bool mbTextEditNewObj : 1; // current edited object was just recreated
bool mbQuickTextEditMode : 1; // persistent(->CrtV). Default=TRUE
bool mbMacroDown : 1;
+ bool mbInteractiveSlideShow : 1; // IASS
rtl::Reference< sdr::SelectionController > mxSelectionController;
rtl::Reference< sdr::SelectionController > mxLastSelectionController;
+ // check/set if we are in IASS and need to refresh evtl.
+ void setInteractiveSlideShow(bool bNew) { mbInteractiveSlideShow = bNew; }
+ bool isInteractiveSlideShow() const { return mbInteractiveSlideShow; }
+
private:
EditUndoManager* mpOldTextEditUndoManager;
std::unique_ptr<SdrUndoManager> mpLocalTextEditUndoManager;
diff --git a/sd/source/ui/view/sdview.cxx b/sd/source/ui/view/sdview.cxx
index 345ef782ea84..9c4713fcb0ac 100644
--- a/sd/source/ui/view/sdview.cxx
+++ b/sd/source/ui/view/sdview.cxx
@@ -24,6 +24,7 @@
#include <com/sun/star/linguistic2/XSpellChecker1.hpp>
#include <View.hxx>
+#include <slideshow.hxx>
#include <avmedia/mediawindow.hxx>
#include <editeng/outlobj.hxx>
#include <editeng/unolingu.hxx>
@@ -698,6 +699,11 @@ bool View::SdrBeginTextEdit(
pOutl->SetDefaultLanguage( Application::GetSettings().GetLanguageTag().getLanguageType() );
}
+ // check if we have IASS active and propagate that info to the view with the active TextEdit
+ rtl::Reference< SlideShow > xSlideshow(SlideShow::GetSlideShow(mpViewSh->GetViewShellBase()));
+ const bool bIASS(xSlideshow.is() && xSlideshow->isRunning() && xSlideshow->IsInteractiveSlideshow());
+ setInteractiveSlideShow(bIASS);
+
bool bReturn = FmFormView::SdrBeginTextEdit(
pObj, pPV, pWin, bIsNewObj, pOutl,
pGivenOutlinerView, bDontDeleteOutliner,
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 )
{