xref: /trunk/main/sfx2/source/appl/newhelp.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
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_sfx2.hxx"
30 
31 #include "newhelp.hxx"
32 #include <sfx2/sfxuno.hxx>
33 #include "sfx2/sfxresid.hxx"
34 #include "helpinterceptor.hxx"
35 #include "helper.hxx"
36 #include <sfx2/msgpool.hxx>
37 #include <sfx2/app.hxx>
38 #include "sfxtypes.hxx"
39 #include "panelist.hxx"
40 #include "sfx2/imgmgr.hxx"
41 #include "srchdlg.hxx"
42 #include "sfx2/sfxhelp.hxx"
43 
44 #include "app.hrc"
45 #include "newhelp.hrc"
46 #include "helpid.hrc"
47 
48 #include <hash_map>
49 #include <rtl/ustrbuf.hxx>
50 #include <comphelper/processfactory.hxx>
51 #include <comphelper/configurationhelper.hxx>
52 #include <toolkit/helper/vclunohelper.hxx>
53 #include <com/sun/star/util/XModifiable.hpp>
54 #include <com/sun/star/frame/XComponentLoader.hpp>
55 #include <com/sun/star/util/XCloseable.hpp>
56 #include <com/sun/star/util/CloseVetoException.hpp>
57 #include <com/sun/star/lang/XComponent.hpp>
58 #include <com/sun/star/lang/DisposedException.hpp>
59 #include <com/sun/star/awt/PosSize.hpp>
60 #include <com/sun/star/awt/XWindow.hpp>
61 #include <com/sun/star/beans/Property.hpp>
62 #include <com/sun/star/beans/PropertyValue.hpp>
63 #include <com/sun/star/beans/XPropertySetInfo.hpp>
64 #include <com/sun/star/container/XIndexAccess.hpp>
65 #include <com/sun/star/frame/XTitle.hpp>
66 #include <com/sun/star/frame/XLayoutManager.hpp>
67 #include <com/sun/star/frame/DispatchResultState.hpp>
68 #include <com/sun/star/frame/XController.hpp>
69 #include <com/sun/star/frame/XDispatch.hpp>
70 #include <com/sun/star/frame/XDispatchProvider.hpp>
71 #include <com/sun/star/frame/XDispatchProviderInterception.hpp>
72 #include <com/sun/star/frame/XFrame.hpp>
73 #ifndef _COM_SUN_STAR_TEXT_XBREAKITERATOR_HPP_
74 #include <com/sun/star/i18n/XBreakIterator.hpp>
75 #endif
76 #include <com/sun/star/i18n/WordType.hpp>
77 #include <com/sun/star/lang/XComponent.hpp>
78 #include <com/sun/star/style/XStyle.hpp>
79 #include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
80 #include <com/sun/star/text/XText.hpp>
81 #include <com/sun/star/text/XTextCursor.hpp>
82 #include <com/sun/star/text/XTextDocument.hpp>
83 #include <com/sun/star/text/XTextRange.hpp>
84 #include <com/sun/star/text/XTextViewCursor.hpp>
85 #include <com/sun/star/text/XTextViewCursorSupplier.hpp>
86 #include <com/sun/star/ucb/CommandAbortedException.hpp>
87 #include <com/sun/star/util/URL.hpp>
88 #include <com/sun/star/util/XSearchable.hpp>
89 #include <com/sun/star/util/XSearchDescriptor.hpp>
90 #include <com/sun/star/util/XURLTransformer.hpp>
91 #include <com/sun/star/view/XSelectionSupplier.hpp>
92 #include <com/sun/star/view/XViewSettingsSupplier.hpp>
93 #include <com/sun/star/ui/XDockingAreaAcceptor.hpp>
94 #include <svtools/helpopt.hxx>
95 #include <unotools/historyoptions.hxx>
96 #include <svtools/menuoptions.hxx>
97 #include <unotools/pathoptions.hxx>
98 #include <unotools/viewoptions.hxx>
99 #include <svtools/svtdata.hxx>
100 #include <tools/urlobj.hxx>
101 #include <tools/cachestr.hxx>
102 #include <unotools/streamhelper.hxx>
103 #include <svtools/imagemgr.hxx>
104 #include <svtools/miscopt.hxx>
105 #include <svtools/imgdef.hxx>
106 #include <vcl/unohelp.hxx>
107 #include <vcl/i18nhelp.hxx>
108 
109 #include <ucbhelper/content.hxx>
110 #include <vcl/msgbox.hxx>
111 #include <vcl/waitobj.hxx>
112 #include <unotools/ucbhelper.hxx>
113 
114 #include <sfx2/viewfrm.hxx>
115 #include <sfx2/objsh.hxx>
116 #include <sfx2/docfac.hxx>
117 
118 using namespace ::ucbhelper;
119 using namespace ::com::sun::star::ucb;
120 
121 using namespace ::com::sun::star;
122 using namespace ::com::sun::star::beans;
123 using namespace ::com::sun::star::container;
124 using namespace ::com::sun::star::frame;
125 using namespace ::com::sun::star::i18n;
126 using namespace ::com::sun::star::lang;
127 using namespace ::com::sun::star::style;
128 using namespace ::com::sun::star::text;
129 using namespace ::com::sun::star::uno;
130 using namespace ::com::sun::star::util;
131 using namespace ::com::sun::star::view;
132 using namespace ::com::sun::star::ui;
133 
134 using namespace ::comphelper;
135 
136 extern void AppendConfigToken_Impl( String& rURL, sal_Bool bQuestionMark ); // sfxhelp.cxx
137 
138 // defines ---------------------------------------------------------------
139 
140 #define SPLITSET_ID         0
141 #define COLSET_ID           1
142 #define INDEXWIN_ID         2
143 #define TEXTWIN_ID          3
144 
145 #define TOOLBOX_OFFSET      3
146 
147 #define TBI_INDEX           1001
148 #define TBI_BACKWARD        1002
149 #define TBI_FORWARD         1003
150 #define TBI_START           1004
151 #define TBI_PRINT           1005
152 #define TBI_COPY            1006
153 #define TBI_BOOKMARKS       1007
154 #define TBI_SEARCHDIALOG    1008
155 #define TBI_SOURCEVIEW      1009
156 #define TBI_SELECTIONMODE   1010
157 #define TBI_ONSTARTUP       1011
158 
159 #define CONFIGNAME_HELPWIN      DEFINE_CONST_UNICODE("OfficeHelp")
160 #define CONFIGNAME_INDEXWIN     DEFINE_CONST_UNICODE("OfficeHelpIndex")
161 #define CONFIGNAME_SEARCHPAGE   DEFINE_CONST_UNICODE("OfficeHelpSearch")
162 #define IMAGE_URL               DEFINE_CONST_UNICODE("private:factory/")
163 
164 #define PROPERTY_KEYWORDLIST    DEFINE_CONST_OUSTRING("KeywordList")
165 #define PROPERTY_KEYWORDREF     DEFINE_CONST_OUSTRING("KeywordRef")
166 #define PROPERTY_ANCHORREF      DEFINE_CONST_OUSTRING("KeywordAnchorForRef")
167 #define PROPERTY_TITLEREF       DEFINE_CONST_OUSTRING("KeywordTitleForRef")
168 #define PROPERTY_TITLE          DEFINE_CONST_OUSTRING("Title")
169 #define HELP_URL                DEFINE_CONST_OUSTRING("vnd.sun.star.help://")
170 #define HELP_SEARCH_TAG         DEFINE_CONST_OUSTRING("/?Query=")
171 #define USERITEM_NAME           DEFINE_CONST_OUSTRING("UserItem")
172 
173 #define PACKAGE_SETUP           DEFINE_CONST_OUSTRING("/org.openoffice.Setup")
174 #define PATH_OFFICE_FACTORIES   DEFINE_CONST_OUSTRING("Office/Factories/")
175 #define KEY_HELP_ON_OPEN        DEFINE_CONST_OUSTRING("ooSetupFactoryHelpOnOpen")
176 #define KEY_UI_NAME             DEFINE_CONST_OUSTRING("ooSetupFactoryUIName")
177 
178 #define PARSE_URL( aURL ) \
179     Reference < XURLTransformer > xTrans( ::comphelper::getProcessServiceFactory()->createInstance( \
180             DEFINE_CONST_UNICODE("com.sun.star.util.URLTransformer" )), UNO_QUERY ); \
181     xTrans->parseStrict( aURL )
182 
183 //.........................................................................
184 namespace sfx2
185 {
186 //.........................................................................
187 
188     void HandleTaskPaneList( Window* pWindow, sal_Bool bAddToList )
189     {
190         Window* pParent = pWindow->GetParent();
191         DBG_ASSERT( pParent, "HandleTaskPaneList(): every window here should have a parent" );
192 
193         SystemWindow* pSysWin = pParent->GetSystemWindow();
194         if( pSysWin )
195         {
196             TaskPaneList* pTaskPaneList = pSysWin->GetTaskPaneList();
197             if( pTaskPaneList )
198             {
199                 if( bAddToList )
200                     pTaskPaneList->AddWindow( pWindow );
201                 else
202                     pTaskPaneList->RemoveWindow( pWindow );
203             }
204         }
205     }
206 
207     /** Prepare a search string for searching or selecting.
208         For searching every search word needs the postfix '*' and the delimiter ' ' if necessary.
209         For selecting the delimiter '|' is required to search with regular expressions.
210         Samples:
211         search string | output for searching | output for selecting
212         -----------------------------------------------------------
213         "text"        | "text*"              | "text"
214         "text*"       | "text*"              | "text"
215         "text menu"   | "text* menu*"        | "text|menu"
216     */
217     String PrepareSearchString( const String& rSearchString,
218                                 Reference< XBreakIterator > xBreak, bool bForSearch )
219     {
220         String sSearchStr;
221         sal_Int32 nStartPos = 0;
222         const Locale aLocale = Application::GetSettings().GetUILocale();
223         Boundary aBoundary = xBreak->getWordBoundary(
224             rSearchString, nStartPos, aLocale, WordType::ANYWORD_IGNOREWHITESPACES, sal_True );
225 
226         while ( aBoundary.startPos != aBoundary.endPos )
227         {
228             nStartPos = aBoundary.endPos;
229             String sSearchToken( rSearchString.Copy(
230                 (sal_uInt16)aBoundary.startPos, (sal_uInt16)aBoundary.endPos - (sal_uInt16)aBoundary.startPos ) );
231             if ( sSearchToken.Len() > 0 && ( sSearchToken.Len() > 1 || sSearchToken.GetChar(0) != '.' ) )
232             {
233                 if ( bForSearch && sSearchToken.GetChar( sSearchToken.Len() - 1 ) != '*' )
234                     sSearchToken += '*';
235 
236                 if ( sSearchToken.Len() > 1 ||
237                      ( sSearchToken.Len() > 0 && sSearchToken.GetChar( 0 ) != '*' ) )
238                 {
239                     if ( sSearchStr.Len() > 0 )
240                     {
241                         if ( bForSearch )
242                             sSearchStr += ' ';
243                         else
244                             sSearchStr += '|';
245                     }
246                     sSearchStr += sSearchToken;
247                 }
248             }
249             aBoundary = xBreak->nextWord( rSearchString, nStartPos,
250                                           aLocale, WordType::ANYWORD_IGNOREWHITESPACES );
251         }
252 
253         return sSearchStr;
254     }
255 //.........................................................................
256 // namespace sfx2
257 }
258 //.........................................................................
259 
260 // struct IndexEntry_Impl ------------------------------------------------
261 
262 struct IndexEntry_Impl
263 {
264     sal_Bool        m_bSubEntry;
265     String          m_aURL;
266 
267     IndexEntry_Impl( const String& rURL, sal_Bool bSubEntry ) :
268         m_bSubEntry( bSubEntry ), m_aURL( rURL ) {}
269 };
270 
271 #define NEW_ENTRY( url, bool ) \
272     (void*)(sal_uIntPtr)( new IndexEntry_Impl( url, bool ) )
273 
274 // struct ContentEntry_Impl ----------------------------------------------
275 
276 struct ContentEntry_Impl
277 {
278     String      aURL;
279     sal_Bool    bIsFolder;
280 
281     ContentEntry_Impl( const String& rURL, sal_Bool bFolder ) :
282         aURL( rURL ), bIsFolder( bFolder ) {}
283 };
284 
285 // ContentListBox_Impl ---------------------------------------------------
286 
287 ContentListBox_Impl::ContentListBox_Impl( Window* pParent, const ResId& rResId ) :
288 
289     SvTreeListBox( pParent, rResId ),
290 
291     aOpenBookImage      ( SfxResId( IMG_HELP_CONTENT_BOOK_OPEN ) ),
292     aClosedBookImage    ( SfxResId( IMG_HELP_CONTENT_BOOK_CLOSED ) ),
293     aDocumentImage      ( SfxResId( IMG_HELP_CONTENT_DOC ) )
294 
295 {
296     if ( GetSettings().GetStyleSettings().GetHighContrastMode() )
297     {
298         aOpenBookImage = Image( SfxResId( IMG_HELP_CONTENT_BOOK_OPEN_HC ) );
299         aClosedBookImage = Image( SfxResId( IMG_HELP_CONTENT_BOOK_CLOSED_HC ) );
300         aDocumentImage = Image( SfxResId( IMG_HELP_CONTENT_DOC_HC ) );
301     }
302 
303     SetStyle( GetStyle() | WB_HIDESELECTION | WB_HSCROLL );
304 
305     SetEntryHeight( 16 );
306     SetSelectionMode( SINGLE_SELECTION );
307     SetSpaceBetweenEntries( 2 );
308     SetNodeBitmaps( aClosedBookImage, aOpenBookImage );
309 
310     SetSublistOpenWithReturn();
311     SetSublistOpenWithLeftRight();
312 
313     InitRoot();
314 }
315 
316 // -----------------------------------------------------------------------
317 
318 ContentListBox_Impl::~ContentListBox_Impl()
319 {
320     sal_uInt16 nPos = 0;
321     SvLBoxEntry* pEntry = GetEntry( nPos++ );
322     while ( pEntry )
323     {
324         ::rtl::OUString aTemp( GetEntryText( pEntry ) );
325         ClearChildren( pEntry );
326         delete (ContentEntry_Impl*)pEntry->GetUserData();
327         pEntry = GetEntry( nPos++ );
328     }
329 }
330 
331 // -----------------------------------------------------------------------
332 
333 void ContentListBox_Impl::InitRoot()
334 {
335     String aHelpTreeviewURL( DEFINE_CONST_UNICODE("vnd.sun.star.hier://com.sun.star.help.TreeView/") );
336     ::com::sun::star::uno::Sequence< ::rtl::OUString > aList =
337         SfxContentHelper::GetHelpTreeViewContents( aHelpTreeviewURL );
338 
339     const ::rtl::OUString* pEntries  = aList.getConstArray();
340     sal_uInt32 i, nCount = aList.getLength();
341     for ( i = 0; i < nCount; ++i )
342     {
343         String aRow( pEntries[i] );
344         String aTitle, aURL;
345         xub_StrLen nIdx = 0;
346         aTitle = aRow.GetToken( 0, '\t', nIdx );
347         aURL = aRow.GetToken( 0, '\t', nIdx );
348         sal_Unicode cFolder = aRow.GetToken( 0, '\t', nIdx ).GetChar(0);
349         sal_Bool bIsFolder = ( '1' == cFolder );
350         SvLBoxEntry* pEntry = InsertEntry( aTitle, aOpenBookImage, aClosedBookImage, NULL, sal_True );
351         if ( bIsFolder )
352             pEntry->SetUserData( new ContentEntry_Impl( aURL, sal_True ) );
353     }
354 }
355 
356 // -----------------------------------------------------------------------
357 
358 void ContentListBox_Impl::ClearChildren( SvLBoxEntry* pParent )
359 {
360     SvLBoxEntry* pEntry = FirstChild( pParent );
361     while ( pEntry )
362     {
363         ::rtl::OUString aTemp( GetEntryText( pEntry ) );
364         ClearChildren( pEntry );
365         delete (ContentEntry_Impl*)pEntry->GetUserData();
366         pEntry = NextSibling( pEntry );
367     }
368 }
369 
370 // -----------------------------------------------------------------------
371 
372 void ContentListBox_Impl::RequestingChilds( SvLBoxEntry* pParent )
373 {
374     try
375     {
376         if ( !pParent->HasChilds() )
377         {
378             if ( pParent->GetUserData() )
379             {
380                 String aTmpURL( ( (ContentEntry_Impl*)pParent->GetUserData()  )->aURL );
381                 ::com::sun::star::uno::Sequence< ::rtl::OUString > aList =
382                     SfxContentHelper::GetHelpTreeViewContents( aTmpURL );
383 
384                 const ::rtl::OUString* pEntries  = aList.getConstArray();
385                 sal_uInt32 i, nCount = aList.getLength();
386                 for ( i = 0; i < nCount; ++i )
387                 {
388                     String aRow( pEntries[i] );
389                     String aTitle, aURL;
390                     xub_StrLen nIdx = 0;
391                     aTitle = aRow.GetToken( 0, '\t', nIdx );
392                     aURL = aRow.GetToken( 0, '\t', nIdx );
393                     sal_Unicode cFolder = aRow.GetToken( 0, '\t', nIdx ).GetChar(0);
394                     sal_Bool bIsFolder = ( '1' == cFolder );
395                     SvLBoxEntry* pEntry = NULL;
396                     if ( bIsFolder )
397                     {
398                         pEntry = InsertEntry( aTitle, aOpenBookImage, aClosedBookImage, pParent, sal_True );
399                         pEntry->SetUserData( new ContentEntry_Impl( aURL, sal_True ) );
400                     }
401                     else
402                     {
403                         pEntry = InsertEntry( aTitle, aDocumentImage, aDocumentImage, pParent );
404                         Any aAny( ::utl::UCBContentHelper::GetProperty( aURL, String(RTL_CONSTASCII_USTRINGPARAM("TargetURL" ) ) ) );
405                         rtl::OUString aTargetURL;
406                         if ( aAny >>=  aTargetURL )
407                             pEntry->SetUserData( new ContentEntry_Impl( aTargetURL, sal_False ) );
408                     }
409                 }
410             }
411         }
412     }
413     catch( Exception& )
414     {
415         DBG_ERROR( "ContentListBox_Impl::RequestingChilds(): unexpected exception" );
416     }
417 }
418 
419 // -----------------------------------------------------------------------
420 
421 long ContentListBox_Impl::Notify( NotifyEvent& rNEvt )
422 {
423     sal_Bool bHandled = sal_False;
424     if ( rNEvt.GetType() == EVENT_KEYINPUT &&
425          KEY_RETURN == rNEvt.GetKeyEvent()->GetKeyCode().GetCode() )
426     {
427         GetDoubleClickHdl().Call( NULL );
428         bHandled = sal_True;
429     }
430 
431     return bHandled ? 1 : SvTreeListBox::Notify( rNEvt );
432 }
433 
434 // -----------------------------------------------------------------------
435 
436 String ContentListBox_Impl::GetSelectEntry() const
437 {
438     String aRet;
439     SvLBoxEntry* pEntry = FirstSelected();
440     if ( pEntry && !( (ContentEntry_Impl*)pEntry->GetUserData()  )->bIsFolder )
441         aRet = ( (ContentEntry_Impl*)pEntry->GetUserData() )->aURL;
442     return aRet;
443 }
444 
445 // class HelpTabPage_Impl ------------------------------------------------
446 
447 HelpTabPage_Impl::HelpTabPage_Impl(
448     Window* pParent, SfxHelpIndexWindow_Impl* _pIdxWin, const ResId& rResId ) :
449 
450     TabPage( pParent, rResId ),
451 
452     m_pIdxWin( _pIdxWin )
453 
454 {
455 }
456 
457 // class ContentTabPage_Impl ---------------------------------------------
458 
459 ContentTabPage_Impl::ContentTabPage_Impl( Window* pParent, SfxHelpIndexWindow_Impl* _pIdxWin ) :
460 
461     HelpTabPage_Impl( pParent, _pIdxWin, SfxResId( TP_HELP_CONTENT ) ),
462 
463     aContentBox( this, SfxResId( LB_CONTENTS ) )
464 
465 {
466     FreeResource();
467 
468     aContentBox.Show();
469 }
470 
471 // -----------------------------------------------------------------------
472 
473 void ContentTabPage_Impl::Resize()
474 {
475     Size aSize = GetOutputSizePixel();
476     aSize.Width() -= 8;
477     aSize.Height() -= 8;
478     aContentBox.SetPosSizePixel( Point( 4, 4 ), aSize );
479 }
480 
481 // -----------------------------------------------------------------------
482 
483 void ContentTabPage_Impl::ActivatePage()
484 {
485     if ( !m_pIdxWin->WasCursorLeftOrRight() )
486         SetFocusOnBox();
487 }
488 
489 // -----------------------------------------------------------------------
490 
491 Control* ContentTabPage_Impl::GetLastFocusControl()
492 {
493     return &aContentBox;
494 }
495 
496 // class IndexBox_Impl ---------------------------------------------------
497 
498 IndexBox_Impl::IndexBox_Impl( Window* pParent, const ResId& rResId ) :
499 
500     ComboBox( pParent, rResId )
501 
502 {
503     EnableAutocomplete( sal_True );
504     EnableUserDraw( sal_True );
505 }
506 
507 // -----------------------------------------------------------------------
508 
509 void IndexBox_Impl::UserDraw( const UserDrawEvent& rUDEvt )
510 {
511     IndexEntry_Impl* pEntry = (IndexEntry_Impl*)(sal_uIntPtr)GetEntryData( rUDEvt.GetItemId() );
512     if ( pEntry && pEntry->m_bSubEntry )
513     {
514         // indent sub entries
515         Point aPos( rUDEvt.GetRect().TopLeft() );
516         aPos.X() += 8;
517         aPos.Y() += ( rUDEvt.GetRect().GetHeight() - rUDEvt.GetDevice()->GetTextHeight() ) / 2;
518         String aEntry( GetEntry( rUDEvt.GetItemId() ) );
519         sal_uInt16 nPos = aEntry.Search( ';' );
520         rUDEvt.GetDevice()->DrawText( aPos, ( nPos != STRING_NOTFOUND ) ? aEntry.Copy( nPos + 1 ) : aEntry );
521     }
522     else
523         DrawEntry( rUDEvt, sal_False, sal_True, sal_True );
524 }
525 
526 // -----------------------------------------------------------------------
527 
528 long IndexBox_Impl::Notify( NotifyEvent& rNEvt )
529 {
530     sal_Bool bHandled = sal_False;
531     if ( rNEvt.GetType() == EVENT_KEYINPUT &&
532          KEY_RETURN == rNEvt.GetKeyEvent()->GetKeyCode().GetCode() )
533     {
534         GetDoubleClickHdl().Call( NULL );
535         bHandled = sal_True;
536     }
537 
538     return bHandled ? 1 : ComboBox::Notify( rNEvt );
539 }
540 
541 // -----------------------------------------------------------------------
542 
543 void IndexBox_Impl::SelectExecutableEntry()
544 {
545     sal_uInt16 nPos = GetEntryPos( GetText() );
546     if ( nPos != COMBOBOX_ENTRY_NOTFOUND )
547     {
548         sal_uInt16 nOldPos = nPos;
549         String aEntryText;
550         IndexEntry_Impl* pEntry = (IndexEntry_Impl*)(sal_uIntPtr)GetEntryData( nPos );
551         sal_uInt16 nCount = GetEntryCount();
552         while ( nPos < nCount && ( !pEntry || pEntry->m_aURL.Len() == 0 ) )
553         {
554             pEntry = (IndexEntry_Impl*)(sal_uIntPtr)GetEntryData( ++nPos );
555             aEntryText = GetEntry( nPos );
556         }
557 
558         if ( nOldPos != nPos )
559             SetText( aEntryText );
560     }
561 }
562 
563 // class IndexTabPage_Impl -----------------------------------------------
564 
565 IndexTabPage_Impl::IndexTabPage_Impl( Window* pParent, SfxHelpIndexWindow_Impl* _pIdxWin ) :
566 
567     HelpTabPage_Impl( pParent, _pIdxWin, SfxResId( TP_HELP_INDEX ) ),
568 
569     aExpressionFT   ( this, SfxResId( FT_EXPRESSION ) ),
570     aIndexCB        ( this, SfxResId( CB_INDEX ) ),
571     aOpenBtn        ( this, SfxResId( PB_OPEN_INDEX ) ),
572 
573     bIsActivated    ( sal_False )
574 
575 {
576     FreeResource();
577 
578     aOpenBtn.SetClickHdl( LINK( this, IndexTabPage_Impl, OpenHdl ) );
579     Link aTimeoutLink = LINK( this, IndexTabPage_Impl, TimeoutHdl );
580     aFactoryTimer.SetTimeoutHdl( aTimeoutLink );
581     aFactoryTimer.SetTimeout( 300 );
582     aKeywordTimer.SetTimeoutHdl( aTimeoutLink );
583     aFactoryTimer.SetTimeout( 300 );
584 
585     nMinWidth = aOpenBtn.GetSizePixel().Width();
586 }
587 
588 // -----------------------------------------------------------------------
589 
590 IndexTabPage_Impl::~IndexTabPage_Impl()
591 {
592     ClearIndex();
593 }
594 
595 // -----------------------------------------------------------------------
596 
597 namespace sfx2 {
598 
599     struct equalOUString
600     {
601         bool operator()( const ::rtl::OUString& rKey1, const ::rtl::OUString& rKey2 ) const
602         {
603             return !!( rKey1 == rKey2 );
604         }
605     };
606 
607 
608     struct hashOUString
609     {
610         size_t operator()( const ::rtl::OUString& rName ) const
611         {
612             return rName.hashCode();
613         }
614     };
615 
616     typedef ::std::hash_map< ::rtl::OUString, int, hashOUString, equalOUString > KeywordInfo;
617 }
618 
619 #define UNIFY_AND_INSERT_TOKEN( aToken )                                                            \
620     it =                                                                                            \
621     aInfo.insert( sfx2::KeywordInfo::value_type( aToken, 0 ) ).first;                               \
622     if ( ( tmp = it->second++ ) != 0 )                                                              \
623        nPos = aIndexCB.InsertEntry( aToken + rtl::OUString( append, tmp ) );                        \
624     else                                                                                            \
625        nPos = aIndexCB.InsertEntry( aToken )
626 
627 #define INSERT_DATA( j )                                                                            \
628     if ( aAnchorList[j].getLength() > 0 )                                                           \
629     {                                                                                               \
630         aData.append( aRefList[j] ).append( sal_Unicode('#') ).append( aAnchorList[j] );            \
631         aIndexCB.SetEntryData( nPos, NEW_ENTRY( aData.makeStringAndClear(), insert ) );             \
632     }                                                                                               \
633     else                                                                                            \
634         aIndexCB.SetEntryData( nPos, NEW_ENTRY( aRefList[j], insert ) );
635 
636 // -----------------------------------------------------------------------
637 
638 void IndexTabPage_Impl::InitializeIndex()
639 {
640     WaitObject( this );
641 
642     // By now more than 256 equal entries are not allowed
643     sal_Unicode append[256];
644     for( int k = 0; k < 256; ++k )
645         append[k] = sal_Unicode( ' ' );
646 
647     sfx2::KeywordInfo aInfo;
648     aIndexCB.SetUpdateMode( sal_False );
649 
650     try
651     {
652         ::rtl::OUString aURL = HELP_URL;
653         aURL += ::rtl::OUString( sFactory );
654 
655         String aTemp = aURL;
656         AppendConfigToken_Impl( aTemp, sal_True );
657         aURL = aTemp;
658 
659         Content aCnt( aURL, Reference< ::com::sun::star::ucb::XCommandEnvironment > () );
660         ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > xInfo = aCnt.getProperties();
661         if ( xInfo->hasPropertyByName( PROPERTY_ANCHORREF ) )
662         {
663             ::com::sun::star::uno::Sequence< ::rtl::OUString > aPropSeq( 4 );
664             aPropSeq[0] = PROPERTY_KEYWORDLIST;
665             aPropSeq[1] = PROPERTY_KEYWORDREF;
666             aPropSeq[2] = PROPERTY_ANCHORREF;
667             aPropSeq[3] = PROPERTY_TITLEREF;
668 
669             // abi: use one possibly remote call only
670             ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any > aAnySeq =
671                   aCnt.getPropertyValues( aPropSeq );
672 
673             ::com::sun::star::uno::Sequence< ::rtl::OUString > aKeywordList;
674             ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< ::rtl::OUString > > aKeywordRefList;
675             ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< ::rtl::OUString > > aAnchorRefList;
676             ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< ::rtl::OUString > > aTitleRefList;
677 
678             if ( ( aAnySeq[0] >>= aKeywordList ) && ( aAnySeq[1] >>= aKeywordRefList ) &&
679                  ( aAnySeq[2] >>= aAnchorRefList ) && ( aAnySeq[3] >>= aTitleRefList ) )
680             {
681                 sal_Bool insert;
682                 sal_uInt16 nPos;
683                 int ndx,tmp;
684                 ::rtl::OUString aIndex, aTempString;
685                 ::rtl::OUStringBuffer aData( 128 );            // Capacity of up to 128 characters
686                 sfx2::KeywordInfo::iterator it;
687 
688                 for ( int i = 0; i < aKeywordList.getLength(); ++i )
689                 {
690                     // abi: Do not copy, but use references
691                     const ::rtl::OUString& aKeywordPair = aKeywordList[i];
692                     DBG_ASSERT( aKeywordPair.getLength() > 0, "invalid help index" );
693                     const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aRefList = aKeywordRefList[i];
694                     const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aAnchorList = aAnchorRefList[i];
695                     const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aTitleList = aTitleRefList[i];
696 
697                     DBG_ASSERT( aRefList.getLength() == aAnchorList.getLength(),"reference list and title list of different length" );
698 
699                     insert = ( ( ndx = aKeywordPair.indexOf( sal_Unicode( ';' ) ) ) == -1 ? sal_False : sal_True );
700 
701                     if ( insert )
702                     {
703                         aTempString = aKeywordPair.copy( 0, ndx );
704                         if ( aIndex != aTempString )
705                         {
706                             aIndex = aTempString;
707                             UNIFY_AND_INSERT_TOKEN( aTempString );
708                         }
709                     }
710                     else
711                         aIndex = ::rtl::OUString();
712 
713                     // Assume the token is trimed
714                     UNIFY_AND_INSERT_TOKEN( aKeywordPair );
715 
716                     sal_uInt32 nRefListLen = aRefList.getLength();
717 
718                     DBG_ASSERT( aAnchorList.getLength(), "*IndexTabPage_Impl::InitializeIndex(): AnchorList is empty!" );           \
719                     DBG_ASSERT( nRefListLen, "*IndexTabPage_Impl::InitializeIndex(): RefList is empty!" );          \
720 
721                     if ( aAnchorList.getLength() && nRefListLen )
722                     {
723                         INSERT_DATA( 0 );
724                     }
725 
726                     for ( sal_uInt32 j = 1; j < nRefListLen ; ++j )
727                     {
728                         aData
729                             .append( aKeywordPair )
730                             .append( sal_Unicode(' ') )
731                             .append( sal_Unicode('-') )
732                             .append( sal_Unicode(' ') )
733                             .append( aTitleList[j] );
734 
735                         aTempString = aData.makeStringAndClear();
736                         UNIFY_AND_INSERT_TOKEN( aTempString );
737                         INSERT_DATA( j );
738                     }
739                 }
740             }
741         }
742     }
743     catch( Exception& )
744     {
745         DBG_ERROR( "IndexTabPage_Impl::InitializeIndex(): unexpected exception" );
746     }
747 
748     aIndexCB.SetUpdateMode( sal_True );
749 
750     if ( sKeyword.Len() > 0 )
751         aKeywordLink.Call( this );
752 }
753 
754 #undef INSERT_DATA
755 #undef UNIFY_AND_INSERT_TOKEN
756 
757 // -----------------------------------------------------------------------
758 
759 void IndexTabPage_Impl::ClearIndex()
760 {
761     sal_uInt16 nCount = aIndexCB.GetEntryCount();
762     for ( sal_uInt16 i = 0; i < nCount; ++i )
763         delete (IndexEntry_Impl*)(sal_uIntPtr)aIndexCB.GetEntryData(i);
764     aIndexCB.Clear();
765 }
766 
767 // -----------------------------------------------------------------------
768 
769 IMPL_LINK( IndexTabPage_Impl, OpenHdl, PushButton*, EMPTYARG )
770 {
771     aIndexCB.GetDoubleClickHdl().Call( &aIndexCB );
772     return 0;
773 }
774 
775 // -----------------------------------------------------------------------
776 
777 IMPL_LINK( IndexTabPage_Impl, TimeoutHdl, Timer*, pTimer )
778 {
779     if ( &aFactoryTimer == pTimer )
780         InitializeIndex();
781     else if ( &aKeywordTimer == pTimer && sKeyword.Len() > 0 )
782         aKeywordLink.Call( this );
783     return 0;
784 }
785 
786 // -----------------------------------------------------------------------
787 
788 void IndexTabPage_Impl::Resize()
789 {
790     Size aSize = GetSizePixel();
791     if ( aSize.Width() < nMinWidth )
792         aSize.Width() = nMinWidth;
793     Point aPnt = aExpressionFT.GetPosPixel();
794     Size aNewSize = aExpressionFT.GetSizePixel();
795     aNewSize.Width() = aSize.Width() - ( aPnt.X() * 2 );
796     aExpressionFT.SetSizePixel( aNewSize );
797 
798     Size a6Size = LogicToPixel( Size( 6, 6 ), MAP_APPFONT );
799     Size aBtnSize = aOpenBtn.GetSizePixel();
800 
801     aPnt = aIndexCB.GetPosPixel();
802     aNewSize = aIndexCB.GetSizePixel();
803     aNewSize.Width() = aSize.Width() - ( aPnt.X() * 2 );
804     aNewSize.Height() = aSize.Height() - aPnt.Y();
805     aNewSize.Height() -= ( aBtnSize.Height() + ( a6Size.Height() * 3 / 2 ) );
806     aIndexCB.SetSizePixel( aNewSize );
807 
808     aPnt.X() += ( aNewSize.Width() - aBtnSize.Width() );
809     aPnt.Y() += aNewSize.Height() + ( a6Size.Height() / 2 );
810     long nMinX = aIndexCB.GetPosPixel().X();
811     if ( aPnt.X() < nMinX )
812         aPnt.X() = nMinX;
813     aOpenBtn.SetPosPixel( aPnt );
814 }
815 
816 // -----------------------------------------------------------------------
817 
818 void IndexTabPage_Impl::ActivatePage()
819 {
820     if ( !bIsActivated )
821     {
822         bIsActivated = sal_True;
823         aFactoryTimer.Start();
824     }
825 
826     if ( !m_pIdxWin->WasCursorLeftOrRight() )
827         SetFocusOnBox();
828 }
829 
830 // -----------------------------------------------------------------------
831 
832 Control* IndexTabPage_Impl::GetLastFocusControl()
833 {
834     return &aOpenBtn;
835 }
836 
837 // -----------------------------------------------------------------------
838 
839 void IndexTabPage_Impl::SetDoubleClickHdl( const Link& rLink )
840 {
841     aIndexCB.SetDoubleClickHdl( rLink );
842 }
843 
844 // -----------------------------------------------------------------------
845 
846 void IndexTabPage_Impl::SetFactory( const String& rFactory )
847 {
848     String sNewFactory( rFactory );
849     DBG_ASSERT( sNewFactory.Len() > 0, "empty factory" );
850     bool bValid = m_pIdxWin->IsValidFactory( rFactory );
851 
852     if ( sFactory.Len() == 0 && !bValid )
853     {
854         sNewFactory = SfxHelp::GetDefaultHelpModule();
855         bValid = true;
856     }
857 
858     if ( sNewFactory != sFactory && bValid )
859     {
860         sFactory = sNewFactory;
861         ClearIndex();
862         if ( bIsActivated )
863             aFactoryTimer.Start();
864     }
865 }
866 
867 // -----------------------------------------------------------------------
868 
869 String IndexTabPage_Impl::GetSelectEntry() const
870 {
871     String aRet;
872     IndexEntry_Impl* pEntry = (IndexEntry_Impl*)(sal_uIntPtr)aIndexCB.GetEntryData( aIndexCB.GetEntryPos( aIndexCB.GetText() ) );
873     if ( pEntry )
874         aRet = pEntry->m_aURL;
875     return aRet;
876 }
877 
878 // -----------------------------------------------------------------------
879 
880 void IndexTabPage_Impl::SetKeyword( const String& rKeyword )
881 {
882     sKeyword = rKeyword;
883 
884     if ( aIndexCB.GetEntryCount() > 0 )
885         aKeywordTimer.Start();
886     else if ( !bIsActivated )
887         aFactoryTimer.Start();
888 }
889 
890 // -----------------------------------------------------------------------
891 
892 sal_Bool IndexTabPage_Impl::HasKeyword() const
893 {
894     sal_Bool bRet = sal_False;
895     if ( sKeyword.Len() > 0 )
896     {
897         sal_uInt16 nPos = aIndexCB.GetEntryPos( sKeyword );
898         bRet = ( nPos != LISTBOX_ENTRY_NOTFOUND );
899     }
900 
901     return bRet;
902 }
903 
904 // -----------------------------------------------------------------------
905 //added by BerryJia for fixing Bug98251, 2002-12-11
906 sal_Bool IndexTabPage_Impl::HasKeywordIgnoreCase()
907 {
908     sal_Bool bRet = sal_False;
909     if ( sKeyword.Len() > 0 )
910     {
911         sal_uInt16 nEntries = aIndexCB.GetEntryCount();
912         String sIndexItem;
913         const vcl::I18nHelper& rI18nHelper = GetSettings().GetLocaleI18nHelper();
914         for ( sal_uInt16 n = 0; n < nEntries; n++)
915         {
916             sIndexItem = aIndexCB.GetEntry( n );
917             if (rI18nHelper.MatchString( sIndexItem, sKeyword ))
918             {
919                 sKeyword = sIndexItem;
920                 bRet = sal_True;
921             }
922         }
923     }
924 
925     return bRet;
926 }
927 
928 // -----------------------------------------------------------------------
929 
930 void IndexTabPage_Impl::OpenKeyword()
931 {
932     if ( sKeyword.Len() > 0 )
933     {
934         aIndexCB.SetText( sKeyword );
935         aIndexCB.GetDoubleClickHdl().Call( NULL );
936         sKeyword.Erase();
937     }
938 }
939 
940 // class SearchBox_Impl --------------------------------------------------
941 
942 long SearchBox_Impl::PreNotify( NotifyEvent& rNEvt )
943 {
944     sal_Bool bHandled = sal_False;
945     if ( !IsInDropDown() &&
946          rNEvt.GetWindow() == GetSubEdit() &&
947          rNEvt.GetType() == EVENT_KEYINPUT &&
948          KEY_RETURN == rNEvt.GetKeyEvent()->GetKeyCode().GetCode() )
949     {
950         aSearchLink.Call( NULL );
951         bHandled = sal_True;
952     }
953     return bHandled ? 1 : ComboBox::PreNotify( rNEvt );
954 }
955 
956 // -----------------------------------------------------------------------
957 
958 void SearchBox_Impl::Select()
959 {
960     if ( !IsTravelSelect() )
961         aSearchLink.Call( NULL );
962 }
963 
964 // class SearchResultsBox_Impl -------------------------------------------
965 
966 long SearchResultsBox_Impl::Notify( NotifyEvent& rNEvt )
967 {
968     sal_Bool bHandled = sal_False;
969     if ( rNEvt.GetType() == EVENT_KEYINPUT &&
970          KEY_RETURN == rNEvt.GetKeyEvent()->GetKeyCode().GetCode() )
971     {
972         GetDoubleClickHdl().Call( NULL );
973         bHandled = sal_True;
974     }
975 
976     return bHandled ? 1 : ListBox::Notify( rNEvt );
977 }
978 
979 // class SearchTabPage_Impl ----------------------------------------------
980 
981 SearchTabPage_Impl::SearchTabPage_Impl( Window* pParent, SfxHelpIndexWindow_Impl* _pIdxWin ) :
982 
983     HelpTabPage_Impl( pParent, _pIdxWin, SfxResId( TP_HELP_SEARCH ) ),
984 
985     aSearchFT       ( this, SfxResId( FT_SEARCH ) ),
986     aSearchED       ( this, SfxResId( ED_SEARCH ) ),
987     aSearchBtn      ( this, SfxResId( PB_SEARCH ) ),
988     aFullWordsCB    ( this, SfxResId( CB_FULLWORDS ) ),
989     aScopeCB        ( this, SfxResId( CB_SCOPE ) ),
990     aResultsLB      ( this, SfxResId( LB_RESULT ) ),
991     aOpenBtn        ( this, SfxResId( PB_OPEN_SEARCH ) ),
992     xBreakIterator  ( vcl::unohelper::CreateBreakIterator() )
993 
994 {
995     FreeResource();
996 
997     Link aLink = LINK( this, SearchTabPage_Impl, SearchHdl );
998     aSearchED.SetSearchLink( aLink );
999     aSearchBtn.SetClickHdl( aLink );
1000     aSearchED.SetModifyHdl( LINK( this, SearchTabPage_Impl, ModifyHdl ) );
1001     aOpenBtn.SetClickHdl( LINK( this, SearchTabPage_Impl, OpenHdl ) );
1002 
1003     aMinSize = GetSizePixel();
1004 
1005     SvtViewOptions aViewOpt( E_TABPAGE, CONFIGNAME_SEARCHPAGE );
1006     if ( aViewOpt.Exists() )
1007     {
1008         String aUserData;
1009         Any aUserItem = aViewOpt.GetUserItem( USERITEM_NAME );
1010         ::rtl::OUString aTemp;
1011         if ( aUserItem >>= aTemp )
1012         {
1013             aUserData = String( aTemp );
1014             sal_Bool bChecked = ( 1 == aUserData.GetToken(0).ToInt32() ) ? sal_True : sal_False;
1015             aFullWordsCB.Check( bChecked );
1016             bChecked = ( 1 == aUserData.GetToken(1).ToInt32() ) ? sal_True : sal_False;
1017             aScopeCB.Check( bChecked );
1018 
1019             for ( sal_uInt16 i = 2; i < aUserData.GetTokenCount(); ++i )
1020             {
1021                 String aToken = aUserData.GetToken(i);
1022                 aSearchED.InsertEntry( INetURLObject::decode(
1023                     aToken, '%', INetURLObject::DECODE_WITH_CHARSET ) );
1024             }
1025         }
1026     }
1027 
1028     ModifyHdl( &aSearchED );
1029 }
1030 
1031 // -----------------------------------------------------------------------
1032 
1033 SearchTabPage_Impl::~SearchTabPage_Impl()
1034 {
1035     SvtViewOptions aViewOpt( E_TABPAGE, CONFIGNAME_SEARCHPAGE );
1036     sal_Int32 nChecked = aFullWordsCB.IsChecked() ? 1 : 0;
1037     String aUserData = String::CreateFromInt32( nChecked );
1038     aUserData += ';';
1039     nChecked = aScopeCB.IsChecked() ? 1 : 0;
1040     aUserData += String::CreateFromInt32( nChecked );
1041     aUserData += ';';
1042     sal_uInt16 nCount = Min( aSearchED.GetEntryCount(), (sal_uInt16)10 );  // save only 10 entries
1043 
1044     for ( sal_uInt16 i = 0; i < nCount; ++i )
1045     {
1046         rtl::OUString aText = aSearchED.GetEntry(i);
1047         aUserData += String(INetURLObject::encode(
1048             aText, INetURLObject::PART_UNO_PARAM_VALUE, '%',
1049             INetURLObject::ENCODE_ALL ));
1050         aUserData += ';';
1051     }
1052 
1053     aUserData.EraseTrailingChars(';');
1054     Any aUserItem = makeAny( ::rtl::OUString( aUserData ) );
1055     aViewOpt.SetUserItem( USERITEM_NAME, aUserItem );
1056 }
1057 
1058 // -----------------------------------------------------------------------
1059 
1060 void SearchTabPage_Impl::ClearSearchResults()
1061 {
1062     sal_uInt16 nCount = aResultsLB.GetEntryCount();
1063     for ( sal_uInt16 i = 0; i < nCount; ++i )
1064         delete (String*)(sal_uIntPtr)aResultsLB.GetEntryData(i);
1065     aResultsLB.Clear();
1066     aResultsLB.Update();
1067 }
1068 
1069 // -----------------------------------------------------------------------
1070 
1071 void SearchTabPage_Impl::RememberSearchText( const String& rSearchText )
1072 {
1073     for ( sal_uInt16 i = 0; i < aSearchED.GetEntryCount(); ++i )
1074     {
1075         if ( rSearchText == aSearchED.GetEntry(i) )
1076         {
1077             aSearchED.RemoveEntry(i);
1078             break;
1079         }
1080     }
1081 
1082     aSearchED.InsertEntry( rSearchText, 0 );
1083 }
1084 
1085 // -----------------------------------------------------------------------
1086 
1087 IMPL_LINK( SearchTabPage_Impl, SearchHdl, PushButton*, EMPTYARG )
1088 {
1089     String aSearchText = TRIM( aSearchED.GetText() );
1090     if ( aSearchText.Len() > 0 )
1091     {
1092         EnterWait();
1093         ClearSearchResults();
1094         RememberSearchText( aSearchText );
1095         String aSearchURL = HELP_URL;
1096         aSearchURL += aFactory;
1097         aSearchURL += String( HELP_SEARCH_TAG );
1098         if ( !aFullWordsCB.IsChecked() )
1099             aSearchText = sfx2::PrepareSearchString( aSearchText, xBreakIterator, true );
1100         aSearchURL += aSearchText;
1101         AppendConfigToken_Impl( aSearchURL, sal_False );
1102         if ( aScopeCB.IsChecked() )
1103             aSearchURL += DEFINE_CONST_UNICODE("&Scope=Heading");
1104         Sequence< ::rtl::OUString > aFactories = SfxContentHelper::GetResultSet( aSearchURL );
1105         const ::rtl::OUString* pFacs  = aFactories.getConstArray();
1106         sal_uInt32 i, nCount = aFactories.getLength();
1107         for ( i = 0; i < nCount; ++i )
1108         {
1109             String aRow( pFacs[i] );
1110             String aTitle, aType;
1111             xub_StrLen nIdx = 0;
1112             aTitle = aRow.GetToken( 0, '\t', nIdx );
1113             aType = aRow.GetToken( 0, '\t', nIdx );
1114             String* pURL = new String( aRow.GetToken( 0, '\t', nIdx ) );
1115             sal_uInt16 nPos = aResultsLB.InsertEntry( aTitle );
1116             aResultsLB.SetEntryData( nPos, (void*)(sal_uIntPtr)pURL );
1117         }
1118         LeaveWait();
1119 
1120         if ( !nCount )
1121         {
1122             InfoBox aBox( this, SfxResId( RID_INFO_NOSEARCHRESULTS ) );
1123             aBox.SetText( String( SfxResId( STR_HELP_WINDOW_TITLE ) ) );
1124             aBox.Execute();
1125         }
1126     }
1127     return 0;
1128 }
1129 
1130 // -----------------------------------------------------------------------
1131 
1132 IMPL_LINK( SearchTabPage_Impl, OpenHdl, PushButton*, EMPTYARG )
1133 {
1134     aResultsLB.GetDoubleClickHdl().Call( &aResultsLB );
1135     return 0;
1136 }
1137 
1138 // -----------------------------------------------------------------------
1139 
1140 IMPL_LINK( SearchTabPage_Impl, ModifyHdl, Edit*, EMPTYARG )
1141 {
1142     String aSearchText = TRIM( aSearchED.GetText() );
1143     aSearchBtn.Enable( aSearchText.Len() > 0 );
1144     return 0;
1145 }
1146 
1147 // -----------------------------------------------------------------------
1148 
1149 void SearchTabPage_Impl::Resize()
1150 {
1151     Size a6Size = LogicToPixel( Size( 6, 6 ), MAP_APPFONT );
1152     Size aSize = GetSizePixel();
1153     if ( aSize.Width() < aMinSize.Width() )
1154         aSize.Width() = aMinSize.Width();
1155     Point aPnt = aSearchFT.GetPosPixel();
1156     Size aNewSize = aSearchFT.GetSizePixel();
1157     aNewSize.Width() = aSize.Width() - ( aPnt.X() * 2 );
1158     aSearchFT.SetSizePixel( aNewSize );
1159     aNewSize.Height() = aResultsLB.GetSizePixel().Height();
1160     aResultsLB.SetSizePixel( aNewSize );
1161     aNewSize.Height() = aFullWordsCB.GetSizePixel().Height();
1162     aFullWordsCB.SetSizePixel( aNewSize );
1163     aScopeCB.SetSizePixel( aNewSize );
1164     aNewSize = aSearchED.GetSizePixel();
1165     aNewSize.Width() = aSize.Width() - ( aPnt.X() * 2 ) -
1166                        ( aSearchBtn.GetSizePixel().Width() + ( aPnt.X() / 2 ) );
1167     aSearchED.SetSizePixel( aNewSize );
1168     Point aNewPnt = aSearchBtn.GetPosPixel();
1169     aNewPnt.X() = aPnt.X() + aNewSize.Width() + ( aPnt.X() / 2 );
1170     aSearchBtn.SetPosPixel( aNewPnt );
1171 
1172     if ( aSize.Height() > aMinSize.Height() )
1173     {
1174         long n3Height = a6Size.Height() / 2;
1175         Size aBtnSize = aOpenBtn.GetSizePixel();
1176         long nExtraHeight = aBtnSize.Height() + n3Height;
1177 
1178         aPnt = aResultsLB.GetPosPixel();
1179         aNewSize = aResultsLB.GetSizePixel();
1180         aNewSize.Height() = aSize.Height() - aPnt.Y();
1181         aNewSize.Height() -= ( nExtraHeight + ( a6Size.Height() * 3 / 2 ) );
1182         aResultsLB.SetSizePixel( aNewSize );
1183 
1184         aPnt.X() += ( aNewSize.Width() - aBtnSize.Width() );
1185         aPnt.Y() += aNewSize.Height() + a6Size.Height();
1186         aOpenBtn.SetPosPixel( aPnt );
1187     }
1188 }
1189 
1190 // -----------------------------------------------------------------------
1191 
1192 void SearchTabPage_Impl::ActivatePage()
1193 {
1194     if ( !m_pIdxWin->WasCursorLeftOrRight() )
1195         aSearchED.GrabFocus();
1196 }
1197 
1198 // -----------------------------------------------------------------------
1199 
1200 Control* SearchTabPage_Impl::GetLastFocusControl()
1201 {
1202     return &aOpenBtn;
1203 }
1204 
1205 // -----------------------------------------------------------------------
1206 
1207 void SearchTabPage_Impl::SetDoubleClickHdl( const Link& rLink )
1208 {
1209     aResultsLB.SetDoubleClickHdl( rLink );
1210 }
1211 
1212 // -----------------------------------------------------------------------
1213 
1214 String SearchTabPage_Impl::GetSelectEntry() const
1215 {
1216     String aRet;
1217     String* pData = (String*)(sal_uIntPtr)aResultsLB.GetEntryData( aResultsLB.GetSelectEntryPos() );
1218     if ( pData )
1219         aRet = String( *pData );
1220     return aRet;
1221 }
1222 
1223 // -----------------------------------------------------------------------
1224 
1225 void SearchTabPage_Impl::ClearPage()
1226 {
1227     ClearSearchResults();
1228     aSearchED.SetText( String() );
1229 }
1230 
1231 // -----------------------------------------------------------------------
1232 
1233 sal_Bool SearchTabPage_Impl::OpenKeyword( const String& rKeyword )
1234 {
1235     sal_Bool bRet = sal_False;
1236     aSearchED.SetText( rKeyword );
1237     SearchHdl( NULL );
1238     if ( aResultsLB.GetEntryCount() > 0 )
1239     {
1240         // found keyword -> open it
1241         aResultsLB.SelectEntryPos(0);
1242         OpenHdl( NULL );
1243         bRet = sal_True;
1244     }
1245 
1246     return bRet;
1247 }
1248 
1249 // class BookmarksTabPage_Impl -------------------------------------------
1250 
1251 void GetBookmarkEntry_Impl
1252 (
1253     Sequence< PropertyValue >& aBookmarkEntry,
1254     ::rtl::OUString& rTitle,
1255     ::rtl::OUString& rURL
1256 )
1257 {
1258     for ( int i = 0; i < aBookmarkEntry.getLength(); i++ )
1259     {
1260         PropertyValue aValue = aBookmarkEntry[i];
1261         if ( aValue.Name == HISTORY_PROPERTYNAME_URL )
1262             aValue.Value >>= rURL;
1263         else if ( aValue.Name == HISTORY_PROPERTYNAME_TITLE )
1264             aValue.Value >>= rTitle;
1265     }
1266 }
1267 
1268 // -----------------------------------------------------------------------
1269 
1270 BookmarksBox_Impl::BookmarksBox_Impl( Window* pParent, const ResId& rResId ) :
1271 
1272     ListBox( pParent, rResId )
1273 
1274 {
1275 }
1276 
1277 // -----------------------------------------------------------------------
1278 
1279 BookmarksBox_Impl::~BookmarksBox_Impl()
1280 {
1281     // save bookmarks to configuration
1282     SvtHistoryOptions aHistOpt;
1283     aHistOpt.Clear( eHELPBOOKMARKS );
1284     rtl::OUString sEmpty;
1285     sal_uInt16 nCount = GetEntryCount();
1286     for ( sal_uInt16 i = 0; i < nCount; ++i )
1287     {
1288         String aTitle = GetEntry(i);
1289         String* pURL = (String*)(sal_uIntPtr)GetEntryData(i);
1290         aHistOpt.AppendItem( eHELPBOOKMARKS, rtl::OUString( *pURL ), sEmpty, rtl::OUString( aTitle ), sEmpty );
1291         delete pURL;
1292     }
1293 }
1294 
1295 // -----------------------------------------------------------------------
1296 
1297 void BookmarksBox_Impl::DoAction( sal_uInt16 nAction )
1298 {
1299     switch ( nAction )
1300     {
1301         case MID_OPEN :
1302             GetDoubleClickHdl().Call( NULL );
1303             break;
1304 
1305         case MID_RENAME :
1306         {
1307             sal_uInt16 nPos = GetSelectEntryPos();
1308             if ( nPos != LISTBOX_ENTRY_NOTFOUND )
1309             {
1310                 SfxAddHelpBookmarkDialog_Impl aDlg( this, sal_True );
1311                 aDlg.SetTitle( GetEntry( nPos ) );
1312                 if ( aDlg.Execute() == RET_OK )
1313                 {
1314                     String* pURL = (String*)(sal_uIntPtr)GetEntryData( nPos );
1315                     RemoveEntry( nPos );
1316                     rtl::OUString aImageURL = IMAGE_URL;
1317                     aImageURL += INetURLObject( *pURL ).GetHost();
1318                     nPos = InsertEntry( aDlg.GetTitle(), SvFileInformationManager::GetImage( aImageURL ) );
1319                     SetEntryData( nPos, (void*)(sal_uIntPtr)( new String( *pURL ) ) );
1320                     SelectEntryPos( nPos );
1321                     delete pURL;
1322                 }
1323             }
1324             break;
1325         }
1326 
1327         case MID_DELETE :
1328         {
1329             sal_uInt16 nPos = GetSelectEntryPos();
1330             if ( nPos != LISTBOX_ENTRY_NOTFOUND )
1331             {
1332                 RemoveEntry( nPos );
1333                 sal_uInt16 nCount = GetEntryCount();
1334                 if ( nCount )
1335                 {
1336                     if ( nPos >= nCount )
1337                         nPos = nCount - 1;
1338                     SelectEntryPos( nPos );
1339                 }
1340             }
1341             break;
1342         }
1343     }
1344 }
1345 
1346 // -----------------------------------------------------------------------
1347 
1348 long BookmarksBox_Impl::Notify( NotifyEvent& rNEvt )
1349 {
1350     long nRet = 0;
1351     sal_uInt16 nType = rNEvt.GetType();
1352     if ( EVENT_KEYINPUT == nType )
1353     {
1354         sal_uInt16 nCode = rNEvt.GetKeyEvent()->GetKeyCode().GetCode();
1355         if ( KEY_DELETE == nCode && GetEntryCount() > 0 )
1356         {
1357             DoAction( MID_DELETE );
1358             nRet = 1;
1359         }
1360         else if ( KEY_RETURN == nCode )
1361         {
1362             GetDoubleClickHdl().Call( NULL );
1363             nRet = 1;
1364         }
1365     }
1366     else if ( EVENT_COMMAND == nType )
1367     {
1368         const CommandEvent* pCEvt = rNEvt.GetCommandEvent();
1369         if ( pCEvt->GetCommand() == COMMAND_CONTEXTMENU )
1370         {
1371             PopupMenu aMenu( SfxResId( MENU_HELP_BOOKMARKS ) );
1372             sal_uInt16 nId = aMenu.Execute( this, pCEvt->GetMousePosPixel() );
1373             if ( nId != MENU_ITEM_NOTFOUND )
1374                 DoAction( nId );
1375             nRet = 1;
1376         }
1377     }
1378 
1379     return nRet ? nRet : ListBox::Notify( rNEvt );
1380 }
1381 
1382 // class BookmarksTabPage_Impl -------------------------------------------
1383 
1384 BookmarksTabPage_Impl::BookmarksTabPage_Impl( Window* pParent, SfxHelpIndexWindow_Impl* _pIdxWin ) :
1385 
1386     HelpTabPage_Impl( pParent, _pIdxWin, SfxResId( TP_HELP_BOOKMARKS ) ),
1387 
1388     aBookmarksFT    ( this, SfxResId( FT_BOOKMARKS ) ),
1389     aBookmarksBox   ( this, SfxResId( LB_BOOKMARKS ) ),
1390     aBookmarksPB    ( this, SfxResId( PB_BOOKMARKS ) )
1391 
1392 {
1393     FreeResource();
1394 
1395     nMinWidth = aBookmarksPB.GetSizePixel().Width();
1396 
1397     aBookmarksPB.SetClickHdl( LINK( this, BookmarksTabPage_Impl, OpenHdl ) );
1398 
1399     // load bookmarks from configuration
1400     Sequence< Sequence< PropertyValue > > aBookmarkSeq;
1401     aBookmarkSeq = SvtHistoryOptions().GetList( eHELPBOOKMARKS );
1402 
1403     ::rtl::OUString aTitle;
1404     ::rtl::OUString aURL;
1405 
1406     sal_uInt32 i, nCount = aBookmarkSeq.getLength();
1407     for ( i = 0; i < nCount; ++i )
1408     {
1409         GetBookmarkEntry_Impl( aBookmarkSeq[i], aTitle, aURL );
1410         AddBookmarks( aTitle, aURL );
1411     }
1412 }
1413 
1414 // -----------------------------------------------------------------------
1415 
1416 IMPL_LINK( BookmarksTabPage_Impl, OpenHdl, PushButton*, EMPTYARG )
1417 {
1418     aBookmarksBox.GetDoubleClickHdl().Call( &aBookmarksBox );
1419     return 0;
1420 }
1421 
1422 // -----------------------------------------------------------------------
1423 
1424 void BookmarksTabPage_Impl::Resize()
1425 {
1426     Size aSize = GetSizePixel();
1427     if ( aSize.Width() < nMinWidth )
1428         aSize.Width() = nMinWidth;
1429     Point aPnt = aBookmarksFT.GetPosPixel();
1430     Size aNewSize = aBookmarksFT.GetSizePixel();
1431     aNewSize.Width() = aSize.Width() - ( aPnt.X() * 2 );
1432     aBookmarksFT.SetSizePixel( aNewSize );
1433 
1434     Size a6Size = LogicToPixel( Size( 6, 6 ), MAP_APPFONT );
1435     Size aBtnSize = aBookmarksPB.GetSizePixel();
1436 
1437     aPnt = aBookmarksBox.GetPosPixel();
1438     aNewSize = aBookmarksBox.GetSizePixel();
1439     aNewSize.Width() = aSize.Width() - ( aPnt.X() * 2 );
1440     aNewSize.Height() = aSize.Height() - aPnt.Y();
1441     aNewSize.Height() -= ( aBtnSize.Height() + ( a6Size.Height() * 3 / 2 ) );
1442     aBookmarksBox.SetSizePixel( aNewSize );
1443 
1444     aPnt.X() += ( aNewSize.Width() - aBtnSize.Width() );
1445     aPnt.Y() += aNewSize.Height() + ( a6Size.Height() / 2 );
1446     long nMinX = aBookmarksBox.GetPosPixel().X();
1447     if ( aPnt.X() < nMinX )
1448         aPnt.X() = nMinX;
1449     aBookmarksPB.SetPosPixel( aPnt );
1450 }
1451 
1452 // -----------------------------------------------------------------------
1453 
1454 void BookmarksTabPage_Impl::ActivatePage()
1455 {
1456     if ( !m_pIdxWin->WasCursorLeftOrRight() )
1457         SetFocusOnBox();
1458 }
1459 
1460 // -----------------------------------------------------------------------
1461 
1462 Control* BookmarksTabPage_Impl::GetLastFocusControl()
1463 {
1464     return &aBookmarksPB;
1465 }
1466 
1467 // -----------------------------------------------------------------------
1468 
1469 void BookmarksTabPage_Impl::SetDoubleClickHdl( const Link& rLink )
1470 {
1471     aBookmarksBox.SetDoubleClickHdl( rLink );
1472 }
1473 
1474 // -----------------------------------------------------------------------
1475 
1476 String BookmarksTabPage_Impl::GetSelectEntry() const
1477 {
1478     String aRet;
1479     String* pData = (String*)(sal_uIntPtr)aBookmarksBox.GetEntryData( aBookmarksBox.GetSelectEntryPos() );
1480     if ( pData )
1481         aRet = String( *pData );
1482     return aRet;
1483 }
1484 
1485 // -----------------------------------------------------------------------
1486 
1487 void BookmarksTabPage_Impl::AddBookmarks( const String& rTitle, const String& rURL )
1488 {
1489     rtl::OUString aImageURL = IMAGE_URL;
1490     aImageURL += INetURLObject( rURL ).GetHost();
1491     sal_uInt16 nPos = aBookmarksBox.InsertEntry( rTitle, SvFileInformationManager::GetImage( aImageURL ) );
1492     aBookmarksBox.SetEntryData( nPos, (void*)(sal_uIntPtr)( new String( rURL ) ) );
1493 }
1494 
1495 // class SfxHelpIndexWindow_Impl -----------------------------------------
1496 
1497 sal_Bool SfxHelpWindow_Impl::splitHelpURL(const ::rtl::OUString& sHelpURL,
1498                                                 ::rtl::OUString& sFactory,
1499                                                 ::rtl::OUString& sContent,
1500                                                 ::rtl::OUString& sAnchor )
1501 {
1502     Reference < XURLTransformer > xParser( ::comphelper::getProcessServiceFactory()->createInstance(
1503             DEFINE_CONST_UNICODE("com.sun.star.util.URLTransformer" )), UNO_QUERY_THROW );
1504 
1505     URL aURL;
1506     aURL.Complete = sHelpURL;
1507     sal_Bool bResult = xParser->parseStrict(aURL);
1508 
1509     sFactory = aURL.Server;
1510     sContent = aURL.Path.copy(1); // strip "/"!
1511     sAnchor  = aURL.Mark;
1512 
1513     return bResult;
1514 }
1515 
1516 ::rtl::OUString SfxHelpWindow_Impl::buildHelpURL(const ::rtl::OUString& sFactory        ,
1517                                                  const ::rtl::OUString& sContent        ,
1518                                                  const ::rtl::OUString& sAnchor         ,
1519                                                        sal_Bool         bUseQuestionMark)
1520 {
1521     ::rtl::OUStringBuffer sHelpURL(256);
1522     sHelpURL.append(HELP_URL);
1523     sHelpURL.append(sFactory);
1524     sHelpURL.append(sContent);
1525     String sURL = String(sHelpURL.makeStringAndClear());
1526     AppendConfigToken_Impl(sURL, bUseQuestionMark);
1527     if (sAnchor.getLength())
1528         sURL += String(sAnchor);
1529     return ::rtl::OUString(sURL);
1530 }
1531 
1532 void SfxHelpWindow_Impl::loadHelpContent(const ::rtl::OUString& sHelpURL, sal_Bool bAddToHistory)
1533 {
1534     Reference< XComponentLoader > xLoader(getTextFrame(), UNO_QUERY);
1535     if (!xLoader.is())
1536         return;
1537 
1538     // --> PB 2007-03-12 #134037#
1539     // If a print job runs do not open a new page
1540     Reference< XFrame >      xTextFrame      = pTextWin->getFrame();
1541     Reference< XController > xTextController ;
1542     if (xTextFrame.is())
1543         xTextController = xTextFrame->getController ();
1544     if ( xTextController.is() && !xTextController->suspend( sal_True ) )
1545     {
1546         xTextController->suspend( sal_False );
1547         return;
1548     }
1549     // <--
1550 
1551     // save url to history
1552     if (bAddToHistory)
1553         pHelpInterceptor->addURL(sHelpURL);
1554 
1555     if ( !IsWait() )
1556         EnterWait();
1557     sal_Bool bSuccess = sal_False;
1558 // TODO implement locale fallback ... see below    while(sal_True)
1559     {
1560         try
1561         {
1562             Reference< XComponent > xContent = xLoader->loadComponentFromURL(sHelpURL, DEFINE_CONST_UNICODE("_self"), 0, Sequence< PropertyValue >());
1563             if (xContent.is())
1564             {
1565                 bSuccess = sal_True;
1566 //                break;
1567             }
1568         }
1569         catch(const RuntimeException&)
1570             { throw; }
1571         catch(const Exception&)
1572             { /*break;*/ }
1573 
1574         /* TODO try next locale ...
1575                 no further locale available? => break loop and show error page
1576         */
1577     }
1578     openDone(sHelpURL, bSuccess);
1579     if ( IsWait() )
1580         LeaveWait();
1581 }
1582 
1583 SfxHelpIndexWindow_Impl::SfxHelpIndexWindow_Impl( SfxHelpWindow_Impl* _pParent ) :
1584 
1585     Window( _pParent, SfxResId( WIN_HELPINDEX ) ),
1586 
1587     aActiveLB           ( this, SfxResId( LB_ACTIVE ) ),
1588     aActiveLine         ( this, SfxResId( FL_ACTIVE ) ),
1589     aTabCtrl            ( this, SfxResId( TC_INDEX ) ),
1590 
1591     aIndexKeywordLink   ( LINK( this, SfxHelpIndexWindow_Impl, KeywordHdl ) ),
1592     pParentWin          ( _pParent ),
1593 
1594     pCPage              ( NULL ),
1595     pIPage              ( NULL ),
1596     pSPage              ( NULL ),
1597     pBPage              ( NULL ),
1598 
1599     bWasCursorLeftOrRight( false ),
1600     bIsInitDone          ( false )
1601 
1602 {
1603     FreeResource();
1604 
1605     sfx2::AddToTaskPaneList( this );
1606 
1607     aTabCtrl.SetActivatePageHdl( LINK( this, SfxHelpIndexWindow_Impl, ActivatePageHdl ) );
1608     aTabCtrl.Show();
1609 
1610     sal_Int32 nPageId = HELP_INDEX_PAGE_INDEX;
1611     SvtViewOptions aViewOpt( E_TABDIALOG, CONFIGNAME_INDEXWIN );
1612     if ( aViewOpt.Exists() )
1613         nPageId = aViewOpt.GetPageID();
1614     aTabCtrl.SetCurPageId( (sal_uInt16)nPageId );
1615     ActivatePageHdl( &aTabCtrl );
1616     aActiveLB.SetSelectHdl( LINK( this, SfxHelpIndexWindow_Impl, SelectHdl ) );
1617     nMinWidth = ( aActiveLB.GetSizePixel().Width() / 2 );
1618 
1619     aTimer.SetTimeoutHdl( LINK( this, SfxHelpIndexWindow_Impl, InitHdl ) );
1620     aTimer.SetTimeout( 200 );
1621     aTimer.Start();
1622 }
1623 
1624 // -----------------------------------------------------------------------
1625 
1626 SfxHelpIndexWindow_Impl::~SfxHelpIndexWindow_Impl()
1627 {
1628     sfx2::RemoveFromTaskPaneList( this );
1629 
1630     DELETEZ( pCPage );
1631     DELETEZ( pIPage );
1632     DELETEZ( pSPage );
1633     DELETEZ( pBPage );
1634 
1635     for ( sal_uInt16 i = 0; i < aActiveLB.GetEntryCount(); ++i )
1636         delete (String*)(sal_uIntPtr)aActiveLB.GetEntryData(i);
1637 
1638     SvtViewOptions aViewOpt( E_TABDIALOG, CONFIGNAME_INDEXWIN );
1639     aViewOpt.SetPageID( (sal_Int32)aTabCtrl.GetCurPageId() );
1640 }
1641 
1642 // -----------------------------------------------------------------------
1643 
1644 void SfxHelpIndexWindow_Impl::Initialize()
1645 {
1646     String aHelpURL = HELP_URL;
1647     AppendConfigToken_Impl( aHelpURL, sal_True );
1648     Sequence< ::rtl::OUString > aFactories = SfxContentHelper::GetResultSet( aHelpURL );
1649     const ::rtl::OUString* pFacs  = aFactories.getConstArray();
1650     sal_uInt32 i, nCount = aFactories.getLength();
1651     for ( i = 0; i < nCount; ++i )
1652     {
1653         String aRow( pFacs[i] );
1654         String aTitle, aType, aURL;
1655         xub_StrLen nIdx = 0;
1656         aTitle = aRow.GetToken( 0, '\t', nIdx );
1657         aType = aRow.GetToken( 0, '\t', nIdx );
1658         aURL = aRow.GetToken( 0, '\t', nIdx );
1659         String* pFactory = new String( INetURLObject( aURL ).GetHost() );
1660         sal_uInt16 nPos = aActiveLB.InsertEntry( aTitle );
1661         aActiveLB.SetEntryData( nPos, (void*)(sal_uIntPtr)pFactory );
1662     }
1663 
1664     aActiveLB.SetDropDownLineCount( (sal_uInt16)nCount );
1665     if ( aActiveLB.GetSelectEntryPos() == LISTBOX_ENTRY_NOTFOUND )
1666         SetActiveFactory();
1667 }
1668 
1669 // -----------------------------------------------------------------------
1670 
1671 void SfxHelpIndexWindow_Impl::SetActiveFactory()
1672 {
1673     DBG_ASSERT( pIPage, "index page not initialized" );
1674     if ( !bIsInitDone && !aActiveLB.GetEntryCount() )
1675     {
1676         aTimer.Stop();
1677         InitHdl( NULL );
1678     }
1679 
1680     for ( sal_uInt16 i = 0; i < aActiveLB.GetEntryCount(); ++i )
1681     {
1682         String* pFactory = (String*)(sal_uIntPtr)aActiveLB.GetEntryData(i);
1683         pFactory->ToLowerAscii();
1684         if ( *pFactory == pIPage->GetFactory() )
1685         {
1686             if ( aActiveLB.GetSelectEntryPos() != i )
1687             {
1688                 aActiveLB.SelectEntryPos(i);
1689                 aSelectFactoryLink.Call( NULL );
1690             }
1691             break;
1692         }
1693     }
1694 }
1695 
1696 // -----------------------------------------------------------------------
1697 
1698 HelpTabPage_Impl* SfxHelpIndexWindow_Impl::GetCurrentPage( sal_uInt16& rCurId )
1699 {
1700     rCurId = aTabCtrl.GetCurPageId();
1701     HelpTabPage_Impl* pPage = NULL;
1702 
1703     switch ( rCurId )
1704     {
1705         case HELP_INDEX_PAGE_CONTENTS:
1706         {
1707             pPage = GetContentPage();
1708             break;
1709         }
1710 
1711         case HELP_INDEX_PAGE_INDEX:
1712         {
1713             pPage = GetIndexPage();
1714             break;
1715         }
1716 
1717         case HELP_INDEX_PAGE_SEARCH:
1718         {
1719             pPage = GetSearchPage();
1720             break;
1721         }
1722 
1723         case HELP_INDEX_PAGE_BOOKMARKS:
1724         {
1725             pPage = GetBookmarksPage();
1726             break;
1727         }
1728     }
1729 
1730     DBG_ASSERT( pPage, "SfxHelpIndexWindow_Impl::GetCurrentPage(): no current page" );
1731     return pPage;
1732 }
1733 
1734 // -----------------------------------------------------------------------
1735 
1736 IMPL_LINK( SfxHelpIndexWindow_Impl, ActivatePageHdl, TabControl *, pTabCtrl )
1737 {
1738     sal_uInt16 nId = 0;
1739     TabPage* pPage = GetCurrentPage( nId );
1740     pTabCtrl->SetTabPage( nId, pPage );
1741     return 0;
1742 }
1743 
1744 // -----------------------------------------------------------------------
1745 
1746 IMPL_LINK( SfxHelpIndexWindow_Impl, SelectHdl, ListBox *, EMPTYARG )
1747 {
1748     aTimer.Start();
1749 
1750     return 0;
1751 }
1752 
1753 // -----------------------------------------------------------------------
1754 
1755 IMPL_LINK( SfxHelpIndexWindow_Impl, InitHdl, Timer *, EMPTYARG )
1756 {
1757     bIsInitDone = true;
1758     Initialize();
1759 
1760     // now use the timer for selection
1761     aTimer.SetTimeoutHdl( LINK( this, SfxHelpIndexWindow_Impl, SelectFactoryHdl ) );
1762     aTimer.SetTimeout( 1000 );
1763 
1764     return 0;
1765 }
1766 
1767 // -----------------------------------------------------------------------
1768 
1769 IMPL_LINK( SfxHelpIndexWindow_Impl, SelectFactoryHdl, Timer *, EMPTYARG )
1770 {
1771     String* pFactory = (String*)(sal_uIntPtr)aActiveLB.GetEntryData( aActiveLB.GetSelectEntryPos() );
1772     if ( pFactory )
1773     {
1774         String aFactory( *pFactory );
1775         aFactory.ToLowerAscii();
1776         SetFactory( aFactory, sal_False );
1777         aSelectFactoryLink.Call( this );
1778     }
1779 
1780     return 0;
1781 }
1782 
1783 // -----------------------------------------------------------------------
1784 
1785 IMPL_LINK( SfxHelpIndexWindow_Impl, KeywordHdl, IndexTabPage_Impl *, EMPTYARG )
1786 {
1787     // keyword found on index?
1788     sal_Bool bIndex = pIPage->HasKeyword();
1789     //The following two lines are added by BerryJia for fixing Bug98251, 2002-12-11
1790     if( !bIndex)
1791         bIndex = pIPage->HasKeywordIgnoreCase();
1792     // then set index or search page as current.
1793     sal_uInt16 nPageId = ( bIndex ) ? HELP_INDEX_PAGE_INDEX :  HELP_INDEX_PAGE_SEARCH;
1794     if ( nPageId != aTabCtrl.GetCurPageId() )
1795     {
1796         aTabCtrl.SetCurPageId( nPageId );
1797         ActivatePageHdl( &aTabCtrl );
1798     }
1799 
1800     // at last we open the keyword
1801     if ( bIndex )
1802         pIPage->OpenKeyword();
1803     else if ( !pSPage->OpenKeyword( sKeyword ) )
1804         pParentWin->ShowStartPage();
1805 
1806     return 0;
1807 }
1808 
1809 // -----------------------------------------------------------------------
1810 
1811 void SfxHelpIndexWindow_Impl::Resize()
1812 {
1813     Size aSize = GetOutputSizePixel();
1814     if ( aSize.Width() < nMinWidth )
1815         aSize.Width() = nMinWidth;
1816 
1817     Point aPnt = aActiveLB.GetPosPixel();
1818     Size aNewSize = aActiveLB.GetSizePixel();
1819     aNewSize.Width() = aSize.Width() - ( aPnt.X() * 2 );
1820     aActiveLB.SetSizePixel( aNewSize );
1821     aPnt = aActiveLine.GetPosPixel();
1822     aNewSize = aActiveLine.GetSizePixel();
1823     aNewSize.Width() = aSize.Width() - ( aPnt.X() * 2 );
1824     aActiveLine.SetSizePixel( aNewSize );
1825     aPnt = aTabCtrl.GetPosPixel();
1826     aNewSize = aSize;
1827     aSize.Width() -= aPnt.X();
1828     aSize.Height() -= aPnt.Y();
1829     aTabCtrl.SetSizePixel( aSize );
1830 }
1831 
1832 // -----------------------------------------------------------------------
1833 
1834 long SfxHelpIndexWindow_Impl::PreNotify( NotifyEvent& rNEvt )
1835 {
1836     long nDone = 0;
1837     sal_uInt16 nType = rNEvt.GetType();
1838     if ( EVENT_KEYINPUT == nType && rNEvt.GetKeyEvent() )
1839     {
1840         const KeyCode& rKeyCode = rNEvt.GetKeyEvent()->GetKeyCode();
1841         sal_uInt16 nCode = rKeyCode.GetCode();
1842 
1843         if (  KEY_TAB == nCode )
1844         {
1845             // don't exit index pane with <TAB>
1846             sal_uInt16 nPageId = 0;
1847             HelpTabPage_Impl* pCurPage = GetCurrentPage( nPageId );
1848             Control* pControl = pCurPage->GetLastFocusControl();
1849             sal_Bool bShift = rKeyCode.IsShift();
1850             sal_Bool bCtrl = rKeyCode.IsMod1();
1851             if ( !bCtrl && bShift && aActiveLB.HasChildPathFocus() )
1852             {
1853                 pControl->GrabFocus();
1854                 nDone = 1;
1855             }
1856             else if ( !bCtrl && !bShift && pControl->HasChildPathFocus() )
1857             {
1858                 aActiveLB.GrabFocus();
1859                 nDone = 1;
1860             }
1861             else if ( bCtrl )
1862             {
1863                 // <STRG><TAB> moves through the pages
1864                 if ( nPageId < HELP_INDEX_PAGE_LAST )
1865                     nPageId++;
1866                 else
1867                     nPageId = HELP_INDEX_PAGE_FIRST;
1868                 aTabCtrl.SetCurPageId( (sal_uInt16)nPageId );
1869                 ActivatePageHdl( &aTabCtrl );
1870                 nDone = 1;
1871             }
1872         }
1873         else if ( aTabCtrl.HasFocus() && ( KEY_LEFT == nCode || KEY_RIGHT == nCode ) )
1874         {
1875             bWasCursorLeftOrRight = true;
1876         }
1877     }
1878 
1879     return nDone ? nDone : Window::PreNotify( rNEvt );
1880 }
1881 
1882 // -----------------------------------------------------------------------
1883 
1884 void SfxHelpIndexWindow_Impl::DataChanged( const DataChangedEvent& rDCEvt )
1885 {
1886     Window::DataChanged( rDCEvt );
1887 
1888     if ( ( ( rDCEvt.GetType() == DATACHANGED_SETTINGS ) ||
1889            ( rDCEvt.GetType() == DATACHANGED_DISPLAY ) ) &&
1890          ( rDCEvt.GetFlags() & SETTINGS_STYLE ) )
1891     {
1892         SetBackground( Wallpaper( GetSettings().GetStyleSettings().GetFaceColor() ) );
1893     }
1894 }
1895 
1896 // -----------------------------------------------------------------------
1897 
1898 void SfxHelpIndexWindow_Impl::SetDoubleClickHdl( const Link& rLink )
1899 {
1900     aPageDoubleClickLink = rLink;
1901     if ( pCPage )
1902         pCPage->SetOpenHdl( aPageDoubleClickLink );
1903     if ( pIPage )
1904         pIPage->SetDoubleClickHdl( aPageDoubleClickLink );
1905     if ( pSPage )
1906         pSPage->SetDoubleClickHdl( aPageDoubleClickLink );
1907     if ( pBPage )
1908         pBPage->SetDoubleClickHdl( aPageDoubleClickLink );
1909 }
1910 
1911 // -----------------------------------------------------------------------
1912 
1913 void SfxHelpIndexWindow_Impl::SetFactory( const String& rFactory, sal_Bool bActive )
1914 {
1915     if ( rFactory.Len() > 0 )
1916     {
1917         GetIndexPage()->SetFactory( rFactory );
1918         // the index page did a check if rFactory is valid,
1919         // so the index page always returns a valid factory
1920         GetSearchPage()->SetFactory( GetIndexPage()->GetFactory() );
1921         if ( bActive )
1922             SetActiveFactory();
1923     }
1924 }
1925 
1926 // -----------------------------------------------------------------------
1927 
1928 String SfxHelpIndexWindow_Impl::GetSelectEntry() const
1929 {
1930     String sRet;
1931 
1932     switch ( aTabCtrl.GetCurPageId() )
1933     {
1934         case HELP_INDEX_PAGE_CONTENTS:
1935             sRet = pCPage->GetSelectEntry();
1936             break;
1937 
1938         case HELP_INDEX_PAGE_INDEX:
1939             sRet = pIPage->GetSelectEntry();
1940             break;
1941 
1942         case HELP_INDEX_PAGE_SEARCH:
1943             sRet = pSPage->GetSelectEntry();
1944             break;
1945 
1946         case HELP_INDEX_PAGE_BOOKMARKS:
1947             sRet = pBPage->GetSelectEntry();
1948             break;
1949     }
1950 
1951     return sRet;
1952 }
1953 
1954 // -----------------------------------------------------------------------
1955 
1956 void SfxHelpIndexWindow_Impl::AddBookmarks( const String& rTitle, const String& rURL )
1957 {
1958     GetBookmarksPage()->AddBookmarks( rTitle, rURL );
1959 }
1960 
1961 // -----------------------------------------------------------------------
1962 
1963 bool SfxHelpIndexWindow_Impl::IsValidFactory( const String& _rFactory )
1964 {
1965     bool bValid = false;
1966     for ( sal_uInt16 i = 0; i < aActiveLB.GetEntryCount(); ++i )
1967     {
1968         String* pFactory = (String*)(sal_uIntPtr)aActiveLB.GetEntryData(i);
1969         if ( *pFactory == _rFactory )
1970         {
1971             bValid = true;
1972             break;
1973         }
1974     }
1975     return bValid;
1976 }
1977 
1978 // -----------------------------------------------------------------------
1979 
1980 void SfxHelpIndexWindow_Impl::ClearSearchPage()
1981 {
1982     if ( pSPage )
1983         pSPage->ClearPage();
1984 }
1985 
1986 // -----------------------------------------------------------------------
1987 
1988 void SfxHelpIndexWindow_Impl::GrabFocusBack()
1989 {
1990     if ( aTabCtrl.GetCurPageId() == HELP_INDEX_PAGE_CONTENTS && pCPage )
1991         pCPage->SetFocusOnBox();
1992     else if ( aTabCtrl.GetCurPageId() == HELP_INDEX_PAGE_INDEX && pIPage )
1993         pIPage->SetFocusOnBox();
1994     else if ( aTabCtrl.GetCurPageId() == HELP_INDEX_PAGE_SEARCH && pSPage )
1995         pSPage->SetFocusOnBox();
1996     else if ( aTabCtrl.GetCurPageId() == HELP_INDEX_PAGE_BOOKMARKS && pBPage )
1997         pBPage->SetFocusOnBox();
1998 }
1999 
2000 // -----------------------------------------------------------------------
2001 
2002 sal_Bool SfxHelpIndexWindow_Impl::HasFocusOnEdit() const
2003 {
2004     sal_Bool bRet = sal_False;
2005     if ( aTabCtrl.GetCurPageId() == HELP_INDEX_PAGE_INDEX && pIPage )
2006         bRet = pIPage->HasFocusOnEdit();
2007     else if ( aTabCtrl.GetCurPageId() == HELP_INDEX_PAGE_SEARCH && pSPage )
2008         bRet = pSPage->HasFocusOnEdit();
2009     return bRet;
2010 }
2011 
2012 // -----------------------------------------------------------------------
2013 
2014 String SfxHelpIndexWindow_Impl::GetSearchText() const
2015 {
2016     String sRet;
2017     if ( aTabCtrl.GetCurPageId() == HELP_INDEX_PAGE_SEARCH && pSPage )
2018         sRet = pSPage->GetSearchText();
2019     return sRet;
2020 }
2021 
2022 // -----------------------------------------------------------------------
2023 
2024 sal_Bool SfxHelpIndexWindow_Impl::IsFullWordSearch() const
2025 {
2026     sal_Bool bRet = sal_False;
2027     if ( aTabCtrl.GetCurPageId() == HELP_INDEX_PAGE_SEARCH && pSPage )
2028         bRet = pSPage->IsFullWordSearch();
2029     return bRet;
2030 }
2031 
2032 // -----------------------------------------------------------------------
2033 
2034 void SfxHelpIndexWindow_Impl::OpenKeyword( const String& rKeyword )
2035 {
2036     sKeyword = rKeyword;
2037     DBG_ASSERT( pIPage, "invalid index page" );
2038     pIPage->SetKeyword( sKeyword );
2039 }
2040 
2041 // -----------------------------------------------------------------------
2042 
2043 void SfxHelpIndexWindow_Impl::SelectExecutableEntry()
2044 {
2045     if ( aTabCtrl.GetCurPageId() == HELP_INDEX_PAGE_INDEX && pIPage )
2046         pIPage->SelectExecutableEntry();
2047 }
2048 
2049 // class TextWin_Impl ----------------------------------------------------
2050 
2051 TextWin_Impl::TextWin_Impl( Window* p ) : DockingWindow( p, 0 )
2052 {
2053 }
2054 
2055 TextWin_Impl::~TextWin_Impl()
2056 {
2057 }
2058 
2059 long TextWin_Impl::Notify( NotifyEvent& rNEvt )
2060 {
2061     if( ( rNEvt.GetType() == EVENT_KEYINPUT ) && rNEvt.GetKeyEvent()->GetKeyCode().GetCode() == KEY_TAB )
2062         return GetParent()->Notify( rNEvt );
2063     else
2064         return DockingWindow::Notify( rNEvt );
2065 }
2066 
2067 // -----------------------------------------------------------------------
2068 // remove docking area acceptor from layoutmanager, so it will not layout anything further .-)
2069 void lcl_disableLayoutOfFrame(const Reference< XFrame >& xFrame)
2070 {
2071     static const ::rtl::OUString PROP_LAYOUT_MANAGER(DEFINE_CONST_UNICODE("LayoutManager"));
2072 
2073     Reference< XPropertySet > xPropSet(xFrame, UNO_QUERY_THROW);
2074     xPropSet->setPropertyValue(PROP_LAYOUT_MANAGER, makeAny(Reference< XLayoutManager >()));
2075 }
2076 
2077 // class SfxHelpTextWindow_Impl ------------------------------------------
2078 
2079 SfxHelpTextWindow_Impl::SfxHelpTextWindow_Impl( SfxHelpWindow_Impl* pParent ) :
2080 
2081     Window( pParent, WB_CLIPCHILDREN | WB_TABSTOP | WB_DIALOGCONTROL ),
2082 
2083     aToolBox            ( this, 0 ),
2084     aOnStartupCB        ( this, SfxResId( RID_HELP_ONSTARTUP_BOX ) ),
2085     aIndexOnImage       ( SfxResId( IMG_HELP_TOOLBOX_INDEX_ON ) ),
2086     aIndexOffImage      ( SfxResId( IMG_HELP_TOOLBOX_INDEX_OFF ) ),
2087     aIndexOnText        ( SfxResId( STR_HELP_BUTTON_INDEX_ON ) ),
2088     aIndexOffText       ( SfxResId( STR_HELP_BUTTON_INDEX_OFF ) ),
2089     aOnStartupText      ( SfxResId( RID_HELP_ONSTARTUP_TEXT ) ),
2090     pHelpWin            ( pParent ),
2091     pTextWin            ( new TextWin_Impl( this ) ),
2092     pSrchDlg            ( NULL ),
2093     nMinPos             ( 0 ),
2094     bIsDebug            ( sal_False ),
2095     bIsIndexOn          ( sal_False ),
2096     bIsInClose          ( sal_False ),
2097     bIsFullWordSearch   ( sal_False )
2098 
2099 {
2100     sfx2::AddToTaskPaneList( &aToolBox );
2101 
2102     xFrame = Reference < XFrame > ( ::comphelper::getProcessServiceFactory()->createInstance(
2103         DEFINE_CONST_UNICODE("com.sun.star.frame.Frame") ), UNO_QUERY );
2104     xFrame->initialize( VCLUnoHelper::GetInterface ( pTextWin ) );
2105     xFrame->setName( DEFINE_CONST_UNICODE("OFFICE_HELP") );
2106     lcl_disableLayoutOfFrame(xFrame);
2107 
2108     aToolBox.SetHelpId( HID_HELP_TOOLBOX );
2109 
2110     aToolBox.InsertItem( TBI_INDEX, aIndexOffText );
2111     aToolBox.SetHelpId( TBI_INDEX, HID_HELP_TOOLBOXITEM_INDEX );
2112     aToolBox.InsertSeparator();
2113     aToolBox.InsertItem( TBI_BACKWARD, String( SfxResId( STR_HELP_BUTTON_PREV ) ) );
2114     aToolBox.SetHelpId( TBI_BACKWARD, HID_HELP_TOOLBOXITEM_BACKWARD );
2115     aToolBox.InsertItem( TBI_FORWARD, String( SfxResId( STR_HELP_BUTTON_NEXT ) ) );
2116     aToolBox.SetHelpId( TBI_FORWARD, HID_HELP_TOOLBOXITEM_FORWARD );
2117     aToolBox.InsertItem( TBI_START, String( SfxResId( STR_HELP_BUTTON_START ) ) );
2118     aToolBox.SetHelpId( TBI_START, HID_HELP_TOOLBOXITEM_START );
2119     aToolBox.InsertSeparator();
2120     aToolBox.InsertItem( TBI_PRINT, String( SfxResId( STR_HELP_BUTTON_PRINT ) ) );
2121     aToolBox.SetHelpId( TBI_PRINT, HID_HELP_TOOLBOXITEM_PRINT );
2122     aToolBox.InsertItem( TBI_BOOKMARKS, String( SfxResId( STR_HELP_BUTTON_ADDBOOKMARK ) ) );
2123     aToolBox.SetHelpId( TBI_BOOKMARKS, HID_HELP_TOOLBOXITEM_BOOKMARKS );
2124     aToolBox.InsertItem( TBI_SEARCHDIALOG, String( SfxResId( STR_HELP_BUTTON_SEARCHDIALOG ) ) );
2125     aToolBox.SetHelpId( TBI_SEARCHDIALOG, HID_HELP_TOOLBOXITEM_SEARCHDIALOG );
2126 
2127     InitToolBoxImages();
2128     aToolBox.Show();
2129     InitOnStartupBox( false );
2130     aOnStartupCB.SetClickHdl( LINK( this, SfxHelpTextWindow_Impl, CheckHdl ) );
2131 
2132     aSelectTimer.SetTimeoutHdl( LINK( this, SfxHelpTextWindow_Impl, SelectHdl ) );
2133     aSelectTimer.SetTimeout( 1000 );
2134 
2135     char* pEnv = getenv( "help_debug" );
2136     if ( pEnv )
2137         bIsDebug = sal_True;
2138 
2139     SvtMiscOptions().AddListenerLink( LINK( this, SfxHelpTextWindow_Impl, NotifyHdl ) );
2140 
2141     if ( !aOnStartupCB.GetHelpId().getLength() )
2142         aOnStartupCB.SetHelpId( HID_HELP_ONSTARTUP_BOX );
2143 }
2144 
2145 // -----------------------------------------------------------------------
2146 
2147 SfxHelpTextWindow_Impl::~SfxHelpTextWindow_Impl()
2148 {
2149     sfx2::RemoveFromTaskPaneList( &aToolBox );
2150 
2151     bIsInClose = sal_True;
2152     SvtMiscOptions().RemoveListenerLink( LINK( this, SfxHelpTextWindow_Impl, NotifyHdl ) );
2153     delete pSrchDlg;
2154 }
2155 
2156 // -----------------------------------------------------------------------
2157 
2158 sal_Bool SfxHelpTextWindow_Impl::HasSelection() const
2159 {
2160     // is there any selection in the text and not only a cursor?
2161     sal_Bool bRet = sal_False;
2162     Reference < XTextRange > xRange = getCursor();
2163     if ( xRange.is() )
2164     {
2165         Reference < XText > xText = xRange->getText();
2166         Reference < XTextCursor > xCursor = xText->createTextCursorByRange( xRange );
2167         bRet = !xCursor->isCollapsed();
2168     }
2169 
2170     return bRet;
2171 }
2172 
2173 // -----------------------------------------------------------------------
2174 
2175 void SfxHelpTextWindow_Impl::InitToolBoxImages()
2176 {
2177     sal_Bool bLarge = SvtMiscOptions().AreCurrentSymbolsLarge();
2178     sal_Bool bHiContrast = GetSettings().GetStyleSettings().GetHighContrastMode();
2179 
2180     aIndexOnImage = Image( SfxResId(
2181         bLarge ? bHiContrast ? IMG_HELP_TOOLBOX_HCL_INDEX_ON : IMG_HELP_TOOLBOX_L_INDEX_ON
2182                : bHiContrast ? IMG_HELP_TOOLBOX_HC_INDEX_ON : IMG_HELP_TOOLBOX_INDEX_ON ) );
2183     aIndexOffImage = Image( SfxResId(
2184         bLarge ? bHiContrast ? IMG_HELP_TOOLBOX_HCL_INDEX_OFF : IMG_HELP_TOOLBOX_L_INDEX_OFF
2185                : bHiContrast ? IMG_HELP_TOOLBOX_HC_INDEX_OFF : IMG_HELP_TOOLBOX_INDEX_OFF ) );
2186     aToolBox.SetItemImage( TBI_INDEX, bIsIndexOn ? aIndexOffImage : aIndexOnImage );
2187 
2188     aToolBox.SetItemImage( TBI_BACKWARD, Image( SfxResId(
2189         bLarge ? bHiContrast ? IMG_HELP_TOOLBOX_HCL_PREV : IMG_HELP_TOOLBOX_L_PREV
2190                : bHiContrast ? IMG_HELP_TOOLBOX_HC_PREV : IMG_HELP_TOOLBOX_PREV ) ) );
2191     aToolBox.SetItemImage( TBI_FORWARD, Image( SfxResId(
2192         bLarge ? bHiContrast ? IMG_HELP_TOOLBOX_HCL_NEXT : IMG_HELP_TOOLBOX_L_NEXT
2193                : bHiContrast ? IMG_HELP_TOOLBOX_HC_NEXT : IMG_HELP_TOOLBOX_NEXT ) ) );
2194     aToolBox.SetItemImage( TBI_START, Image( SfxResId(
2195         bLarge ? bHiContrast ? IMG_HELP_TOOLBOX_HCL_START : IMG_HELP_TOOLBOX_L_START
2196                : bHiContrast ? IMG_HELP_TOOLBOX_HC_START : IMG_HELP_TOOLBOX_START ) ) );
2197     aToolBox.SetItemImage( TBI_PRINT, Image( SfxResId(
2198         bLarge ? bHiContrast ? IMG_HELP_TOOLBOX_HCL_PRINT : IMG_HELP_TOOLBOX_L_PRINT
2199                : bHiContrast ? IMG_HELP_TOOLBOX_HC_PRINT : IMG_HELP_TOOLBOX_PRINT ) ) );
2200     aToolBox.SetItemImage( TBI_BOOKMARKS, Image( SfxResId(
2201         bLarge ? bHiContrast ? IMG_HELP_TOOLBOX_HCL_BOOKMARKS : IMG_HELP_TOOLBOX_L_BOOKMARKS
2202                : bHiContrast ? IMG_HELP_TOOLBOX_HC_BOOKMARKS : IMG_HELP_TOOLBOX_BOOKMARKS ) ) );
2203     aToolBox.SetItemImage( TBI_SEARCHDIALOG, Image( SfxResId(
2204         bLarge ? bHiContrast ? IMG_HELP_TOOLBOX_HCL_SEARCHDIALOG : IMG_HELP_TOOLBOX_L_SEARCHDIALOG
2205                : bHiContrast ? IMG_HELP_TOOLBOX_HC_SEARCHDIALOG : IMG_HELP_TOOLBOX_SEARCHDIALOG ) ) );
2206 
2207     Size aSize = aToolBox.CalcWindowSizePixel();
2208     aSize.Height() += TOOLBOX_OFFSET;
2209     aToolBox.SetPosSizePixel( Point( 0, TOOLBOX_OFFSET ), aSize );
2210 
2211     SvtMiscOptions aMiscOptions;
2212     if ( aMiscOptions.GetToolboxStyle() != aToolBox.GetOutStyle() )
2213         aToolBox.SetOutStyle( aMiscOptions.GetToolboxStyle() );
2214 }
2215 
2216 // -----------------------------------------------------------------------
2217 
2218 void SfxHelpTextWindow_Impl::InitOnStartupBox( bool bOnlyText )
2219 {
2220     sCurrentFactory = SfxHelp::GetCurrentModuleIdentifier();
2221 
2222     Reference< XMultiServiceFactory > xMultiServiceFac = ::comphelper::getProcessServiceFactory();
2223     Reference< XInterface > xConfig;
2224     ::rtl::OUString sPath( PATH_OFFICE_FACTORIES );
2225     sPath += sCurrentFactory;
2226     ::rtl::OUString sKey( KEY_HELP_ON_OPEN );
2227 
2228     // Attention: This check boy knows two states:
2229     // 1) Reading of the config key fails with an exception or by getting an empty Any (!) => check box must be hidden
2230     // 2) We read sal_True/sal_False => check box must be shown and enabled/disabled
2231 
2232     bool bHideBox = true;
2233     sal_Bool bHelpAtStartup = sal_False;
2234     try
2235     {
2236         xConfiguration = ConfigurationHelper::openConfig(
2237             xMultiServiceFac, PACKAGE_SETUP, ConfigurationHelper::E_STANDARD );
2238         if ( xConfiguration.is() )
2239         {
2240             Any aAny = ConfigurationHelper::readRelativeKey( xConfiguration, sPath, sKey );
2241             if (aAny >>= bHelpAtStartup)
2242                 bHideBox = false;
2243         }
2244     }
2245     catch( Exception& )
2246     {
2247         bHideBox = true;
2248     }
2249 
2250     if ( bHideBox )
2251         aOnStartupCB.Hide();
2252     else
2253     {
2254         // detect module name
2255         String sModuleName;
2256 
2257         if ( xConfiguration.is() )
2258         {
2259             ::rtl::OUString sTemp;
2260             sKey = KEY_UI_NAME;
2261             try
2262             {
2263                 Any aAny = ConfigurationHelper::readRelativeKey( xConfiguration, sPath, sKey );
2264                 aAny >>= sTemp;
2265             }
2266             catch( Exception& )
2267             {
2268                 DBG_ERRORFILE( "SfxHelpTextWindow_Impl::InitOnStartupBox(): unexpected exception" );
2269             }
2270             sModuleName = String( sTemp );
2271         }
2272 
2273         if ( sModuleName.Len() > 0 )
2274         {
2275             // set module name in checkbox text
2276             String sText( aOnStartupText );
2277             sText.SearchAndReplace( String::CreateFromAscii( "%MODULENAME" ), sModuleName );
2278             aOnStartupCB.SetText( sText );
2279             // and show it
2280             aOnStartupCB.Show();
2281             // set check state
2282             aOnStartupCB.Check( bHelpAtStartup );
2283             aOnStartupCB.SaveValue();
2284 
2285             // calculate and set optimal width of the onstartup checkbox
2286             String sCBText( DEFINE_CONST_UNICODE( "XXX" ) );
2287             sCBText += aOnStartupCB.GetText();
2288             long nTextWidth = aOnStartupCB.GetTextWidth( sCBText );
2289             Size aSize = aOnStartupCB.GetSizePixel();
2290             aSize.Width() = nTextWidth;
2291             aOnStartupCB.SetSizePixel( aSize );
2292             SetOnStartupBoxPosition();
2293         }
2294 
2295         if ( !bOnlyText )
2296         {
2297             // set position of the checkbox
2298             Size a3Size = LogicToPixel( Size( 3, 3 ), MAP_APPFONT );
2299             Size aTBSize = aToolBox.GetSizePixel();
2300             Size aCBSize = aOnStartupCB.GetSizePixel();
2301             Point aPnt = aToolBox.GetPosPixel();
2302             aPnt.X() += aTBSize.Width() + a3Size.Width();
2303             aPnt.Y() += ( ( aTBSize.Height() - aCBSize.Height() ) / 2 );
2304             aOnStartupCB.SetPosPixel( aPnt );
2305             nMinPos = aPnt.X();
2306         }
2307     }
2308 }
2309 
2310 // -----------------------------------------------------------------------
2311 
2312 void SfxHelpTextWindow_Impl::SetOnStartupBoxPosition()
2313 {
2314     long nX = Max( GetOutputSizePixel().Width() - aOnStartupCB.GetSizePixel().Width(), nMinPos );
2315     Point aPos = aOnStartupCB.GetPosPixel();
2316     aPos.X() = nX;
2317     aOnStartupCB.SetPosPixel( aPos );
2318 }
2319 
2320 // -----------------------------------------------------------------------
2321 
2322 Reference< XBreakIterator > SfxHelpTextWindow_Impl::GetBreakIterator()
2323 {
2324     if ( !xBreakIterator.is() )
2325         xBreakIterator = vcl::unohelper::CreateBreakIterator();
2326     DBG_ASSERT( xBreakIterator.is(), "Could not create BreakIterator" );
2327     return xBreakIterator;
2328 }
2329 
2330 // -----------------------------------------------------------------------
2331 
2332 Reference< XTextRange > SfxHelpTextWindow_Impl::getCursor() const
2333 {
2334     // return the current cursor
2335     Reference< XTextRange > xCursor;
2336 
2337     try
2338     {
2339         Reference < XSelectionSupplier > xSelSup( xFrame->getController(), UNO_QUERY );
2340         if ( xSelSup.is() )
2341         {
2342             Any aAny = xSelSup->getSelection();
2343             Reference < XIndexAccess > xSelection;
2344             if ( aAny >>= xSelection )
2345             {
2346                 if ( xSelection->getCount() == 1 )
2347                 {
2348                     aAny = xSelection->getByIndex(0);
2349                     aAny >>= xCursor;
2350                 }
2351             }
2352         }
2353     }
2354     catch( Exception& )
2355     {
2356         DBG_ERROR( "SfxHelpTextWindow_Impl::getCursor(): unexpected exception" );
2357     }
2358 
2359     return xCursor;
2360 }
2361 
2362 // -----------------------------------------------------------------------
2363 
2364 bool SfxHelpTextWindow_Impl::isHandledKey( const KeyCode& _rKeyCode )
2365 {
2366     bool bRet = false;
2367     sal_uInt16 nCode = _rKeyCode.GetCode();
2368 
2369     // the keys <STRG><A> (select all), <STRG><C> (copy),
2370     //          <STRG><F> (find), <STRG><P> (print) and <STRG><W> (close window)
2371     // were handled in help
2372     if ( _rKeyCode.IsMod1() &&
2373          ( KEY_A == nCode || KEY_C == nCode || KEY_F == nCode || KEY_P == nCode || KEY_W == nCode ) )
2374     {
2375         if ( KEY_F == nCode )
2376             DoSearch();
2377         else
2378             bRet = true;
2379     }
2380 
2381     return bRet;
2382 }
2383 
2384 // -----------------------------------------------------------------------
2385 
2386 IMPL_LINK( SfxHelpTextWindow_Impl, SelectHdl, Timer*, EMPTYARG )
2387 {
2388     try
2389     {
2390         // select the words, which are equal to the search text of the search page
2391         Reference < XController > xController = xFrame->getController();
2392         if ( xController.is() )
2393         {
2394             // get document
2395             Reference < XSearchable > xSearchable( xController->getModel(), UNO_QUERY );
2396             if ( xSearchable.is() )
2397             {
2398                 // create descriptor, set string and find all words
2399                 Reference < XSearchDescriptor > xSrchDesc = xSearchable->createSearchDescriptor();
2400                 Reference < XPropertySet > xPropSet( xSrchDesc, UNO_QUERY );
2401                 xPropSet->setPropertyValue( DEFINE_CONST_OUSTRING("SearchRegularExpression"),
2402                                             makeAny( sal_Bool( sal_True ) ) );
2403                 if ( bIsFullWordSearch )
2404                     xPropSet->setPropertyValue( DEFINE_CONST_OUSTRING("SearchWords"),
2405                                                 makeAny( sal_Bool( sal_True ) ) );
2406 
2407                 String sSearchString = sfx2::PrepareSearchString( aSearchText, GetBreakIterator(), false );
2408                 xSrchDesc->setSearchString( sSearchString );
2409                 Reference< XIndexAccess > xSelection = xSearchable->findAll( xSrchDesc );
2410 
2411                 // then select all found words
2412                 Reference < XSelectionSupplier > xSelectionSup( xController, UNO_QUERY );
2413                 if ( xSelectionSup.is() )
2414                 {
2415                     Any aAny;
2416                     aAny <<= xSelection;
2417                     xSelectionSup->select( aAny );
2418                 }
2419             }
2420         }
2421     }
2422     catch( Exception& )
2423     {
2424         DBG_ERROR( "SfxHelpTextWindow_Impl::SelectHdl(): unexpected exception" );
2425     }
2426 
2427     return 1;
2428 }
2429 
2430 // -----------------------------------------------------------------------
2431 
2432 IMPL_LINK( SfxHelpTextWindow_Impl, NotifyHdl, SvtMiscOptions*, pOptions )
2433 {
2434     (void)pOptions; // unused variable
2435     InitToolBoxImages();
2436     Resize();
2437     aToolBox.Invalidate();
2438     return 0;
2439 }
2440 
2441 // -----------------------------------------------------------------------
2442 
2443 IMPL_LINK( SfxHelpTextWindow_Impl, FindHdl, sfx2::SearchDialog*, pDlg )
2444 {
2445     bool bWrapAround = ( NULL == pDlg );
2446     if ( bWrapAround )
2447         pDlg = pSrchDlg;
2448     DBG_ASSERT( pDlg, "invalid search dialog" );
2449     String sSearchText = pDlg->GetSearchText();
2450     try
2451     {
2452         // select the words, which are equal to the search text of the search page
2453         Reference < XController > xController = xFrame->getController();
2454         if ( xController.is() )
2455         {
2456             // get document
2457             Reference < XSearchable > xSearchable( xController->getModel(), UNO_QUERY );
2458             if ( xSearchable.is() )
2459             {
2460                 // create descriptor, set string and find all words
2461                 Reference < XSearchDescriptor > xSrchDesc = xSearchable->createSearchDescriptor();
2462                 Reference < XPropertySet > xPropSet( xSrchDesc, UNO_QUERY );
2463                 xPropSet->setPropertyValue( DEFINE_CONST_OUSTRING("SearchWords"), makeAny( sal_Bool( pDlg->IsOnlyWholeWords() != false ) ) );
2464                 xPropSet->setPropertyValue( DEFINE_CONST_OUSTRING("SearchCaseSensitive"), makeAny( sal_Bool( pDlg->IsMarchCase() != false ) ) );
2465                 xPropSet->setPropertyValue( DEFINE_CONST_OUSTRING("SearchBackwards"), makeAny( sal_Bool( pDlg->IsSearchBackwards() != false ) ) );
2466                 xSrchDesc->setSearchString( sSearchText );
2467                 Reference< XInterface > xSelection;
2468                 Reference< XTextRange > xCursor = getCursor();
2469 
2470                 if ( xCursor.is() )
2471                 {
2472                     if ( pDlg->IsSearchBackwards() )
2473                         xCursor = xCursor->getStart();
2474                     xSelection = xSearchable->findNext( xCursor, xSrchDesc );
2475                 }
2476                 else
2477                     xSelection = xSearchable->findFirst( xSrchDesc );
2478 
2479                 // then select the found word
2480                 if ( xSelection.is() )
2481                 {
2482                     Reference < XSelectionSupplier > xSelectionSup( xController, UNO_QUERY );
2483                     if ( xSelectionSup.is() )
2484                     {
2485                         Any aAny;
2486                         aAny <<= xSelection;
2487                         xSelectionSup->select( aAny );
2488                     }
2489                 }
2490                 else if ( pDlg->IsWrapAround() && !bWrapAround )
2491                 {
2492                     Reference < text::XTextViewCursorSupplier > xCrsrSupp( xController, uno::UNO_QUERY );
2493                     Reference < text::XTextViewCursor > xTVCrsr( xCrsrSupp->getViewCursor(), uno::UNO_QUERY );
2494                     if ( xTVCrsr.is() )
2495                     {
2496                         Reference < text::XTextDocument > xDoc( xController->getModel(), uno::UNO_QUERY );
2497                         Reference < text::XText > xText = xDoc->getText();
2498                         if ( xText.is() )
2499                         {
2500                             if ( pDlg->IsSearchBackwards() )
2501                                 xTVCrsr->gotoRange( xText->getEnd(), sal_False );
2502                             else
2503                                 xTVCrsr->gotoRange( xText->getStart(), sal_False );
2504                             FindHdl( NULL );
2505                         }
2506                     }
2507                 }
2508                 else
2509                 {
2510                     DBG_ASSERT( pSrchDlg, "no search dialog" );
2511                     InfoBox aBox( pSrchDlg, SfxResId( RID_INFO_NOSEARCHTEXTFOUND ) );
2512                     aBox.Execute();
2513                     pSrchDlg->SetFocusOnEdit();
2514                 }
2515             }
2516         }
2517     }
2518     catch( Exception& )
2519     {
2520         DBG_ERROR( "SfxHelpTextWindow_Impl::SelectHdl(): unexpected exception" );
2521     }
2522 
2523     return 0;
2524 }
2525 
2526 // -----------------------------------------------------------------------
2527 
2528 IMPL_LINK( SfxHelpTextWindow_Impl, CloseHdl, sfx2::SearchDialog*, pDlg )
2529 {
2530     if ( pDlg )
2531         delete pSrchDlg;
2532     pSrchDlg = NULL;
2533     return 0;
2534 }
2535 
2536 // -----------------------------------------------------------------------
2537 
2538 IMPL_LINK( SfxHelpTextWindow_Impl, CheckHdl, CheckBox*, pBox )
2539 {
2540     if ( xConfiguration.is() )
2541     {
2542         sal_Bool bChecked = pBox->IsChecked();
2543         ::rtl::OUString sPath( PATH_OFFICE_FACTORIES );
2544         sPath += sCurrentFactory;
2545         try
2546         {
2547             ConfigurationHelper::writeRelativeKey(
2548                 xConfiguration, sPath, KEY_HELP_ON_OPEN, makeAny( bChecked ) );
2549             ConfigurationHelper::flush( xConfiguration );
2550         }
2551         catch( Exception& )
2552         {
2553             DBG_ERRORFILE( "SfxHelpTextWindow_Impl::CheckHdl(): unexpected exception" );
2554         }
2555     }
2556 
2557     return 0;
2558 }
2559 
2560 // -----------------------------------------------------------------------
2561 
2562 void SfxHelpTextWindow_Impl::Resize()
2563 {
2564     Size aSize = GetOutputSizePixel();
2565     long nToolBoxHeight = aToolBox.GetSizePixel().Height() + TOOLBOX_OFFSET;
2566     aSize.Height() -= nToolBoxHeight;
2567     pTextWin->SetPosSizePixel( Point( 0, nToolBoxHeight  ), aSize );
2568     SetOnStartupBoxPosition();
2569 }
2570 
2571 // -----------------------------------------------------------------------
2572 
2573 long SfxHelpTextWindow_Impl::PreNotify( NotifyEvent& rNEvt )
2574 {
2575     long nDone = 0;
2576     sal_uInt16 nType = rNEvt.GetType();
2577     if ( EVENT_COMMAND == nType && rNEvt.GetCommandEvent() )
2578     {
2579         const CommandEvent* pCmdEvt = rNEvt.GetCommandEvent();
2580         Window* pCmdWin = rNEvt.GetWindow();
2581 
2582         if ( pCmdEvt->GetCommand() == COMMAND_CONTEXTMENU && pCmdWin != this && pCmdWin != &aToolBox )
2583         {
2584             sal_Bool bHiContrast = GetSettings().GetStyleSettings().GetHighContrastMode();
2585             Point aPos;
2586             if ( pCmdEvt->IsMouseEvent() )
2587                 aPos = pCmdEvt->GetMousePosPixel();
2588             else
2589                 aPos = Point( pTextWin->GetPosPixel().X() + 20, 20 );
2590             aPos.Y() += pTextWin->GetPosPixel().Y();
2591             PopupMenu aMenu;
2592             if ( bIsIndexOn )
2593                 aMenu.InsertItem( TBI_INDEX, aIndexOffText, Image( SfxResId(
2594                     bHiContrast ? IMG_HELP_TOOLBOX_HC_INDEX_OFF : IMG_HELP_TOOLBOX_INDEX_OFF ) ) );
2595             else
2596                 aMenu.InsertItem( TBI_INDEX, aIndexOnText, Image( SfxResId(
2597                     bHiContrast ? IMG_HELP_TOOLBOX_HC_INDEX_ON : IMG_HELP_TOOLBOX_INDEX_ON ) ) );
2598             aMenu.SetHelpId( TBI_INDEX, HID_HELP_TOOLBOXITEM_INDEX );
2599             aMenu.InsertSeparator();
2600             aMenu.InsertItem( TBI_BACKWARD, String( SfxResId( STR_HELP_BUTTON_PREV ) ),
2601                 Image( SfxResId( bHiContrast ? IMG_HELP_TOOLBOX_HC_PREV : IMG_HELP_TOOLBOX_PREV ) ) );
2602             aMenu.SetHelpId( TBI_BACKWARD, HID_HELP_TOOLBOXITEM_BACKWARD );
2603             aMenu.EnableItem( TBI_BACKWARD, pHelpWin->HasHistoryPredecessor() );
2604             aMenu.InsertItem( TBI_FORWARD, String( SfxResId( STR_HELP_BUTTON_NEXT ) ),
2605                 Image( SfxResId( bHiContrast ? IMG_HELP_TOOLBOX_HC_NEXT : IMG_HELP_TOOLBOX_NEXT ) ) );
2606             aMenu.SetHelpId( TBI_FORWARD, HID_HELP_TOOLBOXITEM_FORWARD );
2607             aMenu.EnableItem( TBI_FORWARD, pHelpWin->HasHistorySuccessor() );
2608             aMenu.InsertItem( TBI_START, String( SfxResId( STR_HELP_BUTTON_START ) ),
2609                 Image( SfxResId( bHiContrast ? IMG_HELP_TOOLBOX_HC_START : IMG_HELP_TOOLBOX_START ) ) );
2610             aMenu.SetHelpId( TBI_START, HID_HELP_TOOLBOXITEM_START );
2611             aMenu.InsertSeparator();
2612             aMenu.InsertItem( TBI_PRINT, String( SfxResId( STR_HELP_BUTTON_PRINT ) ),
2613                 Image( SfxResId( bHiContrast ? IMG_HELP_TOOLBOX_HC_PRINT : IMG_HELP_TOOLBOX_PRINT ) ) );
2614             aMenu.SetHelpId( TBI_PRINT, HID_HELP_TOOLBOXITEM_PRINT );
2615             aMenu.InsertItem( TBI_BOOKMARKS, String( SfxResId( STR_HELP_BUTTON_ADDBOOKMARK ) ),
2616                 Image( SfxResId( bHiContrast ? IMG_HELP_TOOLBOX_HC_BOOKMARKS : IMG_HELP_TOOLBOX_BOOKMARKS ) ) );
2617             aMenu.SetHelpId( TBI_BOOKMARKS, HID_HELP_TOOLBOXITEM_BOOKMARKS );
2618             aMenu.InsertItem( TBI_SEARCHDIALOG, String( SfxResId( STR_HELP_BUTTON_SEARCHDIALOG ) ),
2619                 Image( SfxResId( bHiContrast ? IMG_HELP_TOOLBOX_HC_SEARCHDIALOG : IMG_HELP_TOOLBOX_SEARCHDIALOG ) ) );
2620             aMenu.SetHelpId( TBI_SEARCHDIALOG, HID_HELP_TOOLBOXITEM_SEARCHDIALOG );
2621             aMenu.InsertSeparator();
2622             aMenu.InsertItem( TBI_SELECTIONMODE, String( SfxResId( STR_HELP_MENU_TEXT_SELECTION_MODE ) ) );
2623             aMenu.SetHelpId( TBI_SELECTIONMODE, HID_HELP_TEXT_SELECTION_MODE );
2624             Reference < XDispatchProvider > xProv( xFrame, UNO_QUERY );
2625             URL aURL;
2626             aURL.Complete = DEFINE_CONST_UNICODE(".uno:SelectTextMode");
2627             PARSE_URL( aURL );
2628             Reference < XDispatch > xDisp = xProv.is() ?
2629                     xProv->queryDispatch( aURL, rtl::OUString(), 0 ) : Reference < XDispatch >();
2630             if(xDisp.is())
2631             {
2632                 HelpStatusListener_Impl* pStateListener;
2633                 Reference<XStatusListener>xStateListener = pStateListener =
2634                                         new HelpStatusListener_Impl(xDisp, aURL );
2635                 FeatureStateEvent rEvent = pStateListener->GetStateEvent();
2636                 sal_Bool bCheck = sal_False;
2637                 rEvent.State >>= bCheck;
2638                 aMenu.CheckItem(TBI_SELECTIONMODE, bCheck);
2639             }
2640             aMenu.InsertSeparator();
2641             aMenu.InsertItem( TBI_COPY, String( SfxResId( STR_HELP_MENU_TEXT_COPY ) ),
2642                 Image( SfxResId( bHiContrast ? IMG_HELP_TOOLBOX_HC_COPY : IMG_HELP_TOOLBOX_COPY ) ) );
2643             aMenu.SetHelpId( TBI_COPY, ".uno:Copy" );
2644             aMenu.EnableItem( TBI_COPY, HasSelection() );
2645 
2646             if ( bIsDebug )
2647             {
2648                 aMenu.InsertSeparator();
2649                 aMenu.InsertItem( TBI_SOURCEVIEW, String( SfxResId( STR_HELP_BUTTON_SOURCEVIEW ) ) );
2650             }
2651 
2652             if( SvtMenuOptions().IsEntryHidingEnabled() == sal_False )
2653                 aMenu.SetMenuFlags( aMenu.GetMenuFlags() | MENU_FLAG_HIDEDISABLEDENTRIES );
2654 
2655             sal_uInt16 nId = aMenu.Execute( this, aPos );
2656             pHelpWin->DoAction( nId );
2657             nDone = 1;
2658         }
2659     }
2660     else if ( EVENT_KEYINPUT == nType && rNEvt.GetKeyEvent() )
2661     {
2662         const KeyEvent* pKEvt = rNEvt.GetKeyEvent();
2663         const KeyCode& rKeyCode = pKEvt->GetKeyCode();
2664         sal_uInt16 nKeyGroup = rKeyCode.GetGroup();
2665         sal_uInt16 nKey = rKeyCode.GetCode();
2666         if ( KEYGROUP_ALPHA == nKeyGroup &&  !isHandledKey( rKeyCode ) )
2667         {
2668             // do nothing disables the writer accelerators
2669             nDone = 1;
2670         }
2671         else if ( rKeyCode.IsMod1() && ( KEY_F4 == nKey || KEY_W == nKey ) )
2672         {
2673             // <STRG><F4> or <STRG><W> -> close top frame
2674             pHelpWin->CloseWindow();
2675             nDone = 1;
2676         }
2677         else if ( KEY_TAB == nKey && aOnStartupCB.HasChildPathFocus() )
2678         {
2679             aToolBox.GrabFocus();
2680             nDone = 1;
2681         }
2682     }
2683 
2684     return nDone ? nDone : Window::PreNotify( rNEvt );
2685 }
2686 
2687 // -----------------------------------------------------------------------
2688 
2689 void SfxHelpTextWindow_Impl::GetFocus()
2690 {
2691     if ( !bIsInClose )
2692     {
2693         try
2694         {
2695             if( xFrame.is() )
2696             {
2697                 Reference< ::com::sun::star::awt::XWindow > xWindow = xFrame->getComponentWindow();
2698                 if( xWindow.is() )
2699                     xWindow->setFocus();
2700             }
2701         }
2702         catch( Exception& )
2703         {
2704             DBG_ERRORFILE( "SfxHelpTextWindow_Impl::GetFocus(): unexpected exception" );
2705         }
2706     }
2707 }
2708 
2709 // -----------------------------------------------------------------------
2710 
2711 void SfxHelpTextWindow_Impl::DataChanged( const DataChangedEvent& rDCEvt )
2712 {
2713     Window::DataChanged( rDCEvt );
2714 
2715     if ( ( ( rDCEvt.GetType() == DATACHANGED_SETTINGS ) ||
2716            ( rDCEvt.GetType() == DATACHANGED_DISPLAY ) ) &&
2717          ( rDCEvt.GetFlags() & SETTINGS_STYLE ) )
2718     {
2719         SetBackground( Wallpaper( GetSettings().GetStyleSettings().GetFaceColor() ) );
2720         InitToolBoxImages();
2721     }
2722 }
2723 
2724 // -----------------------------------------------------------------------
2725 
2726 void SfxHelpTextWindow_Impl::ToggleIndex( sal_Bool bOn )
2727 {
2728     bIsIndexOn = bOn;
2729     if ( bIsIndexOn )
2730     {
2731         aToolBox.SetItemImage( TBI_INDEX, aIndexOffImage );
2732         aToolBox.SetItemText( TBI_INDEX, aIndexOffText );
2733     }
2734     else
2735     {
2736         aToolBox.SetItemImage( TBI_INDEX, aIndexOnImage );
2737         aToolBox.SetItemText( TBI_INDEX, aIndexOnText );
2738     }
2739 }
2740 
2741 // -----------------------------------------------------------------------
2742 
2743 void SfxHelpTextWindow_Impl::SelectSearchText( const String& rSearchText, sal_Bool _bIsFullWordSearch )
2744 {
2745     aSearchText = rSearchText;
2746     bIsFullWordSearch = _bIsFullWordSearch;
2747     aSelectTimer.Start();
2748 }
2749 
2750 // -----------------------------------------------------------------------
2751 
2752 void SfxHelpTextWindow_Impl::SetPageStyleHeaderOff() const
2753 {
2754 #ifdef DBG_UTIL
2755     sal_Bool bSetOff = sal_False;
2756 #endif
2757     // set off the pagestyle header to prevent print output of the help URL
2758     try
2759     {
2760         Reference < XController > xController = xFrame->getController();
2761         Reference < XSelectionSupplier > xSelSup( xController, UNO_QUERY );
2762         if ( xSelSup.is() )
2763         {
2764             Reference < XIndexAccess > xSelection;
2765             if ( xSelSup->getSelection() >>= xSelection )
2766             {
2767                 Reference < XTextRange > xRange;
2768                 if ( xSelection->getByIndex(0) >>= xRange )
2769                 {
2770                     Reference < XText > xText = xRange->getText();
2771                     Reference < XPropertySet > xProps( xText->createTextCursorByRange( xRange ), UNO_QUERY );
2772                     ::rtl::OUString sStyleName;
2773                     if ( xProps->getPropertyValue( DEFINE_CONST_OUSTRING("PageStyleName") ) >>= sStyleName )
2774                     {
2775                         Reference < XStyleFamiliesSupplier > xStyles( xController->getModel(), UNO_QUERY );
2776                         Reference < XNameContainer > xContainer;
2777                         if ( xStyles->getStyleFamilies()->getByName( DEFINE_CONST_OUSTRING("PageStyles") )
2778                              >>= xContainer )
2779                         {
2780                             Reference < XStyle > xStyle;
2781                             if ( xContainer->getByName( sStyleName ) >>= xStyle )
2782                             {
2783                                 Reference < XPropertySet > xPropSet( xStyle, UNO_QUERY );
2784                                 xPropSet->setPropertyValue( DEFINE_CONST_OUSTRING("HeaderIsOn"),
2785                                                             makeAny( sal_Bool( sal_False ) ) );
2786 
2787                                 Reference< XModifiable > xReset(xStyles, UNO_QUERY);
2788                                 xReset->setModified(sal_False);
2789 #ifdef DBG_UTIL
2790                                 bSetOff = sal_True;
2791 #endif
2792                             }
2793                         }
2794                     }
2795                 }
2796             }
2797         }
2798     }
2799     catch( Exception& )
2800     {
2801         DBG_ERRORFILE( "SfxHelpTextWindow_Impl::SetPageStyleHeaderOff(): unexpected exception" );
2802     }
2803 
2804 #ifdef DBG_UTIL
2805     if ( !bSetOff )
2806     {
2807         DBG_ERRORFILE( "SfxHelpTextWindow_Impl::SetPageStyleHeaderOff(): set off failed" );
2808     }
2809 #endif
2810 }
2811 
2812 // -----------------------------------------------------------------------
2813 
2814 void SfxHelpTextWindow_Impl::CloseFrame()
2815 {
2816     bIsInClose = sal_True;
2817     try
2818     {
2819         ::com::sun::star::uno::Reference< ::com::sun::star::util::XCloseable > xCloseable  ( xFrame, ::com::sun::star::uno::UNO_QUERY );
2820         if (xCloseable.is())
2821             xCloseable->close(sal_True);
2822     }
2823     catch( ::com::sun::star::util::CloseVetoException& )
2824     {
2825     }
2826 }
2827 
2828 // -----------------------------------------------------------------------
2829 
2830 void SfxHelpTextWindow_Impl::DoSearch()
2831 {
2832     if ( !pSrchDlg )
2833     {
2834         // create the search dialog
2835         pSrchDlg = new sfx2::SearchDialog( pTextWin, DEFINE_CONST_UNICODE("HelpSearchDialog") );
2836         // set handler
2837         pSrchDlg->SetFindHdl( LINK( this, SfxHelpTextWindow_Impl, FindHdl ) );
2838         pSrchDlg->SetCloseHdl( LINK( this, SfxHelpTextWindow_Impl, CloseHdl ) );
2839         // get selected text of the help page to set it as the search text
2840         Reference< XTextRange > xCursor = getCursor();
2841         if ( xCursor.is() )
2842         {
2843             String sText = xCursor->getString();
2844             if ( sText.Len() > 0 )
2845                 pSrchDlg->SetSearchText( sText );
2846         }
2847         pSrchDlg->Show();
2848     }
2849 }
2850 
2851 // class SfxHelpWindow_Impl ----------------------------------------------
2852 
2853 void SfxHelpWindow_Impl::Resize()
2854 {
2855     SplitWindow::Resize();
2856     InitSizes();
2857 }
2858 
2859 // -----------------------------------------------------------------------
2860 
2861 void SfxHelpWindow_Impl::Split()
2862 {
2863     static long nMinSplitSize = 5;
2864     static long nMaxSplitSize = 99 - nMinSplitSize;
2865 
2866     SplitWindow::Split();
2867 
2868     nIndexSize = GetItemSize( INDEXWIN_ID );
2869     nTextSize = GetItemSize( TEXTWIN_ID );
2870 
2871     sal_Bool        bMod = sal_False;
2872     if( nIndexSize < nMinSplitSize )
2873     {
2874         nIndexSize = nMinSplitSize;
2875         nTextSize = nMaxSplitSize;
2876 
2877         bMod = sal_True;
2878     }
2879     else if( nTextSize < nMinSplitSize )
2880     {
2881         nTextSize = nMinSplitSize;
2882         nIndexSize = nMaxSplitSize;
2883 
2884         bMod = sal_True;
2885     }
2886     else
2887         bMod = sal_False;
2888 
2889     if( bMod )
2890     {
2891         SetItemSize( INDEXWIN_ID, nIndexSize );
2892         SetItemSize( TEXTWIN_ID, nTextSize );
2893     }
2894 
2895     InitSizes();
2896 }
2897 
2898 // -----------------------------------------------------------------------
2899 
2900 void SfxHelpWindow_Impl::GetFocus()
2901 {
2902     pTextWin->GrabFocus();
2903 }
2904 
2905 // -----------------------------------------------------------------------
2906 
2907 void SfxHelpWindow_Impl::MakeLayout()
2908 {
2909     if ( nHeight > 0 && xWindow.is() )
2910     {
2911         Window* pScreenWin = VCLUnoHelper::GetWindow( xWindow );
2912 
2913         /* #i55528#
2914             Hide() / Show() will produce starnge effects.
2915             The returned size (used later to be written back into the configuration)
2916             isnt the right after a resize during the window is hidden.
2917             If this resize is done if the window is visible evyrthing works as aspected.
2918             Some VCL-patches could not solve this problem so I've established the
2919             workaround: resize the help window if it's visible .-)
2920         */
2921 //      pScreenWin->Hide();
2922 
2923         ::com::sun::star::awt::Rectangle aRect = xWindow->getPosSize();
2924         sal_Int32 nOldWidth = bIndex ? nCollapseWidth : nExpandWidth;
2925         sal_Int32 nWidth = bIndex ? nExpandWidth : nCollapseWidth;
2926         xWindow->setPosSize( aRect.X, aRect.Y, nWidth, nHeight, ::com::sun::star::awt::PosSize::SIZE );
2927 
2928         if ( aRect.Width > 0 && aRect.Height > 0 )
2929         {
2930             Rectangle aScreenRect = pScreenWin->GetClientWindowExtentsRelative( NULL );
2931             Point aNewPos = aScreenRect.TopLeft();
2932             sal_Int32 nDiffWidth = nOldWidth - nWidth;
2933             aNewPos.X() += nDiffWidth;
2934             pScreenWin->SetPosPixel( aNewPos );
2935         }
2936         else if ( aWinPos.X() > 0 && aWinPos.Y() > 0 )
2937             pScreenWin->SetPosPixel( aWinPos );
2938 
2939 //      pScreenWin->Show();
2940     }
2941 
2942     Clear();
2943 
2944     if ( bIndex )
2945     {
2946         pIndexWin->Show();
2947         InsertItem( COLSET_ID, 100, SPLITWINDOW_APPEND, SPLITSET_ID, SWIB_PERCENTSIZE | SWIB_COLSET );
2948         InsertItem( INDEXWIN_ID, pIndexWin, nIndexSize, SPLITWINDOW_APPEND, COLSET_ID, SWIB_PERCENTSIZE );
2949         InsertItem( TEXTWIN_ID, pTextWin, nTextSize, SPLITWINDOW_APPEND, COLSET_ID, SWIB_PERCENTSIZE );
2950     }
2951     else
2952     {
2953         pIndexWin->Hide();
2954         InsertItem( COLSET_ID, 100, SPLITWINDOW_APPEND, SPLITSET_ID, SWIB_PERCENTSIZE | SWIB_COLSET );
2955         InsertItem( TEXTWIN_ID, pTextWin, 100, SPLITWINDOW_APPEND, 1, SWIB_PERCENTSIZE );
2956     }
2957 }
2958 
2959 // -----------------------------------------------------------------------
2960 
2961 void SfxHelpWindow_Impl::InitSizes()
2962 {
2963     if ( xWindow.is() )
2964     {
2965         ::com::sun::star::awt::Rectangle aRect = xWindow->getPosSize();
2966         nHeight = aRect.Height;
2967 
2968         if ( bIndex )
2969         {
2970             nExpandWidth = aRect.Width;
2971             nCollapseWidth = nExpandWidth * nTextSize / 100;
2972         }
2973         else
2974         {
2975             nCollapseWidth = aRect.Width;
2976             nExpandWidth = nCollapseWidth * 100 / nTextSize;
2977         }
2978     }
2979 }
2980 
2981 // -----------------------------------------------------------------------
2982 
2983 void SfxHelpWindow_Impl::LoadConfig()
2984 {
2985     SvtViewOptions aViewOpt( E_WINDOW, CONFIGNAME_HELPWIN );
2986     if ( aViewOpt.Exists() )
2987     {
2988         bIndex = aViewOpt.IsVisible();
2989         String aUserData;
2990         Any aUserItem = aViewOpt.GetUserItem( USERITEM_NAME );
2991         rtl::OUString aTemp;
2992         if ( aUserItem >>= aTemp )
2993         {
2994             aUserData = String( aTemp );
2995             DBG_ASSERT( aUserData.GetTokenCount() == 6, "invalid user data" );
2996             sal_uInt16 nIdx = 0;
2997             nIndexSize = aUserData.GetToken( 0, ';', nIdx ).ToInt32();
2998             nTextSize = aUserData.GetToken( 0, ';', nIdx ).ToInt32();
2999             sal_Int32 nWidth = aUserData.GetToken( 0, ';', nIdx ).ToInt32();
3000             nHeight = aUserData.GetToken( 0, ';', nIdx ).ToInt32();
3001             aWinPos.X() = aUserData.GetToken( 0, ';', nIdx ).ToInt32();
3002             aWinPos.Y() = aUserData.GetToken( 0, ';', nIdx ).ToInt32();
3003             if ( bIndex )
3004             {
3005                 nExpandWidth = nWidth;
3006                 nCollapseWidth = nExpandWidth * nTextSize / 100;
3007             }
3008             else
3009             {
3010                 nCollapseWidth = nWidth;
3011                 nExpandWidth = nCollapseWidth * 100 / nTextSize;
3012             }
3013         }
3014 
3015         pTextWin->ToggleIndex( bIndex );
3016     }
3017 }
3018 
3019 // -----------------------------------------------------------------------
3020 
3021 void SfxHelpWindow_Impl::SaveConfig()
3022 {
3023     SvtViewOptions aViewOpt( E_WINDOW, CONFIGNAME_HELPWIN );
3024     sal_Int32 nW = 0, nH = 0;
3025 
3026     if ( xWindow.is() )
3027     {
3028         ::com::sun::star::awt::Rectangle aRect = xWindow->getPosSize();
3029         nW = aRect.Width;
3030         nH = aRect.Height;
3031     }
3032 
3033     aViewOpt.SetVisible( bIndex );
3034     String aUserData = String::CreateFromInt32( nIndexSize );
3035     aUserData += ';';
3036     aUserData += String::CreateFromInt32( nTextSize );
3037     aUserData += ';';
3038     aUserData += String::CreateFromInt32( nW );
3039     aUserData += ';';
3040     aUserData += String::CreateFromInt32( nH );
3041 
3042     Window* pScreenWin = VCLUnoHelper::GetWindow( xWindow );
3043     aWinPos = pScreenWin->GetWindowExtentsRelative( NULL ).TopLeft();
3044     aUserData += ';';
3045     aUserData += String::CreateFromInt32( aWinPos.X() );
3046     aUserData += ';';
3047     aUserData += String::CreateFromInt32( aWinPos.Y() );
3048 
3049     aViewOpt.SetUserItem( USERITEM_NAME, makeAny( rtl::OUString( aUserData ) ) );
3050 }
3051 
3052 // -----------------------------------------------------------------------
3053 
3054 void SfxHelpWindow_Impl::ShowStartPage()
3055 {
3056     ::rtl::OUString sHelpURL = SfxHelpWindow_Impl::buildHelpURL(pIndexWin->GetFactory(),
3057                                                                 DEFINE_CONST_UNICODE("/start"),
3058                                                                 ::rtl::OUString(),
3059                                                                 sal_True);
3060     loadHelpContent(sHelpURL);
3061 }
3062 
3063 // -----------------------------------------------------------------------
3064 
3065 IMPL_LINK( SfxHelpWindow_Impl, SelectHdl, ToolBox* , pToolBox )
3066 {
3067     if ( pToolBox )
3068     {
3069         bGrabFocusToToolBox = pToolBox->HasChildPathFocus();
3070         DoAction( pToolBox->GetCurItemId() );
3071     }
3072 
3073     return 1;
3074 }
3075 
3076 //-------------------------------------------------------------------------
3077 
3078 IMPL_LINK( SfxHelpWindow_Impl, OpenHdl, SfxHelpIndexWindow_Impl* , EMPTYARG )
3079 {
3080     pIndexWin->SelectExecutableEntry();
3081     String aEntry = pIndexWin->GetSelectEntry();
3082 
3083     if ( aEntry.Len() < 1 )
3084         return 0;
3085 
3086     ::rtl::OUString sHelpURL;
3087 
3088 //  INetURLObject aObj(aEntry);
3089 //  sal_Bool bComplete = ( aObj.GetProtocol() == INET_PROT_VND_SUN_STAR_HELP );
3090 
3091     sal_Bool bComplete = rtl::OUString(aEntry).toAsciiLowerCase().match(rtl::OUString::createFromAscii("vnd.sun.star.help"),0);
3092 
3093     if (bComplete)
3094         sHelpURL = ::rtl::OUString(aEntry);
3095     else
3096     {
3097         String aId;
3098         String aAnchor = String('#');
3099         if ( aEntry.GetTokenCount( '#' ) == 2 )
3100         {
3101             aId = aEntry.GetToken( 0, '#' );
3102             aAnchor += aEntry.GetToken( 1, '#' );
3103         }
3104         else
3105             aId = aEntry;
3106 
3107         aEntry  = '/';
3108         aEntry += aId;
3109 
3110         sHelpURL = SfxHelpWindow_Impl::buildHelpURL(pIndexWin->GetFactory(),
3111                                                     aEntry,
3112                                                     aAnchor,
3113                                                     sal_True);
3114     }
3115 
3116     loadHelpContent(sHelpURL);
3117 
3118     return 0;
3119 }
3120 
3121 //-------------------------------------------------------------------------
3122 
3123 IMPL_LINK( SfxHelpWindow_Impl, SelectFactoryHdl, SfxHelpIndexWindow_Impl* , pWin )
3124 {
3125     if ( sTitle.Len() == 0 )
3126         sTitle = GetParent()->GetText();
3127 
3128     String aNewTitle = sTitle;
3129     aNewTitle += DEFINE_CONST_UNICODE(" - ");
3130     aNewTitle += pIndexWin->GetActiveFactoryTitle();
3131 
3132     Reference< XTitle > xTitle(xFrame, UNO_QUERY);
3133     if (xTitle.is ())
3134         xTitle->setTitle (aNewTitle);
3135 
3136     if ( pWin )
3137         ShowStartPage();
3138     pIndexWin->ClearSearchPage();
3139 
3140     return 0;
3141 }
3142 
3143 // -----------------------------------------------------------------------
3144 
3145 IMPL_LINK( SfxHelpWindow_Impl, ChangeHdl, HelpListener_Impl*, pListener )
3146 {
3147     SetFactory( pListener->GetFactory() );
3148     return 0;
3149 }
3150 
3151 // -----------------------------------------------------------------------
3152 
3153 void SfxHelpWindow_Impl::openDone(const ::rtl::OUString& sURL    ,
3154                                         sal_Bool         bSuccess)
3155 {
3156     INetURLObject aObj( sURL );
3157     if ( aObj.GetProtocol() == INET_PROT_VND_SUN_STAR_HELP )
3158         SetFactory( aObj.GetHost() );
3159     if ( IsWait() )
3160         LeaveWait();
3161     if ( bGrabFocusToToolBox )
3162     {
3163         pTextWin->GetToolBox().GrabFocus();
3164         bGrabFocusToToolBox = sal_False;
3165     }
3166     else
3167         pIndexWin->GrabFocusBack();
3168     if ( bSuccess )
3169     {
3170         // set some view settings: "prevent help tips" and "helpid == 68245"
3171         try
3172         {
3173             Reference < XController > xController = pTextWin->getFrame()->getController();
3174             if ( xController.is() )
3175             {
3176                 Reference < XViewSettingsSupplier > xSettings( xController, UNO_QUERY );
3177                 Reference < XPropertySet > xViewProps = xSettings->getViewSettings();
3178                 Reference< XPropertySetInfo > xInfo = xViewProps->getPropertySetInfo();
3179                 Any aBoolAny = makeAny( sal_Bool( sal_True ) );
3180                 xViewProps->setPropertyValue( DEFINE_CONST_OUSTRING("PreventHelpTips"), aBoolAny );
3181                 xViewProps->setPropertyValue( DEFINE_CONST_OUSTRING("ShowGraphics"), aBoolAny );
3182                 xViewProps->setPropertyValue( DEFINE_CONST_OUSTRING("ShowTables"), aBoolAny );
3183                 xViewProps->setPropertyValue( DEFINE_CONST_OUSTRING("HelpURL"), makeAny( DEFINE_CONST_OUSTRING("HID:SFX2_HID_HELP_ONHELP") ) );
3184                 ::rtl::OUString sProperty( DEFINE_CONST_OUSTRING("IsExecuteHyperlinks") );
3185                 if ( xInfo->hasPropertyByName( sProperty ) )
3186                     xViewProps->setPropertyValue( sProperty, aBoolAny );
3187                 xController->restoreViewData(pHelpInterceptor->GetViewData());
3188             }
3189         }
3190         catch( Exception& )
3191         {
3192             DBG_ERROR( "SfxHelpWindow_Impl::OpenDoneHdl(): unexpected exception" );
3193         }
3194 
3195         // When the SearchPage opens the help doc, then select all words, which are equal to its text
3196         String sSearchText = TRIM( pIndexWin->GetSearchText() );
3197         if ( sSearchText.Len() > 0 )
3198             pTextWin->SelectSearchText( sSearchText, pIndexWin->IsFullWordSearch() );
3199 
3200         // no page style header -> this prevents a print output of the URL
3201         pTextWin->SetPageStyleHeaderOff();
3202     }
3203 }
3204 
3205 // -----------------------------------------------------------------------
3206 
3207 SfxHelpWindow_Impl::SfxHelpWindow_Impl(
3208     const ::com::sun::star::uno::Reference < ::com::sun::star::frame::XFrame >& rFrame,
3209     Window* pParent, WinBits ) :
3210 
3211     SplitWindow( pParent, WB_3DLOOK | WB_NOSPLITDRAW ),
3212 
3213     xFrame              ( rFrame ),
3214     pIndexWin           ( NULL ),
3215     pTextWin            ( NULL ),
3216     pHelpInterceptor    ( new HelpInterceptor_Impl() ),
3217     pHelpListener       ( new HelpListener_Impl( pHelpInterceptor ) ),
3218     nExpandWidth        ( 0 ),
3219     nCollapseWidth      ( 0 ),
3220     nHeight             ( 0 ),
3221     nIndexSize          ( 40 ),
3222     nTextSize           ( 60 ),
3223     bIndex              ( sal_True ),
3224     bGrabFocusToToolBox ( sal_False ),
3225     aWinPos             ( 0, 0 ),
3226     sTitle              ( pParent->GetText() )
3227 {
3228     SetHelpId( HID_HELP_WINDOW );
3229     SetStyle( GetStyle() | WB_DIALOGCONTROL );
3230 
3231     pHelpInterceptor->InitWaiter( this );
3232     pIndexWin = new SfxHelpIndexWindow_Impl( this );
3233     pIndexWin->SetDoubleClickHdl( LINK( this, SfxHelpWindow_Impl, OpenHdl ) );
3234     pIndexWin->SetSelectFactoryHdl( LINK( this, SfxHelpWindow_Impl, SelectFactoryHdl ) );
3235     pIndexWin->Show();
3236     pTextWin = new SfxHelpTextWindow_Impl( this );
3237     Reference < XFramesSupplier > xSup( rFrame, UNO_QUERY );
3238     Reference < XFrames > xFrames = xSup->getFrames();
3239     xFrames->append( pTextWin->getFrame() );
3240     pTextWin->SetSelectHdl( LINK( this, SfxHelpWindow_Impl, SelectHdl ) );
3241     pTextWin->Show();
3242     pHelpInterceptor->setInterception( pTextWin->getFrame() );
3243     pHelpListener->SetChangeHdl( LINK( this, SfxHelpWindow_Impl, ChangeHdl ) );
3244     LoadConfig();
3245 }
3246 
3247 // -----------------------------------------------------------------------
3248 
3249 SfxHelpWindow_Impl::~SfxHelpWindow_Impl()
3250 {
3251     SaveConfig();
3252     Window* pDel = pIndexWin;
3253     pIndexWin = NULL;
3254     delete pDel;
3255 
3256     pTextWin->CloseFrame();
3257     delete pTextWin;
3258 }
3259 
3260 // -----------------------------------------------------------------------
3261 
3262 long SfxHelpWindow_Impl::PreNotify( NotifyEvent& rNEvt )
3263 {
3264     sal_Bool bHandled = sal_False;
3265     if ( rNEvt.GetType() == EVENT_KEYINPUT )
3266     {
3267         // Backward == <ALT><LEFT> or <BACKSPACE> Forward == <ALT><RIGHT>
3268         const KeyCode& rKeyCode = rNEvt.GetKeyEvent()->GetKeyCode();
3269         sal_uInt16 nKey = rKeyCode.GetCode();
3270         if ( ( rKeyCode.IsMod2() && ( KEY_LEFT == nKey || KEY_RIGHT == nKey ) ) ||
3271              ( !rKeyCode.GetModifier() && KEY_BACKSPACE == nKey && !pIndexWin->HasFocusOnEdit() ) )
3272         {
3273             DoAction( rKeyCode.GetCode() == KEY_RIGHT ? TBI_FORWARD : TBI_BACKWARD );
3274             bHandled = sal_True;
3275         }
3276         else if ( rKeyCode.IsMod1() && ( KEY_F4 == nKey || KEY_W == nKey ) )
3277         {
3278             // <STRG><F4> or <STRG><W> -> close top frame
3279             CloseWindow();
3280             bHandled = sal_True;
3281         }
3282     }
3283     return bHandled ? 1 : Window::PreNotify( rNEvt );
3284 }
3285 
3286 // -----------------------------------------------------------------------
3287 
3288 void SfxHelpWindow_Impl::setContainerWindow( Reference < ::com::sun::star::awt::XWindow > xWin )
3289 {
3290     xWindow = xWin;
3291     MakeLayout();
3292 }
3293 
3294 // -----------------------------------------------------------------------
3295 
3296 void SfxHelpWindow_Impl::SetFactory( const String& rFactory )
3297 {
3298     pIndexWin->SetFactory( rFactory, sal_True );
3299 }
3300 
3301 // -----------------------------------------------------------------------
3302 
3303 void SfxHelpWindow_Impl::SetHelpURL( const String& rURL )
3304 {
3305     INetURLObject aObj( rURL );
3306     if ( aObj.GetProtocol() == INET_PROT_VND_SUN_STAR_HELP )
3307         SetFactory( aObj.GetHost() );
3308 }
3309 
3310 // -----------------------------------------------------------------------
3311 
3312 void SfxHelpWindow_Impl::DoAction( sal_uInt16 nActionId )
3313 {
3314     switch ( nActionId )
3315     {
3316         case TBI_INDEX :
3317         {
3318             bIndex = !bIndex;
3319             MakeLayout();
3320             pTextWin->ToggleIndex( bIndex );
3321             break;
3322         }
3323 
3324         case TBI_START :
3325         {
3326             ShowStartPage();
3327             break;
3328         }
3329 
3330         case TBI_BACKWARD :
3331         case TBI_FORWARD :
3332         {
3333             URL aURL;
3334             aURL.Complete = DEFINE_CONST_UNICODE(".uno:Backward");
3335             if ( TBI_FORWARD == nActionId )
3336                 aURL.Complete = DEFINE_CONST_UNICODE(".uno:Forward");
3337             PARSE_URL( aURL );
3338             pHelpInterceptor->dispatch( aURL, Sequence < PropertyValue >() );
3339             break;
3340         }
3341 
3342         case TBI_SEARCHDIALOG :
3343         {
3344             pTextWin->DoSearch();
3345             break;
3346         }
3347 
3348         case TBI_PRINT :
3349         case TBI_SOURCEVIEW :
3350         case TBI_COPY :
3351         case TBI_SELECTIONMODE:
3352         {
3353             Reference < XDispatchProvider > xProv( pTextWin->getFrame(), UNO_QUERY );
3354             if ( xProv.is() )
3355             {
3356                 URL aURL;
3357                 if ( TBI_PRINT == nActionId )
3358                     aURL.Complete = DEFINE_CONST_UNICODE(".uno:Print");
3359                 else if ( TBI_SOURCEVIEW == nActionId )
3360                     aURL.Complete = DEFINE_CONST_UNICODE(".uno:SourceView");
3361                 else if ( TBI_COPY == nActionId )
3362                     aURL.Complete = DEFINE_CONST_UNICODE(".uno:Copy");
3363                 else if ( TBI_SELECTIONMODE == nActionId )
3364                     aURL.Complete = DEFINE_CONST_UNICODE(".uno:SelectTextMode");
3365                 else
3366                     aURL.Complete = DEFINE_CONST_UNICODE(".uno:SearchDialog");
3367                 PARSE_URL( aURL );
3368                 Reference < XDispatch > xDisp = xProv->queryDispatch( aURL, String(), 0 );
3369                 if ( xDisp.is() )
3370                     xDisp->dispatch( aURL, Sequence < PropertyValue >() );
3371             }
3372             break;
3373         }
3374 
3375         case TBI_BOOKMARKS :
3376         {
3377             String aURL = pHelpInterceptor->GetCurrentURL();
3378             if ( aURL.Len() > 0 )
3379             {
3380                 try
3381                 {
3382                     Content aCnt( aURL, Reference< ::com::sun::star::ucb::XCommandEnvironment > () );
3383                     ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > xInfo = aCnt.getProperties();
3384                     if ( xInfo->hasPropertyByName( PROPERTY_TITLE ) )
3385                     {
3386                         ::com::sun::star::uno::Any aAny = aCnt.getPropertyValue( PROPERTY_TITLE );
3387                         rtl::OUString aValue;
3388                         if ( aAny >>= aValue )
3389                         {
3390                             String aTitle( aValue );
3391                             SfxAddHelpBookmarkDialog_Impl aDlg( this, sal_False );
3392                             aDlg.SetTitle( aTitle );
3393                             if ( aDlg.Execute() == RET_OK )
3394                             {
3395                                 aTitle = aDlg.GetTitle();
3396                                 pIndexWin->AddBookmarks( aTitle, aURL );
3397                             }
3398                         }
3399                     }
3400                 }
3401                 catch( Exception& )
3402                 {
3403                     DBG_ERROR( "SfxHelpWindow_Impl::DoAction(): unexpected exception" );
3404                 }
3405             }
3406             break;
3407         }
3408     }
3409 }
3410 
3411 // -----------------------------------------------------------------------
3412 
3413 void SfxHelpWindow_Impl::CloseWindow()
3414 {
3415     try
3416     {
3417         // search for top frame
3418         Reference< XFramesSupplier > xCreator = getTextFrame()->getCreator();
3419         while ( xCreator.is() && !xCreator->isTop() )
3420         {
3421             xCreator = xCreator->getCreator();
3422         }
3423 
3424         // when found, close it
3425         if ( xCreator.is() && xCreator->isTop() )
3426         {
3427             Reference < XCloseable > xCloser( xCreator, UNO_QUERY );
3428             if ( xCloser.is() )
3429                 xCloser->close( sal_False );
3430         }
3431     }
3432     catch( Exception& )
3433     {
3434         DBG_ERRORFILE( "SfxHelpWindow_Impl::CloseWindow(): caught an exception" );
3435     }
3436 }
3437 
3438 // -----------------------------------------------------------------------
3439 
3440 void SfxHelpWindow_Impl::UpdateToolbox()
3441 {
3442     pTextWin->GetToolBox().EnableItem( TBI_BACKWARD, pHelpInterceptor->HasHistoryPred() );
3443     pTextWin->GetToolBox().EnableItem( TBI_FORWARD, pHelpInterceptor->HasHistorySucc() );
3444 }
3445 
3446 // -----------------------------------------------------------------------
3447 
3448 sal_Bool SfxHelpWindow_Impl::HasHistoryPredecessor() const
3449 {
3450     return pHelpInterceptor->HasHistoryPred();
3451 }
3452 
3453 // -----------------------------------------------------------------------
3454 
3455 sal_Bool SfxHelpWindow_Impl::HasHistorySuccessor() const
3456 {
3457     return pHelpInterceptor->HasHistorySucc();
3458 }
3459 
3460 // class SfxAddHelpBookmarkDialog_Impl -----------------------------------
3461 
3462 SfxAddHelpBookmarkDialog_Impl::SfxAddHelpBookmarkDialog_Impl( Window* pParent, sal_Bool bRename ) :
3463 
3464     ModalDialog( pParent, SfxResId( DLG_HELP_ADDBOOKMARK ) ),
3465 
3466     aTitleFT    ( this, SfxResId( FT_BOOKMARK_TITLE ) ),
3467     aTitleED    ( this, SfxResId( ED_BOOKMARK_TITLE ) ),
3468     aOKBtn      ( this, SfxResId( PB_BOOKMARK_OK ) ),
3469     aEscBtn     ( this, SfxResId( PB_BOOKMARK_CANCEL ) ),
3470     aHelpBtn    ( this, SfxResId( PB_BOOKMARK_HELP ) )
3471 
3472 {
3473     if ( bRename )
3474         SetText( String( SfxResId( STR_BOOKMARK_RENAME ) ) );
3475 
3476     FreeResource();
3477 }
3478 
3479 // -----------------------------------------------------------------------
3480 
3481 SfxAddHelpBookmarkDialog_Impl::~SfxAddHelpBookmarkDialog_Impl()
3482 {
3483 }
3484 
3485 // -----------------------------------------------------------------------
3486 
3487 void SfxAddHelpBookmarkDialog_Impl::SetTitle( const String& rTitle )
3488 {
3489     aTitleED.SetText( rTitle );
3490     aTitleED.SetSelection( Selection( 0, rTitle.Len() ) );
3491 }
3492 
3493