xref: /AOO41X/main/framework/source/uielement/recentfilesmenucontroller.cxx (revision 6d739b60ff8f4ed2134ae1442e284f9da90334b4)
1*6d739b60SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*6d739b60SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*6d739b60SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*6d739b60SAndrew Rist  * distributed with this work for additional information
6*6d739b60SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*6d739b60SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*6d739b60SAndrew Rist  * "License"); you may not use this file except in compliance
9*6d739b60SAndrew Rist  * with the License.  You may obtain a copy of the License at
10cdf0e10cSrcweir  *
11*6d739b60SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
13*6d739b60SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*6d739b60SAndrew Rist  * software distributed under the License is distributed on an
15*6d739b60SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*6d739b60SAndrew Rist  * KIND, either express or implied.  See the License for the
17*6d739b60SAndrew Rist  * specific language governing permissions and limitations
18*6d739b60SAndrew Rist  * under the License.
19cdf0e10cSrcweir  *
20*6d739b60SAndrew Rist  *************************************************************/
21*6d739b60SAndrew Rist 
22*6d739b60SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_framework.hxx"
26cdf0e10cSrcweir #include <uielement/recentfilesmenucontroller.hxx>
27cdf0e10cSrcweir 
28cdf0e10cSrcweir //_________________________________________________________________________________________________________________
29cdf0e10cSrcweir //	my own includes
30cdf0e10cSrcweir //_________________________________________________________________________________________________________________
31cdf0e10cSrcweir #include <threadhelp/resetableguard.hxx>
32cdf0e10cSrcweir #include "services.h"
33cdf0e10cSrcweir 
34cdf0e10cSrcweir #ifndef __FRAMEWORK_CLASSES_RESOURCE_HRC_
35cdf0e10cSrcweir #include <classes/resource.hrc>
36cdf0e10cSrcweir #endif
37cdf0e10cSrcweir #include <classes/fwkresid.hxx>
38cdf0e10cSrcweir 
39cdf0e10cSrcweir //_________________________________________________________________________________________________________________
40cdf0e10cSrcweir //	interface includes
41cdf0e10cSrcweir //_________________________________________________________________________________________________________________
42cdf0e10cSrcweir #include <com/sun/star/awt/XDevice.hpp>
43cdf0e10cSrcweir #include <com/sun/star/beans/PropertyValue.hpp>
44cdf0e10cSrcweir #include <com/sun/star/awt/MenuItemStyle.hpp>
45cdf0e10cSrcweir #include <com/sun/star/util/XStringWidth.hpp>
46cdf0e10cSrcweir //_________________________________________________________________________________________________________________
47cdf0e10cSrcweir //	includes of other projects
48cdf0e10cSrcweir //_________________________________________________________________________________________________________________
49cdf0e10cSrcweir 
50cdf0e10cSrcweir #ifndef _VCL_MENU_HXX_
51cdf0e10cSrcweir #include <vcl/menu.hxx>
52cdf0e10cSrcweir #endif
53cdf0e10cSrcweir #include <vcl/svapp.hxx>
54cdf0e10cSrcweir #include <vcl/i18nhelp.hxx>
55cdf0e10cSrcweir #include <tools/urlobj.hxx>
56cdf0e10cSrcweir #include <rtl/ustrbuf.hxx>
57cdf0e10cSrcweir #include <unotools/historyoptions.hxx>
58cdf0e10cSrcweir #include <cppuhelper/implbase1.hxx>
59cdf0e10cSrcweir #include <osl/file.hxx>
60cdf0e10cSrcweir //#include <tools/solar.hrc>
61cdf0e10cSrcweir #include <dispatch/uieventloghelper.hxx>
62cdf0e10cSrcweir #include <vos/mutex.hxx>
63cdf0e10cSrcweir 
64cdf0e10cSrcweir //_________________________________________________________________________________________________________________
65cdf0e10cSrcweir //	Defines
66cdf0e10cSrcweir //_________________________________________________________________________________________________________________
67cdf0e10cSrcweir //
68cdf0e10cSrcweir 
69cdf0e10cSrcweir using namespace com::sun::star::uno;
70cdf0e10cSrcweir using namespace com::sun::star::lang;
71cdf0e10cSrcweir using namespace com::sun::star::frame;
72cdf0e10cSrcweir using namespace com::sun::star::beans;
73cdf0e10cSrcweir using namespace com::sun::star::util;
74cdf0e10cSrcweir using namespace com::sun::star::container;
75cdf0e10cSrcweir 
76cdf0e10cSrcweir static const char SFX_REFERER_USER[] = "private:user";
77cdf0e10cSrcweir 
78cdf0e10cSrcweir namespace framework
79cdf0e10cSrcweir {
80cdf0e10cSrcweir 
81cdf0e10cSrcweir class RecentFilesStringLength : public ::cppu::WeakImplHelper1< ::com::sun::star::util::XStringWidth >
82cdf0e10cSrcweir {
83cdf0e10cSrcweir 	public:
84cdf0e10cSrcweir 		RecentFilesStringLength() {}
85cdf0e10cSrcweir 		virtual ~RecentFilesStringLength() {}
86cdf0e10cSrcweir 
87cdf0e10cSrcweir 		// XStringWidth
88cdf0e10cSrcweir 		sal_Int32 SAL_CALL queryStringWidth( const ::rtl::OUString& aString )
89cdf0e10cSrcweir 			throw (::com::sun::star::uno::RuntimeException)
90cdf0e10cSrcweir 		{
91cdf0e10cSrcweir 			return aString.getLength();
92cdf0e10cSrcweir 		}
93cdf0e10cSrcweir };
94cdf0e10cSrcweir 
95cdf0e10cSrcweir DEFINE_XSERVICEINFO_MULTISERVICE        (   RecentFilesMenuController                   ,
96cdf0e10cSrcweir                                             OWeakObject                                 ,
97cdf0e10cSrcweir                                             SERVICENAME_POPUPMENUCONTROLLER		        ,
98cdf0e10cSrcweir 											IMPLEMENTATIONNAME_RECENTFILESMENUCONTROLLER
99cdf0e10cSrcweir 										)
100cdf0e10cSrcweir 
101cdf0e10cSrcweir DEFINE_INIT_SERVICE                     (   RecentFilesMenuController, {} )
102cdf0e10cSrcweir 
103cdf0e10cSrcweir RecentFilesMenuController::RecentFilesMenuController( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceManager ) :
104cdf0e10cSrcweir 	svt::PopupMenuControllerBase( xServiceManager ),
105cdf0e10cSrcweir     m_bDisabled( sal_False )
106cdf0e10cSrcweir {
107cdf0e10cSrcweir }
108cdf0e10cSrcweir 
109cdf0e10cSrcweir RecentFilesMenuController::~RecentFilesMenuController()
110cdf0e10cSrcweir {
111cdf0e10cSrcweir }
112cdf0e10cSrcweir 
113cdf0e10cSrcweir // private function
114cdf0e10cSrcweir void RecentFilesMenuController::fillPopupMenu( Reference< css::awt::XPopupMenu >& rPopupMenu )
115cdf0e10cSrcweir {
116cdf0e10cSrcweir     VCLXPopupMenu*                                     pPopupMenu        = (VCLXPopupMenu *)VCLXMenu::GetImplementation( rPopupMenu );
117cdf0e10cSrcweir     PopupMenu*                                         pVCLPopupMenu     = 0;
118cdf0e10cSrcweir 
119cdf0e10cSrcweir     vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
120cdf0e10cSrcweir 
121cdf0e10cSrcweir     resetPopupMenu( rPopupMenu );
122cdf0e10cSrcweir     if ( pPopupMenu )
123cdf0e10cSrcweir         pVCLPopupMenu = (PopupMenu *)pPopupMenu->GetMenu();
124cdf0e10cSrcweir 
125cdf0e10cSrcweir     if ( pVCLPopupMenu )
126cdf0e10cSrcweir     {
127cdf0e10cSrcweir 	    Sequence< Sequence< PropertyValue > > aHistoryList = SvtHistoryOptions().GetList( ePICKLIST );
128cdf0e10cSrcweir 	    Reference< XStringWidth > xStringLength( new RecentFilesStringLength );
129cdf0e10cSrcweir 
130cdf0e10cSrcweir 	    int nPickListMenuItems = ( aHistoryList.getLength() > 99 ) ? 99 : aHistoryList.getLength();
131cdf0e10cSrcweir 
132cdf0e10cSrcweir         // New vnd.sun.star.popup: command URL to support direct dispatches
133cdf0e10cSrcweir         const rtl::OUString aCmdPrefix( RTL_CONSTASCII_USTRINGPARAM( "vnd.sun.star.popup:RecentFileList?entry=" ));
134cdf0e10cSrcweir 
135cdf0e10cSrcweir         m_aRecentFilesItems.clear();
136cdf0e10cSrcweir         if (( nPickListMenuItems > 0 ) && !m_bDisabled )
137cdf0e10cSrcweir         {
138cdf0e10cSrcweir             for ( int i = 0; i < nPickListMenuItems; i++ )
139cdf0e10cSrcweir 	        {
140cdf0e10cSrcweir 		        Sequence< PropertyValue >& rPickListEntry = aHistoryList[i];
141cdf0e10cSrcweir 		        RecentFile aRecentFile;
142cdf0e10cSrcweir 
143cdf0e10cSrcweir 		        for ( int j = 0; j < rPickListEntry.getLength(); j++ )
144cdf0e10cSrcweir 		        {
145cdf0e10cSrcweir 			        Any a = rPickListEntry[j].Value;
146cdf0e10cSrcweir 
147cdf0e10cSrcweir 			        if ( rPickListEntry[j].Name == HISTORY_PROPERTYNAME_URL )
148cdf0e10cSrcweir 				        a >>= aRecentFile.aURL;
149cdf0e10cSrcweir 			        else if ( rPickListEntry[j].Name == HISTORY_PROPERTYNAME_FILTER )
150cdf0e10cSrcweir 				        a >>= aRecentFile.aFilter;
151cdf0e10cSrcweir 			        else if ( rPickListEntry[j].Name == HISTORY_PROPERTYNAME_TITLE )
152cdf0e10cSrcweir 				        a >>= aRecentFile.aTitle;
153cdf0e10cSrcweir 			        else if ( rPickListEntry[j].Name == HISTORY_PROPERTYNAME_PASSWORD )
154cdf0e10cSrcweir 				        a >>= aRecentFile.aPassword;
155cdf0e10cSrcweir 		        }
156cdf0e10cSrcweir 
157cdf0e10cSrcweir                 m_aRecentFilesItems.push_back( aRecentFile );
158cdf0e10cSrcweir 	        }
159cdf0e10cSrcweir         }
160cdf0e10cSrcweir 
161cdf0e10cSrcweir 	    if ( !m_aRecentFilesItems.empty() )
162cdf0e10cSrcweir 	    {
163cdf0e10cSrcweir 		    URL aTargetURL;
164cdf0e10cSrcweir 
165cdf0e10cSrcweir             const sal_uInt32 nCount = m_aRecentFilesItems.size();
166cdf0e10cSrcweir             for ( sal_uInt32 i = 0; i < nCount; i++ )
167cdf0e10cSrcweir 			{
168cdf0e10cSrcweir 				char menuShortCut[5] = "~n: ";
169cdf0e10cSrcweir 
170cdf0e10cSrcweir 				::rtl::OUString aMenuShortCut;
171cdf0e10cSrcweir 				if ( i <= 9 )
172cdf0e10cSrcweir 				{
173cdf0e10cSrcweir 					if ( i == 9 )
174cdf0e10cSrcweir 						aMenuShortCut = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "1~0: " ));
175cdf0e10cSrcweir 					else
176cdf0e10cSrcweir 					{
177cdf0e10cSrcweir 						menuShortCut[1] = (char)( '1' + i );
178cdf0e10cSrcweir 						aMenuShortCut = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( menuShortCut ));
179cdf0e10cSrcweir 					}
180cdf0e10cSrcweir 				}
181cdf0e10cSrcweir 				else
182cdf0e10cSrcweir 				{
183cdf0e10cSrcweir 					aMenuShortCut = rtl::OUString::valueOf((sal_Int32)( i + 1 ));
184cdf0e10cSrcweir 					aMenuShortCut += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ": " ));
185cdf0e10cSrcweir 				}
186cdf0e10cSrcweir 
187cdf0e10cSrcweir 				// Abbreviate URL
188cdf0e10cSrcweir                 rtl::OUString	aURLString( aCmdPrefix + rtl::OUString::valueOf( sal_Int32( i )));
189cdf0e10cSrcweir 				rtl::OUString	aTipHelpText;
190cdf0e10cSrcweir 				rtl::OUString	aMenuTitle;
191cdf0e10cSrcweir 				INetURLObject	aURL( m_aRecentFilesItems[i].aURL );
192cdf0e10cSrcweir 
193cdf0e10cSrcweir 				if ( aURL.GetProtocol() == INET_PROT_FILE )
194cdf0e10cSrcweir 				{
195cdf0e10cSrcweir 					// Do handle file URL differently => convert it to a system
196cdf0e10cSrcweir 					// path and abbreviate it with a special function:
197cdf0e10cSrcweir 					String aFileSystemPath( aURL.getFSysPath( INetURLObject::FSYS_DETECT ) );
198cdf0e10cSrcweir 
199cdf0e10cSrcweir 					::rtl::OUString	aSystemPath( aFileSystemPath );
200cdf0e10cSrcweir 					::rtl::OUString	aCompactedSystemPath;
201cdf0e10cSrcweir 
202cdf0e10cSrcweir 					aTipHelpText = aSystemPath;
203cdf0e10cSrcweir 					oslFileError nError = osl_abbreviateSystemPath( aSystemPath.pData, &aCompactedSystemPath.pData, 46, NULL );
204cdf0e10cSrcweir 					if ( !nError )
205cdf0e10cSrcweir 						aMenuTitle = String( aCompactedSystemPath );
206cdf0e10cSrcweir 					else
207cdf0e10cSrcweir 						aMenuTitle = aSystemPath;
208cdf0e10cSrcweir 				}
209cdf0e10cSrcweir 				else
210cdf0e10cSrcweir 				{
211cdf0e10cSrcweir 					// Use INetURLObject to abbreviate all other URLs
212cdf0e10cSrcweir 					String	aShortURL;
213cdf0e10cSrcweir 					aShortURL = aURL.getAbbreviated( xStringLength, 46, INetURLObject::DECODE_UNAMBIGUOUS );
214cdf0e10cSrcweir 					aMenuTitle += aShortURL;
215cdf0e10cSrcweir 					aTipHelpText = aURLString;
216cdf0e10cSrcweir 				}
217cdf0e10cSrcweir 
218cdf0e10cSrcweir 				::rtl::OUString aTitle( aMenuShortCut + aMenuTitle );
219cdf0e10cSrcweir 
220cdf0e10cSrcweir 				pVCLPopupMenu->InsertItem( sal_uInt16( i+1 ), aTitle );
221cdf0e10cSrcweir 				pVCLPopupMenu->SetTipHelpText( sal_uInt16( i+1 ), aTipHelpText );
222cdf0e10cSrcweir                 pVCLPopupMenu->SetItemCommand( sal_uInt16( i+1 ), aURLString );
223cdf0e10cSrcweir 			}
224cdf0e10cSrcweir 		}
225cdf0e10cSrcweir         else
226cdf0e10cSrcweir         {
227cdf0e10cSrcweir             // No recent documents => insert "no document" string
228cdf0e10cSrcweir             String aNoDocumentStr = String( FwkResId( STR_NODOCUMENT ));
229cdf0e10cSrcweir             pVCLPopupMenu->InsertItem( 1, aNoDocumentStr );
230cdf0e10cSrcweir             pVCLPopupMenu->EnableItem( 1, sal_False );
231cdf0e10cSrcweir         }
232cdf0e10cSrcweir 	}
233cdf0e10cSrcweir }
234cdf0e10cSrcweir 
235cdf0e10cSrcweir void RecentFilesMenuController::executeEntry( sal_Int32 nIndex )
236cdf0e10cSrcweir {
237cdf0e10cSrcweir     static int NUM_OF_PICKLIST_ARGS = 3;
238cdf0e10cSrcweir 
239cdf0e10cSrcweir     Reference< css::awt::XPopupMenu > xPopupMenu;
240cdf0e10cSrcweir     Reference< XDispatch >            xDispatch;
241cdf0e10cSrcweir     Reference< XDispatchProvider >    xDispatchProvider;
242cdf0e10cSrcweir     Reference< XMultiServiceFactory > xServiceManager;
243cdf0e10cSrcweir 
244cdf0e10cSrcweir     osl::ClearableMutexGuard aLock( m_aMutex );
245cdf0e10cSrcweir     xPopupMenu          = m_xPopupMenu;
246cdf0e10cSrcweir     xDispatchProvider   = Reference< XDispatchProvider >( m_xFrame, UNO_QUERY );
247cdf0e10cSrcweir     xServiceManager     = m_xServiceManager;
248cdf0e10cSrcweir     aLock.clear();
249cdf0e10cSrcweir 
250cdf0e10cSrcweir     css::util::URL            aTargetURL;
251cdf0e10cSrcweir     Sequence< PropertyValue > aArgsList;
252cdf0e10cSrcweir 
253cdf0e10cSrcweir     if (( nIndex >= 0 ) &&
254cdf0e10cSrcweir         ( nIndex < sal::static_int_cast<sal_Int32>( m_aRecentFilesItems.size() )))
255cdf0e10cSrcweir     {
256cdf0e10cSrcweir         const RecentFile& rRecentFile = m_aRecentFilesItems[ nIndex ];
257cdf0e10cSrcweir 
258cdf0e10cSrcweir         aTargetURL.Complete = rRecentFile.aURL;
259cdf0e10cSrcweir         m_xURLTransformer->parseStrict( aTargetURL );
260cdf0e10cSrcweir 
261cdf0e10cSrcweir         aArgsList.realloc( NUM_OF_PICKLIST_ARGS );
262cdf0e10cSrcweir         aArgsList[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Referer" ));
263cdf0e10cSrcweir         aArgsList[0].Value = makeAny( ::rtl::OUString::createFromAscii( SFX_REFERER_USER ));
264cdf0e10cSrcweir 
265cdf0e10cSrcweir         // documents in the picklist will never be opened as templates
266cdf0e10cSrcweir         aArgsList[1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "AsTemplate" ));
267cdf0e10cSrcweir         aArgsList[1].Value = makeAny( (sal_Bool) sal_False );
268cdf0e10cSrcweir 
269cdf0e10cSrcweir         ::rtl::OUString  aFilter( rRecentFile.aFilter );
270cdf0e10cSrcweir         sal_Int32 nPos = aFilter.indexOf( '|' );
271cdf0e10cSrcweir         if ( nPos >= 0 )
272cdf0e10cSrcweir         {
273cdf0e10cSrcweir 	        ::rtl::OUString aFilterOptions;
274cdf0e10cSrcweir 
275cdf0e10cSrcweir 	        if ( nPos < ( aFilter.getLength() - 1 ) )
276cdf0e10cSrcweir 		        aFilterOptions = aFilter.copy( nPos+1 );
277cdf0e10cSrcweir 
278cdf0e10cSrcweir 	        aArgsList[2].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "FilterOptions" ));
279cdf0e10cSrcweir 	        aArgsList[2].Value <<= aFilterOptions;
280cdf0e10cSrcweir 
281cdf0e10cSrcweir 	        aFilter = aFilter.copy( 0, nPos-1 );
282cdf0e10cSrcweir 	        aArgsList.realloc( ++NUM_OF_PICKLIST_ARGS );
283cdf0e10cSrcweir         }
284cdf0e10cSrcweir 
285cdf0e10cSrcweir         aArgsList[NUM_OF_PICKLIST_ARGS-1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "FilterName" ));
286cdf0e10cSrcweir         aArgsList[NUM_OF_PICKLIST_ARGS-1].Value <<= aFilter;
287cdf0e10cSrcweir 
288cdf0e10cSrcweir         xDispatch = xDispatchProvider->queryDispatch( aTargetURL, ::rtl::OUString::createFromAscii("_default"), 0 );
289cdf0e10cSrcweir     }
290cdf0e10cSrcweir 
291cdf0e10cSrcweir     if ( xDispatch.is() )
292cdf0e10cSrcweir     {
293cdf0e10cSrcweir         // Call dispatch asychronously as we can be destroyed while dispatch is
294cdf0e10cSrcweir         // executed. VCL is not able to survive this as it wants to call listeners
295cdf0e10cSrcweir         // after select!!!
296cdf0e10cSrcweir         LoadRecentFile* pLoadRecentFile = new LoadRecentFile;
297cdf0e10cSrcweir         pLoadRecentFile->xDispatch  = xDispatch;
298cdf0e10cSrcweir         pLoadRecentFile->aTargetURL = aTargetURL;
299cdf0e10cSrcweir         pLoadRecentFile->aArgSeq    = aArgsList;
300cdf0e10cSrcweir         if(::comphelper::UiEventsLogger::isEnabled()) //#i88653#
301cdf0e10cSrcweir             UiEventLogHelper(::rtl::OUString::createFromAscii("RecentFilesMenuController")).log(m_xServiceManager, m_xFrame, aTargetURL, aArgsList);
302cdf0e10cSrcweir         Application::PostUserEvent( STATIC_LINK(0, RecentFilesMenuController, ExecuteHdl_Impl), pLoadRecentFile );
303cdf0e10cSrcweir     }
304cdf0e10cSrcweir }
305cdf0e10cSrcweir 
306cdf0e10cSrcweir // XEventListener
307cdf0e10cSrcweir void SAL_CALL RecentFilesMenuController::disposing( const EventObject& ) throw ( RuntimeException )
308cdf0e10cSrcweir {
309cdf0e10cSrcweir     Reference< css::awt::XMenuListener > xHolder(( OWeakObject *)this, UNO_QUERY );
310cdf0e10cSrcweir 
311cdf0e10cSrcweir     osl::MutexGuard aLock( m_aMutex );
312cdf0e10cSrcweir     m_xFrame.clear();
313cdf0e10cSrcweir     m_xDispatch.clear();
314cdf0e10cSrcweir     m_xServiceManager.clear();
315cdf0e10cSrcweir 
316cdf0e10cSrcweir     if ( m_xPopupMenu.is() )
317cdf0e10cSrcweir         m_xPopupMenu->removeMenuListener( Reference< css::awt::XMenuListener >(( OWeakObject *)this, UNO_QUERY ));
318cdf0e10cSrcweir     m_xPopupMenu.clear();
319cdf0e10cSrcweir }
320cdf0e10cSrcweir 
321cdf0e10cSrcweir // XStatusListener
322cdf0e10cSrcweir void SAL_CALL RecentFilesMenuController::statusChanged( const FeatureStateEvent& Event ) throw ( RuntimeException )
323cdf0e10cSrcweir {
324cdf0e10cSrcweir     osl::MutexGuard aLock( m_aMutex );
325cdf0e10cSrcweir     m_bDisabled = !Event.IsEnabled;
326cdf0e10cSrcweir }
327cdf0e10cSrcweir 
328cdf0e10cSrcweir void SAL_CALL RecentFilesMenuController::select( const css::awt::MenuEvent& rEvent ) throw (RuntimeException)
329cdf0e10cSrcweir {
330cdf0e10cSrcweir     Reference< css::awt::XPopupMenu > xPopupMenu;
331cdf0e10cSrcweir     Reference< XDispatch >            xDispatch;
332cdf0e10cSrcweir     Reference< XDispatchProvider >    xDispatchProvider;
333cdf0e10cSrcweir     Reference< XMultiServiceFactory > xServiceManager;
334cdf0e10cSrcweir 
335cdf0e10cSrcweir     osl::ClearableMutexGuard aLock( m_aMutex );
336cdf0e10cSrcweir     xPopupMenu          = m_xPopupMenu;
337cdf0e10cSrcweir     xDispatchProvider   = Reference< XDispatchProvider >( m_xFrame, UNO_QUERY );
338cdf0e10cSrcweir     xServiceManager     = m_xServiceManager;
339cdf0e10cSrcweir     aLock.clear();
340cdf0e10cSrcweir 
341cdf0e10cSrcweir     css::util::URL aTargetURL;
342cdf0e10cSrcweir     Sequence< PropertyValue > aArgsList;
343cdf0e10cSrcweir 
344cdf0e10cSrcweir     if ( xPopupMenu.is() && xDispatchProvider.is() )
345cdf0e10cSrcweir     {
346cdf0e10cSrcweir         VCLXPopupMenu* pPopupMenu = (VCLXPopupMenu *)VCLXPopupMenu::GetImplementation( xPopupMenu );
347cdf0e10cSrcweir         if ( pPopupMenu )
348cdf0e10cSrcweir             executeEntry( rEvent.MenuId-1 );
349cdf0e10cSrcweir     }
350cdf0e10cSrcweir }
351cdf0e10cSrcweir 
352cdf0e10cSrcweir void SAL_CALL RecentFilesMenuController::activate( const css::awt::MenuEvent& ) throw (RuntimeException)
353cdf0e10cSrcweir {
354cdf0e10cSrcweir     osl::MutexGuard aLock( m_aMutex );
355cdf0e10cSrcweir     impl_setPopupMenu();
356cdf0e10cSrcweir }
357cdf0e10cSrcweir 
358cdf0e10cSrcweir // XPopupMenuController
359cdf0e10cSrcweir void RecentFilesMenuController::impl_setPopupMenu()
360cdf0e10cSrcweir {
361cdf0e10cSrcweir     if ( m_xPopupMenu.is() )
362cdf0e10cSrcweir         fillPopupMenu( m_xPopupMenu );
363cdf0e10cSrcweir }
364cdf0e10cSrcweir 
365cdf0e10cSrcweir void SAL_CALL RecentFilesMenuController::updatePopupMenu() throw (RuntimeException)
366cdf0e10cSrcweir {
367cdf0e10cSrcweir     osl::ClearableMutexGuard aLock( m_aMutex );
368cdf0e10cSrcweir 
369cdf0e10cSrcweir     throwIfDisposed();
370cdf0e10cSrcweir 
371cdf0e10cSrcweir     Reference< XStatusListener > xStatusListener( static_cast< OWeakObject* >( this ), UNO_QUERY );
372cdf0e10cSrcweir     Reference< XDispatch > xDispatch( m_xDispatch );
373cdf0e10cSrcweir     com::sun::star::util::URL aTargetURL;
374cdf0e10cSrcweir     aTargetURL.Complete = m_aCommandURL;
375cdf0e10cSrcweir     m_xURLTransformer->parseStrict( aTargetURL );
376cdf0e10cSrcweir     aLock.clear();
377cdf0e10cSrcweir 
378cdf0e10cSrcweir     // Add/remove status listener to get a status update once
379cdf0e10cSrcweir     if ( xDispatch.is() )
380cdf0e10cSrcweir     {
381cdf0e10cSrcweir         xDispatch->addStatusListener( xStatusListener, aTargetURL );
382cdf0e10cSrcweir         xDispatch->removeStatusListener( xStatusListener, aTargetURL );
383cdf0e10cSrcweir     }
384cdf0e10cSrcweir }
385cdf0e10cSrcweir 
386cdf0e10cSrcweir // XDispatchProvider
387cdf0e10cSrcweir Reference< XDispatch > SAL_CALL RecentFilesMenuController::queryDispatch(
388cdf0e10cSrcweir     const URL& aURL,
389cdf0e10cSrcweir     const ::rtl::OUString& /*sTarget*/,
390cdf0e10cSrcweir     sal_Int32 /*nFlags*/ )
391cdf0e10cSrcweir throw( RuntimeException )
392cdf0e10cSrcweir {
393cdf0e10cSrcweir     osl::MutexGuard aLock( m_aMutex );
394cdf0e10cSrcweir 
395cdf0e10cSrcweir 	throwIfDisposed();
396cdf0e10cSrcweir 
397cdf0e10cSrcweir     if ( aURL.Complete.indexOf( m_aBaseURL ) == 0 )
398cdf0e10cSrcweir         return Reference< XDispatch >( static_cast< OWeakObject* >( this ), UNO_QUERY );
399cdf0e10cSrcweir     else
400cdf0e10cSrcweir         return Reference< XDispatch >();
401cdf0e10cSrcweir }
402cdf0e10cSrcweir 
403cdf0e10cSrcweir // XDispatch
404cdf0e10cSrcweir void SAL_CALL RecentFilesMenuController::dispatch(
405cdf0e10cSrcweir     const URL& aURL,
406cdf0e10cSrcweir     const Sequence< PropertyValue >& /*seqProperties*/ )
407cdf0e10cSrcweir throw( RuntimeException )
408cdf0e10cSrcweir {
409cdf0e10cSrcweir     osl::MutexGuard aLock( m_aMutex );
410cdf0e10cSrcweir 
411cdf0e10cSrcweir 	throwIfDisposed();
412cdf0e10cSrcweir 
413cdf0e10cSrcweir     if ( aURL.Complete.indexOf( m_aBaseURL ) == 0 )
414cdf0e10cSrcweir     {
415cdf0e10cSrcweir         // Parse URL to retrieve entry argument and its value
416cdf0e10cSrcweir         sal_Int32 nQueryPart = aURL.Complete.indexOf( '?', m_aBaseURL.getLength() );
417cdf0e10cSrcweir         if ( nQueryPart > 0 )
418cdf0e10cSrcweir         {
419cdf0e10cSrcweir             const rtl::OUString aEntryArgStr( RTL_CONSTASCII_USTRINGPARAM( "entry=" ));
420cdf0e10cSrcweir             sal_Int32 nEntryArg = aURL.Complete.indexOf( aEntryArgStr, nQueryPart );
421cdf0e10cSrcweir             sal_Int32 nEntryPos = nEntryArg + aEntryArgStr.getLength();
422cdf0e10cSrcweir             if (( nEntryArg > 0 ) && ( nEntryPos < aURL.Complete.getLength() ))
423cdf0e10cSrcweir             {
424cdf0e10cSrcweir                 sal_Int32 nAddArgs = aURL.Complete.indexOf( '&', nEntryPos );
425cdf0e10cSrcweir                 rtl::OUString aEntryArg;
426cdf0e10cSrcweir 
427cdf0e10cSrcweir                 if ( nAddArgs < 0 )
428cdf0e10cSrcweir                     aEntryArg = aURL.Complete.copy( nEntryPos );
429cdf0e10cSrcweir                 else
430cdf0e10cSrcweir                     aEntryArg = aURL.Complete.copy( nEntryPos, nAddArgs-nEntryPos );
431cdf0e10cSrcweir 
432cdf0e10cSrcweir                 sal_Int32 nEntry = aEntryArg.toInt32();
433cdf0e10cSrcweir                 executeEntry( nEntry );
434cdf0e10cSrcweir             }
435cdf0e10cSrcweir         }
436cdf0e10cSrcweir     }
437cdf0e10cSrcweir }
438cdf0e10cSrcweir 
439cdf0e10cSrcweir void SAL_CALL RecentFilesMenuController::addStatusListener(
440cdf0e10cSrcweir     const Reference< XStatusListener >& xControl,
441cdf0e10cSrcweir     const URL& aURL )
442cdf0e10cSrcweir throw( RuntimeException )
443cdf0e10cSrcweir {
444cdf0e10cSrcweir     osl::MutexGuard aLock( m_aMutex );
445cdf0e10cSrcweir 
446cdf0e10cSrcweir 	throwIfDisposed();
447cdf0e10cSrcweir 
448cdf0e10cSrcweir 	svt::PopupMenuControllerBase::addStatusListener( xControl, aURL );
449cdf0e10cSrcweir }
450cdf0e10cSrcweir 
451cdf0e10cSrcweir void SAL_CALL RecentFilesMenuController::removeStatusListener(
452cdf0e10cSrcweir     const Reference< XStatusListener >& xControl,
453cdf0e10cSrcweir     const URL& aURL )
454cdf0e10cSrcweir throw( RuntimeException )
455cdf0e10cSrcweir {
456cdf0e10cSrcweir 	svt::PopupMenuControllerBase::removeStatusListener( xControl, aURL );
457cdf0e10cSrcweir }
458cdf0e10cSrcweir 
459cdf0e10cSrcweir IMPL_STATIC_LINK_NOINSTANCE( RecentFilesMenuController, ExecuteHdl_Impl, LoadRecentFile*, pLoadRecentFile )
460cdf0e10cSrcweir {
461cdf0e10cSrcweir     try
462cdf0e10cSrcweir     {
463cdf0e10cSrcweir         // Asynchronous execution as this can lead to our own destruction!
464cdf0e10cSrcweir         // Framework can recycle our current frame and the layout manager disposes all user interface
465cdf0e10cSrcweir         // elements if a component gets detached from its frame!
466cdf0e10cSrcweir         pLoadRecentFile->xDispatch->dispatch( pLoadRecentFile->aTargetURL, pLoadRecentFile->aArgSeq );
467cdf0e10cSrcweir     }
468cdf0e10cSrcweir     catch ( Exception& )
469cdf0e10cSrcweir     {
470cdf0e10cSrcweir     }
471cdf0e10cSrcweir 
472cdf0e10cSrcweir     delete pLoadRecentFile;
473cdf0e10cSrcweir     return 0;
474cdf0e10cSrcweir }
475cdf0e10cSrcweir 
476cdf0e10cSrcweir }
477