summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTamás Zolnai <tamas.zolnai@collabora.com>2019-01-02 17:57:22 +0100
committerMiklos Vajna <vmiklos@collabora.com>2019-01-07 10:01:33 +0100
commite562b6cc878a2f68c7e1b5b76f82d6b2548dbf2a (patch)
tree7cab0f6950568bf6112a756a58f1abd772e4fa50
parent89060ea7c639a703187b71c0ec354d9d90706fb8 (diff)
Unfloat: Handle unfloat button visibility
We need to update the state of the button every time when the frame's layout changes or when the selection changes. Show the button if the text frame is selected and it's a floating table which would hang out of the actual page after unfloating. Reviewed-on: https://gerrit.libreoffice.org/65819 Tested-by: Jenkins Reviewed-by: Tamás Zolnai <tamas.zolnai@collabora.com> (cherry picked from commit 6e5c4001c7b5cab2b2cc6419072acbe5fa7cb04a) Change-Id: I6b64affb063f552921915a0735e80889e5fd8124 Reviewed-on: https://gerrit.libreoffice.org/65870 Reviewed-by: Miklos Vajna <vmiklos@collabora.com> Tested-by: Miklos Vajna <vmiklos@collabora.com>
-rw-r--r--sw/source/core/frmedt/fefly1.cxx3
-rw-r--r--sw/source/core/frmedt/feshview.cxx11
-rw-r--r--sw/source/core/inc/flyfrm.hxx9
-rw-r--r--sw/source/core/layout/fly.cxx96
-rw-r--r--sw/source/core/layout/paintfrm.cxx12
5 files changed, 131 insertions, 0 deletions
diff --git a/sw/source/core/frmedt/fefly1.cxx b/sw/source/core/frmedt/fefly1.cxx
index c06bbd6e2951..f498b4a274b2 100644
--- a/sw/source/core/frmedt/fefly1.cxx
+++ b/sw/source/core/frmedt/fefly1.cxx
@@ -252,6 +252,9 @@ void SwFEShell::SelectFlyFrame( SwFlyFrame& rFrame )
pImpl->GetDrawView()->MarkObj( rFrame.GetVirtDrawObj(),
pImpl->GetPageView() );
+
+ rFrame.SelectionHasChanged(this);
+
KillPams();
ClearMark();
SelFlyGrabCursor();
diff --git a/sw/source/core/frmedt/feshview.cxx b/sw/source/core/frmedt/feshview.cxx
index e77e9c5709f4..a35dfd3e6621 100644
--- a/sw/source/core/frmedt/feshview.cxx
+++ b/sw/source/core/frmedt/feshview.cxx
@@ -233,7 +233,11 @@ bool SwFEShell::SelectObj( const Point& rPt, sal_uInt8 nFlag, SdrObject *pObj )
}
}
if ( bUnmark )
+ {
pDView->UnmarkAll();
+ if (pOldSelFly)
+ pOldSelFly->SelectionHasChanged(this);
+ }
}
else
{
@@ -273,6 +277,13 @@ bool SwFEShell::SelectObj( const Point& rPt, sal_uInt8 nFlag, SdrObject *pObj )
}
}
+ if ( rMrkList.GetMarkCount() == 1 )
+ {
+ SwFlyFrame *pSelFly = ::GetFlyFromMarked( &rMrkList, this );
+ if (pSelFly)
+ pSelFly->SelectionHasChanged(this);
+ }
+
if (!(nFlag & SW_ALLOW_TEXTBOX))
{
// If the fly frame is a textbox of a shape, then select the shape instead.
diff --git a/sw/source/core/inc/flyfrm.hxx b/sw/source/core/inc/flyfrm.hxx
index d966f8716311..7dff686e56a4 100644
--- a/sw/source/core/inc/flyfrm.hxx
+++ b/sw/source/core/inc/flyfrm.hxx
@@ -36,6 +36,8 @@ namespace tools { class PolyPolygon; }
class SwFlyDrawContact;
class SwFormat;
class SwViewShell;
+class SwFEShell;
+class SwWrtShell;
/** search an anchor for paragraph bound frames starting from pOldAnch
@@ -266,6 +268,13 @@ public:
Point& ContentPos() { return m_aContentPos; }
void InvalidateContentPos();
+
+ void SelectionHasChanged(SwFEShell* pShell);
+
+private:
+ bool IsShowUnfloatButton(SwWrtShell* pWrtSh) const;
+ void UpdateUnfloatButton(SwWrtShell* pWrtSh, bool bShow) const;
+ void PaintDecorators() const;
};
#endif
diff --git a/sw/source/core/layout/fly.cxx b/sw/source/core/layout/fly.cxx
index c87f952ff5cb..59c825239e60 100644
--- a/sw/source/core/layout/fly.cxx
+++ b/sw/source/core/layout/fly.cxx
@@ -65,6 +65,12 @@
#include <basegfx/polygon/b2dpolygontools.hxx>
#include <basegfx/matrix/b2dhommatrixtools.hxx>
+#include <wrtsh.hxx>
+#include <view.hxx>
+#include <edtwin.hxx>
+#include <bodyfrm.hxx>
+#include <FrameControlsManager.hxx>
+
using namespace ::com::sun::star;
static SwTwips lcl_CalcAutoWidth( const SwLayoutFrame& rFrame );
@@ -277,6 +283,9 @@ void SwFlyFrame::DestroyImpl()
FinitDrawObj();
SwLayoutFrame::DestroyImpl();
+
+ SwWrtShell* pWrtSh = dynamic_cast<SwWrtShell*>(getRootFrame()->GetCurrShell());
+ UpdateUnfloatButton(pWrtSh, false);
}
SwFlyFrame::~SwFlyFrame()
@@ -1755,6 +1764,93 @@ void SwFlyFrame::InvalidateContentPos()
Invalidate_();
}
+void SwFlyFrame::SelectionHasChanged(SwFEShell* pShell)
+{
+ SwWrtShell* pWrtSh = dynamic_cast< SwWrtShell* >(pShell);
+ if (pWrtSh == nullptr)
+ return;
+
+ UpdateUnfloatButton(pWrtSh, IsShowUnfloatButton(pWrtSh));
+}
+
+bool SwFlyFrame::IsShowUnfloatButton(SwWrtShell* pWrtSh) const
+{
+ if (pWrtSh == nullptr)
+ return false;
+
+ // In read only mode we don't allow unfloat operation
+ if (pWrtSh->GetViewOptions()->IsReadonly())
+ return false;
+
+ const SdrObject *pObj = GetFrameFormat().FindRealSdrObject();
+ if (pObj == nullptr)
+ return false;
+
+ // SwFlyFrame itself can mean images, ole objects, etc, but we interested in actual text frames
+ if (SwFEShell::GetObjCntType(*pObj) != OBJCNT_FLY)
+ return false;
+
+ // We show the button only for the selected text frame
+ SwDrawView *pView = pWrtSh->Imp()->GetDrawView();
+ if (pView == nullptr)
+ return false;
+
+ // Fly frame can be selected only alone
+ if (pView->GetMarkedObjectList().GetMarkCount() != 1)
+ return false;
+
+ if(!pView->IsObjMarked(pObj))
+ return false;
+
+ // A frame is a floating table if there is only one table (and maybe some whitespaces) inside it
+ int nTableCount = 0;
+ const SwFrame* pLower = GetLower();
+ const SwTabFrame* pTable = nullptr;
+ while (pLower)
+ {
+ if (pLower->IsTabFrame())
+ {
+ pTable = static_cast<const SwTabFrame*>(pLower);
+ ++nTableCount;
+ if (nTableCount > 1 || pTable == nullptr)
+ return false;
+ }
+
+ if (pLower->IsTextFrame())
+ {
+ const SwTextFrame* pTextFrame = static_cast<const SwTextFrame*>(pLower);
+ if (!pTextFrame->GetText().trim().isEmpty())
+ return false;
+ }
+ pLower = pLower->GetNext();
+ }
+
+ if (nTableCount != 1 || pTable == nullptr)
+ return false;
+
+ // Show the unfold button only for multipage tables
+ const SwBodyFrame *pBody = GetAnchorFrame()->FindBodyFrame();
+ if (pBody == nullptr)
+ return false;
+
+ long nBodyHeight = pBody->getFrameArea().Height();
+ long nTableHeight = pTable->getFrameArea().Height();
+ long nFrameOffset = std::abs(GetAnchorFrame()->getFrameArea().Top() - pBody->getFrameArea().Top());
+
+ return nBodyHeight < nTableHeight + nFrameOffset;
+}
+
+void SwFlyFrame::UpdateUnfloatButton(SwWrtShell* pWrtSh, bool bShow) const
+{
+ if (pWrtSh == nullptr)
+ return;
+
+ SwEditWin& rEditWin = pWrtSh->GetView().GetEditWin();
+ SwFrameControlsManager& rMngr = rEditWin.GetFrameControlsManager();
+ Point aBottomRightPixel = rEditWin.LogicToPixel( getFrameArea().BottomRight() );
+ rMngr.SetFloatingTableButton(this, bShow, aBottomRightPixel);
+}
+
SwTwips SwFlyFrame::Grow_( SwTwips nDist, bool bTst )
{
SwRectFnSet aRectFnSet(this);
diff --git a/sw/source/core/layout/paintfrm.cxx b/sw/source/core/layout/paintfrm.cxx
index fedcd36f2266..b9a157d5b313 100644
--- a/sw/source/core/layout/paintfrm.cxx
+++ b/sw/source/core/layout/paintfrm.cxx
@@ -4171,12 +4171,24 @@ void SwFlyFrame::Paint(vcl::RenderContext& rRenderContext, SwRect const& rRect,
// have to paint frame borders added in heaven layer here...
ProcessPrimitives(gProp.pBLines->GetBorderLines_Clear());
+ PaintDecorators();
+
rRenderContext.Pop();
if ( gProp.pSProgress && pNoText )
gProp.pSProgress->Reschedule();
}
+void SwFlyFrame::PaintDecorators() const
+{
+ // Show the un-float button
+ SwWrtShell* pWrtSh = dynamic_cast< SwWrtShell* >( gProp.pSGlobalShell );
+ if ( pWrtSh )
+ {
+ UpdateUnfloatButton(pWrtSh, IsShowUnfloatButton(pWrtSh));
+ }
+}
+
void SwTabFrame::Paint(vcl::RenderContext& rRenderContext, SwRect const& rRect, SwPrintData const*const) const
{
const SwViewOption* pViewOption = gProp.pSGlobalShell->GetViewOptions();