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 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_svx.hxx"
30 
31 #include "tbunosearchcontrollers.hxx"
32 #include <svx/dialogs.hrc>
33 #include <svx/dialmgr.hxx>
34 
35 #include <com/sun/star/beans/XPropertySet.hpp>
36 #include <com/sun/star/frame/XLayoutManager.hpp>
37 #include <com/sun/star/ui/XUIElement.hpp>
38 #include <com/sun/star/util/URL.hpp>
39 
40 #include <toolkit/helper/vclunohelper.hxx>
41 #include <vcl/toolbox.hxx>
42 #include <vcl/svapp.hxx>
43 #include <vos/mutex.hxx>
44 
45 namespace svx
46 {
47 
48 static const ::rtl::OUString SEARCHITEM_SEARCHSTRING   = ::rtl::OUString::createFromAscii("SearchItem.SearchString");
49 static const ::rtl::OUString SEARCHITEM_SEARCHBACKWARD = ::rtl::OUString::createFromAscii("SearchItem.Backward");
50 
51 static const ::rtl::OUString COMMAND_EXECUTESEARCH = ::rtl::OUString::createFromAscii(".uno:ExecuteSearch");
52 static const ::rtl::OUString COMMAND_FINDTEXT   = ::rtl::OUString::createFromAscii(".uno:FindText")  ;
53 static const ::rtl::OUString COMMAND_DOWNSEARCH = ::rtl::OUString::createFromAscii(".uno:DownSearch");
54 static const ::rtl::OUString COMMAND_UPSEARCH   = ::rtl::OUString::createFromAscii(".uno:UpSearch")  ;
55 static const ::rtl::OUString COMMAND_APPENDSEARCHHISTORY   = ::rtl::OUString::createFromAscii("AppendSearchHistory");
56 
57 static const ::rtl::OUString SERVICENAME_URLTRANSFORMER = ::rtl::OUString::createFromAscii("com.sun.star.util.URLTransformer");
58 static const sal_Int32       REMEMBER_SIZE = 10;
59 
60 void impl_executeSearch( const css::uno::Reference< css::lang::XMultiServiceFactory >& rSMgr, const css::uno::Reference< css::frame::XFrame >& xFrame, const css::uno::Sequence< css::beans::PropertyValue >& lArgs )
61 {
62     css::uno::Reference< css::util::XURLTransformer > xURLTransformer( rSMgr->createInstance(SERVICENAME_URLTRANSFORMER), css::uno::UNO_QUERY );
63     if ( xURLTransformer.is() )
64     {
65         css::util::URL aURL;
66         aURL.Complete = COMMAND_EXECUTESEARCH;
67         xURLTransformer->parseStrict(aURL);
68 
69         css::uno::Reference< css::frame::XDispatchProvider > xDispatchProvider(xFrame, css::uno::UNO_QUERY);
70         if ( xDispatchProvider.is() )
71         {
72             css::uno::Reference< css::frame::XDispatch > xDispatch = xDispatchProvider->queryDispatch( aURL, ::rtl::OUString(), 0 );
73             if ( xDispatch.is() && aURL.Complete.getLength() > 0 )
74                 xDispatch->dispatch( aURL, lArgs );
75         }
76     }
77 }
78 
79 FindTextFieldControl::FindTextFieldControl( Window* pParent, WinBits nStyle,
80     css::uno::Reference< css::frame::XFrame >& xFrame,
81     css::uno::Reference< css::lang::XMultiServiceFactory >& xServiceManager) :
82     ComboBox( pParent, nStyle ),
83     m_xFrame(xFrame),
84     m_xServiceManager(xServiceManager),
85     m_bToClearTextField(sal_True)
86 {
87     InitControls_Impl();
88 }
89 
90 FindTextFieldControl::~FindTextFieldControl()
91 {
92 }
93 
94 void FindTextFieldControl::InitControls_Impl()
95 {
96     SetText( SVX_RESSTR( RID_SVXSTR_FINDBAR_FIND ) );
97     SetControlForeground(GetSettings().GetStyleSettings().GetDisableColor());
98 
99     EnableAutocomplete(sal_True, sal_True);
100 }
101 
102 void FindTextFieldControl::Remember_Impl(const String& rStr)
103 {
104     sal_uInt16 nCount = GetEntryCount();
105 
106     for (sal_uInt16 i=0; i<nCount; ++i)
107     {
108         if ( rStr == GetEntry(i))
109             return;
110     }
111 
112     if (nCount == REMEMBER_SIZE)
113         RemoveEntry(REMEMBER_SIZE-1);
114 
115     InsertEntry(rStr, 0);
116 }
117 
118 void FindTextFieldControl::Modify()
119 {
120     ComboBox::Modify();
121 
122     SetControlForeground( GetSettings().GetStyleSettings().GetWindowTextColor() );
123 }
124 
125 long FindTextFieldControl::PreNotify( NotifyEvent& rNEvt )
126 {
127     long nRet= ComboBox::PreNotify( rNEvt );
128 
129     switch ( rNEvt.GetType() )
130     {
131         case EVENT_KEYINPUT:
132         {
133             const KeyEvent* pKeyEvent = rNEvt.GetKeyEvent();
134             sal_Bool bCtrl = pKeyEvent->GetKeyCode().IsMod1();
135             sal_Bool bAlt = pKeyEvent->GetKeyCode().IsMod2();
136             sal_Bool bShift = pKeyEvent->GetKeyCode().IsShift();
137             sal_uInt16 nCode = pKeyEvent->GetKeyCode().GetCode();
138 
139             if ( (bCtrl && bAlt && KEY_F == nCode) || KEY_ESCAPE == nCode )
140             {
141                 nRet = 1;
142                 GrabFocusToDocument();
143             }
144 
145             if ( KEY_RETURN == nCode )
146             {
147                 Remember_Impl(GetText());
148 
149                 ::rtl::OUString sFindText = GetText();
150                 css::uno::Sequence< css::beans::PropertyValue > lArgs(2);
151 
152                 lArgs[0].Name = SEARCHITEM_SEARCHSTRING;
153                 lArgs[0].Value <<= sFindText;
154 
155                 lArgs[1].Name = SEARCHITEM_SEARCHBACKWARD;
156                 if (bShift)
157                     lArgs[1].Value <<= sal_True;
158                 else
159                     lArgs[1].Value <<= sal_False;
160 
161                 impl_executeSearch(m_xServiceManager, m_xFrame, lArgs);
162                 nRet = 1;
163             }
164             break;
165         }
166 
167         case EVENT_GETFOCUS:
168             if ( m_bToClearTextField )
169             {
170                 SetText( String() );
171                 m_bToClearTextField = sal_False;
172             }
173             SetSelection( Selection( SELECTION_MIN, SELECTION_MAX ) );
174             break;
175 
176         case EVENT_LOSEFOCUS:
177             if ( GetText().Len() == 0 )
178             {
179                 SetText( SVX_RESSTR( RID_SVXSTR_FINDBAR_FIND ) );
180                 SetControlForeground(GetSettings().GetStyleSettings().GetDisableColor());
181                 m_bToClearTextField = sal_True;
182             }
183             break;
184     }
185 
186     return nRet;
187 }
188 
189 
190 //-----------------------------------------------------------------------------------------------------------
191 // SearchToolbarControllersManager
192 
193 SearchToolbarControllersManager* SearchToolbarControllersManager::m_pInstance = 0;
194 
195 SearchToolbarControllersManager::SearchToolbarControllersManager()
196 {
197 }
198 
199 SearchToolbarControllersManager::~SearchToolbarControllersManager()
200 {
201 }
202 
203 SearchToolbarControllersManager* SearchToolbarControllersManager::createControllersManager()
204 {
205     if (!m_pInstance)
206         m_pInstance = new SearchToolbarControllersManager();
207 
208     return m_pInstance;
209 }
210 
211 void SearchToolbarControllersManager::registryController( const css::uno::Reference< css::frame::XFrame >& xFrame, const css::uno::Reference< css::frame::XStatusListener >& xStatusListener, const ::rtl::OUString& sCommandURL )
212 {
213     SearchToolbarControllersMap::iterator pIt = aSearchToolbarControllersMap.find(xFrame);
214     if (pIt == aSearchToolbarControllersMap.end())
215     {
216         SearchToolbarControllersVec lControllers(1);
217         lControllers[0].Name = sCommandURL;
218         lControllers[0].Value <<= xStatusListener;
219         aSearchToolbarControllersMap.insert(SearchToolbarControllersMap::value_type(xFrame, lControllers));
220     }
221     else
222     {
223         sal_Int32 nSize = pIt->second.size();
224         for (sal_Int32 i=0; i<nSize; ++i)
225         {
226             if (pIt->second[i].Name.equals(sCommandURL))
227                 return;
228         }
229 
230         pIt->second.resize(nSize+1);
231         pIt->second[nSize].Name = sCommandURL;
232         pIt->second[nSize].Value <<= xStatusListener;
233     }
234 }
235 
236 void SearchToolbarControllersManager::freeController( const css::uno::Reference< css::frame::XFrame >& xFrame, const css::uno::Reference< css::frame::XStatusListener >& /*xStatusListener*/, const ::rtl::OUString& sCommandURL )
237 {
238     SearchToolbarControllersMap::iterator pIt = aSearchToolbarControllersMap.find(xFrame);
239     if (pIt != aSearchToolbarControllersMap.end())
240     {
241         for (SearchToolbarControllersVec::iterator pItCtrl=pIt->second.begin(); pItCtrl!=pIt->second.end(); ++pItCtrl)
242         {
243             if (pItCtrl->Name.equals(sCommandURL))
244             {
245                 pIt->second.erase(pItCtrl);
246                 break;
247             }
248         }
249 
250         if (pIt->second.empty())
251             aSearchToolbarControllersMap.erase(pIt);
252     }
253 }
254 
255 css::uno::Reference< css::frame::XStatusListener > SearchToolbarControllersManager::findController( const css::uno::Reference< css::frame::XFrame >& xFrame, const ::rtl::OUString& sCommandURL )
256 {
257     css::uno::Reference< css::frame::XStatusListener > xStatusListener;
258 
259     SearchToolbarControllersMap::iterator pIt = aSearchToolbarControllersMap.find(xFrame);
260     if (pIt != aSearchToolbarControllersMap.end())
261     {
262         for (SearchToolbarControllersVec::iterator pItCtrl =pIt->second.begin(); pItCtrl != pIt->second.end(); ++pItCtrl)
263         {
264             if (pItCtrl->Name.equals(sCommandURL))
265             {
266                 pItCtrl->Value >>= xStatusListener;
267                 break;
268             }
269         }
270     }
271 
272     return xStatusListener;
273 }
274 
275 //-----------------------------------------------------------------------------------------------------------
276 // FindTextToolbarController
277 
278 FindTextToolbarController::FindTextToolbarController( const css::uno::Reference< css::lang::XMultiServiceFactory >& rServiceManager )
279     :svt::ToolboxController( rServiceManager,
280     css::uno::Reference< css::frame::XFrame >(),
281     COMMAND_FINDTEXT )
282 {
283 }
284 
285 FindTextToolbarController::~FindTextToolbarController()
286 {
287 }
288 
289 // XInterface
290 css::uno::Any SAL_CALL FindTextToolbarController::queryInterface( const css::uno::Type& aType ) throw ( css::uno::RuntimeException )
291 {
292     css::uno::Any a = ToolboxController::queryInterface( aType );
293     if ( a.hasValue() )
294         return a;
295 
296     return ::cppu::queryInterface( aType, static_cast< css::lang::XServiceInfo* >( this ) );
297 }
298 
299 void SAL_CALL FindTextToolbarController::acquire() throw ()
300 {
301     ToolboxController::acquire();
302 }
303 
304 void SAL_CALL FindTextToolbarController::release() throw ()
305 {
306     ToolboxController::release();
307 }
308 
309 // XServiceInfo
310 ::rtl::OUString SAL_CALL FindTextToolbarController::getImplementationName() throw( css::uno::RuntimeException )
311 {
312     return getImplementationName_Static();
313 }
314 
315 sal_Bool SAL_CALL FindTextToolbarController::supportsService( const ::rtl::OUString& ServiceName ) throw( css::uno::RuntimeException )
316 {
317     const css::uno::Sequence< ::rtl::OUString > aSNL( getSupportedServiceNames() );
318     const ::rtl::OUString * pArray = aSNL.getConstArray();
319 
320     for( sal_Int32 i = 0; i < aSNL.getLength(); i++ )
321         if( pArray[i] == ServiceName )
322             return true;
323 
324     return false;
325 }
326 
327 css::uno::Sequence< ::rtl::OUString > SAL_CALL FindTextToolbarController::getSupportedServiceNames() throw( css::uno::RuntimeException )
328 {
329     return getSupportedServiceNames_Static();
330 }
331 
332 css::uno::Sequence< ::rtl::OUString >  FindTextToolbarController::getSupportedServiceNames_Static() throw()
333 {
334     css::uno::Sequence< ::rtl::OUString > aSNS( 1 );
335     aSNS.getArray()[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.frame.ToolbarController" ) );
336     return aSNS;
337 }
338 
339 // XComponent
340 void SAL_CALL FindTextToolbarController::dispose() throw ( css::uno::RuntimeException )
341 {
342     vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
343 
344     SearchToolbarControllersManager::createControllersManager()->freeController(m_xFrame, css::uno::Reference< css::frame::XStatusListener >(static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY), m_aCommandURL);
345 
346     svt::ToolboxController::dispose();
347     delete m_pFindTextFieldControl;
348     m_pFindTextFieldControl = 0;
349 }
350 
351 // XInitialization
352 void SAL_CALL FindTextToolbarController::initialize( const css::uno::Sequence< ::com::sun::star::uno::Any >& aArguments ) throw ( css::uno::Exception, css::uno::RuntimeException)
353 {
354     svt::ToolboxController::initialize(aArguments);
355 
356     Window* pWindow = VCLUnoHelper::GetWindow( getParent() );
357     ToolBox* pToolBox = (ToolBox*)pWindow;
358     if ( pToolBox )
359     {
360         sal_uInt16 nItemCount = pToolBox->GetItemCount();
361         for ( sal_uInt16 i=0; i<nItemCount; ++i )
362         {
363             ::rtl::OUString sItemCommand = pToolBox->GetItemCommand(i);
364             if ( sItemCommand.equals( COMMAND_DOWNSEARCH ) )
365                 m_nDownSearchId = i;
366             else if (sItemCommand.equals( COMMAND_UPSEARCH ))
367                 m_nUpSearchId = i;
368         }
369     }
370 
371     SearchToolbarControllersManager::createControllersManager()->registryController(m_xFrame, css::uno::Reference< css::frame::XStatusListener >(static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY), m_aCommandURL);
372 }
373 
374 // XToolbarController
375 void SAL_CALL FindTextToolbarController::execute( sal_Int16 /*KeyModifier*/ ) throw ( css::uno::RuntimeException )
376 {
377 }
378 
379 css::uno::Reference< css::awt::XWindow > SAL_CALL FindTextToolbarController::createItemWindow( const css::uno::Reference< css::awt::XWindow >& Parent ) throw ( css::uno::RuntimeException )
380 {
381     css::uno::Reference< css::awt::XWindow > xItemWindow;
382 
383     css::uno::Reference< css::awt::XWindow > xParent( Parent );
384     Window* pParent = VCLUnoHelper::GetWindow( xParent );
385     if ( pParent )
386     {
387         ToolBox* pToolbar =  ( ToolBox* )pParent;
388         m_pFindTextFieldControl = new FindTextFieldControl( pToolbar, WinBits( WB_DROPDOWN | WB_VSCROLL), m_xFrame, m_xServiceManager );
389 
390         Size aSize(100, m_pFindTextFieldControl->GetTextHeight() + 200);
391         m_pFindTextFieldControl->SetSizePixel( aSize );
392         m_pFindTextFieldControl->SetModifyHdl(LINK(this, FindTextToolbarController, EditModifyHdl));
393     }
394     xItemWindow = VCLUnoHelper::GetInterface( m_pFindTextFieldControl );
395 
396     return xItemWindow;
397 }
398 
399 // XStatusListener
400 void SAL_CALL FindTextToolbarController::statusChanged( const css::frame::FeatureStateEvent& rEvent ) throw ( css::uno::RuntimeException )
401 {
402     vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
403     if ( m_bDisposed )
404         return;
405 
406     ::rtl::OUString aFeatureURL = rEvent.FeatureURL.Complete;
407     if (aFeatureURL.equalsAscii("AppendSearchHistory"))
408     {
409         m_pFindTextFieldControl->Remember_Impl(m_pFindTextFieldControl->GetText());
410     }
411 }
412 
413 IMPL_LINK( FindTextToolbarController, EditModifyHdl, void *, EMPTYARG )
414 {
415     // enable or disable item DownSearch/UpSearch of findbar
416     Window* pWindow = VCLUnoHelper::GetWindow( getParent() );
417     ToolBox* pToolBox = (ToolBox*)pWindow;
418     if ( pToolBox && m_pFindTextFieldControl )
419     {
420         if (m_pFindTextFieldControl->GetText().Len()>0)
421         {
422             if ( !pToolBox->IsItemEnabled(m_nDownSearchId) )
423                 pToolBox->EnableItem(m_nDownSearchId, sal_True);
424             if ( !pToolBox->IsItemEnabled(m_nUpSearchId) )
425                 pToolBox->EnableItem(m_nUpSearchId, sal_True);
426         }
427         else
428         {
429             if ( pToolBox->IsItemEnabled(m_nDownSearchId) )
430                 pToolBox->EnableItem(m_nDownSearchId, sal_False);
431             if ( pToolBox->IsItemEnabled(m_nUpSearchId) )
432                 pToolBox->EnableItem(m_nUpSearchId, sal_False);
433         }
434     }
435 
436     return 0;
437 }
438 
439 //-----------------------------------------------------------------------------------------------------------
440 // class DownSearchToolboxController
441 
442 DownSearchToolboxController::DownSearchToolboxController(const css::uno::Reference< css::lang::XMultiServiceFactory >& rServiceManager )
443     : svt::ToolboxController( rServiceManager,
444     css::uno::Reference< css::frame::XFrame >(),
445     COMMAND_DOWNSEARCH )
446 {
447 }
448 
449 DownSearchToolboxController::~DownSearchToolboxController()
450 {
451 }
452 
453 // XInterface
454 css::uno::Any SAL_CALL DownSearchToolboxController::queryInterface( const css::uno::Type& aType ) throw ( css::uno::RuntimeException )
455 {
456     css::uno::Any a = ToolboxController::queryInterface( aType );
457     if ( a.hasValue() )
458         return a;
459 
460     return ::cppu::queryInterface( aType, static_cast< css::lang::XServiceInfo* >( this ) );
461 }
462 
463 void SAL_CALL DownSearchToolboxController::acquire() throw ()
464 {
465     ToolboxController::acquire();
466 }
467 
468 void SAL_CALL DownSearchToolboxController::release() throw ()
469 {
470     ToolboxController::release();
471 }
472 
473 // XServiceInfo
474 ::rtl::OUString SAL_CALL DownSearchToolboxController::getImplementationName() throw( css::uno::RuntimeException )
475 {
476     return getImplementationName_Static();
477 }
478 
479 sal_Bool SAL_CALL DownSearchToolboxController::supportsService( const ::rtl::OUString& ServiceName ) throw( css::uno::RuntimeException )
480 {
481     const css::uno::Sequence< ::rtl::OUString > aSNL( getSupportedServiceNames() );
482     const ::rtl::OUString * pArray = aSNL.getConstArray();
483 
484     for( sal_Int32 i = 0; i < aSNL.getLength(); i++ )
485         if( pArray[i] == ServiceName )
486             return true;
487 
488     return false;
489 }
490 
491 css::uno::Sequence< ::rtl::OUString > SAL_CALL DownSearchToolboxController::getSupportedServiceNames() throw( css::uno::RuntimeException )
492 {
493     return getSupportedServiceNames_Static();
494 }
495 
496 css::uno::Sequence< ::rtl::OUString >  DownSearchToolboxController::getSupportedServiceNames_Static() throw()
497 {
498     css::uno::Sequence< ::rtl::OUString > aSNS( 1 );
499     aSNS.getArray()[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.frame.ToolbarController" ));
500     return aSNS;
501 }
502 
503 // XComponent
504 void SAL_CALL DownSearchToolboxController::dispose() throw ( css::uno::RuntimeException )
505 {
506     vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
507 
508     SearchToolbarControllersManager::createControllersManager()->freeController(m_xFrame, css::uno::Reference< css::frame::XStatusListener >(static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY), m_aCommandURL);
509 
510     svt::ToolboxController::dispose();
511 }
512 
513 // XInitialization
514 void SAL_CALL DownSearchToolboxController::initialize( const css::uno::Sequence< css::uno::Any >& aArguments ) throw ( css::uno::Exception, css::uno::RuntimeException )
515 {
516     svt::ToolboxController::initialize( aArguments );
517     SearchToolbarControllersManager::createControllersManager()->registryController(m_xFrame, css::uno::Reference< css::frame::XStatusListener >(static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY), m_aCommandURL);
518 }
519 
520 // XToolbarController
521 void SAL_CALL DownSearchToolboxController::execute( sal_Int16 /*KeyModifier*/ ) throw ( css::uno::RuntimeException)
522 {
523     if ( m_bDisposed )
524         throw css::lang::DisposedException();
525 
526     ::rtl::OUString sFindText;
527     Window* pWindow = VCLUnoHelper::GetWindow( getParent() );
528     ToolBox* pToolBox = (ToolBox*)pWindow;
529     if ( pToolBox )
530     {
531         sal_uInt16 nItemCount = pToolBox->GetItemCount();
532         for ( sal_uInt16 i=0; i<nItemCount; ++i )
533         {
534             ::rtl::OUString sItemCommand = pToolBox->GetItemCommand(i);
535             if ( sItemCommand.equals( COMMAND_FINDTEXT ) )
536             {
537                 Window* pItemWin = pToolBox->GetItemWindow(i);
538                 if (pItemWin)
539                     sFindText = pItemWin->GetText();
540                 break;
541             }
542         }
543     }
544 
545     css::uno::Sequence< css::beans::PropertyValue > lArgs(2);
546     lArgs[0].Name = SEARCHITEM_SEARCHSTRING;
547     lArgs[0].Value <<= sFindText;
548     lArgs[1].Name = SEARCHITEM_SEARCHBACKWARD;
549     lArgs[1].Value <<= sal_False;
550 
551     impl_executeSearch(m_xServiceManager, m_xFrame, lArgs);
552 
553     css::frame::FeatureStateEvent aEvent;
554     aEvent.FeatureURL.Complete = COMMAND_APPENDSEARCHHISTORY;
555     css::uno::Reference< css::frame::XStatusListener > xStatusListener = SearchToolbarControllersManager::createControllersManager()->findController(m_xFrame, COMMAND_FINDTEXT);
556     if (xStatusListener.is())
557         xStatusListener->statusChanged( aEvent );
558 }
559 
560 // XStatusListener
561 void SAL_CALL DownSearchToolboxController::statusChanged( const css::frame::FeatureStateEvent& /*rEvent*/ ) throw ( css::uno::RuntimeException )
562 {
563     vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
564     if ( m_bDisposed )
565         return;
566 }
567 
568 //-----------------------------------------------------------------------------------------------------------
569 // class UpSearchToolboxController
570 
571 UpSearchToolboxController::UpSearchToolboxController( const css::uno::Reference< css::lang::XMultiServiceFactory > & rServiceManager )
572     :svt::ToolboxController( rServiceManager,
573     css::uno::Reference< css::frame::XFrame >(),
574     COMMAND_UPSEARCH )
575 {
576 }
577 
578 UpSearchToolboxController::~UpSearchToolboxController()
579 {
580 }
581 
582 // XInterface
583 css::uno::Any SAL_CALL UpSearchToolboxController::queryInterface( const css::uno::Type& aType ) throw ( css::uno::RuntimeException )
584 {
585     css::uno::Any a = ToolboxController::queryInterface( aType );
586     if ( a.hasValue() )
587         return a;
588 
589     return ::cppu::queryInterface( aType, static_cast< css::lang::XServiceInfo* >( this ) );
590 }
591 
592 void SAL_CALL UpSearchToolboxController::acquire() throw ()
593 {
594     ToolboxController::acquire();
595 }
596 
597 void SAL_CALL UpSearchToolboxController::release() throw ()
598 {
599     ToolboxController::release();
600 }
601 
602 // XServiceInfo
603 ::rtl::OUString SAL_CALL UpSearchToolboxController::getImplementationName() throw( css::uno::RuntimeException )
604 {
605     return getImplementationName_Static();
606 }
607 
608 sal_Bool SAL_CALL UpSearchToolboxController::supportsService( const ::rtl::OUString& ServiceName ) throw( css::uno::RuntimeException )
609 {
610     const css::uno::Sequence< ::rtl::OUString > aSNL( getSupportedServiceNames() );
611     const ::rtl::OUString * pArray = aSNL.getConstArray();
612 
613     for( sal_Int32 i = 0; i < aSNL.getLength(); i++ )
614         if( pArray[i] == ServiceName )
615             return true;
616 
617     return false;
618 }
619 
620 css::uno::Sequence< ::rtl::OUString > SAL_CALL UpSearchToolboxController::getSupportedServiceNames() throw( css::uno::RuntimeException )
621 {
622     return getSupportedServiceNames_Static();
623 }
624 
625 css::uno::Sequence< ::rtl::OUString >  UpSearchToolboxController::getSupportedServiceNames_Static() throw()
626 {
627     css::uno::Sequence< ::rtl::OUString > aSNS( 1 );
628     aSNS.getArray()[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.frame.ToolbarController" ) );
629     return aSNS;
630 }
631 
632 // XComponent
633 void SAL_CALL UpSearchToolboxController::dispose() throw ( css::uno::RuntimeException )
634 {
635     vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
636 
637     SearchToolbarControllersManager::createControllersManager()->freeController(m_xFrame, css::uno::Reference< css::frame::XStatusListener >(static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY), m_aCommandURL);
638 
639     svt::ToolboxController::dispose();
640 }
641 
642 // XInitialization
643 void SAL_CALL UpSearchToolboxController::initialize( const css::uno::Sequence< css::uno::Any >& aArguments ) throw ( css::uno::Exception, css::uno::RuntimeException )
644 {
645     svt::ToolboxController::initialize( aArguments );
646     SearchToolbarControllersManager::createControllersManager()->registryController(m_xFrame, css::uno::Reference< css::frame::XStatusListener >(static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY), m_aCommandURL);
647 }
648 
649 // XToolbarController
650 void SAL_CALL UpSearchToolboxController::execute( sal_Int16 /*KeyModifier*/ ) throw ( css::uno::RuntimeException )
651 {
652     if ( m_bDisposed )
653         throw css::lang::DisposedException();
654 
655     ::rtl::OUString sFindText;
656     Window* pWindow = VCLUnoHelper::GetWindow( getParent() );
657     ToolBox* pToolBox = (ToolBox*)pWindow;
658     if ( pToolBox )
659     {
660         sal_uInt16 nItemCount = pToolBox->GetItemCount();
661         for ( sal_uInt16 i=0; i<nItemCount; ++i )
662         {
663             ::rtl::OUString sItemCommand = pToolBox->GetItemCommand(i);
664             if ( sItemCommand.equals( COMMAND_FINDTEXT ) )
665             {
666                 Window* pItemWin = pToolBox->GetItemWindow(i);
667                 if (pItemWin)
668                     sFindText = pItemWin->GetText();
669                 break;
670             }
671         }
672     }
673 
674     css::uno::Sequence< css::beans::PropertyValue > lArgs(2);
675     lArgs[0].Name = SEARCHITEM_SEARCHSTRING;
676     lArgs[0].Value <<= sFindText;
677     lArgs[1].Name =  SEARCHITEM_SEARCHBACKWARD;
678     lArgs[1].Value <<= sal_True;
679 
680     impl_executeSearch(m_xServiceManager, m_xFrame, lArgs);
681 
682     css::frame::FeatureStateEvent aEvent;
683     aEvent.FeatureURL.Complete = COMMAND_APPENDSEARCHHISTORY;
684     css::uno::Reference< css::frame::XStatusListener > xStatusListener = SearchToolbarControllersManager::createControllersManager()->findController(m_xFrame, COMMAND_FINDTEXT);
685     if (xStatusListener.is())
686         xStatusListener->statusChanged( aEvent );
687 }
688 
689 // XStatusListener
690 void SAL_CALL UpSearchToolboxController::statusChanged( const css::frame::FeatureStateEvent& /*rEvent*/ ) throw ( css::uno::RuntimeException )
691 {
692     vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
693     if ( m_bDisposed )
694         return;
695 }
696 
697 //-----------------------------------------------------------------------------------------------------------
698 // class FindbarDispatcher
699 
700 FindbarDispatcher::FindbarDispatcher(const css::uno::Reference< css::lang::XMultiServiceFactory >& xFactory)
701     : m_xFactory( xFactory )
702 {
703 }
704 
705 FindbarDispatcher::~FindbarDispatcher()
706 {
707     m_xFactory = NULL;
708     m_xFrame = NULL;
709 }
710 
711 // XInterface
712 css::uno::Any SAL_CALL FindbarDispatcher::queryInterface( const css::uno::Type& aType ) throw( css::uno::RuntimeException )
713 {
714     css::uno::Any aReturn( ::cppu::queryInterface( aType,
715         static_cast< css::lang::XServiceInfo* >(this),
716         static_cast< css::lang::XInitialization* >(this),
717         static_cast< css::frame::XDispatchProvider* >(this),
718         static_cast< css::frame::XDispatch* >(this)) );
719 
720     if ( aReturn.hasValue() )
721         return aReturn;
722 
723     return OWeakObject::queryInterface( aType );
724 }
725 
726 void SAL_CALL FindbarDispatcher::acquire() throw()
727 {
728     OWeakObject::acquire();
729 }
730 
731 void SAL_CALL FindbarDispatcher::release() throw()
732 {
733     OWeakObject::release();
734 }
735 
736 // XServiceInfo
737 ::rtl::OUString SAL_CALL FindbarDispatcher::getImplementationName() throw( css::uno::RuntimeException )
738 {
739     return getImplementationName_Static();
740 }
741 
742 sal_Bool SAL_CALL FindbarDispatcher::supportsService( const ::rtl::OUString& ServiceName ) throw( css::uno::RuntimeException )
743 {
744     return (
745         ServiceName.equalsAscii("com.sun.star.comp.svx.FindbarDispatcher") ||
746         ServiceName.equalsAscii("com.sun.star.frame.ProtocolHandler")
747         );
748 }
749 
750 css::uno::Sequence< ::rtl::OUString > SAL_CALL FindbarDispatcher::getSupportedServiceNames() throw( css::uno::RuntimeException )
751 {
752     return getSupportedServiceNames_Static();
753 }
754 
755 css::uno::Sequence< ::rtl::OUString >  FindbarDispatcher::getSupportedServiceNames_Static() throw()
756 {
757     css::uno::Sequence< ::rtl::OUString > aSNS( 2 );
758     aSNS.getArray()[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.svx.FindbarDispatcher" ));
759     aSNS.getArray()[1] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.frame.ProtocolHandler" ));
760     return aSNS;
761 }
762 
763 // XInitialization
764 void SAL_CALL FindbarDispatcher::initialize( const css::uno::Sequence< css::uno::Any >& aArguments ) throw ( css::uno::Exception, css::uno::RuntimeException )
765 {
766     if ( aArguments.getLength() )
767         aArguments[0] >>= m_xFrame;
768 }
769 
770 // XDispatchProvider
771 css::uno::Reference< css::frame::XDispatch > SAL_CALL FindbarDispatcher::queryDispatch( const css::util::URL& aURL, const ::rtl::OUString& /*sTargetFrameName*/, sal_Int32 /*nSearchFlags*/ ) throw( css::uno::RuntimeException )
772 {
773     css::uno::Reference< css::frame::XDispatch > xDispatch;
774 
775     if ( aURL.Protocol.equalsAscii("vnd.sun.star.findbar:") )
776         xDispatch = this;
777 
778     return xDispatch;
779 }
780 
781 css::uno::Sequence < css::uno::Reference< css::frame::XDispatch > > SAL_CALL FindbarDispatcher::queryDispatches( const css::uno::Sequence < css::frame::DispatchDescriptor >& seqDescripts ) throw( css::uno::RuntimeException )
782 {
783     sal_Int32 nCount = seqDescripts.getLength();
784     css::uno::Sequence < css::uno::Reference < XDispatch > > lDispatcher( nCount );
785 
786     for( sal_Int32 i=0; i<nCount; ++i )
787         lDispatcher[i] = queryDispatch( seqDescripts[i].FeatureURL, seqDescripts[i].FrameName, seqDescripts[i].SearchFlags );
788 
789     return lDispatcher;
790 }
791 
792 // XDispatch
793 void SAL_CALL FindbarDispatcher::dispatch( const css::util::URL& aURL, const css::uno::Sequence < css::beans::PropertyValue >& /*lArgs*/ ) throw( css::uno::RuntimeException )
794 {
795     //vnd.sun.star.findbar:FocusToFindbar  - set cursor to the FindTextFieldControl of the findbar
796     if ( aURL.Path.equalsAscii("FocusToFindbar") )
797     {
798         css::uno::Reference< css::beans::XPropertySet > xPropSet(m_xFrame, css::uno::UNO_QUERY);
799         if(!xPropSet.is())
800             return;
801 
802         css::uno::Reference< css::frame::XLayoutManager > xLayoutManager;
803         css::uno::Any aValue = xPropSet->getPropertyValue( ::rtl::OUString::createFromAscii("LayoutManager") );
804         aValue >>= xLayoutManager;
805         if (!xLayoutManager.is())
806             return;
807 
808         const ::rtl::OUString sResourceURL = ::rtl::OUString::createFromAscii("private:resource/toolbar/findbar");
809         css::uno::Reference< css::ui::XUIElement > xUIElement = xLayoutManager->getElement(sResourceURL);
810         if (!xUIElement.is())
811             return;
812 
813         css::uno::Reference< css::awt::XWindow > xWindow(xUIElement->getRealInterface(), css::uno::UNO_QUERY);
814         Window* pWindow = VCLUnoHelper::GetWindow( xWindow );
815         ToolBox* pToolBox = (ToolBox*)pWindow;
816         if ( pToolBox )
817         {
818             sal_uInt16 nItemCount = pToolBox->GetItemCount();
819             for ( sal_uInt16 i=0; i<nItemCount; ++i )
820             {
821                 ::rtl::OUString sItemCommand = pToolBox->GetItemCommand(i);
822                 if ( sItemCommand.equalsAscii(".uno:FindText") )
823                 {
824                     Window* pItemWin = pToolBox->GetItemWindow( i );
825                     if ( pItemWin )
826                     {
827                         pItemWin->GrabFocus();
828                         return;
829                     }
830                 }
831             }
832         }
833 
834     }
835 }
836 
837 void SAL_CALL FindbarDispatcher::addStatusListener( const css::uno::Reference< css::frame::XStatusListener >& /*xControl*/, const css::util::URL& /*aURL*/ ) throw ( css::uno::RuntimeException )
838 {
839 }
840 
841 void SAL_CALL FindbarDispatcher::removeStatusListener( const css::uno::Reference< css::frame::XStatusListener >& /*xControl*/, const css::util::URL& /*aURL*/ ) throw ( css::uno::RuntimeException )
842 {
843 }
844 
845 //-----------------------------------------------------------------------------------------------------------
846 // create Instance
847 
848 css::uno::Reference< css::uno::XInterface > SAL_CALL FindTextToolbarController_createInstance(
849     const css::uno::Reference< css::lang::XMultiServiceFactory >& rSMgr )
850 {
851     return *new FindTextToolbarController( rSMgr );
852 }
853 
854 css::uno::Reference< css::uno::XInterface > SAL_CALL DownSearchToolboxController_createInstance(
855     const css::uno::Reference< css::lang::XMultiServiceFactory >& rSMgr )
856 {
857     return *new DownSearchToolboxController( rSMgr );
858 }
859 
860 css::uno::Reference< css::uno::XInterface > SAL_CALL UpSearchToolboxController_createInstance(
861     const css::uno::Reference< css::lang::XMultiServiceFactory >& rSMgr )
862 {
863     return *new UpSearchToolboxController( rSMgr );
864 }
865 
866 css::uno::Reference< css::uno::XInterface > SAL_CALL FindbarDispatcher_createInstance(
867     const css::uno::Reference< css::lang::XMultiServiceFactory >& rSMgr )
868 {
869     return *new FindbarDispatcher( rSMgr );
870 }
871 
872 //-----------------------------------------------------------------------------------------------------------
873 }
874