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