1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_desktop.hxx"
26 
27 #include "cppuhelper/implbase2.hxx"
28 #include "cppuhelper/implementationentry.hxx"
29 #include "unotools/configmgr.hxx"
30 #include "comphelper/servicedecl.hxx"
31 #include "comphelper/unwrapargs.hxx"
32 #include "i18npool/mslangid.hxx"
33 #include "vcl/svapp.hxx"
34 #include "vcl/msgbox.hxx"
35 #include "toolkit/helper/vclunohelper.hxx"
36 #include "com/sun/star/lang/XServiceInfo.hpp"
37 #include "com/sun/star/task/XJobExecutor.hpp"
38 #include "svtools/svmedit.hxx"
39 #include "svl/lstner.hxx"
40 #include "svtools/xtextedt.hxx"
41 #include <vcl/scrbar.hxx>
42 #include "vcl/threadex.hxx"
43 
44 
45 
46 #include "boost/bind.hpp"
47 #include "dp_gui_shared.hxx"
48 #include "license_dialog.hxx"
49 #include "dp_gui.hrc"
50 
51 using namespace ::dp_misc;
52 namespace cssu = ::com::sun::star::uno;
53 using namespace ::com::sun::star;
54 using namespace ::com::sun::star::uno;
55 using ::rtl::OUString;
56 
57 namespace dp_gui {
58 
59 class LicenseView : public MultiLineEdit, public SfxListener
60 {
61     sal_Bool            mbEndReached;
62     Link            maEndReachedHdl;
63     Link            maScrolledHdl;
64 
65 public:
66     LicenseView( Window* pParent, const ResId& rResId );
67     ~LicenseView();
68 
69     void ScrollDown( ScrollType eScroll );
70 
71     sal_Bool IsEndReached() const;
EndReached() const72     sal_Bool EndReached() const { return mbEndReached; }
SetEndReached(sal_Bool bEnd)73     void SetEndReached( sal_Bool bEnd ) { mbEndReached = bEnd; }
74 
SetEndReachedHdl(const Link & rHdl)75     void SetEndReachedHdl( const Link& rHdl )  { maEndReachedHdl = rHdl; }
GetAutocompleteHdl() const76     const Link& GetAutocompleteHdl() const { return maEndReachedHdl; }
77 
SetScrolledHdl(const Link & rHdl)78     void SetScrolledHdl( const Link& rHdl )  { maScrolledHdl = rHdl; }
GetScrolledHdl() const79     const Link& GetScrolledHdl() const { return maScrolledHdl; }
80 
81     virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint );
82 
83 protected:
84     using MultiLineEdit::Notify;
85 };
86 
87 struct LicenseDialogImpl : public ModalDialog
88 {
89 	cssu::Reference<cssu::XComponentContext> m_xComponentContext;
90 	FixedText m_ftHead;
91     FixedText m_ftBody1;
92     FixedText m_ftBody1Txt;
93     FixedText m_ftBody2;
94     FixedText m_ftBody2Txt;
95 	FixedImage m_fiArrow1;
96 	FixedImage m_fiArrow2;
97     LicenseView m_mlLicense;
98     PushButton m_pbDown;
99 	FixedLine m_flBottom;
100 
101     OKButton m_acceptButton;
102 	CancelButton m_declineButton;
103 
104 	DECL_LINK(PageDownHdl, PushButton*);
105 	DECL_LINK(ScrolledHdl, LicenseView*);
106 	DECL_LINK(EndReachedHdl, LicenseView*);
107 
108 	bool m_bLicenseRead;
109 
110     virtual ~LicenseDialogImpl();
111 
112 	LicenseDialogImpl(
113         Window * pParent,
114         css::uno::Reference< css::uno::XComponentContext > const & xContext,
115         const ::rtl::OUString & sExtensionName,
116 		const ::rtl::OUString & sLicenseText);
117 
118 	virtual void Activate();
119 
120 };
121 
LicenseView(Window * pParent,const ResId & rResId)122 LicenseView::LicenseView( Window* pParent, const ResId& rResId )
123     : MultiLineEdit( pParent, rResId )
124 {
125     SetLeftMargin( 5 );
126     mbEndReached = IsEndReached();
127     StartListening( *GetTextEngine() );
128 }
129 
~LicenseView()130 LicenseView::~LicenseView()
131 {
132     maEndReachedHdl = Link();
133     maScrolledHdl   = Link();
134     EndListeningAll();
135 }
136 
ScrollDown(ScrollType eScroll)137 void LicenseView::ScrollDown( ScrollType eScroll )
138 {
139     ScrollBar*  pScroll = GetVScrollBar();
140     if ( pScroll )
141         pScroll->DoScrollAction( eScroll );
142 }
143 
IsEndReached() const144 sal_Bool LicenseView::IsEndReached() const
145 {
146     sal_Bool bEndReached;
147 
148     ExtTextView*    pView = GetTextView();
149     ExtTextEngine*  pEdit = GetTextEngine();
150     sal_uLong           nHeight = pEdit->GetTextHeight();
151     Size            aOutSize = pView->GetWindow()->GetOutputSizePixel();
152     Point           aBottom( 0, aOutSize.Height() );
153 
154     if ( (sal_uLong) pView->GetDocPos( aBottom ).Y() >= nHeight - 1 )
155         bEndReached = sal_True;
156     else
157         bEndReached = sal_False;
158 
159     return bEndReached;
160 }
161 
Notify(SfxBroadcaster &,const SfxHint & rHint)162 void LicenseView::Notify( SfxBroadcaster&, const SfxHint& rHint )
163 {
164     if ( rHint.IsA( TYPE(TextHint) ) )
165     {
166         sal_Bool    bLastVal = EndReached();
167         sal_uLong   nId = ((const TextHint&)rHint).GetId();
168 
169         if ( nId == TEXT_HINT_PARAINSERTED )
170         {
171             if ( bLastVal )
172                 mbEndReached = IsEndReached();
173         }
174         else if ( nId == TEXT_HINT_VIEWSCROLLED )
175         {
176             if ( ! mbEndReached )
177                 mbEndReached = IsEndReached();
178             maScrolledHdl.Call( this );
179         }
180 
181         if ( EndReached() && !bLastVal )
182         {
183             maEndReachedHdl.Call( this );
184         }
185     }
186 }
187 
188 //==============================================================================================================
189 
LicenseDialogImpl(Window * pParent,cssu::Reference<cssu::XComponentContext> const & xContext,const::rtl::OUString & sExtensionName,const::rtl::OUString & sLicenseText)190 LicenseDialogImpl::LicenseDialogImpl(
191 	Window * pParent,
192 	cssu::Reference< cssu::XComponentContext > const & xContext,
193     const ::rtl::OUString & sExtensionName,
194     const ::rtl::OUString & sLicenseText):
195 		ModalDialog(pParent, DpGuiResId(RID_DLG_LICENSE))
196 		,m_xComponentContext(xContext)
197 		,m_ftHead(this, DpGuiResId(FT_LICENSE_HEADER))
198 		,m_ftBody1(this, DpGuiResId(FT_LICENSE_BODY_1))
199 		,m_ftBody1Txt(this, DpGuiResId(FT_LICENSE_BODY_1_TXT))
200 		,m_ftBody2(this, DpGuiResId(FT_LICENSE_BODY_2))
201 		,m_ftBody2Txt(this, DpGuiResId(FT_LICENSE_BODY_2_TXT))
202 		,m_fiArrow1(this, DpGuiResId(FI_LICENSE_ARROW1))
203 		,m_fiArrow2(this, DpGuiResId(FI_LICENSE_ARROW2))
204 		,m_mlLicense(this, DpGuiResId(ML_LICENSE))
205 		,m_pbDown(this, DpGuiResId(PB_LICENSE_DOWN))
206 		,m_flBottom(this, DpGuiResId(FL_LICENSE))
207 		,m_acceptButton(this, DpGuiResId(BTN_LICENSE_ACCEPT))
208 		,m_declineButton(this, DpGuiResId(BTN_LICENSE_DECLINE))
209 		,m_bLicenseRead(false)
210 
211 {
212 
213 	if (GetSettings().GetStyleSettings().GetHighContrastMode())
214     {
215         // high contrast mode needs other images
216         m_fiArrow1.SetImage(Image(DpGuiResId(IMG_LICENCE_ARROW_HC)));
217         m_fiArrow2.SetImage(Image(DpGuiResId(IMG_LICENCE_ARROW_HC)));
218 	}
219 
220 	FreeResource();
221 
222 	m_acceptButton.SetUniqueId(UID_BTN_LICENSE_ACCEPT);
223 	m_fiArrow1.Show(true);
224 	m_fiArrow2.Show(false);
225 	m_mlLicense.SetText(sLicenseText);
226     m_ftHead.SetText(m_ftHead.GetText() + OUString('\n') + sExtensionName);
227 
228 	m_mlLicense.SetEndReachedHdl( LINK(this, LicenseDialogImpl, EndReachedHdl) );
229 	m_mlLicense.SetScrolledHdl( LINK(this, LicenseDialogImpl, ScrolledHdl) );
230     m_pbDown.SetClickHdl( LINK(this, LicenseDialogImpl, PageDownHdl) );
231 
232 	// We want a automatic repeating page down button
233     WinBits aStyle = m_pbDown.GetStyle();
234     aStyle |= WB_REPEAT;
235     m_pbDown.SetStyle( aStyle );
236 }
237 
~LicenseDialogImpl()238 LicenseDialogImpl::~LicenseDialogImpl()
239 {
240 }
241 
Activate()242 void LicenseDialogImpl::Activate()
243 {
244 	if (!m_bLicenseRead)
245 	{
246 		//Only enable the scroll down button if the license text does not fit into the window
247 		if (m_mlLicense.IsEndReached())
248 		{
249 			m_pbDown.Disable();
250 			m_acceptButton.Enable();
251 			m_acceptButton.GrabFocus();
252 		}
253 		else
254 		{
255 			m_pbDown.Enable();
256 			m_pbDown.GrabFocus();
257 			m_acceptButton.Disable();
258 		}
259 	}
260 }
261 
IMPL_LINK(LicenseDialogImpl,ScrolledHdl,LicenseView *,EMPTYARG)262 IMPL_LINK( LicenseDialogImpl, ScrolledHdl, LicenseView *, EMPTYARG )
263 {
264 
265 	if (m_mlLicense.IsEndReached())
266         m_pbDown.Disable();
267 	else
268         m_pbDown.Enable();
269 
270     return 0;
271 }
272 
IMPL_LINK(LicenseDialogImpl,PageDownHdl,PushButton *,EMPTYARG)273 IMPL_LINK( LicenseDialogImpl, PageDownHdl, PushButton *, EMPTYARG )
274 {
275     m_mlLicense.ScrollDown( SCROLL_PAGEDOWN );
276     return 0;
277 }
278 
IMPL_LINK(LicenseDialogImpl,EndReachedHdl,LicenseView *,EMPTYARG)279 IMPL_LINK( LicenseDialogImpl, EndReachedHdl, LicenseView *, EMPTYARG )
280 {
281     m_acceptButton.Enable();
282 	m_acceptButton.GrabFocus();
283 	m_fiArrow1.Show(false);
284 	m_fiArrow2.Show(true);
285 	m_bLicenseRead = true;
286     return 0;
287 }
288 
289 //=================================================================================
290 
291 
292 
293 
LicenseDialog(Sequence<Any> const & args,Reference<XComponentContext> const & xComponentContext)294 LicenseDialog::LicenseDialog( Sequence<Any> const& args,
295                           Reference<XComponentContext> const& xComponentContext)
296     : m_xComponentContext(xComponentContext)
297 {
298     comphelper::unwrapArgs( args, m_parent, m_sExtensionName, m_sLicenseText );
299 }
300 
301 // XExecutableDialog
302 //______________________________________________________________________________
setTitle(OUString const &)303 void LicenseDialog::setTitle( OUString const & ) throw (RuntimeException)
304 {
305 
306 }
307 
308 //______________________________________________________________________________
execute()309 sal_Int16 LicenseDialog::execute() throw (RuntimeException)
310 {
311     return vcl::solarthread::syncExecute(
312         boost::bind( &LicenseDialog::solar_execute, this));
313 }
314 
solar_execute()315 sal_Int16 LicenseDialog::solar_execute()
316 {
317 	std::auto_ptr<LicenseDialogImpl> dlg(
318         new LicenseDialogImpl(
319             VCLUnoHelper::GetWindow(m_parent),
320             m_xComponentContext, m_sExtensionName, m_sLicenseText));
321 
322     return dlg->Execute();
323 }
324 
325 } // namespace dp_gui
326 
327