xref: /aoo42x/main/sfx2/source/appl/newhelp.cxx (revision cdf0e10c)
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