xref: /core/sw/source/uibase/sidebar/PageOrientationControl.cxx (revision 56e0bd7f4280c52111ba211fee618a412b2b7e9c)
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  *   Licensed to the Apache Software Foundation (ASF) under one or more
12  *   contributor license agreements. See the NOTICE file distributed
13  *   with this work for additional information regarding copyright
14  *   ownership. The ASF licenses this file to you under the Apache
15  *   License, Version 2.0 (the "License"); you may not use this file
16  *   except in compliance with the License. You may obtain a copy of
17  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include "PageOrientationControl.hxx"
21 #include "PageMarginControl.hxx"
22 #include <PageOrientationPopup.hxx>
23 #include <com/sun/star/document/XUndoManager.hpp>
24 #include <com/sun/star/document/XUndoManagerSupplier.hpp>
25 #include <com/sun/star/frame/XFrame.hpp>
26 
27 #include <sfx2/viewsh.hxx>
28 #include <sfx2/dispatch.hxx>
29 #include <sfx2/viewfrm.hxx>
30 #include <cmdid.h>
31 
32 namespace {
getUndoManager(const css::uno::Reference<css::frame::XFrame> & rxFrame)33     css::uno::Reference< css::document::XUndoManager > getUndoManager( const css::uno::Reference< css::frame::XFrame >& rxFrame )
34     {
35         const css::uno::Reference< css::frame::XController > xController = rxFrame->getController();
36         if ( xController.is() )
37         {
38             const css::uno::Reference< css::frame::XModel > xModel = xController->getModel();
39             if ( xModel.is() )
40             {
41                 const css::uno::Reference< css::document::XUndoManagerSupplier > xSuppUndo( xModel, css::uno::UNO_QUERY_THROW );
42                 return css::uno::Reference< css::document::XUndoManager >( xSuppUndo->getUndoManager(), css::uno::UNO_SET_THROW );
43             }
44         }
45 
46         return css::uno::Reference< css::document::XUndoManager > ();
47     }
48 }
49 
50 namespace sw::sidebar {
51 
PageOrientationControl(PageOrientationPopup * pControl,weld::Widget * pParent)52 PageOrientationControl::PageOrientationControl(PageOrientationPopup* pControl, weld::Widget* pParent)
53     : WeldToolbarPopup(pControl->getFrameInterface(), pParent, u"modules/swriter/ui/pageorientationcontrol.ui"_ustr, u"PageOrientationControl"_ustr)
54     , m_xPortrait(m_xBuilder->weld_button(u"portrait"_ustr))
55     , m_xLandscape(m_xBuilder->weld_button(u"landscape"_ustr))
56     , m_xControl(pControl)
57     , mpPageItem( new SvxPageItem(SID_ATTR_PAGE) )
58     , mpPageSizeItem( new SvxSizeItem(SID_ATTR_PAGE_SIZE) )
59     , mpPageLRMarginItem( new SvxLongLRSpaceItem( 0, 0, SID_ATTR_PAGE_LRSPACE ) )
60     , mpPageULMarginItem( new SvxLongULSpaceItem( 0, 0, SID_ATTR_PAGE_ULSPACE ) )
61 {
62     m_xPortrait->connect_clicked( LINK( this, PageOrientationControl,ImplOrientationHdl ) );
63     m_xLandscape->connect_clicked( LINK( this, PageOrientationControl,ImplOrientationHdl ) );
64 }
65 
GrabFocus()66 void PageOrientationControl::GrabFocus()
67 {
68     m_xPortrait->grab_focus();
69 }
70 
~PageOrientationControl()71 PageOrientationControl::~PageOrientationControl()
72 {
73 }
74 
ExecuteMarginLRChange(const tools::Long nPageLeftMargin,const tools::Long nPageRightMargin)75 void PageOrientationControl::ExecuteMarginLRChange(
76     const tools::Long nPageLeftMargin,
77     const tools::Long nPageRightMargin )
78 {
79     mpPageLRMarginItem->SetLeft( nPageLeftMargin );
80     mpPageLRMarginItem->SetRight( nPageRightMargin );
81     if (SfxViewFrame* pViewFrm = SfxViewFrame::Current())
82         pViewFrm->GetDispatcher()->ExecuteList(SID_ATTR_PAGE_LRSPACE,
83             SfxCallMode::RECORD, { mpPageLRMarginItem.get() });
84 }
85 
ExecuteMarginULChange(const tools::Long nPageTopMargin,const tools::Long nPageBottomMargin)86 void PageOrientationControl::ExecuteMarginULChange(
87     const tools::Long nPageTopMargin,
88     const tools::Long nPageBottomMargin )
89 {
90     mpPageULMarginItem->SetUpper( nPageTopMargin );
91     mpPageULMarginItem->SetLower( nPageBottomMargin );
92     if (SfxViewFrame* pViewFrm = SfxViewFrame::Current())
93         pViewFrm->GetDispatcher()->ExecuteList(SID_ATTR_PAGE_ULSPACE,
94             SfxCallMode::RECORD, { mpPageULMarginItem.get() });
95 }
96 
ExecuteOrientationChange(const bool bLandscape)97 void PageOrientationControl::ExecuteOrientationChange( const bool bLandscape )
98 {
99     SfxViewFrame* pViewFrm = SfxViewFrame::Current();
100     if (!pViewFrm)
101         return;
102 
103     css::uno::Reference< css::document::XUndoManager > mxUndoManager(
104                 getUndoManager( pViewFrm->GetFrame().GetFrameInterface() ) );
105 
106     if ( mxUndoManager.is() )
107         mxUndoManager->enterUndoContext( u""_ustr );
108 
109     SfxPoolItemHolder aResult;
110     pViewFrm->GetBindings().GetDispatcher()->QueryState(SID_ATTR_PAGE_SIZE, aResult);
111     mpPageSizeItem.reset(static_cast<const SvxSizeItem*>(aResult.getItem())->Clone());
112 
113     // Prevent accidental toggling of page orientation
114     if ((mpPageSizeItem->GetWidth() > mpPageSizeItem->GetHeight()) == bLandscape)
115     {
116         if ( mxUndoManager.is() )
117             mxUndoManager->leaveUndoContext();
118         return;
119     }
120 
121     pViewFrm->GetBindings().GetDispatcher()->QueryState(SID_ATTR_PAGE_LRSPACE, aResult);
122     mpPageLRMarginItem.reset(static_cast<const SvxLongLRSpaceItem*>(aResult.getItem())->Clone());
123 
124     pViewFrm->GetBindings().GetDispatcher()->QueryState(SID_ATTR_PAGE_ULSPACE, aResult);
125     mpPageULMarginItem.reset(static_cast<const SvxLongULSpaceItem*>(aResult.getItem())->Clone());
126 
127     {
128         // set new page orientation
129         mpPageItem->SetLandscape( bLandscape );
130 
131         // swap the width and height of the page size
132         const tools::Long nRotatedWidth = mpPageSizeItem->GetSize().Height();
133         const tools::Long nRotatedHeight = mpPageSizeItem->GetSize().Width();
134         mpPageSizeItem->SetSize(Size(nRotatedWidth, nRotatedHeight));
135 
136         // apply changed attributes
137         pViewFrm->GetDispatcher()->ExecuteList(SID_ATTR_PAGE_SIZE,
138             SfxCallMode::RECORD, { mpPageSizeItem.get(), mpPageItem.get() });
139     }
140 
141     // check, if margin values still fit to the changed page size.
142     // if not, adjust margin values
143     {
144         const tools::Long nML = mpPageLRMarginItem->GetLeft();
145         const tools::Long nMR = mpPageLRMarginItem->GetRight();
146         const tools::Long nTmpPW = nML + nMR + MINBODY;
147 
148         const tools::Long nPW  = mpPageSizeItem->GetSize().Width();
149 
150         if ( nTmpPW > nPW )
151         {
152             if ( nML <= nMR )
153             {
154                 ExecuteMarginLRChange( mpPageLRMarginItem->GetLeft(), nMR - (nTmpPW - nPW ) );
155             }
156             else
157             {
158                 ExecuteMarginLRChange( nML - (nTmpPW - nPW ), mpPageLRMarginItem->GetRight() );
159             }
160         }
161 
162         const tools::Long nMT = mpPageULMarginItem->GetUpper();
163         const tools::Long nMB = mpPageULMarginItem->GetLower();
164         const tools::Long nTmpPH = nMT + nMB + MINBODY;
165 
166         const tools::Long nPH  = mpPageSizeItem->GetSize().Height();
167 
168         if ( nTmpPH > nPH )
169         {
170             if ( nMT <= nMB )
171             {
172                 ExecuteMarginULChange( mpPageULMarginItem->GetUpper(), nMB - ( nTmpPH - nPH ) );
173             }
174             else
175             {
176                 ExecuteMarginULChange( nMT - ( nTmpPH - nPH ), mpPageULMarginItem->GetLower() );
177             }
178         }
179     }
180 
181     if ( mxUndoManager.is() )
182         mxUndoManager->leaveUndoContext();
183 }
184 
IMPL_LINK(PageOrientationControl,ImplOrientationHdl,weld::Button &,rControl,void)185 IMPL_LINK(PageOrientationControl, ImplOrientationHdl, weld::Button&, rControl, void)
186 {
187     if (&rControl == m_xPortrait.get())
188         ExecuteOrientationChange( false );
189     else
190         ExecuteOrientationChange( true );
191 
192     m_xControl->EndPopupMode();
193 }
194 
195 } // end of namespace sw::sidebar
196 
197 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
198