Version 3.6.0.4, tag libreoffice-3.6.0.4
[LibreOffice.git] / sfx2 / source / appl / newhelp.cxx
blobbc7900f29488a00a61193f93b20c9cc60a710f11
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
30 #include "newhelp.hxx"
31 #include <sfx2/sfxuno.hxx>
32 #include "sfx2/sfxresid.hxx"
33 #include "helpinterceptor.hxx"
34 #include "helper.hxx"
35 #include <sfx2/msgpool.hxx>
36 #include <sfx2/app.hxx>
37 #include "sfxtypes.hxx"
38 #include "panelist.hxx"
39 #include "sfx2/imgmgr.hxx"
40 #include "srchdlg.hxx"
41 #include "sfx2/sfxhelp.hxx"
43 #include "app.hrc"
44 #include "newhelp.hrc"
45 #include "helpid.hrc"
47 #include <boost/unordered_map.hpp>
48 #include <rtl/ustrbuf.hxx>
49 #include <comphelper/configurationhelper.hxx>
50 #include <comphelper/processfactory.hxx>
51 #include <comphelper/string.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 #include <com/sun/star/i18n/XBreakIterator.hpp>
74 #include <com/sun/star/i18n/WordType.hpp>
75 #include <com/sun/star/style/XStyle.hpp>
76 #include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
77 #include <com/sun/star/text/XText.hpp>
78 #include <com/sun/star/text/XTextCursor.hpp>
79 #include <com/sun/star/text/XTextDocument.hpp>
80 #include <com/sun/star/text/XTextRange.hpp>
81 #include <com/sun/star/text/XTextViewCursor.hpp>
82 #include <com/sun/star/text/XTextViewCursorSupplier.hpp>
83 #include <com/sun/star/ucb/CommandAbortedException.hpp>
84 #include <com/sun/star/util/URL.hpp>
85 #include <com/sun/star/util/XSearchable.hpp>
86 #include <com/sun/star/util/XSearchDescriptor.hpp>
87 #include <com/sun/star/util/XURLTransformer.hpp>
88 #include <com/sun/star/view/XSelectionSupplier.hpp>
89 #include <com/sun/star/view/XViewSettingsSupplier.hpp>
90 #include <com/sun/star/ui/XDockingAreaAcceptor.hpp>
91 #include <svtools/helpopt.hxx>
92 #include <unotools/historyoptions.hxx>
93 #include <svtools/menuoptions.hxx>
94 #include <unotools/pathoptions.hxx>
95 #include <unotools/viewoptions.hxx>
96 #include <svtools/svtresid.hxx>
97 #include <tools/urlobj.hxx>
98 #include <unotools/streamhelper.hxx>
99 #include <svtools/imagemgr.hxx>
100 #include <svtools/miscopt.hxx>
101 #include <svtools/imgdef.hxx>
102 #include <vcl/unohelp.hxx>
103 #include <vcl/i18nhelp.hxx>
105 #include <ucbhelper/content.hxx>
106 #include <vcl/msgbox.hxx>
107 #include <vcl/waitobj.hxx>
108 #include <unotools/ucbhelper.hxx>
110 #include <sfx2/viewfrm.hxx>
111 #include <sfx2/objsh.hxx>
112 #include <sfx2/docfac.hxx>
114 using namespace ::ucbhelper;
115 using namespace ::com::sun::star::ucb;
117 using namespace ::com::sun::star;
118 using namespace ::com::sun::star::beans;
119 using namespace ::com::sun::star::container;
120 using namespace ::com::sun::star::frame;
121 using namespace ::com::sun::star::i18n;
122 using namespace ::com::sun::star::lang;
123 using namespace ::com::sun::star::style;
124 using namespace ::com::sun::star::text;
125 using namespace ::com::sun::star::uno;
126 using namespace ::com::sun::star::util;
127 using namespace ::com::sun::star::view;
128 using namespace ::com::sun::star::ui;
130 using namespace ::comphelper;
132 // defines ---------------------------------------------------------------
134 #define SPLITSET_ID 0
135 #define COLSET_ID 1
136 #define INDEXWIN_ID 2
137 #define TEXTWIN_ID 3
139 #define TOOLBOX_OFFSET 3
141 #define TBI_INDEX 1001
142 #define TBI_BACKWARD 1002
143 #define TBI_FORWARD 1003
144 #define TBI_START 1004
145 #define TBI_PRINT 1005
146 #define TBI_COPY 1006
147 #define TBI_BOOKMARKS 1007
148 #define TBI_SEARCHDIALOG 1008
149 #define TBI_SOURCEVIEW 1009
150 #define TBI_SELECTIONMODE 1010
151 #define TBI_ONSTARTUP 1011
153 #define CONFIGNAME_HELPWIN DEFINE_CONST_UNICODE("OfficeHelp")
154 #define CONFIGNAME_INDEXWIN DEFINE_CONST_UNICODE("OfficeHelpIndex")
155 #define CONFIGNAME_SEARCHPAGE DEFINE_CONST_UNICODE("OfficeHelpSearch")
156 #define IMAGE_URL DEFINE_CONST_UNICODE("private:factory/")
158 #define PROPERTY_KEYWORDLIST DEFINE_CONST_OUSTRING("KeywordList")
159 #define PROPERTY_KEYWORDREF DEFINE_CONST_OUSTRING("KeywordRef")
160 #define PROPERTY_ANCHORREF DEFINE_CONST_OUSTRING("KeywordAnchorForRef")
161 #define PROPERTY_TITLEREF DEFINE_CONST_OUSTRING("KeywordTitleForRef")
162 #define PROPERTY_TITLE DEFINE_CONST_OUSTRING("Title")
163 #define HELP_URL DEFINE_CONST_OUSTRING("vnd.sun.star.help://")
164 #define HELP_SEARCH_TAG DEFINE_CONST_OUSTRING("/?Query=")
165 #define USERITEM_NAME DEFINE_CONST_OUSTRING("UserItem")
167 #define PACKAGE_SETUP DEFINE_CONST_OUSTRING("/org.openoffice.Setup")
168 #define PATH_OFFICE_FACTORIES DEFINE_CONST_OUSTRING("Office/Factories/")
169 #define KEY_HELP_ON_OPEN DEFINE_CONST_OUSTRING("ooSetupFactoryHelpOnOpen")
170 #define KEY_UI_NAME DEFINE_CONST_OUSTRING("ooSetupFactoryUIName")
172 #define PARSE_URL( aURL ) \
173 Reference < XURLTransformer > xTrans( ::comphelper::getProcessServiceFactory()->createInstance( \
174 DEFINE_CONST_UNICODE("com.sun.star.util.URLTransformer" )), UNO_QUERY ); \
175 xTrans->parseStrict( aURL )
177 //.........................................................................
178 namespace sfx2
180 //.........................................................................
182 void HandleTaskPaneList( Window* pWindow, sal_Bool bAddToList )
184 Window* pParent = pWindow->GetParent();
185 DBG_ASSERT( pParent, "HandleTaskPaneList(): every window here should have a parent" );
187 SystemWindow* pSysWin = pParent->GetSystemWindow();
188 if( pSysWin )
190 TaskPaneList* pTaskPaneList = pSysWin->GetTaskPaneList();
191 if( pTaskPaneList )
193 if( bAddToList )
194 pTaskPaneList->AddWindow( pWindow );
195 else
196 pTaskPaneList->RemoveWindow( pWindow );
201 /** Prepare a search string for searching or selecting.
202 For searching every search word needs the postfix '*' and the delimiter ' ' if necessary.
203 For selecting the delimiter '|' is required to search with regular expressions.
204 Samples:
205 search string | output for searching | output for selecting
206 -----------------------------------------------------------
207 "text" | "text*" | "text"
208 "text*" | "text*" | "text"
209 "text menu" | "text* menu*" | "text|menu"
211 String PrepareSearchString( const String& rSearchString,
212 Reference< XBreakIterator > xBreak, bool bForSearch )
214 String sSearchStr;
215 sal_Int32 nStartPos = 0;
216 const Locale aLocale = Application::GetSettings().GetUILocale();
217 Boundary aBoundary = xBreak->getWordBoundary(
218 rSearchString, nStartPos, aLocale, WordType::ANYWORD_IGNOREWHITESPACES, sal_True );
220 while ( aBoundary.startPos != aBoundary.endPos )
222 nStartPos = aBoundary.endPos;
223 String sSearchToken( rSearchString.Copy(
224 (sal_uInt16)aBoundary.startPos, (sal_uInt16)aBoundary.endPos - (sal_uInt16)aBoundary.startPos ) );
225 if ( sSearchToken.Len() > 0 && ( sSearchToken.Len() > 1 || sSearchToken.GetChar(0) != '.' ) )
227 if ( bForSearch && sSearchToken.GetChar( sSearchToken.Len() - 1 ) != '*' )
228 sSearchToken += '*';
230 if ( sSearchToken.Len() > 1 ||
231 ( sSearchToken.Len() > 0 && sSearchToken.GetChar( 0 ) != '*' ) )
233 if ( sSearchStr.Len() > 0 )
235 if ( bForSearch )
236 sSearchStr += ' ';
237 else
238 sSearchStr += '|';
240 sSearchStr += sSearchToken;
243 aBoundary = xBreak->nextWord( rSearchString, nStartPos,
244 aLocale, WordType::ANYWORD_IGNOREWHITESPACES );
247 return sSearchStr;
249 //.........................................................................
250 // namespace sfx2
252 //.........................................................................
254 // struct IndexEntry_Impl ------------------------------------------------
256 struct IndexEntry_Impl
258 sal_Bool m_bSubEntry;
259 String m_aURL;
261 IndexEntry_Impl( const String& rURL, sal_Bool bSubEntry ) :
262 m_bSubEntry( bSubEntry ), m_aURL( rURL ) {}
265 #define NEW_ENTRY( url, bool ) \
266 (void*)(sal_uIntPtr)( new IndexEntry_Impl( url, bool ) )
268 // struct ContentEntry_Impl ----------------------------------------------
270 struct ContentEntry_Impl
272 String aURL;
273 sal_Bool bIsFolder;
275 ContentEntry_Impl( const String& rURL, sal_Bool bFolder ) :
276 aURL( rURL ), bIsFolder( bFolder ) {}
279 // ContentListBox_Impl ---------------------------------------------------
281 ContentListBox_Impl::ContentListBox_Impl( Window* pParent, const ResId& rResId ) :
283 SvTreeListBox( pParent, rResId ),
285 aOpenBookImage ( SfxResId( IMG_HELP_CONTENT_BOOK_OPEN ) ),
286 aClosedBookImage ( SfxResId( IMG_HELP_CONTENT_BOOK_CLOSED ) ),
287 aDocumentImage ( SfxResId( IMG_HELP_CONTENT_DOC ) )
290 SetStyle( GetStyle() | WB_HIDESELECTION | WB_HSCROLL );
292 SetEntryHeight( 16 );
293 SetSelectionMode( SINGLE_SELECTION );
294 SetSpaceBetweenEntries( 2 );
295 SetNodeBitmaps( aClosedBookImage, aOpenBookImage );
297 SetSublistOpenWithReturn();
298 SetSublistOpenWithLeftRight();
300 InitRoot();
303 // -----------------------------------------------------------------------
305 ContentListBox_Impl::~ContentListBox_Impl()
307 sal_uInt16 nPos = 0;
308 SvLBoxEntry* pEntry = GetEntry( nPos++ );
309 while ( pEntry )
311 ::rtl::OUString aTemp( GetEntryText( pEntry ) );
312 ClearChildren( pEntry );
313 delete (ContentEntry_Impl*)pEntry->GetUserData();
314 pEntry = GetEntry( nPos++ );
318 // -----------------------------------------------------------------------
320 void ContentListBox_Impl::InitRoot()
322 String aHelpTreeviewURL( DEFINE_CONST_UNICODE("vnd.sun.star.hier://com.sun.star.help.TreeView/") );
323 ::com::sun::star::uno::Sequence< ::rtl::OUString > aList =
324 SfxContentHelper::GetHelpTreeViewContents( aHelpTreeviewURL );
326 const ::rtl::OUString* pEntries = aList.getConstArray();
327 sal_uInt32 i, nCount = aList.getLength();
328 for ( i = 0; i < nCount; ++i )
330 String aRow( pEntries[i] );
331 String aTitle, aURL;
332 xub_StrLen nIdx = 0;
333 aTitle = aRow.GetToken( 0, '\t', nIdx );
334 aURL = aRow.GetToken( 0, '\t', nIdx );
335 sal_Unicode cFolder = aRow.GetToken( 0, '\t', nIdx ).GetChar(0);
336 sal_Bool bIsFolder = ( '1' == cFolder );
337 SvLBoxEntry* pEntry = InsertEntry( aTitle, aOpenBookImage, aClosedBookImage, NULL, sal_True );
338 if ( bIsFolder )
339 pEntry->SetUserData( new ContentEntry_Impl( aURL, sal_True ) );
343 // -----------------------------------------------------------------------
345 void ContentListBox_Impl::ClearChildren( SvLBoxEntry* pParent )
347 SvLBoxEntry* pEntry = FirstChild( pParent );
348 while ( pEntry )
350 ::rtl::OUString aTemp( GetEntryText( pEntry ) );
351 ClearChildren( pEntry );
352 delete (ContentEntry_Impl*)pEntry->GetUserData();
353 pEntry = NextSibling( pEntry );
357 // -----------------------------------------------------------------------
359 void ContentListBox_Impl::RequestingChildren( SvLBoxEntry* pParent )
363 if ( !pParent->HasChildren() )
365 if ( pParent->GetUserData() )
367 String aTmpURL( ( (ContentEntry_Impl*)pParent->GetUserData() )->aURL );
368 ::com::sun::star::uno::Sequence< ::rtl::OUString > aList =
369 SfxContentHelper::GetHelpTreeViewContents( aTmpURL );
371 const ::rtl::OUString* pEntries = aList.getConstArray();
372 sal_uInt32 i, nCount = aList.getLength();
373 for ( i = 0; i < nCount; ++i )
375 String aRow( pEntries[i] );
376 String aTitle, aURL;
377 xub_StrLen nIdx = 0;
378 aTitle = aRow.GetToken( 0, '\t', nIdx );
379 aURL = aRow.GetToken( 0, '\t', nIdx );
380 sal_Unicode cFolder = aRow.GetToken( 0, '\t', nIdx ).GetChar(0);
381 sal_Bool bIsFolder = ( '1' == cFolder );
382 SvLBoxEntry* pEntry = NULL;
383 if ( bIsFolder )
385 pEntry = InsertEntry( aTitle, aOpenBookImage, aClosedBookImage, pParent, sal_True );
386 pEntry->SetUserData( new ContentEntry_Impl( aURL, sal_True ) );
388 else
390 pEntry = InsertEntry( aTitle, aDocumentImage, aDocumentImage, pParent );
391 Any aAny( ::utl::UCBContentHelper::GetProperty( aURL, String("TargetURL" ) ) );
392 rtl::OUString aTargetURL;
393 if ( aAny >>= aTargetURL )
394 pEntry->SetUserData( new ContentEntry_Impl( aTargetURL, sal_False ) );
400 catch( Exception& )
402 OSL_FAIL( "ContentListBox_Impl::RequestingChildren(): unexpected exception" );
406 // -----------------------------------------------------------------------
408 long ContentListBox_Impl::Notify( NotifyEvent& rNEvt )
410 sal_Bool bHandled = sal_False;
411 if ( rNEvt.GetType() == EVENT_KEYINPUT &&
412 KEY_RETURN == rNEvt.GetKeyEvent()->GetKeyCode().GetCode() )
414 GetDoubleClickHdl().Call( NULL );
415 bHandled = sal_True;
418 return bHandled ? 1 : SvTreeListBox::Notify( rNEvt );
421 // -----------------------------------------------------------------------
423 String ContentListBox_Impl::GetSelectEntry() const
425 String aRet;
426 SvLBoxEntry* pEntry = FirstSelected();
427 if ( pEntry && !( (ContentEntry_Impl*)pEntry->GetUserData() )->bIsFolder )
428 aRet = ( (ContentEntry_Impl*)pEntry->GetUserData() )->aURL;
429 return aRet;
432 // class HelpTabPage_Impl ------------------------------------------------
434 HelpTabPage_Impl::HelpTabPage_Impl(
435 Window* pParent, SfxHelpIndexWindow_Impl* _pIdxWin, const ResId& rResId ) :
437 TabPage( pParent, rResId ),
439 m_pIdxWin( _pIdxWin )
444 // class ContentTabPage_Impl ---------------------------------------------
446 ContentTabPage_Impl::ContentTabPage_Impl( Window* pParent, SfxHelpIndexWindow_Impl* _pIdxWin ) :
448 HelpTabPage_Impl( pParent, _pIdxWin, SfxResId( TP_HELP_CONTENT ) ),
450 aContentBox( this, SfxResId( LB_CONTENTS ) )
453 FreeResource();
455 aContentBox.Show();
458 // -----------------------------------------------------------------------
460 void ContentTabPage_Impl::Resize()
462 Size aSize = GetOutputSizePixel();
463 aSize.Width() -= 8;
464 aSize.Height() -= 8;
465 aContentBox.SetPosSizePixel( Point( 4, 4 ), aSize );
468 // -----------------------------------------------------------------------
470 void ContentTabPage_Impl::ActivatePage()
472 if ( !m_pIdxWin->WasCursorLeftOrRight() )
473 SetFocusOnBox();
476 // -----------------------------------------------------------------------
478 Control* ContentTabPage_Impl::GetLastFocusControl()
480 return &aContentBox;
483 // class IndexBox_Impl ---------------------------------------------------
485 IndexBox_Impl::IndexBox_Impl( Window* pParent, const ResId& rResId ) :
487 ComboBox( pParent, rResId )
490 EnableAutocomplete( sal_True );
491 EnableUserDraw( sal_True );
494 // -----------------------------------------------------------------------
496 void IndexBox_Impl::UserDraw( const UserDrawEvent& rUDEvt )
498 IndexEntry_Impl* pEntry = (IndexEntry_Impl*)(sal_uIntPtr)GetEntryData( rUDEvt.GetItemId() );
499 if ( pEntry && pEntry->m_bSubEntry )
501 // indent sub entries
502 Point aPos( rUDEvt.GetRect().TopLeft() );
503 aPos.X() += 8;
504 aPos.Y() += ( rUDEvt.GetRect().GetHeight() - rUDEvt.GetDevice()->GetTextHeight() ) / 2;
505 String aEntry( GetEntry( rUDEvt.GetItemId() ) );
506 sal_uInt16 nPos = aEntry.Search( ';' );
507 rUDEvt.GetDevice()->DrawText( aPos, ( nPos != STRING_NOTFOUND ) ? aEntry.Copy( nPos + 1 ) : aEntry );
509 else
510 DrawEntry( rUDEvt, sal_False, sal_True, sal_True );
513 // -----------------------------------------------------------------------
515 long IndexBox_Impl::Notify( NotifyEvent& rNEvt )
517 sal_Bool bHandled = sal_False;
518 if ( rNEvt.GetType() == EVENT_KEYINPUT &&
519 KEY_RETURN == rNEvt.GetKeyEvent()->GetKeyCode().GetCode() )
521 GetDoubleClickHdl().Call( NULL );
522 bHandled = sal_True;
525 return bHandled ? 1 : ComboBox::Notify( rNEvt );
528 // -----------------------------------------------------------------------
530 void IndexBox_Impl::SelectExecutableEntry()
532 sal_uInt16 nPos = GetEntryPos( GetText() );
533 if ( nPos != COMBOBOX_ENTRY_NOTFOUND )
535 sal_uInt16 nOldPos = nPos;
536 String aEntryText;
537 IndexEntry_Impl* pEntry = (IndexEntry_Impl*)(sal_uIntPtr)GetEntryData( nPos );
538 sal_uInt16 nCount = GetEntryCount();
539 while ( nPos < nCount && ( !pEntry || pEntry->m_aURL.Len() == 0 ) )
541 pEntry = (IndexEntry_Impl*)(sal_uIntPtr)GetEntryData( ++nPos );
542 aEntryText = GetEntry( nPos );
545 if ( nOldPos != nPos )
546 SetText( aEntryText );
550 // class IndexTabPage_Impl -----------------------------------------------
552 IndexTabPage_Impl::IndexTabPage_Impl( Window* pParent, SfxHelpIndexWindow_Impl* _pIdxWin ) :
554 HelpTabPage_Impl( pParent, _pIdxWin, SfxResId( TP_HELP_INDEX ) ),
556 aExpressionFT ( this, SfxResId( FT_EXPRESSION ) ),
557 aIndexCB ( this, SfxResId( CB_INDEX ) ),
558 aOpenBtn ( this, SfxResId( PB_OPEN_INDEX ) ),
560 bIsActivated ( sal_False )
563 FreeResource();
565 aOpenBtn.SetClickHdl( LINK( this, IndexTabPage_Impl, OpenHdl ) );
566 Link aTimeoutLink = LINK( this, IndexTabPage_Impl, TimeoutHdl );
567 aFactoryTimer.SetTimeoutHdl( aTimeoutLink );
568 aFactoryTimer.SetTimeout( 300 );
569 aKeywordTimer.SetTimeoutHdl( aTimeoutLink );
570 aFactoryTimer.SetTimeout( 300 );
572 nMinWidth = aOpenBtn.GetSizePixel().Width();
575 // -----------------------------------------------------------------------
577 IndexTabPage_Impl::~IndexTabPage_Impl()
579 ClearIndex();
582 // -----------------------------------------------------------------------
584 namespace sfx2 {
586 struct equalOUString
588 bool operator()( const ::rtl::OUString& rKey1, const ::rtl::OUString& rKey2 ) const
590 return !!( rKey1 == rKey2 );
595 struct hashOUString
597 size_t operator()( const ::rtl::OUString& rName ) const
599 return rName.hashCode();
603 typedef ::boost::unordered_map< ::rtl::OUString, int, hashOUString, equalOUString > KeywordInfo;
606 #define UNIFY_AND_INSERT_TOKEN( aToken ) \
607 it = \
608 aInfo.insert( sfx2::KeywordInfo::value_type( aToken, 0 ) ).first; \
609 if ( ( tmp = it->second++ ) != 0 ) \
610 nPos = aIndexCB.InsertEntry( aToken + rtl::OUString( append, tmp ) ); \
611 else \
612 nPos = aIndexCB.InsertEntry( aToken )
614 #define INSERT_DATA( j ) \
615 if ( aAnchorList[j].getLength() > 0 ) \
617 aData.append( aRefList[j] ).append( sal_Unicode('#') ).append( aAnchorList[j] ); \
618 aIndexCB.SetEntryData( nPos, NEW_ENTRY( aData.makeStringAndClear(), insert ) ); \
620 else \
621 aIndexCB.SetEntryData( nPos, NEW_ENTRY( aRefList[j], insert ) );
623 // -----------------------------------------------------------------------
625 void IndexTabPage_Impl::InitializeIndex()
627 WaitObject( this );
629 // By now more than 256 equal entries are not allowed
630 sal_Unicode append[256];
631 for( int k = 0; k < 256; ++k )
632 append[k] = sal_Unicode( ' ' );
634 sfx2::KeywordInfo aInfo;
635 aIndexCB.SetUpdateMode( sal_False );
639 ::rtl::OUString aURL = HELP_URL;
640 aURL += ::rtl::OUString( sFactory );
642 String aTemp = aURL;
643 AppendConfigToken( aTemp, sal_True );
644 aURL = aTemp;
646 Content aCnt( aURL, Reference< ::com::sun::star::ucb::XCommandEnvironment > () );
647 ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > xInfo = aCnt.getProperties();
648 if ( xInfo->hasPropertyByName( PROPERTY_ANCHORREF ) )
650 ::com::sun::star::uno::Sequence< ::rtl::OUString > aPropSeq( 4 );
651 aPropSeq[0] = PROPERTY_KEYWORDLIST;
652 aPropSeq[1] = PROPERTY_KEYWORDREF;
653 aPropSeq[2] = PROPERTY_ANCHORREF;
654 aPropSeq[3] = PROPERTY_TITLEREF;
656 // abi: use one possibly remote call only
657 ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any > aAnySeq =
658 aCnt.getPropertyValues( aPropSeq );
660 ::com::sun::star::uno::Sequence< ::rtl::OUString > aKeywordList;
661 ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< ::rtl::OUString > > aKeywordRefList;
662 ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< ::rtl::OUString > > aAnchorRefList;
663 ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< ::rtl::OUString > > aTitleRefList;
665 if ( ( aAnySeq[0] >>= aKeywordList ) && ( aAnySeq[1] >>= aKeywordRefList ) &&
666 ( aAnySeq[2] >>= aAnchorRefList ) && ( aAnySeq[3] >>= aTitleRefList ) )
668 sal_Bool insert;
669 sal_uInt16 nPos;
670 int ndx,tmp;
671 ::rtl::OUString aIndex, aTempString;
672 ::rtl::OUStringBuffer aData( 128 ); // Capacity of up to 128 characters
673 sfx2::KeywordInfo::iterator it;
675 for ( int i = 0; i < aKeywordList.getLength(); ++i )
677 // abi: Do not copy, but use references
678 const ::rtl::OUString& aKeywordPair = aKeywordList[i];
679 DBG_ASSERT( !aKeywordPair.isEmpty(), "invalid help index" );
680 const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aRefList = aKeywordRefList[i];
681 const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aAnchorList = aAnchorRefList[i];
682 const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aTitleList = aTitleRefList[i];
684 DBG_ASSERT( aRefList.getLength() == aAnchorList.getLength(),"reference list and title list of different length" );
686 insert = ( ( ndx = aKeywordPair.indexOf( sal_Unicode( ';' ) ) ) == -1 ? sal_False : sal_True );
688 if ( insert )
690 aTempString = aKeywordPair.copy( 0, ndx );
691 if ( aIndex != aTempString )
693 aIndex = aTempString;
694 UNIFY_AND_INSERT_TOKEN( aTempString );
697 else
698 aIndex = ::rtl::OUString();
700 // Assume the token is trimed
701 UNIFY_AND_INSERT_TOKEN( aKeywordPair );
703 sal_uInt32 nRefListLen = aRefList.getLength();
705 DBG_ASSERT( aAnchorList.getLength(), "*IndexTabPage_Impl::InitializeIndex(): AnchorList is empty!" ); \
706 DBG_ASSERT( nRefListLen, "*IndexTabPage_Impl::InitializeIndex(): RefList is empty!" ); \
708 if ( aAnchorList.getLength() && nRefListLen )
710 INSERT_DATA( 0 );
713 for ( sal_uInt32 j = 1; j < nRefListLen ; ++j )
715 aData
716 .append( aKeywordPair )
717 .append( sal_Unicode(' ') )
718 .append( sal_Unicode('-') )
719 .append( sal_Unicode(' ') )
720 .append( aTitleList[j] );
722 aTempString = aData.makeStringAndClear();
723 UNIFY_AND_INSERT_TOKEN( aTempString );
724 INSERT_DATA( j );
730 catch( Exception& )
732 OSL_FAIL( "IndexTabPage_Impl::InitializeIndex(): unexpected exception" );
735 aIndexCB.SetUpdateMode( sal_True );
737 if ( sKeyword.Len() > 0 )
738 aKeywordLink.Call( this );
741 #undef INSERT_DATA
742 #undef UNIFY_AND_INSERT_TOKEN
744 // -----------------------------------------------------------------------
746 void IndexTabPage_Impl::ClearIndex()
748 sal_uInt16 nCount = aIndexCB.GetEntryCount();
749 for ( sal_uInt16 i = 0; i < nCount; ++i )
750 delete (IndexEntry_Impl*)(sal_uIntPtr)aIndexCB.GetEntryData(i);
751 aIndexCB.Clear();
754 // -----------------------------------------------------------------------
756 IMPL_LINK_NOARG(IndexTabPage_Impl, OpenHdl)
758 aIndexCB.GetDoubleClickHdl().Call( &aIndexCB );
759 return 0;
762 // -----------------------------------------------------------------------
764 IMPL_LINK( IndexTabPage_Impl, TimeoutHdl, Timer*, pTimer )
766 if ( &aFactoryTimer == pTimer )
767 InitializeIndex();
768 else if ( &aKeywordTimer == pTimer && sKeyword.Len() > 0 )
769 aKeywordLink.Call( this );
770 return 0;
773 // -----------------------------------------------------------------------
775 void IndexTabPage_Impl::Resize()
777 Size aSize = GetSizePixel();
778 if ( aSize.Width() < nMinWidth )
779 aSize.Width() = nMinWidth;
780 Point aPnt = aExpressionFT.GetPosPixel();
781 Size aNewSize = aExpressionFT.GetSizePixel();
782 aNewSize.Width() = aSize.Width() - ( aPnt.X() * 2 );
783 aExpressionFT.SetSizePixel( aNewSize );
785 Size a6Size = LogicToPixel( Size( 6, 6 ), MAP_APPFONT );
786 Size aBtnSize = aOpenBtn.GetSizePixel();
788 aPnt = aIndexCB.GetPosPixel();
789 aNewSize = aIndexCB.GetSizePixel();
790 aNewSize.Width() = aSize.Width() - ( aPnt.X() * 2 );
791 aNewSize.Height() = aSize.Height() - aPnt.Y();
792 aNewSize.Height() -= ( aBtnSize.Height() + ( a6Size.Height() * 3 / 2 ) );
793 aIndexCB.SetSizePixel( aNewSize );
795 aPnt.X() += ( aNewSize.Width() - aBtnSize.Width() );
796 aPnt.Y() += aNewSize.Height() + ( a6Size.Height() / 2 );
797 long nMinX = aIndexCB.GetPosPixel().X();
798 if ( aPnt.X() < nMinX )
799 aPnt.X() = nMinX;
800 aOpenBtn.SetPosPixel( aPnt );
803 // -----------------------------------------------------------------------
805 void IndexTabPage_Impl::ActivatePage()
807 if ( !bIsActivated )
809 bIsActivated = sal_True;
810 aFactoryTimer.Start();
813 if ( !m_pIdxWin->WasCursorLeftOrRight() )
814 SetFocusOnBox();
817 // -----------------------------------------------------------------------
819 Control* IndexTabPage_Impl::GetLastFocusControl()
821 return &aOpenBtn;
824 // -----------------------------------------------------------------------
826 void IndexTabPage_Impl::SetDoubleClickHdl( const Link& rLink )
828 aIndexCB.SetDoubleClickHdl( rLink );
831 // -----------------------------------------------------------------------
833 void IndexTabPage_Impl::SetFactory( const String& rFactory )
835 String sNewFactory( rFactory );
836 DBG_ASSERT( sNewFactory.Len() > 0, "empty factory" );
837 bool bValid = m_pIdxWin->IsValidFactory( rFactory );
839 if ( sFactory.Len() == 0 && !bValid )
841 sNewFactory = SfxHelp::GetDefaultHelpModule();
842 bValid = true;
845 if ( sNewFactory != sFactory && bValid )
847 sFactory = sNewFactory;
848 ClearIndex();
849 if ( bIsActivated )
850 aFactoryTimer.Start();
854 // -----------------------------------------------------------------------
856 String IndexTabPage_Impl::GetSelectEntry() const
858 String aRet;
859 IndexEntry_Impl* pEntry = (IndexEntry_Impl*)(sal_uIntPtr)aIndexCB.GetEntryData( aIndexCB.GetEntryPos( aIndexCB.GetText() ) );
860 if ( pEntry )
861 aRet = pEntry->m_aURL;
862 return aRet;
865 // -----------------------------------------------------------------------
867 void IndexTabPage_Impl::SetKeyword( const String& rKeyword )
869 sKeyword = rKeyword;
871 if ( aIndexCB.GetEntryCount() > 0 )
872 aKeywordTimer.Start();
873 else if ( !bIsActivated )
874 aFactoryTimer.Start();
877 // -----------------------------------------------------------------------
879 sal_Bool IndexTabPage_Impl::HasKeyword() const
881 sal_Bool bRet = sal_False;
882 if ( sKeyword.Len() > 0 )
884 sal_uInt16 nPos = aIndexCB.GetEntryPos( sKeyword );
885 bRet = ( nPos != LISTBOX_ENTRY_NOTFOUND );
888 return bRet;
891 // -----------------------------------------------------------------------
893 sal_Bool IndexTabPage_Impl::HasKeywordIgnoreCase()
895 sal_Bool bRet = sal_False;
896 if ( sKeyword.Len() > 0 )
898 sal_uInt16 nEntries = aIndexCB.GetEntryCount();
899 String sIndexItem;
900 const vcl::I18nHelper& rI18nHelper = GetSettings().GetLocaleI18nHelper();
901 for ( sal_uInt16 n = 0; n < nEntries; n++)
903 sIndexItem = aIndexCB.GetEntry( n );
904 if (rI18nHelper.MatchString( sIndexItem, sKeyword ))
906 sKeyword = sIndexItem;
907 bRet = sal_True;
912 return bRet;
915 // -----------------------------------------------------------------------
917 void IndexTabPage_Impl::OpenKeyword()
919 if ( sKeyword.Len() > 0 )
921 aIndexCB.SetText( sKeyword );
922 aIndexCB.GetDoubleClickHdl().Call( NULL );
923 sKeyword.Erase();
927 // class SearchBox_Impl --------------------------------------------------
929 long SearchBox_Impl::PreNotify( NotifyEvent& rNEvt )
931 sal_Bool bHandled = sal_False;
932 if ( !IsInDropDown() &&
933 rNEvt.GetWindow() == GetSubEdit() &&
934 rNEvt.GetType() == EVENT_KEYINPUT &&
935 KEY_RETURN == rNEvt.GetKeyEvent()->GetKeyCode().GetCode() )
937 aSearchLink.Call( NULL );
938 bHandled = sal_True;
940 return bHandled ? 1 : ComboBox::PreNotify( rNEvt );
943 // -----------------------------------------------------------------------
945 void SearchBox_Impl::Select()
947 if ( !IsTravelSelect() )
948 aSearchLink.Call( NULL );
951 // class SearchResultsBox_Impl -------------------------------------------
953 long SearchResultsBox_Impl::Notify( NotifyEvent& rNEvt )
955 sal_Bool bHandled = sal_False;
956 if ( rNEvt.GetType() == EVENT_KEYINPUT &&
957 KEY_RETURN == rNEvt.GetKeyEvent()->GetKeyCode().GetCode() )
959 GetDoubleClickHdl().Call( NULL );
960 bHandled = sal_True;
963 return bHandled ? 1 : ListBox::Notify( rNEvt );
966 // class SearchTabPage_Impl ----------------------------------------------
968 SearchTabPage_Impl::SearchTabPage_Impl( Window* pParent, SfxHelpIndexWindow_Impl* _pIdxWin ) :
970 HelpTabPage_Impl( pParent, _pIdxWin, SfxResId( TP_HELP_SEARCH ) ),
972 aSearchFT ( this, SfxResId( FT_SEARCH ) ),
973 aSearchED ( this, SfxResId( ED_SEARCH ) ),
974 aSearchBtn ( this, SfxResId( PB_SEARCH ) ),
975 aFullWordsCB ( this, SfxResId( CB_FULLWORDS ) ),
976 aScopeCB ( this, SfxResId( CB_SCOPE ) ),
977 aResultsLB ( this, SfxResId( LB_RESULT ) ),
978 aOpenBtn ( this, SfxResId( PB_OPEN_SEARCH ) ),
979 xBreakIterator ( vcl::unohelper::CreateBreakIterator() )
982 FreeResource();
984 Link aLink = LINK( this, SearchTabPage_Impl, SearchHdl );
985 aSearchED.SetSearchLink( aLink );
986 aSearchBtn.SetClickHdl( aLink );
987 aSearchED.SetModifyHdl( LINK( this, SearchTabPage_Impl, ModifyHdl ) );
988 aOpenBtn.SetClickHdl( LINK( this, SearchTabPage_Impl, OpenHdl ) );
990 aMinSize = GetSizePixel();
992 SvtViewOptions aViewOpt( E_TABPAGE, CONFIGNAME_SEARCHPAGE );
993 if ( aViewOpt.Exists() )
995 String aUserData;
996 Any aUserItem = aViewOpt.GetUserItem( USERITEM_NAME );
997 ::rtl::OUString aTemp;
998 if ( aUserItem >>= aTemp )
1000 aUserData = String( aTemp );
1001 sal_Bool bChecked = ( 1 == aUserData.GetToken(0).ToInt32() ) ? sal_True : sal_False;
1002 aFullWordsCB.Check( bChecked );
1003 bChecked = ( 1 == aUserData.GetToken(1).ToInt32() ) ? sal_True : sal_False;
1004 aScopeCB.Check( bChecked );
1006 for ( sal_uInt16 i = 2; i < comphelper::string::getTokenCount(aUserData, ';'); ++i )
1008 String aToken = aUserData.GetToken(i, ';');
1009 aSearchED.InsertEntry( INetURLObject::decode(
1010 aToken, '%', INetURLObject::DECODE_WITH_CHARSET ) );
1015 ModifyHdl( &aSearchED );
1018 // -----------------------------------------------------------------------
1020 SearchTabPage_Impl::~SearchTabPage_Impl()
1022 SvtViewOptions aViewOpt( E_TABPAGE, CONFIGNAME_SEARCHPAGE );
1023 sal_Int32 nChecked = aFullWordsCB.IsChecked() ? 1 : 0;
1024 String aUserData = String::CreateFromInt32( nChecked );
1025 aUserData += ';';
1026 nChecked = aScopeCB.IsChecked() ? 1 : 0;
1027 aUserData += String::CreateFromInt32( nChecked );
1028 aUserData += ';';
1029 sal_uInt16 nCount = Min( aSearchED.GetEntryCount(), (sal_uInt16)10 ); // save only 10 entries
1031 for ( sal_uInt16 i = 0; i < nCount; ++i )
1033 rtl::OUString aText = aSearchED.GetEntry(i);
1034 aUserData += String(INetURLObject::encode(
1035 aText, INetURLObject::PART_UNO_PARAM_VALUE, '%',
1036 INetURLObject::ENCODE_ALL ));
1037 aUserData += ';';
1040 aUserData = comphelper::string::stripEnd(aUserData, ';');
1041 Any aUserItem = makeAny( ::rtl::OUString( aUserData ) );
1042 aViewOpt.SetUserItem( USERITEM_NAME, aUserItem );
1045 // -----------------------------------------------------------------------
1047 void SearchTabPage_Impl::ClearSearchResults()
1049 sal_uInt16 nCount = aResultsLB.GetEntryCount();
1050 for ( sal_uInt16 i = 0; i < nCount; ++i )
1051 delete (String*)(sal_uIntPtr)aResultsLB.GetEntryData(i);
1052 aResultsLB.Clear();
1053 aResultsLB.Update();
1056 // -----------------------------------------------------------------------
1058 void SearchTabPage_Impl::RememberSearchText( const String& rSearchText )
1060 for ( sal_uInt16 i = 0; i < aSearchED.GetEntryCount(); ++i )
1062 if ( rSearchText == aSearchED.GetEntry(i) )
1064 aSearchED.RemoveEntry(i);
1065 break;
1069 aSearchED.InsertEntry( rSearchText, 0 );
1072 // -----------------------------------------------------------------------
1074 IMPL_LINK_NOARG(SearchTabPage_Impl, SearchHdl)
1076 String aSearchText = TRIM( aSearchED.GetText() );
1077 if ( aSearchText.Len() > 0 )
1079 EnterWait();
1080 ClearSearchResults();
1081 RememberSearchText( aSearchText );
1082 String aSearchURL = HELP_URL;
1083 aSearchURL += aFactory;
1084 aSearchURL += String( HELP_SEARCH_TAG );
1085 if ( !aFullWordsCB.IsChecked() )
1086 aSearchText = sfx2::PrepareSearchString( aSearchText, xBreakIterator, true );
1087 aSearchURL += aSearchText;
1088 AppendConfigToken( aSearchURL, sal_False );
1089 if ( aScopeCB.IsChecked() )
1090 aSearchURL += DEFINE_CONST_UNICODE("&Scope=Heading");
1091 Sequence< ::rtl::OUString > aFactories = SfxContentHelper::GetResultSet( aSearchURL );
1092 const ::rtl::OUString* pFacs = aFactories.getConstArray();
1093 sal_uInt32 i, nCount = aFactories.getLength();
1094 for ( i = 0; i < nCount; ++i )
1096 String aRow( pFacs[i] );
1097 String aTitle, aType;
1098 xub_StrLen nIdx = 0;
1099 aTitle = aRow.GetToken( 0, '\t', nIdx );
1100 aType = aRow.GetToken( 0, '\t', nIdx );
1101 String* pURL = new String( aRow.GetToken( 0, '\t', nIdx ) );
1102 sal_uInt16 nPos = aResultsLB.InsertEntry( aTitle );
1103 aResultsLB.SetEntryData( nPos, (void*)(sal_uIntPtr)pURL );
1105 LeaveWait();
1107 if ( !nCount )
1109 InfoBox aBox( this, SfxResId( RID_INFO_NOSEARCHRESULTS ) );
1110 aBox.SetText( String( SfxResId( STR_HELP_WINDOW_TITLE ) ) );
1111 aBox.Execute();
1114 return 0;
1117 // -----------------------------------------------------------------------
1119 IMPL_LINK_NOARG(SearchTabPage_Impl, OpenHdl)
1121 aResultsLB.GetDoubleClickHdl().Call( &aResultsLB );
1122 return 0;
1125 // -----------------------------------------------------------------------
1127 IMPL_LINK_NOARG(SearchTabPage_Impl, ModifyHdl)
1129 String aSearchText = TRIM( aSearchED.GetText() );
1130 aSearchBtn.Enable( aSearchText.Len() > 0 );
1131 return 0;
1134 // -----------------------------------------------------------------------
1136 void SearchTabPage_Impl::Resize()
1138 Size a6Size = LogicToPixel( Size( 6, 6 ), MAP_APPFONT );
1139 Size aSize = GetSizePixel();
1140 if ( aSize.Width() < aMinSize.Width() )
1141 aSize.Width() = aMinSize.Width();
1142 Point aPnt = aSearchFT.GetPosPixel();
1143 Size aNewSize = aSearchFT.GetSizePixel();
1144 aNewSize.Width() = aSize.Width() - ( aPnt.X() * 2 );
1145 aSearchFT.SetSizePixel( aNewSize );
1146 aNewSize.Height() = aResultsLB.GetSizePixel().Height();
1147 aResultsLB.SetSizePixel( aNewSize );
1148 aNewSize.Height() = aFullWordsCB.GetSizePixel().Height();
1149 aFullWordsCB.SetSizePixel( aNewSize );
1150 aScopeCB.SetSizePixel( aNewSize );
1151 aNewSize = aSearchED.GetSizePixel();
1152 aNewSize.Width() = aSize.Width() - ( aPnt.X() * 2 ) -
1153 ( aSearchBtn.GetSizePixel().Width() + ( aPnt.X() / 2 ) );
1154 aSearchED.SetSizePixel( aNewSize );
1155 Point aNewPnt = aSearchBtn.GetPosPixel();
1156 aNewPnt.X() = aPnt.X() + aNewSize.Width() + ( aPnt.X() / 2 );
1157 aSearchBtn.SetPosPixel( aNewPnt );
1159 if ( aSize.Height() > aMinSize.Height() )
1161 long n3Height = a6Size.Height() / 2;
1162 Size aBtnSize = aOpenBtn.GetSizePixel();
1163 long nExtraHeight = aBtnSize.Height() + n3Height;
1165 aPnt = aResultsLB.GetPosPixel();
1166 aNewSize = aResultsLB.GetSizePixel();
1167 aNewSize.Height() = aSize.Height() - aPnt.Y();
1168 aNewSize.Height() -= ( nExtraHeight + ( a6Size.Height() * 3 / 2 ) );
1169 aResultsLB.SetSizePixel( aNewSize );
1171 aPnt.X() += ( aNewSize.Width() - aBtnSize.Width() );
1172 aPnt.Y() += aNewSize.Height() + a6Size.Height();
1173 aOpenBtn.SetPosPixel( aPnt );
1177 // -----------------------------------------------------------------------
1179 void SearchTabPage_Impl::ActivatePage()
1181 if ( !m_pIdxWin->WasCursorLeftOrRight() )
1182 aSearchED.GrabFocus();
1185 // -----------------------------------------------------------------------
1187 Control* SearchTabPage_Impl::GetLastFocusControl()
1189 return &aOpenBtn;
1192 // -----------------------------------------------------------------------
1194 void SearchTabPage_Impl::SetDoubleClickHdl( const Link& rLink )
1196 aResultsLB.SetDoubleClickHdl( rLink );
1199 // -----------------------------------------------------------------------
1201 String SearchTabPage_Impl::GetSelectEntry() const
1203 String aRet;
1204 String* pData = (String*)(sal_uIntPtr)aResultsLB.GetEntryData( aResultsLB.GetSelectEntryPos() );
1205 if ( pData )
1206 aRet = String( *pData );
1207 return aRet;
1210 // -----------------------------------------------------------------------
1212 void SearchTabPage_Impl::ClearPage()
1214 ClearSearchResults();
1215 aSearchED.SetText( String() );
1218 // -----------------------------------------------------------------------
1220 sal_Bool SearchTabPage_Impl::OpenKeyword( const String& rKeyword )
1222 sal_Bool bRet = sal_False;
1223 aSearchED.SetText( rKeyword );
1224 SearchHdl( NULL );
1225 if ( aResultsLB.GetEntryCount() > 0 )
1227 // found keyword -> open it
1228 aResultsLB.SelectEntryPos(0);
1229 OpenHdl( NULL );
1230 bRet = sal_True;
1233 return bRet;
1236 // class BookmarksTabPage_Impl -------------------------------------------
1238 void GetBookmarkEntry_Impl
1240 Sequence< PropertyValue >& aBookmarkEntry,
1241 ::rtl::OUString& rTitle,
1242 ::rtl::OUString& rURL
1245 for ( int i = 0; i < aBookmarkEntry.getLength(); i++ )
1247 PropertyValue aValue = aBookmarkEntry[i];
1248 if ( aValue.Name == HISTORY_PROPERTYNAME_URL )
1249 aValue.Value >>= rURL;
1250 else if ( aValue.Name == HISTORY_PROPERTYNAME_TITLE )
1251 aValue.Value >>= rTitle;
1255 // -----------------------------------------------------------------------
1257 BookmarksBox_Impl::BookmarksBox_Impl( Window* pParent, const ResId& rResId ) :
1259 ListBox( pParent, rResId )
1264 // -----------------------------------------------------------------------
1266 BookmarksBox_Impl::~BookmarksBox_Impl()
1268 // save bookmarks to configuration
1269 SvtHistoryOptions aHistOpt;
1270 aHistOpt.Clear( eHELPBOOKMARKS );
1271 rtl::OUString sEmpty;
1272 sal_uInt16 nCount = GetEntryCount();
1273 for ( sal_uInt16 i = 0; i < nCount; ++i )
1275 String aTitle = GetEntry(i);
1276 String* pURL = (String*)(sal_uIntPtr)GetEntryData(i);
1277 aHistOpt.AppendItem( eHELPBOOKMARKS, rtl::OUString( *pURL ), sEmpty, rtl::OUString( aTitle ), sEmpty );
1278 delete pURL;
1282 // -----------------------------------------------------------------------
1284 void BookmarksBox_Impl::DoAction( sal_uInt16 nAction )
1286 switch ( nAction )
1288 case MID_OPEN :
1289 GetDoubleClickHdl().Call( NULL );
1290 break;
1292 case MID_RENAME :
1294 sal_uInt16 nPos = GetSelectEntryPos();
1295 if ( nPos != LISTBOX_ENTRY_NOTFOUND )
1297 SfxAddHelpBookmarkDialog_Impl aDlg( this, sal_True );
1298 aDlg.SetTitle( GetEntry( nPos ) );
1299 if ( aDlg.Execute() == RET_OK )
1301 String* pURL = (String*)(sal_uIntPtr)GetEntryData( nPos );
1302 RemoveEntry( nPos );
1303 rtl::OUString aImageURL = IMAGE_URL;
1304 aImageURL += INetURLObject( *pURL ).GetHost();
1305 nPos = InsertEntry( aDlg.GetTitle(), SvFileInformationManager::GetImage( aImageURL, false ) );
1306 SetEntryData( nPos, (void*)(sal_uIntPtr)( new String( *pURL ) ) );
1307 SelectEntryPos( nPos );
1308 delete pURL;
1311 break;
1314 case MID_DELETE :
1316 sal_uInt16 nPos = GetSelectEntryPos();
1317 if ( nPos != LISTBOX_ENTRY_NOTFOUND )
1319 RemoveEntry( nPos );
1320 sal_uInt16 nCount = GetEntryCount();
1321 if ( nCount )
1323 if ( nPos >= nCount )
1324 nPos = nCount - 1;
1325 SelectEntryPos( nPos );
1328 break;
1333 // -----------------------------------------------------------------------
1335 long BookmarksBox_Impl::Notify( NotifyEvent& rNEvt )
1337 long nRet = 0;
1338 sal_uInt16 nType = rNEvt.GetType();
1339 if ( EVENT_KEYINPUT == nType )
1341 sal_uInt16 nCode = rNEvt.GetKeyEvent()->GetKeyCode().GetCode();
1342 if ( KEY_DELETE == nCode && GetEntryCount() > 0 )
1344 DoAction( MID_DELETE );
1345 nRet = 1;
1347 else if ( KEY_RETURN == nCode )
1349 GetDoubleClickHdl().Call( NULL );
1350 nRet = 1;
1353 else if ( EVENT_COMMAND == nType )
1355 const CommandEvent* pCEvt = rNEvt.GetCommandEvent();
1356 if ( pCEvt->GetCommand() == COMMAND_CONTEXTMENU )
1358 PopupMenu aMenu( SfxResId( MENU_HELP_BOOKMARKS ) );
1359 sal_uInt16 nId = aMenu.Execute( this, pCEvt->GetMousePosPixel() );
1360 if ( nId != MENU_ITEM_NOTFOUND )
1361 DoAction( nId );
1362 nRet = 1;
1366 return nRet ? nRet : ListBox::Notify( rNEvt );
1369 // class BookmarksTabPage_Impl -------------------------------------------
1371 BookmarksTabPage_Impl::BookmarksTabPage_Impl( Window* pParent, SfxHelpIndexWindow_Impl* _pIdxWin ) :
1373 HelpTabPage_Impl( pParent, _pIdxWin, SfxResId( TP_HELP_BOOKMARKS ) ),
1375 aBookmarksFT ( this, SfxResId( FT_BOOKMARKS ) ),
1376 aBookmarksBox ( this, SfxResId( LB_BOOKMARKS ) ),
1377 aBookmarksPB ( this, SfxResId( PB_BOOKMARKS ) )
1380 FreeResource();
1382 nMinWidth = aBookmarksPB.GetSizePixel().Width();
1384 aBookmarksPB.SetClickHdl( LINK( this, BookmarksTabPage_Impl, OpenHdl ) );
1386 // load bookmarks from configuration
1387 Sequence< Sequence< PropertyValue > > aBookmarkSeq;
1388 aBookmarkSeq = SvtHistoryOptions().GetList( eHELPBOOKMARKS );
1390 ::rtl::OUString aTitle;
1391 ::rtl::OUString aURL;
1393 sal_uInt32 i, nCount = aBookmarkSeq.getLength();
1394 for ( i = 0; i < nCount; ++i )
1396 GetBookmarkEntry_Impl( aBookmarkSeq[i], aTitle, aURL );
1397 AddBookmarks( aTitle, aURL );
1401 // -----------------------------------------------------------------------
1403 IMPL_LINK_NOARG(BookmarksTabPage_Impl, OpenHdl)
1405 aBookmarksBox.GetDoubleClickHdl().Call( &aBookmarksBox );
1406 return 0;
1409 // -----------------------------------------------------------------------
1411 void BookmarksTabPage_Impl::Resize()
1413 Size aSize = GetSizePixel();
1414 if ( aSize.Width() < nMinWidth )
1415 aSize.Width() = nMinWidth;
1416 Point aPnt = aBookmarksFT.GetPosPixel();
1417 Size aNewSize = aBookmarksFT.GetSizePixel();
1418 aNewSize.Width() = aSize.Width() - ( aPnt.X() * 2 );
1419 aBookmarksFT.SetSizePixel( aNewSize );
1421 Size a6Size = LogicToPixel( Size( 6, 6 ), MAP_APPFONT );
1422 Size aBtnSize = aBookmarksPB.GetSizePixel();
1424 aPnt = aBookmarksBox.GetPosPixel();
1425 aNewSize = aBookmarksBox.GetSizePixel();
1426 aNewSize.Width() = aSize.Width() - ( aPnt.X() * 2 );
1427 aNewSize.Height() = aSize.Height() - aPnt.Y();
1428 aNewSize.Height() -= ( aBtnSize.Height() + ( a6Size.Height() * 3 / 2 ) );
1429 aBookmarksBox.SetSizePixel( aNewSize );
1431 aPnt.X() += ( aNewSize.Width() - aBtnSize.Width() );
1432 aPnt.Y() += aNewSize.Height() + ( a6Size.Height() / 2 );
1433 long nMinX = aBookmarksBox.GetPosPixel().X();
1434 if ( aPnt.X() < nMinX )
1435 aPnt.X() = nMinX;
1436 aBookmarksPB.SetPosPixel( aPnt );
1439 // -----------------------------------------------------------------------
1441 void BookmarksTabPage_Impl::ActivatePage()
1443 if ( !m_pIdxWin->WasCursorLeftOrRight() )
1444 SetFocusOnBox();
1447 // -----------------------------------------------------------------------
1449 Control* BookmarksTabPage_Impl::GetLastFocusControl()
1451 return &aBookmarksPB;
1454 // -----------------------------------------------------------------------
1456 void BookmarksTabPage_Impl::SetDoubleClickHdl( const Link& rLink )
1458 aBookmarksBox.SetDoubleClickHdl( rLink );
1461 // -----------------------------------------------------------------------
1463 String BookmarksTabPage_Impl::GetSelectEntry() const
1465 String aRet;
1466 String* pData = (String*)(sal_uIntPtr)aBookmarksBox.GetEntryData( aBookmarksBox.GetSelectEntryPos() );
1467 if ( pData )
1468 aRet = String( *pData );
1469 return aRet;
1472 // -----------------------------------------------------------------------
1474 void BookmarksTabPage_Impl::AddBookmarks( const String& rTitle, const String& rURL )
1476 rtl::OUString aImageURL = IMAGE_URL;
1477 aImageURL += INetURLObject( rURL ).GetHost();
1478 sal_uInt16 nPos = aBookmarksBox.InsertEntry( rTitle, SvFileInformationManager::GetImage( aImageURL, false ) );
1479 aBookmarksBox.SetEntryData( nPos, (void*)(sal_uIntPtr)( new String( rURL ) ) );
1482 ::rtl::OUString SfxHelpWindow_Impl::buildHelpURL(const ::rtl::OUString& sFactory ,
1483 const ::rtl::OUString& sContent ,
1484 const ::rtl::OUString& sAnchor ,
1485 sal_Bool bUseQuestionMark)
1487 ::rtl::OUStringBuffer sHelpURL(256);
1488 sHelpURL.append(HELP_URL);
1489 sHelpURL.append(sFactory);
1490 sHelpURL.append(sContent);
1491 String sURL = String(sHelpURL.makeStringAndClear());
1492 AppendConfigToken(sURL, bUseQuestionMark);
1493 if (!sAnchor.isEmpty())
1494 sURL += String(sAnchor);
1495 return ::rtl::OUString(sURL);
1498 void SfxHelpWindow_Impl::loadHelpContent(const ::rtl::OUString& sHelpURL, sal_Bool bAddToHistory)
1500 Reference< XComponentLoader > xLoader(getTextFrame(), UNO_QUERY);
1501 if (!xLoader.is())
1502 return;
1504 // If a print job runs do not open a new page
1505 Reference< XFrame > xTextFrame = pTextWin->getFrame();
1506 Reference< XController > xTextController ;
1507 if (xTextFrame.is())
1508 xTextController = xTextFrame->getController ();
1509 if ( xTextController.is() && !xTextController->suspend( sal_True ) )
1511 xTextController->suspend( sal_False );
1512 return;
1515 // save url to history
1516 if (bAddToHistory)
1517 pHelpInterceptor->addURL(sHelpURL);
1519 if ( !IsWait() )
1520 EnterWait();
1521 sal_Bool bSuccess = sal_False;
1522 // TODO implement locale fallback ... see below while(sal_True)
1526 Reference< XComponent > xContent = xLoader->loadComponentFromURL(sHelpURL, DEFINE_CONST_UNICODE("_self"), 0, Sequence< PropertyValue >());
1527 if (xContent.is())
1529 bSuccess = sal_True;
1532 catch(const RuntimeException&)
1533 { throw; }
1534 catch(const Exception&)
1535 { /*break;*/ }
1537 /* TODO try next locale ...
1538 no further locale available? => break loop and show error page
1541 openDone(sHelpURL, bSuccess);
1542 if ( IsWait() )
1543 LeaveWait();
1546 SfxHelpIndexWindow_Impl::SfxHelpIndexWindow_Impl( SfxHelpWindow_Impl* _pParent ) :
1548 Window( _pParent, SfxResId( WIN_HELPINDEX ) ),
1550 aActiveLB ( this, SfxResId( LB_ACTIVE ) ),
1551 aActiveLine ( this, SfxResId( FL_ACTIVE ) ),
1552 aTabCtrl ( this, SfxResId( TC_INDEX ) ),
1554 aIndexKeywordLink ( LINK( this, SfxHelpIndexWindow_Impl, KeywordHdl ) ),
1555 pParentWin ( _pParent ),
1557 pCPage ( NULL ),
1558 pIPage ( NULL ),
1559 pSPage ( NULL ),
1560 pBPage ( NULL ),
1562 bWasCursorLeftOrRight( false ),
1563 bIsInitDone ( false )
1566 FreeResource();
1568 sfx2::AddToTaskPaneList( this );
1570 aTabCtrl.SetActivatePageHdl( LINK( this, SfxHelpIndexWindow_Impl, ActivatePageHdl ) );
1571 aTabCtrl.Show();
1573 sal_Int32 nPageId = HELP_INDEX_PAGE_INDEX;
1574 SvtViewOptions aViewOpt( E_TABDIALOG, CONFIGNAME_INDEXWIN );
1575 if ( aViewOpt.Exists() )
1576 nPageId = aViewOpt.GetPageID();
1577 aTabCtrl.SetCurPageId( (sal_uInt16)nPageId );
1578 ActivatePageHdl( &aTabCtrl );
1579 aActiveLB.SetSelectHdl( LINK( this, SfxHelpIndexWindow_Impl, SelectHdl ) );
1580 nMinWidth = ( aActiveLB.GetSizePixel().Width() / 2 );
1582 aTimer.SetTimeoutHdl( LINK( this, SfxHelpIndexWindow_Impl, InitHdl ) );
1583 aTimer.SetTimeout( 200 );
1584 aTimer.Start();
1587 // -----------------------------------------------------------------------
1589 SfxHelpIndexWindow_Impl::~SfxHelpIndexWindow_Impl()
1591 sfx2::RemoveFromTaskPaneList( this );
1593 DELETEZ( pCPage );
1594 DELETEZ( pIPage );
1595 DELETEZ( pSPage );
1596 DELETEZ( pBPage );
1598 for ( sal_uInt16 i = 0; i < aActiveLB.GetEntryCount(); ++i )
1599 delete (String*)(sal_uIntPtr)aActiveLB.GetEntryData(i);
1601 SvtViewOptions aViewOpt( E_TABDIALOG, CONFIGNAME_INDEXWIN );
1602 aViewOpt.SetPageID( (sal_Int32)aTabCtrl.GetCurPageId() );
1605 // -----------------------------------------------------------------------
1607 void SfxHelpIndexWindow_Impl::Initialize()
1609 String aHelpURL = HELP_URL;
1610 AppendConfigToken( aHelpURL, sal_True );
1611 Sequence< ::rtl::OUString > aFactories = SfxContentHelper::GetResultSet( aHelpURL );
1612 const ::rtl::OUString* pFacs = aFactories.getConstArray();
1613 sal_uInt32 i, nCount = aFactories.getLength();
1614 for ( i = 0; i < nCount; ++i )
1616 String aRow( pFacs[i] );
1617 String aTitle, aType, aURL;
1618 xub_StrLen nIdx = 0;
1619 aTitle = aRow.GetToken( 0, '\t', nIdx );
1620 aType = aRow.GetToken( 0, '\t', nIdx );
1621 aURL = aRow.GetToken( 0, '\t', nIdx );
1622 String* pFactory = new String( INetURLObject( aURL ).GetHost() );
1623 sal_uInt16 nPos = aActiveLB.InsertEntry( aTitle );
1624 aActiveLB.SetEntryData( nPos, (void*)(sal_uIntPtr)pFactory );
1627 aActiveLB.SetDropDownLineCount( (sal_uInt16)nCount );
1628 if ( aActiveLB.GetSelectEntryPos() == LISTBOX_ENTRY_NOTFOUND )
1629 SetActiveFactory();
1632 // -----------------------------------------------------------------------
1634 void SfxHelpIndexWindow_Impl::SetActiveFactory()
1636 DBG_ASSERT( pIPage, "index page not initialized" );
1637 if ( !bIsInitDone && !aActiveLB.GetEntryCount() )
1639 aTimer.Stop();
1640 InitHdl( NULL );
1643 for ( sal_uInt16 i = 0; i < aActiveLB.GetEntryCount(); ++i )
1645 String* pFactory = (String*)(sal_uIntPtr)aActiveLB.GetEntryData(i);
1646 pFactory->ToLowerAscii();
1647 if ( *pFactory == pIPage->GetFactory() )
1649 if ( aActiveLB.GetSelectEntryPos() != i )
1651 aActiveLB.SelectEntryPos(i);
1652 aSelectFactoryLink.Call( NULL );
1654 break;
1659 // -----------------------------------------------------------------------
1661 HelpTabPage_Impl* SfxHelpIndexWindow_Impl::GetCurrentPage( sal_uInt16& rCurId )
1663 rCurId = aTabCtrl.GetCurPageId();
1664 HelpTabPage_Impl* pPage = NULL;
1666 switch ( rCurId )
1668 case HELP_INDEX_PAGE_CONTENTS:
1670 pPage = GetContentPage();
1671 break;
1674 case HELP_INDEX_PAGE_INDEX:
1676 pPage = GetIndexPage();
1677 break;
1680 case HELP_INDEX_PAGE_SEARCH:
1682 pPage = GetSearchPage();
1683 break;
1686 case HELP_INDEX_PAGE_BOOKMARKS:
1688 pPage = GetBookmarksPage();
1689 break;
1693 DBG_ASSERT( pPage, "SfxHelpIndexWindow_Impl::GetCurrentPage(): no current page" );
1694 return pPage;
1697 // -----------------------------------------------------------------------
1699 IMPL_LINK( SfxHelpIndexWindow_Impl, ActivatePageHdl, TabControl *, pTabCtrl )
1701 sal_uInt16 nId = 0;
1702 TabPage* pPage = GetCurrentPage( nId );
1703 pTabCtrl->SetTabPage( nId, pPage );
1704 return 0;
1707 // -----------------------------------------------------------------------
1709 IMPL_LINK_NOARG(SfxHelpIndexWindow_Impl, SelectHdl)
1711 aTimer.Start();
1713 return 0;
1716 // -----------------------------------------------------------------------
1718 IMPL_LINK_NOARG(SfxHelpIndexWindow_Impl, InitHdl)
1720 bIsInitDone = true;
1721 Initialize();
1723 // now use the timer for selection
1724 aTimer.SetTimeoutHdl( LINK( this, SfxHelpIndexWindow_Impl, SelectFactoryHdl ) );
1725 aTimer.SetTimeout( 1000 );
1727 return 0;
1730 // -----------------------------------------------------------------------
1732 IMPL_LINK_NOARG(SfxHelpIndexWindow_Impl, SelectFactoryHdl)
1734 String* pFactory = (String*)(sal_uIntPtr)aActiveLB.GetEntryData( aActiveLB.GetSelectEntryPos() );
1735 if ( pFactory )
1737 String aFactory( *pFactory );
1738 aFactory.ToLowerAscii();
1739 SetFactory( aFactory, sal_False );
1740 aSelectFactoryLink.Call( this );
1743 return 0;
1746 // -----------------------------------------------------------------------
1748 IMPL_LINK_NOARG(SfxHelpIndexWindow_Impl, KeywordHdl)
1750 // keyword found on index?
1751 sal_Bool bIndex = pIPage->HasKeyword();
1753 if( !bIndex)
1754 bIndex = pIPage->HasKeywordIgnoreCase();
1755 // then set index or search page as current.
1756 sal_uInt16 nPageId = ( bIndex ) ? HELP_INDEX_PAGE_INDEX : HELP_INDEX_PAGE_SEARCH;
1757 if ( nPageId != aTabCtrl.GetCurPageId() )
1759 aTabCtrl.SetCurPageId( nPageId );
1760 ActivatePageHdl( &aTabCtrl );
1763 // at last we open the keyword
1764 if ( bIndex )
1765 pIPage->OpenKeyword();
1766 else if ( !pSPage->OpenKeyword( sKeyword ) )
1767 pParentWin->ShowStartPage();
1769 return 0;
1772 // -----------------------------------------------------------------------
1774 void SfxHelpIndexWindow_Impl::Resize()
1776 Size aSize = GetOutputSizePixel();
1777 if ( aSize.Width() < nMinWidth )
1778 aSize.Width() = nMinWidth;
1780 Point aPnt = aActiveLB.GetPosPixel();
1781 Size aNewSize = aActiveLB.GetSizePixel();
1782 aNewSize.Width() = aSize.Width() - ( aPnt.X() * 2 );
1783 aActiveLB.SetSizePixel( aNewSize );
1784 aPnt = aActiveLine.GetPosPixel();
1785 aNewSize = aActiveLine.GetSizePixel();
1786 aNewSize.Width() = aSize.Width() - ( aPnt.X() * 2 );
1787 aActiveLine.SetSizePixel( aNewSize );
1788 aPnt = aTabCtrl.GetPosPixel();
1789 aNewSize = aSize;
1790 aSize.Width() -= aPnt.X();
1791 aSize.Height() -= aPnt.Y();
1792 aTabCtrl.SetSizePixel( aSize );
1795 // -----------------------------------------------------------------------
1797 long SfxHelpIndexWindow_Impl::PreNotify( NotifyEvent& rNEvt )
1799 long nDone = 0;
1800 sal_uInt16 nType = rNEvt.GetType();
1801 if ( EVENT_KEYINPUT == nType && rNEvt.GetKeyEvent() )
1803 const KeyCode& rKeyCode = rNEvt.GetKeyEvent()->GetKeyCode();
1804 sal_uInt16 nCode = rKeyCode.GetCode();
1806 if ( KEY_TAB == nCode )
1808 // don't exit index pane with <TAB>
1809 sal_uInt16 nPageId = 0;
1810 HelpTabPage_Impl* pCurPage = GetCurrentPage( nPageId );
1811 Control* pControl = pCurPage->GetLastFocusControl();
1812 sal_Bool bShift = rKeyCode.IsShift();
1813 sal_Bool bCtrl = rKeyCode.IsMod1();
1814 if ( !bCtrl && bShift && aActiveLB.HasChildPathFocus() )
1816 pControl->GrabFocus();
1817 nDone = 1;
1819 else if ( !bCtrl && !bShift && pControl->HasChildPathFocus() )
1821 aActiveLB.GrabFocus();
1822 nDone = 1;
1824 else if ( bCtrl )
1826 // <STRG><TAB> moves through the pages
1827 if ( nPageId < HELP_INDEX_PAGE_LAST )
1828 nPageId++;
1829 else
1830 nPageId = HELP_INDEX_PAGE_FIRST;
1831 aTabCtrl.SetCurPageId( (sal_uInt16)nPageId );
1832 ActivatePageHdl( &aTabCtrl );
1833 nDone = 1;
1836 else if ( aTabCtrl.HasFocus() && ( KEY_LEFT == nCode || KEY_RIGHT == nCode ) )
1838 bWasCursorLeftOrRight = true;
1842 return nDone ? nDone : Window::PreNotify( rNEvt );
1845 // -----------------------------------------------------------------------
1847 void SfxHelpIndexWindow_Impl::DataChanged( const DataChangedEvent& rDCEvt )
1849 Window::DataChanged( rDCEvt );
1851 if ( ( ( rDCEvt.GetType() == DATACHANGED_SETTINGS ) ||
1852 ( rDCEvt.GetType() == DATACHANGED_DISPLAY ) ) &&
1853 ( rDCEvt.GetFlags() & SETTINGS_STYLE ) )
1855 SetBackground( Wallpaper( GetSettings().GetStyleSettings().GetFaceColor() ) );
1859 // -----------------------------------------------------------------------
1861 void SfxHelpIndexWindow_Impl::SetDoubleClickHdl( const Link& rLink )
1863 aPageDoubleClickLink = rLink;
1864 if ( pCPage )
1865 pCPage->SetOpenHdl( aPageDoubleClickLink );
1866 if ( pIPage )
1867 pIPage->SetDoubleClickHdl( aPageDoubleClickLink );
1868 if ( pSPage )
1869 pSPage->SetDoubleClickHdl( aPageDoubleClickLink );
1870 if ( pBPage )
1871 pBPage->SetDoubleClickHdl( aPageDoubleClickLink );
1874 // -----------------------------------------------------------------------
1876 void SfxHelpIndexWindow_Impl::SetFactory( const String& rFactory, sal_Bool bActive )
1878 if ( rFactory.Len() > 0 )
1880 GetIndexPage()->SetFactory( rFactory );
1881 // the index page did a check if rFactory is valid,
1882 // so the index page always returns a valid factory
1883 GetSearchPage()->SetFactory( GetIndexPage()->GetFactory() );
1884 if ( bActive )
1885 SetActiveFactory();
1889 // -----------------------------------------------------------------------
1891 String SfxHelpIndexWindow_Impl::GetSelectEntry() const
1893 String sRet;
1895 switch ( aTabCtrl.GetCurPageId() )
1897 case HELP_INDEX_PAGE_CONTENTS:
1898 sRet = pCPage->GetSelectEntry();
1899 break;
1901 case HELP_INDEX_PAGE_INDEX:
1902 sRet = pIPage->GetSelectEntry();
1903 break;
1905 case HELP_INDEX_PAGE_SEARCH:
1906 sRet = pSPage->GetSelectEntry();
1907 break;
1909 case HELP_INDEX_PAGE_BOOKMARKS:
1910 sRet = pBPage->GetSelectEntry();
1911 break;
1914 return sRet;
1917 // -----------------------------------------------------------------------
1919 void SfxHelpIndexWindow_Impl::AddBookmarks( const String& rTitle, const String& rURL )
1921 GetBookmarksPage()->AddBookmarks( rTitle, rURL );
1924 // -----------------------------------------------------------------------
1926 bool SfxHelpIndexWindow_Impl::IsValidFactory( const String& _rFactory )
1928 bool bValid = false;
1929 for ( sal_uInt16 i = 0; i < aActiveLB.GetEntryCount(); ++i )
1931 String* pFactory = (String*)(sal_uIntPtr)aActiveLB.GetEntryData(i);
1932 if ( *pFactory == _rFactory )
1934 bValid = true;
1935 break;
1938 return bValid;
1941 // -----------------------------------------------------------------------
1943 void SfxHelpIndexWindow_Impl::ClearSearchPage()
1945 if ( pSPage )
1946 pSPage->ClearPage();
1949 // -----------------------------------------------------------------------
1951 void SfxHelpIndexWindow_Impl::GrabFocusBack()
1953 if ( aTabCtrl.GetCurPageId() == HELP_INDEX_PAGE_CONTENTS && pCPage )
1954 pCPage->SetFocusOnBox();
1955 else if ( aTabCtrl.GetCurPageId() == HELP_INDEX_PAGE_INDEX && pIPage )
1956 pIPage->SetFocusOnBox();
1957 else if ( aTabCtrl.GetCurPageId() == HELP_INDEX_PAGE_SEARCH && pSPage )
1958 pSPage->SetFocusOnBox();
1959 else if ( aTabCtrl.GetCurPageId() == HELP_INDEX_PAGE_BOOKMARKS && pBPage )
1960 pBPage->SetFocusOnBox();
1963 // -----------------------------------------------------------------------
1965 sal_Bool SfxHelpIndexWindow_Impl::HasFocusOnEdit() const
1967 sal_Bool bRet = sal_False;
1968 if ( aTabCtrl.GetCurPageId() == HELP_INDEX_PAGE_INDEX && pIPage )
1969 bRet = pIPage->HasFocusOnEdit();
1970 else if ( aTabCtrl.GetCurPageId() == HELP_INDEX_PAGE_SEARCH && pSPage )
1971 bRet = pSPage->HasFocusOnEdit();
1972 return bRet;
1975 // -----------------------------------------------------------------------
1977 String SfxHelpIndexWindow_Impl::GetSearchText() const
1979 String sRet;
1980 if ( aTabCtrl.GetCurPageId() == HELP_INDEX_PAGE_SEARCH && pSPage )
1981 sRet = pSPage->GetSearchText();
1982 return sRet;
1985 // -----------------------------------------------------------------------
1987 sal_Bool SfxHelpIndexWindow_Impl::IsFullWordSearch() const
1989 sal_Bool bRet = sal_False;
1990 if ( aTabCtrl.GetCurPageId() == HELP_INDEX_PAGE_SEARCH && pSPage )
1991 bRet = pSPage->IsFullWordSearch();
1992 return bRet;
1995 // -----------------------------------------------------------------------
1997 void SfxHelpIndexWindow_Impl::OpenKeyword( const String& rKeyword )
1999 sKeyword = rKeyword;
2000 DBG_ASSERT( pIPage, "invalid index page" );
2001 pIPage->SetKeyword( sKeyword );
2004 // -----------------------------------------------------------------------
2006 void SfxHelpIndexWindow_Impl::SelectExecutableEntry()
2008 if ( aTabCtrl.GetCurPageId() == HELP_INDEX_PAGE_INDEX && pIPage )
2009 pIPage->SelectExecutableEntry();
2012 // class TextWin_Impl ----------------------------------------------------
2014 TextWin_Impl::TextWin_Impl( Window* p ) : DockingWindow( p, 0 )
2018 TextWin_Impl::~TextWin_Impl()
2022 long TextWin_Impl::Notify( NotifyEvent& rNEvt )
2024 if( ( rNEvt.GetType() == EVENT_KEYINPUT ) && rNEvt.GetKeyEvent()->GetKeyCode().GetCode() == KEY_TAB )
2025 return GetParent()->Notify( rNEvt );
2026 else
2027 return DockingWindow::Notify( rNEvt );
2030 // -----------------------------------------------------------------------
2031 // remove docking area acceptor from layoutmanager, so it will not layout anything further .-)
2032 void lcl_disableLayoutOfFrame(const Reference< XFrame >& xFrame)
2034 static const ::rtl::OUString PROP_LAYOUT_MANAGER(DEFINE_CONST_UNICODE("LayoutManager"));
2036 Reference< XPropertySet > xPropSet(xFrame, UNO_QUERY_THROW);
2037 xPropSet->setPropertyValue(PROP_LAYOUT_MANAGER, makeAny(Reference< XLayoutManager >()));
2040 // class SfxHelpTextWindow_Impl ------------------------------------------
2042 SfxHelpTextWindow_Impl::SfxHelpTextWindow_Impl( SfxHelpWindow_Impl* pParent ) :
2044 Window( pParent, WB_CLIPCHILDREN | WB_TABSTOP | WB_DIALOGCONTROL ),
2046 aToolBox ( this, 0 ),
2047 aOnStartupCB ( this, SfxResId( RID_HELP_ONSTARTUP_BOX ) ),
2048 aIndexOnImage ( SfxResId( IMG_HELP_TOOLBOX_INDEX_ON ) ),
2049 aIndexOffImage ( SfxResId( IMG_HELP_TOOLBOX_INDEX_OFF ) ),
2050 aIndexOnText ( SfxResId( STR_HELP_BUTTON_INDEX_ON ) ),
2051 aIndexOffText ( SfxResId( STR_HELP_BUTTON_INDEX_OFF ) ),
2052 aOnStartupText ( SfxResId( RID_HELP_ONSTARTUP_TEXT ) ),
2053 pHelpWin ( pParent ),
2054 pTextWin ( new TextWin_Impl( this ) ),
2055 pSrchDlg ( NULL ),
2056 nMinPos ( 0 ),
2057 bIsDebug ( sal_False ),
2058 bIsIndexOn ( sal_False ),
2059 bIsInClose ( sal_False ),
2060 bIsFullWordSearch ( sal_False )
2063 sfx2::AddToTaskPaneList( &aToolBox );
2065 xFrame = Reference < XFrame > ( ::comphelper::getProcessServiceFactory()->createInstance(
2066 DEFINE_CONST_UNICODE("com.sun.star.frame.Frame") ), UNO_QUERY );
2067 xFrame->initialize( VCLUnoHelper::GetInterface ( pTextWin ) );
2068 xFrame->setName( DEFINE_CONST_UNICODE("OFFICE_HELP") );
2069 lcl_disableLayoutOfFrame(xFrame);
2071 aToolBox.SetHelpId( HID_HELP_TOOLBOX );
2073 aToolBox.InsertItem( TBI_INDEX, aIndexOffText );
2074 aToolBox.SetHelpId( TBI_INDEX, HID_HELP_TOOLBOXITEM_INDEX );
2075 aToolBox.InsertSeparator();
2076 aToolBox.InsertItem( TBI_BACKWARD, String( SfxResId( STR_HELP_BUTTON_PREV ) ) );
2077 aToolBox.SetHelpId( TBI_BACKWARD, HID_HELP_TOOLBOXITEM_BACKWARD );
2078 aToolBox.InsertItem( TBI_FORWARD, String( SfxResId( STR_HELP_BUTTON_NEXT ) ) );
2079 aToolBox.SetHelpId( TBI_FORWARD, HID_HELP_TOOLBOXITEM_FORWARD );
2080 aToolBox.InsertItem( TBI_START, String( SfxResId( STR_HELP_BUTTON_START ) ) );
2081 aToolBox.SetHelpId( TBI_START, HID_HELP_TOOLBOXITEM_START );
2082 aToolBox.InsertSeparator();
2083 aToolBox.InsertItem( TBI_PRINT, String( SfxResId( STR_HELP_BUTTON_PRINT ) ) );
2084 aToolBox.SetHelpId( TBI_PRINT, HID_HELP_TOOLBOXITEM_PRINT );
2085 aToolBox.InsertItem( TBI_BOOKMARKS, String( SfxResId( STR_HELP_BUTTON_ADDBOOKMARK ) ) );
2086 aToolBox.SetHelpId( TBI_BOOKMARKS, HID_HELP_TOOLBOXITEM_BOOKMARKS );
2087 aToolBox.InsertItem( TBI_SEARCHDIALOG, String( SfxResId( STR_HELP_BUTTON_SEARCHDIALOG ) ) );
2088 aToolBox.SetHelpId( TBI_SEARCHDIALOG, HID_HELP_TOOLBOXITEM_SEARCHDIALOG );
2090 InitToolBoxImages();
2091 aToolBox.Show();
2092 InitOnStartupBox( false );
2093 aOnStartupCB.SetClickHdl( LINK( this, SfxHelpTextWindow_Impl, CheckHdl ) );
2095 aSelectTimer.SetTimeoutHdl( LINK( this, SfxHelpTextWindow_Impl, SelectHdl ) );
2096 aSelectTimer.SetTimeout( 1000 );
2098 char* pEnv = getenv( "help_debug" );
2099 if ( pEnv )
2100 bIsDebug = sal_True;
2102 SvtMiscOptions().AddListenerLink( LINK( this, SfxHelpTextWindow_Impl, NotifyHdl ) );
2104 if ( !aOnStartupCB.GetHelpId().getLength() )
2105 aOnStartupCB.SetHelpId( HID_HELP_ONSTARTUP_BOX );
2108 // -----------------------------------------------------------------------
2110 SfxHelpTextWindow_Impl::~SfxHelpTextWindow_Impl()
2112 sfx2::RemoveFromTaskPaneList( &aToolBox );
2114 bIsInClose = sal_True;
2115 SvtMiscOptions().RemoveListenerLink( LINK( this, SfxHelpTextWindow_Impl, NotifyHdl ) );
2116 delete pSrchDlg;
2119 // -----------------------------------------------------------------------
2121 sal_Bool SfxHelpTextWindow_Impl::HasSelection() const
2123 // is there any selection in the text and not only a cursor?
2124 sal_Bool bRet = sal_False;
2125 Reference < XTextRange > xRange = getCursor();
2126 if ( xRange.is() )
2128 Reference < XText > xText = xRange->getText();
2129 Reference < XTextCursor > xCursor = xText->createTextCursorByRange( xRange );
2130 bRet = !xCursor->isCollapsed();
2133 return bRet;
2136 // -----------------------------------------------------------------------
2138 void SfxHelpTextWindow_Impl::InitToolBoxImages()
2140 sal_Bool bLarge = SvtMiscOptions().AreCurrentSymbolsLarge();
2142 aIndexOnImage = Image( SfxResId( bLarge ? IMG_HELP_TOOLBOX_L_INDEX_ON : IMG_HELP_TOOLBOX_INDEX_ON ) );
2143 aIndexOffImage = Image( SfxResId( bLarge ? IMG_HELP_TOOLBOX_L_INDEX_OFF : IMG_HELP_TOOLBOX_INDEX_OFF ) );
2145 aToolBox.SetItemImage( TBI_INDEX, bIsIndexOn ? aIndexOffImage : aIndexOnImage );
2147 aToolBox.SetItemImage( TBI_BACKWARD,
2148 Image( SfxResId( bLarge ? IMG_HELP_TOOLBOX_L_PREV : IMG_HELP_TOOLBOX_PREV ) )
2151 aToolBox.SetItemImage( TBI_FORWARD,
2152 Image( SfxResId( bLarge ? IMG_HELP_TOOLBOX_L_NEXT : IMG_HELP_TOOLBOX_NEXT ) )
2155 aToolBox.SetItemImage( TBI_START,
2156 Image( SfxResId( bLarge ? IMG_HELP_TOOLBOX_L_START : IMG_HELP_TOOLBOX_START ) )
2159 aToolBox.SetItemImage( TBI_PRINT,
2160 Image( SfxResId( bLarge ? IMG_HELP_TOOLBOX_L_PRINT : IMG_HELP_TOOLBOX_PRINT ) )
2163 aToolBox.SetItemImage( TBI_BOOKMARKS,
2164 Image( SfxResId( bLarge ? IMG_HELP_TOOLBOX_L_BOOKMARKS : IMG_HELP_TOOLBOX_BOOKMARKS ) )
2167 aToolBox.SetItemImage( TBI_SEARCHDIALOG,
2168 Image( SfxResId( bLarge ? IMG_HELP_TOOLBOX_L_SEARCHDIALOG : IMG_HELP_TOOLBOX_SEARCHDIALOG ) )
2171 Size aSize = aToolBox.CalcWindowSizePixel();
2172 aSize.Height() += TOOLBOX_OFFSET;
2173 aToolBox.SetPosSizePixel( Point( 0, TOOLBOX_OFFSET ), aSize );
2175 SvtMiscOptions aMiscOptions;
2176 if ( aMiscOptions.GetToolboxStyle() != aToolBox.GetOutStyle() )
2177 aToolBox.SetOutStyle( aMiscOptions.GetToolboxStyle() );
2180 // -----------------------------------------------------------------------
2182 void SfxHelpTextWindow_Impl::InitOnStartupBox( bool bOnlyText )
2184 sCurrentFactory = SfxHelp::GetCurrentModuleIdentifier();
2186 Reference< XMultiServiceFactory > xMultiServiceFac = ::comphelper::getProcessServiceFactory();
2187 Reference< XInterface > xConfig;
2188 ::rtl::OUString sPath( PATH_OFFICE_FACTORIES );
2189 sPath += sCurrentFactory;
2190 ::rtl::OUString sKey( KEY_HELP_ON_OPEN );
2192 // Attention: This check boy knows two states:
2193 // 1) Reading of the config key fails with an exception or by getting an empty Any (!) => check box must be hidden
2194 // 2) We read sal_True/sal_False => check box must be shown and enabled/disabled
2196 bool bHideBox = true;
2197 sal_Bool bHelpAtStartup = sal_False;
2200 xConfiguration = ConfigurationHelper::openConfig(
2201 xMultiServiceFac, PACKAGE_SETUP, ConfigurationHelper::E_STANDARD );
2202 if ( xConfiguration.is() )
2204 Any aAny = ConfigurationHelper::readRelativeKey( xConfiguration, sPath, sKey );
2205 if (aAny >>= bHelpAtStartup)
2206 bHideBox = false;
2209 catch( Exception& )
2211 bHideBox = true;
2214 if ( bHideBox )
2215 aOnStartupCB.Hide();
2216 else
2218 // detect module name
2219 String sModuleName;
2221 if ( xConfiguration.is() )
2223 ::rtl::OUString sTemp;
2224 sKey = KEY_UI_NAME;
2227 Any aAny = ConfigurationHelper::readRelativeKey( xConfiguration, sPath, sKey );
2228 aAny >>= sTemp;
2230 catch( Exception& )
2232 SAL_WARN( "sfx2.appl", "SfxHelpTextWindow_Impl::InitOnStartupBox(): unexpected exception" );
2234 sModuleName = String( sTemp );
2237 if ( sModuleName.Len() > 0 )
2239 // set module name in checkbox text
2240 String sText( aOnStartupText );
2241 sText.SearchAndReplace( String::CreateFromAscii( "%MODULENAME" ), sModuleName );
2242 aOnStartupCB.SetText( sText );
2243 // and show it
2244 aOnStartupCB.Show();
2245 // set check state
2246 aOnStartupCB.Check( bHelpAtStartup );
2247 aOnStartupCB.SaveValue();
2249 // calculate and set optimal width of the onstartup checkbox
2250 String sCBText( DEFINE_CONST_UNICODE( "XXX" ) );
2251 sCBText += aOnStartupCB.GetText();
2252 long nTextWidth = aOnStartupCB.GetTextWidth( sCBText );
2253 Size aSize = aOnStartupCB.GetSizePixel();
2254 aSize.Width() = nTextWidth;
2255 aOnStartupCB.SetSizePixel( aSize );
2256 SetOnStartupBoxPosition();
2259 if ( !bOnlyText )
2261 // set position of the checkbox
2262 Size a3Size = LogicToPixel( Size( 3, 3 ), MAP_APPFONT );
2263 Size aTBSize = aToolBox.GetSizePixel();
2264 Size aCBSize = aOnStartupCB.GetSizePixel();
2265 Point aPnt = aToolBox.GetPosPixel();
2266 aPnt.X() += aTBSize.Width() + a3Size.Width();
2267 aPnt.Y() += ( ( aTBSize.Height() - aCBSize.Height() ) / 2 );
2268 aOnStartupCB.SetPosPixel( aPnt );
2269 nMinPos = aPnt.X();
2274 // -----------------------------------------------------------------------
2276 void SfxHelpTextWindow_Impl::SetOnStartupBoxPosition()
2278 long nX = Max( GetOutputSizePixel().Width() - aOnStartupCB.GetSizePixel().Width(), nMinPos );
2279 Point aPos = aOnStartupCB.GetPosPixel();
2280 aPos.X() = nX;
2281 aOnStartupCB.SetPosPixel( aPos );
2284 // -----------------------------------------------------------------------
2286 Reference< XBreakIterator > SfxHelpTextWindow_Impl::GetBreakIterator()
2288 if ( !xBreakIterator.is() )
2289 xBreakIterator = vcl::unohelper::CreateBreakIterator();
2290 DBG_ASSERT( xBreakIterator.is(), "Could not create BreakIterator" );
2291 return xBreakIterator;
2294 // -----------------------------------------------------------------------
2296 Reference< XTextRange > SfxHelpTextWindow_Impl::getCursor() const
2298 // return the current cursor
2299 Reference< XTextRange > xCursor;
2303 Reference < XSelectionSupplier > xSelSup( xFrame->getController(), UNO_QUERY );
2304 if ( xSelSup.is() )
2306 Any aAny = xSelSup->getSelection();
2307 Reference < XIndexAccess > xSelection;
2308 if ( aAny >>= xSelection )
2310 if ( xSelection->getCount() == 1 )
2312 aAny = xSelection->getByIndex(0);
2313 aAny >>= xCursor;
2318 catch( Exception& )
2320 OSL_FAIL( "SfxHelpTextWindow_Impl::getCursor(): unexpected exception" );
2323 return xCursor;
2326 // -----------------------------------------------------------------------
2328 bool SfxHelpTextWindow_Impl::isHandledKey( const KeyCode& _rKeyCode )
2330 bool bRet = false;
2331 sal_uInt16 nCode = _rKeyCode.GetCode();
2333 // the keys <STRG><A> (select all), <STRG><C> (copy),
2334 // <STRG><F> (find), <STRG><P> (print) and <STRG><W> (close window)
2335 // were handled in help
2336 if ( _rKeyCode.IsMod1() &&
2337 ( KEY_A == nCode || KEY_C == nCode || KEY_F == nCode || KEY_P == nCode || KEY_W == nCode ) )
2339 if ( KEY_F == nCode )
2340 DoSearch();
2341 else
2342 bRet = true;
2345 return bRet;
2348 // -----------------------------------------------------------------------
2350 IMPL_LINK_NOARG(SfxHelpTextWindow_Impl, SelectHdl)
2354 // select the words, which are equal to the search text of the search page
2355 Reference < XController > xController = xFrame->getController();
2356 if ( xController.is() )
2358 // get document
2359 Reference < XSearchable > xSearchable( xController->getModel(), UNO_QUERY );
2360 if ( xSearchable.is() )
2362 // create descriptor, set string and find all words
2363 Reference < XSearchDescriptor > xSrchDesc = xSearchable->createSearchDescriptor();
2364 Reference < XPropertySet > xPropSet( xSrchDesc, UNO_QUERY );
2365 xPropSet->setPropertyValue( DEFINE_CONST_OUSTRING("SearchRegularExpression"),
2366 makeAny( sal_Bool( sal_True ) ) );
2367 if ( bIsFullWordSearch )
2368 xPropSet->setPropertyValue( DEFINE_CONST_OUSTRING("SearchWords"),
2369 makeAny( sal_Bool( sal_True ) ) );
2371 String sSearchString = sfx2::PrepareSearchString( aSearchText, GetBreakIterator(), false );
2372 xSrchDesc->setSearchString( sSearchString );
2373 Reference< XIndexAccess > xSelection = xSearchable->findAll( xSrchDesc );
2375 // then select all found words
2376 Reference < XSelectionSupplier > xSelectionSup( xController, UNO_QUERY );
2377 if ( xSelectionSup.is() )
2379 Any aAny;
2380 aAny <<= xSelection;
2381 xSelectionSup->select( aAny );
2386 catch( Exception& )
2388 OSL_FAIL( "SfxHelpTextWindow_Impl::SelectHdl(): unexpected exception" );
2391 return 1;
2394 // -----------------------------------------------------------------------
2396 IMPL_LINK( SfxHelpTextWindow_Impl, NotifyHdl, SvtMiscOptions*, pOptions )
2398 (void)pOptions; // unused variable
2399 InitToolBoxImages();
2400 Resize();
2401 aToolBox.Invalidate();
2402 return 0;
2405 // -----------------------------------------------------------------------
2407 IMPL_LINK( SfxHelpTextWindow_Impl, FindHdl, sfx2::SearchDialog*, pDlg )
2409 bool bWrapAround = ( NULL == pDlg );
2410 if ( bWrapAround )
2411 pDlg = pSrchDlg;
2412 DBG_ASSERT( pDlg, "invalid search dialog" );
2413 String sSearchText = pDlg->GetSearchText();
2416 // select the words, which are equal to the search text of the search page
2417 Reference < XController > xController = xFrame->getController();
2418 if ( xController.is() )
2420 // get document
2421 Reference < XSearchable > xSearchable( xController->getModel(), UNO_QUERY );
2422 if ( xSearchable.is() )
2424 // create descriptor, set string and find all words
2425 Reference < XSearchDescriptor > xSrchDesc = xSearchable->createSearchDescriptor();
2426 Reference < XPropertySet > xPropSet( xSrchDesc, UNO_QUERY );
2427 xPropSet->setPropertyValue( DEFINE_CONST_OUSTRING("SearchWords"), makeAny( sal_Bool( pDlg->IsOnlyWholeWords() != false ) ) );
2428 xPropSet->setPropertyValue( DEFINE_CONST_OUSTRING("SearchCaseSensitive"), makeAny( sal_Bool( pDlg->IsMarchCase() != false ) ) );
2429 xPropSet->setPropertyValue( DEFINE_CONST_OUSTRING("SearchBackwards"), makeAny( sal_Bool( pDlg->IsSearchBackwards() != false ) ) );
2430 xSrchDesc->setSearchString( sSearchText );
2431 Reference< XInterface > xSelection;
2432 Reference< XTextRange > xCursor = getCursor();
2434 if ( xCursor.is() )
2436 if ( pDlg->IsSearchBackwards() )
2437 xCursor = xCursor->getStart();
2438 xSelection = xSearchable->findNext( xCursor, xSrchDesc );
2440 else
2441 xSelection = xSearchable->findFirst( xSrchDesc );
2443 // then select the found word
2444 if ( xSelection.is() )
2446 Reference < XSelectionSupplier > xSelectionSup( xController, UNO_QUERY );
2447 if ( xSelectionSup.is() )
2449 Any aAny;
2450 aAny <<= xSelection;
2451 xSelectionSup->select( aAny );
2454 else if ( pDlg->IsWrapAround() && !bWrapAround )
2456 Reference < text::XTextViewCursorSupplier > xCrsrSupp( xController, uno::UNO_QUERY );
2457 Reference < text::XTextViewCursor > xTVCrsr( xCrsrSupp->getViewCursor(), uno::UNO_QUERY );
2458 if ( xTVCrsr.is() )
2460 Reference < text::XTextDocument > xDoc( xController->getModel(), uno::UNO_QUERY );
2461 Reference < text::XText > xText = xDoc->getText();
2462 if ( xText.is() )
2464 if ( pDlg->IsSearchBackwards() )
2465 xTVCrsr->gotoRange( xText->getEnd(), sal_False );
2466 else
2467 xTVCrsr->gotoRange( xText->getStart(), sal_False );
2468 FindHdl( NULL );
2472 else
2474 DBG_ASSERT( pSrchDlg, "no search dialog" );
2475 InfoBox aBox( pSrchDlg, SfxResId( RID_INFO_NOSEARCHTEXTFOUND ) );
2476 aBox.Execute();
2477 pSrchDlg->SetFocusOnEdit();
2482 catch( Exception& )
2484 OSL_FAIL( "SfxHelpTextWindow_Impl::SelectHdl(): unexpected exception" );
2487 return 0;
2490 // -----------------------------------------------------------------------
2492 IMPL_LINK( SfxHelpTextWindow_Impl, CloseHdl, sfx2::SearchDialog*, pDlg )
2494 if ( pDlg )
2495 delete pSrchDlg;
2496 pSrchDlg = NULL;
2497 return 0;
2500 // -----------------------------------------------------------------------
2502 IMPL_LINK( SfxHelpTextWindow_Impl, CheckHdl, CheckBox*, pBox )
2504 if ( xConfiguration.is() )
2506 sal_Bool bChecked = pBox->IsChecked();
2507 ::rtl::OUString sPath( PATH_OFFICE_FACTORIES );
2508 sPath += sCurrentFactory;
2511 ConfigurationHelper::writeRelativeKey(
2512 xConfiguration, sPath, KEY_HELP_ON_OPEN, makeAny( bChecked ) );
2513 ConfigurationHelper::flush( xConfiguration );
2515 catch( Exception& )
2517 SAL_WARN( "sfx2.appl", "SfxHelpTextWindow_Impl::CheckHdl(): unexpected exception" );
2521 return 0;
2524 // -----------------------------------------------------------------------
2526 void SfxHelpTextWindow_Impl::Resize()
2528 Size aSize = GetOutputSizePixel();
2529 long nToolBoxHeight = aToolBox.GetSizePixel().Height() + TOOLBOX_OFFSET;
2530 aSize.Height() -= nToolBoxHeight;
2531 pTextWin->SetPosSizePixel( Point( 0, nToolBoxHeight ), aSize );
2532 SetOnStartupBoxPosition();
2535 // -----------------------------------------------------------------------
2537 long SfxHelpTextWindow_Impl::PreNotify( NotifyEvent& rNEvt )
2539 long nDone = 0;
2540 sal_uInt16 nType = rNEvt.GetType();
2541 if ( EVENT_COMMAND == nType && rNEvt.GetCommandEvent() )
2543 const CommandEvent* pCmdEvt = rNEvt.GetCommandEvent();
2544 Window* pCmdWin = rNEvt.GetWindow();
2546 if ( pCmdEvt->GetCommand() == COMMAND_CONTEXTMENU && pCmdWin != this && pCmdWin != &aToolBox )
2548 Point aPos;
2549 if ( pCmdEvt->IsMouseEvent() )
2550 aPos = pCmdEvt->GetMousePosPixel();
2551 else
2552 aPos = Point( pTextWin->GetPosPixel().X() + 20, 20 );
2553 aPos.Y() += pTextWin->GetPosPixel().Y();
2554 PopupMenu aMenu;
2555 if ( bIsIndexOn )
2556 aMenu.InsertItem( TBI_INDEX, aIndexOffText, Image( SfxResId( IMG_HELP_TOOLBOX_INDEX_OFF ) ) );
2557 else
2558 aMenu.InsertItem( TBI_INDEX, aIndexOnText, Image( SfxResId( IMG_HELP_TOOLBOX_INDEX_ON ) ) );
2560 aMenu.SetHelpId( TBI_INDEX, HID_HELP_TOOLBOXITEM_INDEX );
2561 aMenu.InsertSeparator();
2562 aMenu.InsertItem( TBI_BACKWARD,
2563 String( SfxResId( STR_HELP_BUTTON_PREV ) ),
2564 Image( SfxResId( IMG_HELP_TOOLBOX_PREV ) )
2566 aMenu.SetHelpId( TBI_BACKWARD, HID_HELP_TOOLBOXITEM_BACKWARD );
2567 aMenu.EnableItem( TBI_BACKWARD, pHelpWin->HasHistoryPredecessor() );
2568 aMenu.InsertItem( TBI_FORWARD,
2569 String( SfxResId( STR_HELP_BUTTON_NEXT ) ),
2570 Image( SfxResId( IMG_HELP_TOOLBOX_NEXT ) )
2572 aMenu.SetHelpId( TBI_FORWARD, HID_HELP_TOOLBOXITEM_FORWARD );
2573 aMenu.EnableItem( TBI_FORWARD, pHelpWin->HasHistorySuccessor() );
2574 aMenu.InsertItem( TBI_START,
2575 String( SfxResId( STR_HELP_BUTTON_START ) ),
2576 Image( SfxResId( IMG_HELP_TOOLBOX_START ) )
2578 aMenu.SetHelpId( TBI_START, HID_HELP_TOOLBOXITEM_START );
2579 aMenu.InsertSeparator();
2580 aMenu.InsertItem( TBI_PRINT,
2581 String( SfxResId( STR_HELP_BUTTON_PRINT ) ),
2582 Image( SfxResId( IMG_HELP_TOOLBOX_PRINT ) )
2584 aMenu.SetHelpId( TBI_PRINT, HID_HELP_TOOLBOXITEM_PRINT );
2585 aMenu.InsertItem( TBI_BOOKMARKS,
2586 String( SfxResId( STR_HELP_BUTTON_ADDBOOKMARK ) ),
2587 Image( SfxResId( IMG_HELP_TOOLBOX_BOOKMARKS ) )
2589 aMenu.SetHelpId( TBI_BOOKMARKS, HID_HELP_TOOLBOXITEM_BOOKMARKS );
2590 aMenu.InsertItem( TBI_SEARCHDIALOG,
2591 String( SfxResId( STR_HELP_BUTTON_SEARCHDIALOG ) ),
2592 Image( SfxResId( IMG_HELP_TOOLBOX_SEARCHDIALOG ) )
2594 aMenu.SetHelpId( TBI_SEARCHDIALOG, HID_HELP_TOOLBOXITEM_SEARCHDIALOG );
2595 aMenu.InsertSeparator();
2596 aMenu.InsertItem( TBI_SELECTIONMODE, String( SfxResId( STR_HELP_MENU_TEXT_SELECTION_MODE ) ) );
2597 aMenu.SetHelpId( TBI_SELECTIONMODE, HID_HELP_TEXT_SELECTION_MODE );
2598 Reference < XDispatchProvider > xProv( xFrame, UNO_QUERY );
2599 URL aURL;
2600 aURL.Complete = DEFINE_CONST_UNICODE(".uno:SelectTextMode");
2601 PARSE_URL( aURL );
2602 Reference < XDispatch > xDisp = xProv.is() ?
2603 xProv->queryDispatch( aURL, rtl::OUString(), 0 ) : Reference < XDispatch >();
2604 if(xDisp.is())
2606 HelpStatusListener_Impl* pStateListener;
2607 Reference<XStatusListener>xStateListener = pStateListener =
2608 new HelpStatusListener_Impl(xDisp, aURL );
2609 FeatureStateEvent rEvent = pStateListener->GetStateEvent();
2610 sal_Bool bCheck = sal_False;
2611 rEvent.State >>= bCheck;
2612 aMenu.CheckItem(TBI_SELECTIONMODE, bCheck);
2614 aMenu.InsertSeparator();
2615 aMenu.InsertItem( TBI_COPY,
2616 String( SfxResId( STR_HELP_MENU_TEXT_COPY ) ),
2617 Image( SfxResId( IMG_HELP_TOOLBOX_COPY ) )
2619 aMenu.SetHelpId( TBI_COPY, ".uno:Copy" );
2620 aMenu.EnableItem( TBI_COPY, HasSelection() );
2622 if ( bIsDebug )
2624 aMenu.InsertSeparator();
2625 aMenu.InsertItem( TBI_SOURCEVIEW, String( SfxResId( STR_HELP_BUTTON_SOURCEVIEW ) ) );
2628 if( SvtMenuOptions().IsEntryHidingEnabled() == sal_False )
2629 aMenu.SetMenuFlags( aMenu.GetMenuFlags() | MENU_FLAG_HIDEDISABLEDENTRIES );
2631 sal_uInt16 nId = aMenu.Execute( this, aPos );
2632 pHelpWin->DoAction( nId );
2633 nDone = 1;
2636 else if ( EVENT_KEYINPUT == nType && rNEvt.GetKeyEvent() )
2638 const KeyEvent* pKEvt = rNEvt.GetKeyEvent();
2639 const KeyCode& rKeyCode = pKEvt->GetKeyCode();
2640 sal_uInt16 nKeyGroup = rKeyCode.GetGroup();
2641 sal_uInt16 nKey = rKeyCode.GetCode();
2642 if ( KEYGROUP_ALPHA == nKeyGroup && !isHandledKey( rKeyCode ) )
2644 // do nothing disables the writer accelerators
2645 nDone = 1;
2647 else if ( rKeyCode.IsMod1() && ( KEY_F4 == nKey || KEY_W == nKey ) )
2649 // <STRG><F4> or <STRG><W> -> close top frame
2650 pHelpWin->CloseWindow();
2651 nDone = 1;
2653 else if ( KEY_TAB == nKey && aOnStartupCB.HasChildPathFocus() )
2655 aToolBox.GrabFocus();
2656 nDone = 1;
2660 return nDone ? nDone : Window::PreNotify( rNEvt );
2663 // -----------------------------------------------------------------------
2665 void SfxHelpTextWindow_Impl::GetFocus()
2667 if ( !bIsInClose )
2671 if( xFrame.is() )
2673 Reference< ::com::sun::star::awt::XWindow > xWindow = xFrame->getComponentWindow();
2674 if( xWindow.is() )
2675 xWindow->setFocus();
2678 catch( Exception& )
2680 SAL_WARN( "sfx2.appl", "SfxHelpTextWindow_Impl::GetFocus(): unexpected exception" );
2685 // -----------------------------------------------------------------------
2687 void SfxHelpTextWindow_Impl::DataChanged( const DataChangedEvent& rDCEvt )
2689 Window::DataChanged( rDCEvt );
2691 if ( ( ( rDCEvt.GetType() == DATACHANGED_SETTINGS ) ||
2692 ( rDCEvt.GetType() == DATACHANGED_DISPLAY ) ) &&
2693 ( rDCEvt.GetFlags() & SETTINGS_STYLE ) )
2695 SetBackground( Wallpaper( GetSettings().GetStyleSettings().GetFaceColor() ) );
2696 InitToolBoxImages();
2700 // -----------------------------------------------------------------------
2702 void SfxHelpTextWindow_Impl::ToggleIndex( sal_Bool bOn )
2704 bIsIndexOn = bOn;
2705 if ( bIsIndexOn )
2707 aToolBox.SetItemImage( TBI_INDEX, aIndexOffImage );
2708 aToolBox.SetItemText( TBI_INDEX, aIndexOffText );
2710 else
2712 aToolBox.SetItemImage( TBI_INDEX, aIndexOnImage );
2713 aToolBox.SetItemText( TBI_INDEX, aIndexOnText );
2717 // -----------------------------------------------------------------------
2719 void SfxHelpTextWindow_Impl::SelectSearchText( const String& rSearchText, sal_Bool _bIsFullWordSearch )
2721 aSearchText = rSearchText;
2722 bIsFullWordSearch = _bIsFullWordSearch;
2723 aSelectTimer.Start();
2726 // -----------------------------------------------------------------------
2728 void SfxHelpTextWindow_Impl::SetPageStyleHeaderOff() const
2730 #ifdef DBG_UTIL
2731 sal_Bool bSetOff = sal_False;
2732 #endif
2733 // set off the pagestyle header to prevent print output of the help URL
2736 Reference < XController > xController = xFrame->getController();
2737 Reference < XSelectionSupplier > xSelSup( xController, UNO_QUERY );
2738 if ( xSelSup.is() )
2740 Reference < XIndexAccess > xSelection;
2741 if ( xSelSup->getSelection() >>= xSelection )
2743 Reference < XTextRange > xRange;
2744 if ( xSelection->getByIndex(0) >>= xRange )
2746 Reference < XText > xText = xRange->getText();
2747 Reference < XPropertySet > xProps( xText->createTextCursorByRange( xRange ), UNO_QUERY );
2748 ::rtl::OUString sStyleName;
2749 if ( xProps->getPropertyValue( DEFINE_CONST_OUSTRING("PageStyleName") ) >>= sStyleName )
2751 Reference < XStyleFamiliesSupplier > xStyles( xController->getModel(), UNO_QUERY );
2752 Reference < XNameContainer > xContainer;
2753 if ( xStyles->getStyleFamilies()->getByName( DEFINE_CONST_OUSTRING("PageStyles") )
2754 >>= xContainer )
2756 Reference < XStyle > xStyle;
2757 if ( xContainer->getByName( sStyleName ) >>= xStyle )
2759 Reference < XPropertySet > xPropSet( xStyle, UNO_QUERY );
2760 xPropSet->setPropertyValue( DEFINE_CONST_OUSTRING("HeaderIsOn"),
2761 makeAny( sal_Bool( sal_False ) ) );
2763 Reference< XModifiable > xReset(xStyles, UNO_QUERY);
2764 xReset->setModified(sal_False);
2765 #ifdef DBG_UTIL
2766 bSetOff = sal_True;
2767 #endif
2775 catch( Exception& )
2777 SAL_WARN( "sfx2.appl", "SfxHelpTextWindow_Impl::SetPageStyleHeaderOff(): unexpected exception" );
2780 #ifdef DBG_UTIL
2781 if ( !bSetOff )
2783 SAL_WARN( "sfx2.appl", "SfxHelpTextWindow_Impl::SetPageStyleHeaderOff(): set off failed" );
2785 #endif
2788 // -----------------------------------------------------------------------
2790 void SfxHelpTextWindow_Impl::CloseFrame()
2792 bIsInClose = sal_True;
2795 ::com::sun::star::uno::Reference< ::com::sun::star::util::XCloseable > xCloseable ( xFrame, ::com::sun::star::uno::UNO_QUERY );
2796 if (xCloseable.is())
2797 xCloseable->close(sal_True);
2799 catch( ::com::sun::star::util::CloseVetoException& )
2804 // -----------------------------------------------------------------------
2806 void SfxHelpTextWindow_Impl::DoSearch()
2808 if ( !pSrchDlg )
2810 // create the search dialog
2811 pSrchDlg = new sfx2::SearchDialog( pTextWin, DEFINE_CONST_UNICODE("HelpSearchDialog") );
2812 // set handler
2813 pSrchDlg->SetFindHdl( LINK( this, SfxHelpTextWindow_Impl, FindHdl ) );
2814 pSrchDlg->SetCloseHdl( LINK( this, SfxHelpTextWindow_Impl, CloseHdl ) );
2815 // get selected text of the help page to set it as the search text
2816 Reference< XTextRange > xCursor = getCursor();
2817 if ( xCursor.is() )
2819 String sText = xCursor->getString();
2820 if ( sText.Len() > 0 )
2821 pSrchDlg->SetSearchText( sText );
2823 pSrchDlg->Show();
2827 // class SfxHelpWindow_Impl ----------------------------------------------
2829 void SfxHelpWindow_Impl::Resize()
2831 SplitWindow::Resize();
2832 InitSizes();
2835 // -----------------------------------------------------------------------
2837 void SfxHelpWindow_Impl::Split()
2839 static long nMinSplitSize = 5;
2840 static long nMaxSplitSize = 99 - nMinSplitSize;
2842 SplitWindow::Split();
2844 nIndexSize = GetItemSize( INDEXWIN_ID );
2845 nTextSize = GetItemSize( TEXTWIN_ID );
2847 sal_Bool bMod = sal_False;
2848 if( nIndexSize < nMinSplitSize )
2850 nIndexSize = nMinSplitSize;
2851 nTextSize = nMaxSplitSize;
2853 bMod = sal_True;
2855 else if( nTextSize < nMinSplitSize )
2857 nTextSize = nMinSplitSize;
2858 nIndexSize = nMaxSplitSize;
2860 bMod = sal_True;
2862 else
2863 bMod = sal_False;
2865 if( bMod )
2867 SetItemSize( INDEXWIN_ID, nIndexSize );
2868 SetItemSize( TEXTWIN_ID, nTextSize );
2871 InitSizes();
2874 // -----------------------------------------------------------------------
2876 void SfxHelpWindow_Impl::GetFocus()
2878 pTextWin->GrabFocus();
2881 // -----------------------------------------------------------------------
2883 void SfxHelpWindow_Impl::MakeLayout()
2885 if ( nHeight > 0 && xWindow.is() )
2887 Window* pScreenWin = VCLUnoHelper::GetWindow( xWindow );
2889 /* #i55528#
2890 Hide() / Show() will produce starnge effects.
2891 The returned size (used later to be written back into the configuration)
2892 isnt the right after a resize during the window is hidden.
2893 If this resize is done if the window is visible evyrthing works as aspected.
2894 Some VCL-patches could not solve this problem so I've established the
2895 workaround: resize the help window if it's visible .-)
2898 ::com::sun::star::awt::Rectangle aRect = xWindow->getPosSize();
2899 sal_Int32 nOldWidth = bIndex ? nCollapseWidth : nExpandWidth;
2900 sal_Int32 nWidth = bIndex ? nExpandWidth : nCollapseWidth;
2901 xWindow->setPosSize( aRect.X, aRect.Y, nWidth, nHeight, ::com::sun::star::awt::PosSize::SIZE );
2903 if ( aRect.Width > 0 && aRect.Height > 0 )
2905 Rectangle aScreenRect = pScreenWin->GetClientWindowExtentsRelative( NULL );
2906 Point aNewPos = aScreenRect.TopLeft();
2907 sal_Int32 nDiffWidth = nOldWidth - nWidth;
2908 aNewPos.X() += nDiffWidth;
2909 pScreenWin->SetPosPixel( aNewPos );
2911 else if ( aWinPos.X() > 0 && aWinPos.Y() > 0 )
2912 pScreenWin->SetPosPixel( aWinPos );
2915 Clear();
2917 if ( bIndex )
2919 pIndexWin->Show();
2920 InsertItem( COLSET_ID, 100, SPLITWINDOW_APPEND, SPLITSET_ID, SWIB_PERCENTSIZE | SWIB_COLSET );
2921 InsertItem( INDEXWIN_ID, pIndexWin, nIndexSize, SPLITWINDOW_APPEND, COLSET_ID, SWIB_PERCENTSIZE );
2922 InsertItem( TEXTWIN_ID, pTextWin, nTextSize, SPLITWINDOW_APPEND, COLSET_ID, SWIB_PERCENTSIZE );
2924 else
2926 pIndexWin->Hide();
2927 InsertItem( COLSET_ID, 100, SPLITWINDOW_APPEND, SPLITSET_ID, SWIB_PERCENTSIZE | SWIB_COLSET );
2928 InsertItem( TEXTWIN_ID, pTextWin, 100, SPLITWINDOW_APPEND, 1, SWIB_PERCENTSIZE );
2932 // -----------------------------------------------------------------------
2934 void SfxHelpWindow_Impl::InitSizes()
2936 if ( xWindow.is() )
2938 ::com::sun::star::awt::Rectangle aRect = xWindow->getPosSize();
2939 nHeight = aRect.Height;
2941 if ( bIndex )
2943 nExpandWidth = aRect.Width;
2944 nCollapseWidth = nExpandWidth * nTextSize / 100;
2946 else
2948 nCollapseWidth = aRect.Width;
2949 nExpandWidth = nCollapseWidth * 100 / nTextSize;
2954 // -----------------------------------------------------------------------
2956 void SfxHelpWindow_Impl::LoadConfig()
2958 SvtViewOptions aViewOpt( E_WINDOW, CONFIGNAME_HELPWIN );
2959 if ( aViewOpt.Exists() )
2961 bIndex = aViewOpt.IsVisible();
2962 String aUserData;
2963 Any aUserItem = aViewOpt.GetUserItem( USERITEM_NAME );
2964 rtl::OUString aTemp;
2965 if ( aUserItem >>= aTemp )
2967 aUserData = String( aTemp );
2968 DBG_ASSERT( comphelper::string::getTokenCount(aUserData, ';') == 6, "invalid user data" );
2969 sal_uInt16 nIdx = 0;
2970 nIndexSize = aUserData.GetToken( 0, ';', nIdx ).ToInt32();
2971 nTextSize = aUserData.GetToken( 0, ';', nIdx ).ToInt32();
2972 sal_Int32 nWidth = aUserData.GetToken( 0, ';', nIdx ).ToInt32();
2973 nHeight = aUserData.GetToken( 0, ';', nIdx ).ToInt32();
2974 aWinPos.X() = aUserData.GetToken( 0, ';', nIdx ).ToInt32();
2975 aWinPos.Y() = aUserData.GetToken( 0, ';', nIdx ).ToInt32();
2976 if ( bIndex )
2978 nExpandWidth = nWidth;
2979 nCollapseWidth = nExpandWidth * nTextSize / 100;
2981 else
2983 nCollapseWidth = nWidth;
2984 nExpandWidth = nCollapseWidth * 100 / nTextSize;
2988 pTextWin->ToggleIndex( bIndex );
2992 // -----------------------------------------------------------------------
2994 void SfxHelpWindow_Impl::SaveConfig()
2996 SvtViewOptions aViewOpt( E_WINDOW, CONFIGNAME_HELPWIN );
2997 sal_Int32 nW = 0, nH = 0;
2999 if ( xWindow.is() )
3001 ::com::sun::star::awt::Rectangle aRect = xWindow->getPosSize();
3002 nW = aRect.Width;
3003 nH = aRect.Height;
3006 aViewOpt.SetVisible( bIndex );
3007 String aUserData = String::CreateFromInt32( nIndexSize );
3008 aUserData += ';';
3009 aUserData += String::CreateFromInt32( nTextSize );
3010 aUserData += ';';
3011 aUserData += String::CreateFromInt32( nW );
3012 aUserData += ';';
3013 aUserData += String::CreateFromInt32( nH );
3015 Window* pScreenWin = VCLUnoHelper::GetWindow( xWindow );
3016 aWinPos = pScreenWin->GetWindowExtentsRelative( NULL ).TopLeft();
3017 aUserData += ';';
3018 aUserData += String::CreateFromInt32( aWinPos.X() );
3019 aUserData += ';';
3020 aUserData += String::CreateFromInt32( aWinPos.Y() );
3022 aViewOpt.SetUserItem( USERITEM_NAME, makeAny( rtl::OUString( aUserData ) ) );
3025 // -----------------------------------------------------------------------
3027 void SfxHelpWindow_Impl::ShowStartPage()
3029 ::rtl::OUString sHelpURL = SfxHelpWindow_Impl::buildHelpURL(pIndexWin->GetFactory(),
3030 DEFINE_CONST_UNICODE("/start"),
3031 ::rtl::OUString(),
3032 sal_True);
3033 loadHelpContent(sHelpURL);
3036 // -----------------------------------------------------------------------
3038 IMPL_LINK( SfxHelpWindow_Impl, SelectHdl, ToolBox* , pToolBox )
3040 if ( pToolBox )
3042 bGrabFocusToToolBox = pToolBox->HasChildPathFocus();
3043 DoAction( pToolBox->GetCurItemId() );
3046 return 1;
3049 //-------------------------------------------------------------------------
3051 IMPL_LINK_NOARG(SfxHelpWindow_Impl, OpenHdl)
3053 pIndexWin->SelectExecutableEntry();
3054 String aEntry = pIndexWin->GetSelectEntry();
3056 if ( aEntry.Len() < 1 )
3057 return 0;
3059 ::rtl::OUString sHelpURL;
3061 bool bComplete = rtl::OUString(aEntry).toAsciiLowerCase().match(rtl::OUString("vnd.sun.star.help"),0);
3063 if (bComplete)
3064 sHelpURL = ::rtl::OUString(aEntry);
3065 else
3067 String aId;
3068 String aAnchor = String('#');
3069 if ( comphelper::string::getTokenCount(aEntry, '#') == 2 )
3071 aId = aEntry.GetToken( 0, '#' );
3072 aAnchor += aEntry.GetToken( 1, '#' );
3074 else
3075 aId = aEntry;
3077 aEntry = '/';
3078 aEntry += aId;
3080 sHelpURL = SfxHelpWindow_Impl::buildHelpURL(pIndexWin->GetFactory(),
3081 aEntry,
3082 aAnchor,
3083 sal_True);
3086 loadHelpContent(sHelpURL);
3088 return 0;
3091 //-------------------------------------------------------------------------
3093 IMPL_LINK( SfxHelpWindow_Impl, SelectFactoryHdl, SfxHelpIndexWindow_Impl* , pWin )
3095 if ( sTitle.Len() == 0 )
3096 sTitle = GetParent()->GetText();
3098 String aNewTitle = sTitle;
3099 aNewTitle += DEFINE_CONST_UNICODE(" - ");
3100 aNewTitle += pIndexWin->GetActiveFactoryTitle();
3102 Reference< XTitle > xTitle(xFrame, UNO_QUERY);
3103 if (xTitle.is ())
3104 xTitle->setTitle (aNewTitle);
3106 if ( pWin )
3107 ShowStartPage();
3108 pIndexWin->ClearSearchPage();
3110 return 0;
3113 // -----------------------------------------------------------------------
3115 IMPL_LINK( SfxHelpWindow_Impl, ChangeHdl, HelpListener_Impl*, pListener )
3117 SetFactory( pListener->GetFactory() );
3118 return 0;
3121 // -----------------------------------------------------------------------
3123 void SfxHelpWindow_Impl::openDone(const ::rtl::OUString& sURL ,
3124 sal_Bool bSuccess)
3126 INetURLObject aObj( sURL );
3127 if ( aObj.GetProtocol() == INET_PROT_VND_SUN_STAR_HELP )
3128 SetFactory( aObj.GetHost() );
3129 if ( IsWait() )
3130 LeaveWait();
3131 if ( bGrabFocusToToolBox )
3133 pTextWin->GetToolBox().GrabFocus();
3134 bGrabFocusToToolBox = sal_False;
3136 else
3137 pIndexWin->GrabFocusBack();
3138 if ( bSuccess )
3140 // set some view settings: "prevent help tips" and "helpid == 68245"
3143 Reference < XController > xController = pTextWin->getFrame()->getController();
3144 if ( xController.is() )
3146 Reference < XViewSettingsSupplier > xSettings( xController, UNO_QUERY );
3147 Reference < XPropertySet > xViewProps = xSettings->getViewSettings();
3148 Reference< XPropertySetInfo > xInfo = xViewProps->getPropertySetInfo();
3149 Any aBoolAny = makeAny( sal_Bool( sal_True ) );
3150 xViewProps->setPropertyValue( DEFINE_CONST_OUSTRING("PreventHelpTips"), aBoolAny );
3151 xViewProps->setPropertyValue( DEFINE_CONST_OUSTRING("ShowGraphics"), aBoolAny );
3152 xViewProps->setPropertyValue( DEFINE_CONST_OUSTRING("ShowTables"), aBoolAny );
3153 xViewProps->setPropertyValue( DEFINE_CONST_OUSTRING("HelpURL"), makeAny( DEFINE_CONST_OUSTRING("HID:SFX2_HID_HELP_ONHELP") ) );
3154 ::rtl::OUString sProperty( DEFINE_CONST_OUSTRING("IsExecuteHyperlinks") );
3155 if ( xInfo->hasPropertyByName( sProperty ) )
3156 xViewProps->setPropertyValue( sProperty, aBoolAny );
3157 xController->restoreViewData(pHelpInterceptor->GetViewData());
3160 catch( Exception& )
3162 OSL_FAIL( "SfxHelpWindow_Impl::OpenDoneHdl(): unexpected exception" );
3165 // When the SearchPage opens the help doc, then select all words, which are equal to its text
3166 String sSearchText = TRIM( pIndexWin->GetSearchText() );
3167 if ( sSearchText.Len() > 0 )
3168 pTextWin->SelectSearchText( sSearchText, pIndexWin->IsFullWordSearch() );
3170 // no page style header -> this prevents a print output of the URL
3171 pTextWin->SetPageStyleHeaderOff();
3175 // -----------------------------------------------------------------------
3177 SfxHelpWindow_Impl::SfxHelpWindow_Impl(
3178 const ::com::sun::star::uno::Reference < ::com::sun::star::frame::XFrame >& rFrame,
3179 Window* pParent, WinBits ) :
3181 SplitWindow( pParent, WB_3DLOOK | WB_NOSPLITDRAW ),
3183 xFrame ( rFrame ),
3184 pIndexWin ( NULL ),
3185 pTextWin ( NULL ),
3186 pHelpInterceptor ( new HelpInterceptor_Impl() ),
3187 pHelpListener ( new HelpListener_Impl( pHelpInterceptor ) ),
3188 nExpandWidth ( 0 ),
3189 nCollapseWidth ( 0 ),
3190 nHeight ( 0 ),
3191 nIndexSize ( 40 ),
3192 nTextSize ( 60 ),
3193 bIndex ( sal_True ),
3194 bGrabFocusToToolBox ( sal_False ),
3195 aWinPos ( 0, 0 ),
3196 sTitle ( pParent->GetText() )
3198 SetHelpId( HID_HELP_WINDOW );
3199 SetStyle( GetStyle() | WB_DIALOGCONTROL );
3201 pHelpInterceptor->InitWaiter( this );
3202 pIndexWin = new SfxHelpIndexWindow_Impl( this );
3203 pIndexWin->SetDoubleClickHdl( LINK( this, SfxHelpWindow_Impl, OpenHdl ) );
3204 pIndexWin->SetSelectFactoryHdl( LINK( this, SfxHelpWindow_Impl, SelectFactoryHdl ) );
3205 pIndexWin->Show();
3206 pTextWin = new SfxHelpTextWindow_Impl( this );
3207 Reference < XFramesSupplier > xSup( rFrame, UNO_QUERY );
3208 Reference < XFrames > xFrames = xSup->getFrames();
3209 xFrames->append( pTextWin->getFrame() );
3210 pTextWin->SetSelectHdl( LINK( this, SfxHelpWindow_Impl, SelectHdl ) );
3211 pTextWin->Show();
3212 pHelpInterceptor->setInterception( pTextWin->getFrame() );
3213 pHelpListener->SetChangeHdl( LINK( this, SfxHelpWindow_Impl, ChangeHdl ) );
3214 LoadConfig();
3217 // -----------------------------------------------------------------------
3219 SfxHelpWindow_Impl::~SfxHelpWindow_Impl()
3221 SaveConfig();
3222 Window* pDel = pIndexWin;
3223 pIndexWin = NULL;
3224 delete pDel;
3226 pTextWin->CloseFrame();
3227 delete pTextWin;
3230 // -----------------------------------------------------------------------
3232 long SfxHelpWindow_Impl::PreNotify( NotifyEvent& rNEvt )
3234 sal_Bool bHandled = sal_False;
3235 if ( rNEvt.GetType() == EVENT_KEYINPUT )
3237 // Backward == <ALT><LEFT> or <BACKSPACE> Forward == <ALT><RIGHT>
3238 const KeyCode& rKeyCode = rNEvt.GetKeyEvent()->GetKeyCode();
3239 sal_uInt16 nKey = rKeyCode.GetCode();
3240 if ( ( rKeyCode.IsMod2() && ( KEY_LEFT == nKey || KEY_RIGHT == nKey ) ) ||
3241 ( !rKeyCode.GetModifier() && KEY_BACKSPACE == nKey && !pIndexWin->HasFocusOnEdit() ) )
3243 DoAction( rKeyCode.GetCode() == KEY_RIGHT ? TBI_FORWARD : TBI_BACKWARD );
3244 bHandled = sal_True;
3246 else if ( rKeyCode.IsMod1() && ( KEY_F4 == nKey || KEY_W == nKey ) )
3248 // <STRG><F4> or <STRG><W> -> close top frame
3249 CloseWindow();
3250 bHandled = sal_True;
3253 return bHandled ? 1 : Window::PreNotify( rNEvt );
3256 // -----------------------------------------------------------------------
3258 void SfxHelpWindow_Impl::setContainerWindow( Reference < ::com::sun::star::awt::XWindow > xWin )
3260 xWindow = xWin;
3261 MakeLayout();
3264 // -----------------------------------------------------------------------
3266 void SfxHelpWindow_Impl::SetFactory( const String& rFactory )
3268 pIndexWin->SetFactory( rFactory, sal_True );
3271 // -----------------------------------------------------------------------
3273 void SfxHelpWindow_Impl::SetHelpURL( const String& rURL )
3275 INetURLObject aObj( rURL );
3276 if ( aObj.GetProtocol() == INET_PROT_VND_SUN_STAR_HELP )
3277 SetFactory( aObj.GetHost() );
3280 // -----------------------------------------------------------------------
3282 void SfxHelpWindow_Impl::DoAction( sal_uInt16 nActionId )
3284 switch ( nActionId )
3286 case TBI_INDEX :
3288 bIndex = !bIndex;
3289 MakeLayout();
3290 pTextWin->ToggleIndex( bIndex );
3291 break;
3294 case TBI_START :
3296 ShowStartPage();
3297 break;
3300 case TBI_BACKWARD :
3301 case TBI_FORWARD :
3303 URL aURL;
3304 aURL.Complete = DEFINE_CONST_UNICODE(".uno:Backward");
3305 if ( TBI_FORWARD == nActionId )
3306 aURL.Complete = DEFINE_CONST_UNICODE(".uno:Forward");
3307 PARSE_URL( aURL );
3308 pHelpInterceptor->dispatch( aURL, Sequence < PropertyValue >() );
3309 break;
3312 case TBI_SEARCHDIALOG :
3314 pTextWin->DoSearch();
3315 break;
3318 case TBI_PRINT :
3319 case TBI_SOURCEVIEW :
3320 case TBI_COPY :
3321 case TBI_SELECTIONMODE:
3323 Reference < XDispatchProvider > xProv( pTextWin->getFrame(), UNO_QUERY );
3324 if ( xProv.is() )
3326 URL aURL;
3327 if ( TBI_PRINT == nActionId )
3328 aURL.Complete = DEFINE_CONST_UNICODE(".uno:Print");
3329 else if ( TBI_SOURCEVIEW == nActionId )
3330 aURL.Complete = DEFINE_CONST_UNICODE(".uno:SourceView");
3331 else if ( TBI_COPY == nActionId )
3332 aURL.Complete = DEFINE_CONST_UNICODE(".uno:Copy");
3333 else if ( TBI_SELECTIONMODE == nActionId )
3334 aURL.Complete = DEFINE_CONST_UNICODE(".uno:SelectTextMode");
3335 else
3336 aURL.Complete = DEFINE_CONST_UNICODE(".uno:SearchDialog");
3337 PARSE_URL( aURL );
3338 Reference < XDispatch > xDisp = xProv->queryDispatch( aURL, String(), 0 );
3339 if ( xDisp.is() )
3340 xDisp->dispatch( aURL, Sequence < PropertyValue >() );
3342 break;
3345 case TBI_BOOKMARKS :
3347 String aURL = pHelpInterceptor->GetCurrentURL();
3348 if ( aURL.Len() > 0 )
3352 Content aCnt( aURL, Reference< ::com::sun::star::ucb::XCommandEnvironment > () );
3353 ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > xInfo = aCnt.getProperties();
3354 if ( xInfo->hasPropertyByName( PROPERTY_TITLE ) )
3356 ::com::sun::star::uno::Any aAny = aCnt.getPropertyValue( PROPERTY_TITLE );
3357 rtl::OUString aValue;
3358 if ( aAny >>= aValue )
3360 String aTitle( aValue );
3361 SfxAddHelpBookmarkDialog_Impl aDlg( this, sal_False );
3362 aDlg.SetTitle( aTitle );
3363 if ( aDlg.Execute() == RET_OK )
3365 aTitle = aDlg.GetTitle();
3366 pIndexWin->AddBookmarks( aTitle, aURL );
3371 catch( Exception& )
3373 OSL_FAIL( "SfxHelpWindow_Impl::DoAction(): unexpected exception" );
3376 break;
3381 // -----------------------------------------------------------------------
3383 void SfxHelpWindow_Impl::CloseWindow()
3387 // search for top frame
3388 Reference< XFramesSupplier > xCreator = getTextFrame()->getCreator();
3389 while ( xCreator.is() && !xCreator->isTop() )
3391 xCreator = xCreator->getCreator();
3394 // when found, close it
3395 if ( xCreator.is() && xCreator->isTop() )
3397 Reference < XCloseable > xCloser( xCreator, UNO_QUERY );
3398 if ( xCloser.is() )
3399 xCloser->close( sal_False );
3402 catch( Exception& )
3404 SAL_WARN( "sfx2.appl", "SfxHelpWindow_Impl::CloseWindow(): caught an exception" );
3408 // -----------------------------------------------------------------------
3410 void SfxHelpWindow_Impl::UpdateToolbox()
3412 pTextWin->GetToolBox().EnableItem( TBI_BACKWARD, pHelpInterceptor->HasHistoryPred() );
3413 pTextWin->GetToolBox().EnableItem( TBI_FORWARD, pHelpInterceptor->HasHistorySucc() );
3416 // -----------------------------------------------------------------------
3418 sal_Bool SfxHelpWindow_Impl::HasHistoryPredecessor() const
3420 return pHelpInterceptor->HasHistoryPred();
3423 // -----------------------------------------------------------------------
3425 sal_Bool SfxHelpWindow_Impl::HasHistorySuccessor() const
3427 return pHelpInterceptor->HasHistorySucc();
3430 // class SfxAddHelpBookmarkDialog_Impl -----------------------------------
3432 SfxAddHelpBookmarkDialog_Impl::SfxAddHelpBookmarkDialog_Impl( Window* pParent, sal_Bool bRename ) :
3434 ModalDialog( pParent, SfxResId( DLG_HELP_ADDBOOKMARK ) ),
3436 aTitleFT ( this, SfxResId( FT_BOOKMARK_TITLE ) ),
3437 aTitleED ( this, SfxResId( ED_BOOKMARK_TITLE ) ),
3438 aOKBtn ( this, SfxResId( PB_BOOKMARK_OK ) ),
3439 aEscBtn ( this, SfxResId( PB_BOOKMARK_CANCEL ) ),
3440 aHelpBtn ( this, SfxResId( PB_BOOKMARK_HELP ) )
3443 if ( bRename )
3444 SetText( String( SfxResId( STR_BOOKMARK_RENAME ) ) );
3446 FreeResource();
3449 // -----------------------------------------------------------------------
3451 SfxAddHelpBookmarkDialog_Impl::~SfxAddHelpBookmarkDialog_Impl()
3455 // -----------------------------------------------------------------------
3457 void SfxAddHelpBookmarkDialog_Impl::SetTitle( const String& rTitle )
3459 aTitleED.SetText( rTitle );
3460 aTitleED.SetSelection( Selection( 0, rTitle.Len() ) );
3463 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */