1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // autogen include statement, do not remove
29 #include "precompiled_framework.hxx"
30 
31 #include <classes/fwktabwindow.hxx>
32 #include "framework.hrc"
33 #include <classes/fwkresid.hxx>
34 
35 #include <com/sun/star/awt/PosSize.hpp>
36 #include <com/sun/star/awt/XContainerWindowEventHandler.hpp>
37 #include <com/sun/star/awt/XContainerWindowProvider.hpp>
38 #include <com/sun/star/awt/XWindow.hpp>
39 #include <com/sun/star/awt/XWindowPeer.hpp>
40 #include <com/sun/star/awt/XControl.hpp>
41 #include <com/sun/star/beans/NamedValue.hpp>
42 #include <com/sun/star/graphic/XGraphic.hpp>
43 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
44 
45 #include <comphelper/processfactory.hxx>
46 #include <toolkit/helper/vclunohelper.hxx>
47 #include <tools/stream.hxx>
48 #include <tools/diagnose_ex.h>
49 #include <vcl/bitmap.hxx>
50 #include <vcl/image.hxx>
51 #include <vcl/msgbox.hxx>
52 
53 const ::rtl::OUString SERVICENAME_WINPROVIDER
54                                         = ::rtl::OUString::createFromAscii("com.sun.star.awt.ContainerWindowProvider");
55 const ::rtl::OUString EXTERNAL_EVENT    = ::rtl::OUString::createFromAscii("external_event");
56 const ::rtl::OUString BACK_METHOD       = ::rtl::OUString::createFromAscii("back");
57 const ::rtl::OUString INITIALIZE_METHOD = ::rtl::OUString::createFromAscii("initialize");
58 const ::rtl::OUString OK_METHOD         = ::rtl::OUString::createFromAscii("ok");
59 
60 using namespace ::com::sun::star;
61 
62 namespace framework
63 {
64 
65 // class FwkTabControl ---------------------------------------------------
66 FwkTabControl::FwkTabControl( Window* pParent, const ResId& rResId ) :
67 
68     TabControl( pParent, rResId )
69 {
70 }
71 
72 // -----------------------------------------------------------------------
73 
74 void FwkTabControl::BroadcastEvent( sal_uLong nEvent )
75 {
76     if ( VCLEVENT_TABPAGE_ACTIVATE == nEvent || VCLEVENT_TABPAGE_DEACTIVATE == nEvent )
77         ImplCallEventListeners( nEvent, (void*)(sal_uIntPtr)GetCurPageId() );
78     else
79     {
80         DBG_ERRORFILE( "FwkTabControl::BroadcastEvent(): illegal event" );
81     }
82 }
83 
84 // class FwkTabPage ------------------------------------------------
85 
86 FwkTabPage::FwkTabPage(
87 		       Window* pParent, const rtl::OUString& rPageURL,
88 		       const css::uno::Reference< css::awt::XContainerWindowEventHandler >& rEventHdl,
89 		       const css::uno::Reference< css::awt::XContainerWindowProvider >& rProvider ) :
90 
91     TabPage( pParent, WB_DIALOGCONTROL | WB_TABSTOP | WB_CHILDDLGCTRL ),
92 
93     m_sPageURL          ( rPageURL ),
94     m_xEventHdl         ( rEventHdl ),
95     m_xWinProvider      ( rProvider )
96 
97 {
98 }
99 
100 // -----------------------------------------------------------------------
101 
102 FwkTabPage::~FwkTabPage()
103 {
104     Hide();
105     DeactivatePage();
106 }
107 
108 // -----------------------------------------------------------------------
109 
110 void FwkTabPage::CreateDialog()
111 {
112     try
113     {
114         uno::Reference< uno::XInterface > xHandler;
115         if ( m_xEventHdl.is() )
116 	  xHandler = m_xEventHdl;
117 
118         uno::Reference< awt::XWindowPeer > xParent( VCLUnoHelper::GetInterface( this ), uno::UNO_QUERY );
119         m_xPage = uno::Reference < awt::XWindow >(
120             m_xWinProvider->createContainerWindow(
121                 m_sPageURL, rtl::OUString(), xParent, xHandler ), uno::UNO_QUERY );
122 
123         uno::Reference< awt::XControl > xPageControl( m_xPage, uno::UNO_QUERY );
124         if ( xPageControl.is() )
125         {
126             uno::Reference< awt::XWindowPeer > xWinPeer( xPageControl->getPeer() );
127             if ( xWinPeer.is() )
128             {
129                 Window* pWindow = VCLUnoHelper::GetWindow( xWinPeer );
130                 if ( pWindow )
131                     pWindow->SetStyle( pWindow->GetStyle() | WB_DIALOGCONTROL | WB_CHILDDLGCTRL );
132             }
133         }
134 
135         CallMethod( INITIALIZE_METHOD );
136     }
137     catch ( lang::IllegalArgumentException& )
138     {
139         DBG_ERRORFILE( "FwkTabPage::CreateDialog(): illegal argument" );
140     }
141     catch ( uno::Exception& )
142     {
143         DBG_ERRORFILE( "FwkTabPage::CreateDialog(): exception of XDialogProvider2::createContainerWindow()" );
144     }
145 }
146 
147 // -----------------------------------------------------------------------
148 
149 sal_Bool FwkTabPage::CallMethod( const rtl::OUString& rMethod )
150 {
151     sal_Bool bRet = sal_False;
152     if ( m_xEventHdl.is() )
153     {
154         try
155         {
156             bRet = m_xEventHdl->callHandlerMethod( m_xPage, uno::makeAny( rMethod ), EXTERNAL_EVENT );
157         }
158         catch ( uno::Exception& )
159         {
160             DBG_UNHANDLED_EXCEPTION();
161         }
162     }
163     return bRet;
164 }
165 
166 // -----------------------------------------------------------------------
167 
168 void FwkTabPage::ActivatePage()
169 {
170     TabPage::ActivatePage();
171 
172     if ( !m_xPage.is() )
173         CreateDialog();
174 
175     if ( m_xPage.is() )
176     {
177         Resize ();
178         m_xPage->setVisible( sal_True );
179     }
180 }
181 
182 // -----------------------------------------------------------------------
183 
184 void FwkTabPage::DeactivatePage()
185 {
186     TabPage::DeactivatePage();
187 
188     if ( m_xPage.is() )
189         m_xPage->setVisible( sal_False );
190 }
191 
192 // -----------------------------------------------------------------------
193 
194 void FwkTabPage::Resize()
195 {
196 	if ( m_xPage.is () )
197 	{
198 		Size  aSize = GetSizePixel ();
199         Point aPos  = GetPosPixel  ();
200 
201         m_xPage->setPosSize( 0, 0, aSize.Width()-1 , aSize.Height()-1, awt::PosSize::POSSIZE );
202 	}
203 }
204 
205 // class FwkTabWindow ---------------------------------------------
206 
207 FwkTabWindow::FwkTabWindow( Window* pParent ) :
208 
209     Window( pParent, FwkResId( WIN_TABWINDOW ) ),
210 
211     m_aTabCtrl  ( this, FwkResId( TC_TABCONTROL ) )
212 {
213     uno::Reference < lang::XMultiServiceFactory > xFactory( ::comphelper::getProcessServiceFactory() );
214     m_xWinProvider = uno::Reference < awt::XContainerWindowProvider >(
215         xFactory->createInstance( SERVICENAME_WINPROVIDER ), uno::UNO_QUERY );
216 
217     SetPaintTransparent(true);
218 
219     m_aTabCtrl.SetActivatePageHdl( LINK( this, FwkTabWindow, ActivatePageHdl ) );
220     m_aTabCtrl.SetDeactivatePageHdl( LINK( this, FwkTabWindow, DeactivatePageHdl ) );
221     m_aTabCtrl.Show();
222 }
223 
224 // -----------------------------------------------------------------------
225 
226 FwkTabWindow::~FwkTabWindow()
227 {
228     ClearEntryList();
229 }
230 
231 // -----------------------------------------------------------------------
232 
233 void FwkTabWindow::ClearEntryList()
234 {
235     TabEntryList::const_iterator pIt;
236     for (  pIt  = m_TabList.begin();
237            pIt != m_TabList.end();
238          ++pIt )
239     {
240         delete *pIt;
241     }
242 
243     m_TabList.clear();
244 }
245 
246 // -----------------------------------------------------------------------
247 
248 bool FwkTabWindow::RemoveEntry( sal_Int32 nIndex )
249 {
250     TabEntryList::iterator pIt;
251     for (  pIt  = m_TabList.begin();
252            pIt != m_TabList.end();
253          ++pIt )
254     {
255         if ( (*pIt)->m_nIndex == nIndex )
256             break;
257     }
258 
259     // remove entry from vector
260     if ( pIt != m_TabList.end())
261     {
262         m_TabList.erase(pIt);
263         return true;
264     }
265     else
266         return false;
267 }
268 
269 // -----------------------------------------------------------------------
270 TabEntry* FwkTabWindow::FindEntry( sal_Int32 nIndex ) const
271 {
272     TabEntry* pEntry = NULL;
273 
274     TabEntryList::const_iterator pIt;
275     for (  pIt  = m_TabList.begin();
276            pIt != m_TabList.end();
277          ++pIt )
278     {
279         if ( (*pIt)->m_nIndex == nIndex )
280         {
281             pEntry = *pIt;
282             break;
283         }
284     }
285 
286     return pEntry;
287 }
288 
289 // -----------------------------------------------------------------------
290 
291 IMPL_LINK( FwkTabWindow, ActivatePageHdl, TabControl *, EMPTYARG )
292 {
293     const sal_uInt16 nId = m_aTabCtrl.GetCurPageId();
294     FwkTabPage* pTabPage = static_cast< FwkTabPage* >( m_aTabCtrl.GetTabPage( nId ) );
295     if ( !pTabPage )
296     {
297         TabEntry* pEntry = FindEntry( nId );
298         if ( pEntry )
299         {
300             pTabPage = new FwkTabPage( &m_aTabCtrl, pEntry->m_sPageURL, pEntry->m_xEventHdl, m_xWinProvider );
301             pEntry->m_pPage = pTabPage;
302             m_aTabCtrl.SetTabPage( nId, pTabPage );
303             pTabPage->Show();
304             pTabPage->ActivatePage();
305         }
306     } else {
307         pTabPage->ActivatePage();
308     }
309     m_aTabCtrl.BroadcastEvent( VCLEVENT_TABPAGE_ACTIVATE );
310     return 1;
311 }
312 
313 // -----------------------------------------------------------------------
314 
315 IMPL_LINK( FwkTabWindow, DeactivatePageHdl, TabControl *, EMPTYARG )
316 {
317     m_aTabCtrl.BroadcastEvent( VCLEVENT_TABPAGE_DEACTIVATE );
318     return 1;
319 }
320 
321 // -----------------------------------------------------------------------
322 
323 IMPL_LINK( FwkTabWindow, CloseHdl, PushButton *, EMPTYARG )
324 {
325 //    Close();
326     return 0;
327 }
328 
329 // -----------------------------------------------------------------------
330 
331 void FwkTabWindow::AddEventListener( const Link& rEventListener )
332 {
333     m_aTabCtrl.AddEventListener( rEventListener );
334 }
335 
336 void FwkTabWindow::RemoveEventListener( const Link& rEventListener )
337 {
338     m_aTabCtrl.RemoveEventListener( rEventListener );
339 }
340 
341 // -----------------------------------------------------------------------
342 
343 FwkTabPage* FwkTabWindow::AddTabPage( sal_Int32 nIndex, const uno::Sequence< beans::NamedValue >& rProperties )
344 {
345     ::rtl::OUString sTitle, sToolTip, sPageURL;
346     uno::Reference< css::awt::XContainerWindowEventHandler > xEventHdl;
347     uno::Reference< graphic::XGraphic > xImage;
348     bool bDisabled = false;
349 
350     sal_Int32 i = 0, nLen = rProperties.getLength();
351     for ( i = 0; i < nLen; ++i )
352     {
353         beans::NamedValue aValue = rProperties[i];
354         ::rtl::OUString sName = aValue.Name;
355 
356         if ( sName.equalsAscii("Title") )
357             aValue.Value >>= sTitle;
358         else if ( sName.equalsAscii("ToolTip") )
359             aValue.Value >>= sToolTip;
360         else if ( sName.equalsAscii("PageURL") )
361             aValue.Value >>= sPageURL;
362         else if ( sName.equalsAscii("EventHdl") )
363             aValue.Value >>= xEventHdl;
364         else if ( sName.equalsAscii("Image") )
365             aValue.Value >>= xImage;
366         else if ( sName.equalsAscii("Disabled") )
367             aValue.Value >>= bDisabled;
368     }
369 
370     TabEntry* pEntry = new TabEntry( nIndex, sPageURL, xEventHdl );
371     m_TabList.push_back( pEntry );
372     sal_uInt16 nIdx = static_cast< sal_uInt16 >( nIndex );
373     m_aTabCtrl.InsertPage( nIdx, sTitle );
374     if ( sToolTip.getLength() > 0 )
375         m_aTabCtrl.SetHelpText( nIdx, sToolTip );
376     if ( xImage.is() )
377         m_aTabCtrl.SetPageImage( nIdx, Image( xImage ) );
378     if ( bDisabled )
379         m_aTabCtrl.EnablePage( nIdx, false );
380 
381     return pEntry->m_pPage;
382 }
383 
384 // -----------------------------------------------------------------------
385 
386 void FwkTabWindow::ActivatePage( sal_Int32 nIndex )
387 {
388     m_aTabCtrl.SetCurPageId( static_cast< sal_uInt16 >( nIndex ) );
389     ActivatePageHdl( &m_aTabCtrl );
390 }
391 
392 // -----------------------------------------------------------------------
393 
394 void FwkTabWindow::RemovePage( sal_Int32 nIndex )
395 {
396     TabEntry* pEntry = FindEntry(nIndex);
397     if ( pEntry )
398     {
399         m_aTabCtrl.RemovePage( static_cast< sal_uInt16 >( nIndex ) );
400         if (RemoveEntry(nIndex))
401             delete pEntry;
402     }
403 }
404 
405 // -----------------------------------------------------------------------
406 void FwkTabWindow::Resize()
407 {
408     Size aPageSize = GetSizePixel();
409     m_aTabCtrl.SetTabPageSizePixel( aPageSize );
410 }
411 
412 } // namespace framework
413 
414