bump product version to 4.2.0.1
[LibreOffice.git] / sfx2 / source / appl / newhelp.cxx
blobbcef1d2c7a7ff43651449b2ad768995119ee8599
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include "newhelp.hxx"
22 #include <sfx2/sfxuno.hxx>
23 #include <sfx2/sfxresid.hxx>
24 #include "helpinterceptor.hxx"
25 #include "helper.hxx"
26 #include <sfx2/msgpool.hxx>
27 #include <sfx2/app.hxx>
28 #include "sfxtypes.hxx"
29 #include "panelist.hxx"
30 #include <sfx2/imgmgr.hxx>
31 #include "srchdlg.hxx"
32 #include <sfx2/sfxhelp.hxx>
33 #include <svtools/treelistentry.hxx>
35 #include "app.hrc"
36 #include "newhelp.hrc"
37 #include "helpid.hrc"
39 #include <boost/unordered_map.hpp>
40 #include <rtl/ustrbuf.hxx>
41 #include <comphelper/configurationhelper.hxx>
42 #include <comphelper/processfactory.hxx>
43 #include <comphelper/string.hxx>
44 #include <toolkit/helper/vclunohelper.hxx>
45 #include <com/sun/star/awt/PosSize.hpp>
46 #include <com/sun/star/awt/XWindow.hpp>
47 #include <com/sun/star/beans/Property.hpp>
48 #include <com/sun/star/beans/PropertyValue.hpp>
49 #include <com/sun/star/beans/XPropertySetInfo.hpp>
50 #include <com/sun/star/container/XIndexAccess.hpp>
51 #include <com/sun/star/frame/XComponentLoader.hpp>
52 #include <com/sun/star/frame/XTitle.hpp>
53 #include <com/sun/star/frame/XLayoutManager.hpp>
54 #include <com/sun/star/frame/DispatchResultState.hpp>
55 #include <com/sun/star/frame/XController.hpp>
56 #include <com/sun/star/frame/XDispatch.hpp>
57 #include <com/sun/star/frame/XDispatchProvider.hpp>
58 #include <com/sun/star/frame/XDispatchProviderInterception.hpp>
59 #include <com/sun/star/frame/Frame.hpp>
60 #include <com/sun/star/i18n/XBreakIterator.hpp>
61 #include <com/sun/star/i18n/WordType.hpp>
62 #include <com/sun/star/lang/XComponent.hpp>
63 #include <com/sun/star/lang/DisposedException.hpp>
64 #include <com/sun/star/style/XStyle.hpp>
65 #include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
66 #include <com/sun/star/text/XText.hpp>
67 #include <com/sun/star/text/XTextCursor.hpp>
68 #include <com/sun/star/text/XTextDocument.hpp>
69 #include <com/sun/star/text/XTextRange.hpp>
70 #include <com/sun/star/text/XTextViewCursor.hpp>
71 #include <com/sun/star/text/XTextViewCursorSupplier.hpp>
72 #include <com/sun/star/ucb/CommandAbortedException.hpp>
73 #include <com/sun/star/util/URL.hpp>
74 #include <com/sun/star/util/XSearchable.hpp>
75 #include <com/sun/star/util/XSearchDescriptor.hpp>
76 #include <com/sun/star/util/URLTransformer.hpp>
77 #include <com/sun/star/util/XURLTransformer.hpp>
78 #include <com/sun/star/util/XModifiable.hpp>
79 #include <com/sun/star/util/XCloseable.hpp>
80 #include <com/sun/star/util/CloseVetoException.hpp>
81 #include <com/sun/star/ui/XDockingAreaAcceptor.hpp>
82 #include <com/sun/star/view/XSelectionSupplier.hpp>
83 #include <com/sun/star/view/XViewSettingsSupplier.hpp>
84 #include <svtools/helpopt.hxx>
85 #include <unotools/historyoptions.hxx>
86 #include <svtools/menuoptions.hxx>
87 #include <unotools/pathoptions.hxx>
88 #include <unotools/viewoptions.hxx>
89 #include <svtools/svtresid.hxx>
90 #include <tools/urlobj.hxx>
91 #include <unotools/streamhelper.hxx>
92 #include <svtools/imagemgr.hxx>
93 #include <svtools/miscopt.hxx>
94 #include <svtools/imgdef.hxx>
95 #include <vcl/unohelp.hxx>
96 #include <vcl/i18nhelp.hxx>
98 #include <ucbhelper/content.hxx>
99 #include <vcl/msgbox.hxx>
100 #include <vcl/waitobj.hxx>
101 #include <unotools/ucbhelper.hxx>
103 #include <sfx2/viewfrm.hxx>
104 #include <sfx2/objsh.hxx>
105 #include <sfx2/docfac.hxx>
107 #include <vector>
109 using namespace ::ucbhelper;
110 using namespace ::com::sun::star::ucb;
112 using namespace ::com::sun::star;
113 using namespace ::com::sun::star::beans;
114 using namespace ::com::sun::star::container;
115 using namespace ::com::sun::star::frame;
116 using namespace ::com::sun::star::i18n;
117 using namespace ::com::sun::star::lang;
118 using namespace ::com::sun::star::style;
119 using namespace ::com::sun::star::text;
120 using namespace ::com::sun::star::uno;
121 using namespace ::com::sun::star::util;
122 using namespace ::com::sun::star::view;
123 using namespace ::com::sun::star::ui;
125 using namespace ::comphelper;
127 // defines ---------------------------------------------------------------
129 #define SPLITSET_ID 0
130 #define COLSET_ID 1
131 #define INDEXWIN_ID 2
132 #define TEXTWIN_ID 3
134 #define TOOLBOX_OFFSET 3
136 #define TBI_INDEX 1001
137 #define TBI_BACKWARD 1002
138 #define TBI_FORWARD 1003
139 #define TBI_START 1004
140 #define TBI_PRINT 1005
141 #define TBI_COPY 1006
142 #define TBI_BOOKMARKS 1007
143 #define TBI_SEARCHDIALOG 1008
144 #define TBI_SOURCEVIEW 1009
145 #define TBI_SELECTIONMODE 1010
147 #define CONFIGNAME_HELPWIN "OfficeHelp"
148 #define CONFIGNAME_INDEXWIN "OfficeHelpIndex"
149 #define CONFIGNAME_SEARCHPAGE "OfficeHelpSearch"
150 #define IMAGE_URL "private:factory/"
152 #define PROPERTY_KEYWORDLIST "KeywordList"
153 #define PROPERTY_KEYWORDREF "KeywordRef"
154 #define PROPERTY_ANCHORREF "KeywordAnchorForRef"
155 #define PROPERTY_TITLEREF "KeywordTitleForRef"
156 #define PROPERTY_TITLE "Title"
157 #define HELP_URL "vnd.sun.star.help://"
158 #define HELP_SEARCH_TAG "/?Query="
159 #define USERITEM_NAME "UserItem"
161 #define PACKAGE_SETUP "/org.openoffice.Setup"
162 #define PATH_OFFICE_FACTORIES "Office/Factories/"
163 #define KEY_HELP_ON_OPEN "ooSetupFactoryHelpOnOpen"
164 #define KEY_UI_NAME "ooSetupFactoryUIName"
166 #define PARSE_URL( aURL ) \
167 Reference< util::XURLTransformer > xTrans( util::URLTransformer::create( ::comphelper::getProcessComponentContext() ) ); \
168 xTrans->parseStrict( aURL )
170 //.........................................................................
171 namespace sfx2
173 //.........................................................................
175 void HandleTaskPaneList( Window* pWindow, sal_Bool bAddToList )
177 Window* pParent = pWindow->GetParent();
178 DBG_ASSERT( pParent, "HandleTaskPaneList(): every window here should have a parent" );
180 SystemWindow* pSysWin = pParent->GetSystemWindow();
181 if( pSysWin )
183 TaskPaneList* pTaskPaneList = pSysWin->GetTaskPaneList();
184 if( pTaskPaneList )
186 if( bAddToList )
187 pTaskPaneList->AddWindow( pWindow );
188 else
189 pTaskPaneList->RemoveWindow( pWindow );
194 /** Prepare a search string for searching or selecting.
195 For searching every search word needs the postfix '*' and the delimiter ' ' if necessary.
196 For selecting the delimiter '|' is required to search with regular expressions.
197 Samples:
198 search string | output for searching | output for selecting
199 -----------------------------------------------------------
200 "text" | "text*" | "text"
201 "text*" | "text*" | "text"
202 "text menu" | "text* menu*" | "text|menu"
204 OUString PrepareSearchString( const OUString& rSearchString,
205 Reference< XBreakIterator > xBreak, bool bForSearch )
207 OUString sSearchStr;
208 sal_Int32 nStartPos = 0;
209 const Locale aLocale = Application::GetSettings().GetUILanguageTag().getLocale();
210 Boundary aBoundary = xBreak->getWordBoundary(
211 rSearchString, nStartPos, aLocale, WordType::ANYWORD_IGNOREWHITESPACES, sal_True );
213 while ( aBoundary.startPos != aBoundary.endPos )
215 nStartPos = aBoundary.endPos;
216 OUString sSearchToken( rSearchString.copy(
217 (sal_uInt16)aBoundary.startPos, (sal_uInt16)aBoundary.endPos - (sal_uInt16)aBoundary.startPos ) );
218 if ( !sSearchToken.isEmpty() && ( sSearchToken.getLength() > 1 || sSearchToken[0] != '.' ) )
220 if ( bForSearch && sSearchToken[ sSearchToken.getLength() - 1 ] != '*' )
221 sSearchToken += "*";
223 if ( sSearchToken.getLength() > 1 ||
224 ( sSearchToken.getLength() > 0 && sSearchToken[ 0 ] != '*' ) )
226 if ( !sSearchStr.isEmpty() )
228 if ( bForSearch )
229 sSearchStr += " ";
230 else
231 sSearchStr += "|";
233 sSearchStr += sSearchToken;
236 aBoundary = xBreak->nextWord( rSearchString, nStartPos,
237 aLocale, WordType::ANYWORD_IGNOREWHITESPACES );
240 return sSearchStr;
242 //.........................................................................
243 // namespace sfx2
245 //.........................................................................
247 // struct IndexEntry_Impl ------------------------------------------------
249 struct IndexEntry_Impl
251 sal_Bool m_bSubEntry;
252 OUString m_aURL;
254 IndexEntry_Impl( const OUString& rURL, sal_Bool bSubEntry ) :
255 m_bSubEntry( bSubEntry ), m_aURL( rURL ) {}
258 // struct ContentEntry_Impl ----------------------------------------------
260 struct ContentEntry_Impl
262 OUString aURL;
263 sal_Bool bIsFolder;
265 ContentEntry_Impl( const OUString& rURL, sal_Bool bFolder ) :
266 aURL( rURL ), bIsFolder( bFolder ) {}
269 // ContentListBox_Impl ---------------------------------------------------
271 ContentListBox_Impl::ContentListBox_Impl( Window* pParent, const ResId& rResId ) :
273 SvTreeListBox( pParent, rResId ),
275 aOpenBookImage ( SfxResId( IMG_HELP_CONTENT_BOOK_OPEN ) ),
276 aClosedBookImage ( SfxResId( IMG_HELP_CONTENT_BOOK_CLOSED ) ),
277 aDocumentImage ( SfxResId( IMG_HELP_CONTENT_DOC ) )
280 SetStyle( GetStyle() | WB_HIDESELECTION | WB_HSCROLL );
282 SetEntryHeight( 16 );
283 SetSelectionMode( SINGLE_SELECTION );
284 SetSpaceBetweenEntries( 2 );
285 SetNodeBitmaps( aClosedBookImage, aOpenBookImage );
287 SetSublistOpenWithReturn();
288 SetSublistOpenWithLeftRight();
290 InitRoot();
293 // -----------------------------------------------------------------------
295 ContentListBox_Impl::~ContentListBox_Impl()
297 sal_uInt16 nPos = 0;
298 SvTreeListEntry* pEntry = GetEntry( nPos++ );
299 while ( pEntry )
301 ClearChildren( pEntry );
302 delete (ContentEntry_Impl*)pEntry->GetUserData();
303 pEntry = GetEntry( nPos++ );
307 // -----------------------------------------------------------------------
309 void ContentListBox_Impl::InitRoot()
311 OUString aHelpTreeviewURL( "vnd.sun.star.hier://com.sun.star.help.TreeView/" );
312 std::vector< OUString > aList =
313 SfxContentHelper::GetHelpTreeViewContents( aHelpTreeviewURL );
315 for(size_t i = 0, n = aList.size(); i < n; ++i )
317 const OUString& aRow = aList[i];
318 sal_Int32 nIdx = 0;
319 OUString aTitle = aRow.getToken( 0, '\t', nIdx );
320 OUString aURL = aRow.getToken( 0, '\t', nIdx );
321 sal_Unicode cFolder = aRow.getToken( 0, '\t', nIdx )[0];
322 bool bIsFolder = ( '1' == cFolder );
323 SvTreeListEntry* pEntry = InsertEntry( aTitle, aOpenBookImage, aClosedBookImage, NULL, sal_True );
324 if ( bIsFolder )
325 pEntry->SetUserData( new ContentEntry_Impl( aURL, sal_True ) );
329 // -----------------------------------------------------------------------
331 void ContentListBox_Impl::ClearChildren( SvTreeListEntry* pParent )
333 SvTreeListEntry* pEntry = FirstChild( pParent );
334 while ( pEntry )
336 ClearChildren( pEntry );
337 delete (ContentEntry_Impl*)pEntry->GetUserData();
338 pEntry = NextSibling( pEntry );
342 // -----------------------------------------------------------------------
344 void ContentListBox_Impl::RequestingChildren( SvTreeListEntry* pParent )
348 if ( !pParent->HasChildren() )
350 if ( pParent->GetUserData() )
352 OUString aTmpURL( ( (ContentEntry_Impl*)pParent->GetUserData() )->aURL );
353 std::vector<OUString > aList =
354 SfxContentHelper::GetHelpTreeViewContents( aTmpURL );
356 for (size_t i = 0,n = aList.size(); i < n; ++i )
358 const OUString& aRow = aList[i];
359 sal_Int32 nIdx = 0;
360 OUString aTitle = aRow.getToken( 0, '\t', nIdx );
361 OUString aURL = aRow.getToken( 0, '\t', nIdx );
362 sal_Unicode cFolder = aRow.getToken( 0, '\t', nIdx )[0];
363 bool bIsFolder = ( '1' == cFolder );
364 SvTreeListEntry* pEntry = NULL;
365 if ( bIsFolder )
367 pEntry = InsertEntry( aTitle, aOpenBookImage, aClosedBookImage, pParent, sal_True );
368 pEntry->SetUserData( new ContentEntry_Impl( aURL, sal_True ) );
370 else
372 pEntry = InsertEntry( aTitle, aDocumentImage, aDocumentImage, pParent );
373 Any aAny( ::utl::UCBContentHelper::GetProperty( aURL, OUString("TargetURL" ) ) );
374 OUString aTargetURL;
375 if ( aAny >>= aTargetURL )
376 pEntry->SetUserData( new ContentEntry_Impl( aTargetURL, sal_False ) );
382 catch( Exception& )
384 OSL_FAIL( "ContentListBox_Impl::RequestingChildren(): unexpected exception" );
388 // -----------------------------------------------------------------------
390 long ContentListBox_Impl::Notify( NotifyEvent& rNEvt )
392 sal_Bool bHandled = sal_False;
393 if ( rNEvt.GetType() == EVENT_KEYINPUT &&
394 KEY_RETURN == rNEvt.GetKeyEvent()->GetKeyCode().GetCode() )
396 GetDoubleClickHdl().Call( NULL );
397 bHandled = sal_True;
400 return bHandled ? 1 : SvTreeListBox::Notify( rNEvt );
403 // -----------------------------------------------------------------------
405 OUString ContentListBox_Impl::GetSelectEntry() const
407 OUString aRet;
408 SvTreeListEntry* pEntry = FirstSelected();
409 if ( pEntry && !( (ContentEntry_Impl*)pEntry->GetUserData() )->bIsFolder )
410 aRet = ( (ContentEntry_Impl*)pEntry->GetUserData() )->aURL;
411 return aRet;
414 // class HelpTabPage_Impl ------------------------------------------------
416 HelpTabPage_Impl::HelpTabPage_Impl(
417 Window* pParent, SfxHelpIndexWindow_Impl* _pIdxWin, const ResId& rResId ) :
419 TabPage( pParent, rResId ),
421 m_pIdxWin( _pIdxWin )
426 // class ContentTabPage_Impl ---------------------------------------------
428 ContentTabPage_Impl::ContentTabPage_Impl( Window* pParent, SfxHelpIndexWindow_Impl* _pIdxWin ) :
430 HelpTabPage_Impl( pParent, _pIdxWin, SfxResId( TP_HELP_CONTENT ) ),
432 aContentBox( this, SfxResId( LB_CONTENTS ) )
435 FreeResource();
437 aContentBox.Show();
440 // -----------------------------------------------------------------------
442 void ContentTabPage_Impl::Resize()
444 Size aSize = GetOutputSizePixel();
445 aSize.Width() -= 8;
446 aSize.Height() -= 8;
447 aContentBox.SetPosSizePixel( Point( 4, 4 ), aSize );
450 // -----------------------------------------------------------------------
452 void ContentTabPage_Impl::ActivatePage()
454 if ( !m_pIdxWin->WasCursorLeftOrRight() )
455 SetFocusOnBox();
458 // -----------------------------------------------------------------------
460 Control* ContentTabPage_Impl::GetLastFocusControl()
462 return &aContentBox;
465 // class IndexBox_Impl ---------------------------------------------------
467 IndexBox_Impl::IndexBox_Impl( Window* pParent, const ResId& rResId ) :
469 ComboBox( pParent, rResId )
472 EnableAutocomplete( sal_True );
473 EnableUserDraw( sal_True );
476 // -----------------------------------------------------------------------
478 void IndexBox_Impl::UserDraw( const UserDrawEvent& rUDEvt )
480 IndexEntry_Impl* pEntry = (IndexEntry_Impl*)(sal_uIntPtr)GetEntryData( rUDEvt.GetItemId() );
481 if ( pEntry && pEntry->m_bSubEntry )
483 // indent sub entries
484 Point aPos( rUDEvt.GetRect().TopLeft() );
485 aPos.X() += 8;
486 aPos.Y() += ( rUDEvt.GetRect().GetHeight() - rUDEvt.GetDevice()->GetTextHeight() ) / 2;
487 OUString aEntry( GetEntry( rUDEvt.GetItemId() ) );
488 sal_Int32 nPos = aEntry.indexOf( ';' );
489 rUDEvt.GetDevice()->DrawText( aPos, ( nPos !=-1 ) ? aEntry.copy( nPos + 1 ) : aEntry );
491 else
492 DrawEntry( rUDEvt, sal_False, sal_True, sal_True );
495 // -----------------------------------------------------------------------
497 long IndexBox_Impl::Notify( NotifyEvent& rNEvt )
499 sal_Bool bHandled = sal_False;
500 if ( rNEvt.GetType() == EVENT_KEYINPUT &&
501 KEY_RETURN == rNEvt.GetKeyEvent()->GetKeyCode().GetCode() )
503 GetDoubleClickHdl().Call( NULL );
504 bHandled = sal_True;
507 return bHandled ? 1 : ComboBox::Notify( rNEvt );
510 // -----------------------------------------------------------------------
512 void IndexBox_Impl::SelectExecutableEntry()
514 sal_uInt16 nPos = GetEntryPos( GetText() );
515 if ( nPos != COMBOBOX_ENTRY_NOTFOUND )
517 sal_uInt16 nOldPos = nPos;
518 OUString aEntryText;
519 IndexEntry_Impl* pEntry = (IndexEntry_Impl*)(sal_uIntPtr)GetEntryData( nPos );
520 sal_uInt16 nCount = GetEntryCount();
521 while ( nPos < nCount && ( !pEntry || pEntry->m_aURL.isEmpty() ) )
523 pEntry = (IndexEntry_Impl*)(sal_uIntPtr)GetEntryData( ++nPos );
524 aEntryText = GetEntry( nPos );
527 if ( nOldPos != nPos )
528 SetText( aEntryText );
532 // class IndexTabPage_Impl -----------------------------------------------
534 IndexTabPage_Impl::IndexTabPage_Impl( Window* pParent, SfxHelpIndexWindow_Impl* _pIdxWin ) :
536 HelpTabPage_Impl( pParent, _pIdxWin, SfxResId( TP_HELP_INDEX ) ),
538 aExpressionFT ( this, SfxResId( FT_EXPRESSION ) ),
539 aIndexCB ( this, SfxResId( CB_INDEX ) ),
540 aOpenBtn ( this, SfxResId( PB_OPEN_INDEX ) ),
542 bIsActivated ( sal_False )
545 FreeResource();
547 aOpenBtn.SetClickHdl( LINK( this, IndexTabPage_Impl, OpenHdl ) );
548 Link aTimeoutLink = LINK( this, IndexTabPage_Impl, TimeoutHdl );
549 aFactoryTimer.SetTimeoutHdl( aTimeoutLink );
550 aFactoryTimer.SetTimeout( 300 );
551 aKeywordTimer.SetTimeoutHdl( aTimeoutLink );
552 aFactoryTimer.SetTimeout( 300 );
554 nMinWidth = aOpenBtn.GetSizePixel().Width();
557 // -----------------------------------------------------------------------
559 IndexTabPage_Impl::~IndexTabPage_Impl()
561 ClearIndex();
564 // -----------------------------------------------------------------------
566 namespace sfx2 {
568 struct equalOUString
570 bool operator()( const OUString& rKey1, const OUString& rKey2 ) const
572 return !!( rKey1 == rKey2 );
577 struct hashOUString
579 size_t operator()( const OUString& rName ) const
581 return rName.hashCode();
585 typedef ::boost::unordered_map< OUString, int, hashOUString, equalOUString > KeywordInfo;
588 #define NEW_ENTRY( url, bool ) \
589 (void*)(sal_uIntPtr)( new IndexEntry_Impl( url, bool ) )
591 #define UNIFY_AND_INSERT_TOKEN( aToken ) \
592 it = aInfo.insert( sfx2::KeywordInfo::value_type( aToken, 0 ) ).first; \
593 if ( ( tmp = it->second++ ) != 0 ) \
594 nPos = aIndexCB.InsertEntry( aToken + OUString( append, tmp ) ); \
595 else \
596 nPos = aIndexCB.InsertEntry( aToken )
598 #define INSERT_DATA( j ) \
599 if ( aAnchorList[j].getLength() > 0 ) \
601 aData.append( aRefList[j] ).append( '#' ).append( aAnchorList[j] ); \
602 aIndexCB.SetEntryData( nPos, NEW_ENTRY( aData.makeStringAndClear(), insert ) ); \
604 else \
605 aIndexCB.SetEntryData( nPos, NEW_ENTRY( aRefList[j], insert ) );
607 // -----------------------------------------------------------------------
609 void IndexTabPage_Impl::InitializeIndex()
611 WaitObject aWaitCursor( this );
613 // By now more than 256 equal entries are not allowed
614 sal_Unicode append[256];
615 for( int k = 0; k < 256; ++k )
616 append[k] = ' ';
618 sfx2::KeywordInfo aInfo;
619 aIndexCB.SetUpdateMode( sal_False );
623 OUStringBuffer aURL = HELP_URL;
624 aURL.append(sFactory);
625 AppendConfigToken(aURL, sal_True);
627 Content aCnt( aURL.makeStringAndClear(), Reference< ::com::sun::star::ucb::XCommandEnvironment >(), comphelper::getProcessComponentContext() );
628 ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > xInfo = aCnt.getProperties();
629 if ( xInfo->hasPropertyByName( PROPERTY_ANCHORREF ) )
631 ::com::sun::star::uno::Sequence< OUString > aPropSeq( 4 );
632 aPropSeq[0] = PROPERTY_KEYWORDLIST;
633 aPropSeq[1] = PROPERTY_KEYWORDREF;
634 aPropSeq[2] = PROPERTY_ANCHORREF;
635 aPropSeq[3] = PROPERTY_TITLEREF;
637 // abi: use one possibly remote call only
638 ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any > aAnySeq =
639 aCnt.getPropertyValues( aPropSeq );
641 ::com::sun::star::uno::Sequence< OUString > aKeywordList;
642 ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< OUString > > aKeywordRefList;
643 ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< OUString > > aAnchorRefList;
644 ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< OUString > > aTitleRefList;
646 if ( ( aAnySeq[0] >>= aKeywordList ) && ( aAnySeq[1] >>= aKeywordRefList ) &&
647 ( aAnySeq[2] >>= aAnchorRefList ) && ( aAnySeq[3] >>= aTitleRefList ) )
649 sal_Bool insert;
650 sal_uInt16 nPos;
651 int ndx,tmp;
652 OUString aIndex, aTempString;
653 OUStringBuffer aData( 128 ); // Capacity of up to 128 characters
654 sfx2::KeywordInfo::iterator it;
656 for ( int i = 0; i < aKeywordList.getLength(); ++i )
658 // abi: Do not copy, but use references
659 const OUString& aKeywordPair = aKeywordList[i];
660 DBG_ASSERT( !aKeywordPair.isEmpty(), "invalid help index" );
661 const ::com::sun::star::uno::Sequence< OUString >& aRefList = aKeywordRefList[i];
662 const ::com::sun::star::uno::Sequence< OUString >& aAnchorList = aAnchorRefList[i];
663 const ::com::sun::star::uno::Sequence< OUString >& aTitleList = aTitleRefList[i];
665 DBG_ASSERT( aRefList.getLength() == aAnchorList.getLength(),"reference list and title list of different length" );
667 insert = ( ( ndx = aKeywordPair.indexOf( ';' ) ) == -1 ? sal_False : sal_True );
669 if ( insert )
671 aTempString = aKeywordPair.copy( 0, ndx );
672 if ( aIndex != aTempString )
674 aIndex = aTempString;
675 UNIFY_AND_INSERT_TOKEN( aTempString );
678 else
679 aIndex = OUString();
681 // Assume the token is trimed
682 UNIFY_AND_INSERT_TOKEN( aKeywordPair );
684 sal_uInt32 nRefListLen = aRefList.getLength();
686 DBG_ASSERT( aAnchorList.getLength(), "*IndexTabPage_Impl::InitializeIndex(): AnchorList is empty!" ); \
687 DBG_ASSERT( nRefListLen, "*IndexTabPage_Impl::InitializeIndex(): RefList is empty!" ); \
689 if ( aAnchorList.getLength() && nRefListLen )
691 INSERT_DATA( 0 );
694 for ( sal_uInt32 j = 1; j < nRefListLen ; ++j )
696 aData
697 .append( aKeywordPair )
698 .append( ' ' )
699 .append( '-' )
700 .append( ' ' )
701 .append( aTitleList[j] );
703 aTempString = aData.makeStringAndClear();
704 UNIFY_AND_INSERT_TOKEN( aTempString );
705 INSERT_DATA( j );
711 catch( Exception& )
713 OSL_FAIL( "IndexTabPage_Impl::InitializeIndex(): unexpected exception" );
716 aIndexCB.SetUpdateMode( sal_True );
718 if ( !sKeyword.isEmpty() )
719 aKeywordLink.Call( this );
722 #undef INSERT_DATA
723 #undef UNIFY_AND_INSERT_TOKEN
725 // -----------------------------------------------------------------------
727 void IndexTabPage_Impl::ClearIndex()
729 sal_uInt16 nCount = aIndexCB.GetEntryCount();
730 for ( sal_uInt16 i = 0; i < nCount; ++i )
731 delete (IndexEntry_Impl*)(sal_uIntPtr)aIndexCB.GetEntryData(i);
732 aIndexCB.Clear();
735 // -----------------------------------------------------------------------
737 IMPL_LINK_NOARG(IndexTabPage_Impl, OpenHdl)
739 aIndexCB.GetDoubleClickHdl().Call( &aIndexCB );
740 return 0;
743 // -----------------------------------------------------------------------
745 IMPL_LINK( IndexTabPage_Impl, TimeoutHdl, Timer*, pTimer )
747 if ( &aFactoryTimer == pTimer )
748 InitializeIndex();
749 else if ( &aKeywordTimer == pTimer && !sKeyword.isEmpty() )
750 aKeywordLink.Call( this );
751 return 0;
754 // -----------------------------------------------------------------------
756 void IndexTabPage_Impl::Resize()
758 Size aSize = GetSizePixel();
759 if ( aSize.Width() < nMinWidth )
760 aSize.Width() = nMinWidth;
761 Point aPnt = aExpressionFT.GetPosPixel();
762 Size aNewSize = aExpressionFT.GetSizePixel();
763 aNewSize.Width() = aSize.Width() - ( aPnt.X() * 2 );
764 aExpressionFT.SetSizePixel( aNewSize );
766 Size a6Size = LogicToPixel( Size( 6, 6 ), MAP_APPFONT );
767 Size aBtnSize = aOpenBtn.GetSizePixel();
769 aPnt = aIndexCB.GetPosPixel();
770 aNewSize = aIndexCB.GetSizePixel();
771 aNewSize.Width() = aSize.Width() - ( aPnt.X() * 2 );
772 aNewSize.Height() = aSize.Height() - aPnt.Y();
773 aNewSize.Height() -= ( aBtnSize.Height() + ( a6Size.Height() * 3 / 2 ) );
774 aIndexCB.SetSizePixel( aNewSize );
776 aPnt.X() += ( aNewSize.Width() - aBtnSize.Width() );
777 aPnt.Y() += aNewSize.Height() + ( a6Size.Height() / 2 );
778 long nMinX = aIndexCB.GetPosPixel().X();
779 if ( aPnt.X() < nMinX )
780 aPnt.X() = nMinX;
781 aOpenBtn.SetPosPixel( aPnt );
784 // -----------------------------------------------------------------------
786 void IndexTabPage_Impl::ActivatePage()
788 if ( !bIsActivated )
790 bIsActivated = sal_True;
791 aFactoryTimer.Start();
794 if ( !m_pIdxWin->WasCursorLeftOrRight() )
795 SetFocusOnBox();
798 // -----------------------------------------------------------------------
800 Control* IndexTabPage_Impl::GetLastFocusControl()
802 return &aOpenBtn;
805 // -----------------------------------------------------------------------
807 void IndexTabPage_Impl::SetDoubleClickHdl( const Link& rLink )
809 aIndexCB.SetDoubleClickHdl( rLink );
812 // -----------------------------------------------------------------------
814 void IndexTabPage_Impl::SetFactory( const OUString& rFactory )
816 OUString sNewFactory( rFactory );
817 DBG_ASSERT( !sNewFactory.isEmpty(), "empty factory" );
818 bool bValid = m_pIdxWin->IsValidFactory( rFactory );
820 if ( sFactory.isEmpty() && !bValid )
822 sNewFactory = SfxHelp::GetDefaultHelpModule();
823 bValid = true;
826 if ( sNewFactory != sFactory && bValid )
828 sFactory = sNewFactory;
829 ClearIndex();
830 if ( bIsActivated )
831 aFactoryTimer.Start();
835 // -----------------------------------------------------------------------
837 OUString IndexTabPage_Impl::GetSelectEntry() const
839 OUString aRet;
840 IndexEntry_Impl* pEntry = (IndexEntry_Impl*)(sal_uIntPtr)aIndexCB.GetEntryData( aIndexCB.GetEntryPos( aIndexCB.GetText() ) );
841 if ( pEntry )
842 aRet = pEntry->m_aURL;
843 return aRet;
846 // -----------------------------------------------------------------------
848 void IndexTabPage_Impl::SetKeyword( const OUString& rKeyword )
850 sKeyword = rKeyword;
852 if ( aIndexCB.GetEntryCount() > 0 )
853 aKeywordTimer.Start();
854 else if ( !bIsActivated )
855 aFactoryTimer.Start();
858 // -----------------------------------------------------------------------
860 sal_Bool IndexTabPage_Impl::HasKeyword() const
862 sal_Bool bRet = sal_False;
863 if ( !sKeyword.isEmpty() )
865 sal_uInt16 nPos = aIndexCB.GetEntryPos( sKeyword );
866 bRet = ( nPos != LISTBOX_ENTRY_NOTFOUND );
869 return bRet;
872 // -----------------------------------------------------------------------
874 sal_Bool IndexTabPage_Impl::HasKeywordIgnoreCase()
876 sal_Bool bRet = sal_False;
877 if ( !sKeyword.isEmpty() )
879 sal_uInt16 nEntries = aIndexCB.GetEntryCount();
880 OUString sIndexItem;
881 const vcl::I18nHelper& rI18nHelper = GetSettings().GetLocaleI18nHelper();
882 for ( sal_uInt16 n = 0; n < nEntries; n++)
884 sIndexItem = aIndexCB.GetEntry( n );
885 if (rI18nHelper.MatchString( sIndexItem, sKeyword ))
887 sKeyword = sIndexItem;
888 bRet = sal_True;
893 return bRet;
896 // -----------------------------------------------------------------------
898 void IndexTabPage_Impl::OpenKeyword()
900 if ( !sKeyword.isEmpty() )
902 aIndexCB.SetText( sKeyword );
903 aIndexCB.GetDoubleClickHdl().Call( NULL );
904 sKeyword = "";
908 // class SearchBox_Impl --------------------------------------------------
910 long SearchBox_Impl::PreNotify( NotifyEvent& rNEvt )
912 sal_Bool bHandled = sal_False;
913 if ( !IsInDropDown() &&
914 rNEvt.GetWindow() == GetSubEdit() &&
915 rNEvt.GetType() == EVENT_KEYINPUT &&
916 KEY_RETURN == rNEvt.GetKeyEvent()->GetKeyCode().GetCode() )
918 aSearchLink.Call( NULL );
919 bHandled = sal_True;
921 return bHandled ? 1 : ComboBox::PreNotify( rNEvt );
924 // -----------------------------------------------------------------------
926 void SearchBox_Impl::Select()
928 if ( !IsTravelSelect() )
929 aSearchLink.Call( NULL );
932 // class SearchResultsBox_Impl -------------------------------------------
934 long SearchResultsBox_Impl::Notify( NotifyEvent& rNEvt )
936 sal_Bool bHandled = sal_False;
937 if ( rNEvt.GetType() == EVENT_KEYINPUT &&
938 KEY_RETURN == rNEvt.GetKeyEvent()->GetKeyCode().GetCode() )
940 GetDoubleClickHdl().Call( NULL );
941 bHandled = sal_True;
944 return bHandled ? 1 : ListBox::Notify( rNEvt );
947 // class SearchTabPage_Impl ----------------------------------------------
949 SearchTabPage_Impl::SearchTabPage_Impl( Window* pParent, SfxHelpIndexWindow_Impl* _pIdxWin ) :
951 HelpTabPage_Impl( pParent, _pIdxWin, SfxResId( TP_HELP_SEARCH ) ),
953 aSearchFT ( this, SfxResId( FT_SEARCH ) ),
954 aSearchED ( this, SfxResId( ED_SEARCH ) ),
955 aSearchBtn ( this, SfxResId( PB_SEARCH ) ),
956 aFullWordsCB ( this, SfxResId( CB_FULLWORDS ) ),
957 aScopeCB ( this, SfxResId( CB_SCOPE ) ),
958 aResultsLB ( this, SfxResId( LB_RESULT ) ),
959 aOpenBtn ( this, SfxResId( PB_OPEN_SEARCH ) ),
960 xBreakIterator ( vcl::unohelper::CreateBreakIterator() )
963 FreeResource();
965 Link aLink = LINK( this, SearchTabPage_Impl, SearchHdl );
966 aSearchED.SetSearchLink( aLink );
967 aSearchBtn.SetClickHdl( aLink );
968 aSearchED.SetModifyHdl( LINK( this, SearchTabPage_Impl, ModifyHdl ) );
969 aOpenBtn.SetClickHdl( LINK( this, SearchTabPage_Impl, OpenHdl ) );
971 aMinSize = GetSizePixel();
973 SvtViewOptions aViewOpt( E_TABPAGE, CONFIGNAME_SEARCHPAGE );
974 if ( aViewOpt.Exists() )
976 OUString aUserData;
977 Any aUserItem = aViewOpt.GetUserItem( USERITEM_NAME );
978 if ( aUserItem >>= aUserData )
980 sal_Bool bChecked = ( 1 == aUserData.getToken(0, ';').toInt32() ) ? sal_True : sal_False;
981 aFullWordsCB.Check( bChecked );
982 bChecked = ( 1 == aUserData.getToken(1, ';').toInt32() ) ? sal_True : sal_False;
983 aScopeCB.Check( bChecked );
985 for ( sal_uInt16 i = 2; i < comphelper::string::getTokenCount(aUserData, ';'); ++i )
987 OUString aToken = aUserData.getToken(i, ';');
988 aSearchED.InsertEntry( INetURLObject::decode(
989 aToken, '%', INetURLObject::DECODE_WITH_CHARSET ) );
994 ModifyHdl( &aSearchED );
997 // -----------------------------------------------------------------------
999 SearchTabPage_Impl::~SearchTabPage_Impl()
1001 SvtViewOptions aViewOpt( E_TABPAGE, CONFIGNAME_SEARCHPAGE );
1002 sal_Int32 nChecked = aFullWordsCB.IsChecked() ? 1 : 0;
1003 OUString aUserData = OUString::number( nChecked );
1004 aUserData += ";";
1005 nChecked = aScopeCB.IsChecked() ? 1 : 0;
1006 aUserData += OUString::number( nChecked );
1007 aUserData += ";";
1008 sal_uInt16 nCount = std::min( aSearchED.GetEntryCount(), (sal_uInt16)10 ); // save only 10 entries
1010 for ( sal_uInt16 i = 0; i < nCount; ++i )
1012 OUString aText = aSearchED.GetEntry(i);
1013 aUserData += INetURLObject::encode(
1014 aText, INetURLObject::PART_UNO_PARAM_VALUE, '%',
1015 INetURLObject::ENCODE_ALL );
1016 aUserData += ";";
1019 aUserData = comphelper::string::stripEnd(aUserData, ';');
1020 Any aUserItem = makeAny( OUString( aUserData ) );
1021 aViewOpt.SetUserItem( USERITEM_NAME, aUserItem );
1024 // -----------------------------------------------------------------------
1026 void SearchTabPage_Impl::ClearSearchResults()
1028 sal_uInt16 nCount = aResultsLB.GetEntryCount();
1029 for ( sal_uInt16 i = 0; i < nCount; ++i )
1030 delete (OUString*)(sal_uIntPtr)aResultsLB.GetEntryData(i);
1031 aResultsLB.Clear();
1032 aResultsLB.Update();
1035 // -----------------------------------------------------------------------
1037 void SearchTabPage_Impl::RememberSearchText( const OUString& rSearchText )
1039 for ( sal_uInt16 i = 0; i < aSearchED.GetEntryCount(); ++i )
1041 if ( rSearchText == aSearchED.GetEntry(i) )
1043 aSearchED.RemoveEntryAt(i);
1044 break;
1048 aSearchED.InsertEntry( rSearchText, 0 );
1051 // -----------------------------------------------------------------------
1053 IMPL_LINK_NOARG(SearchTabPage_Impl, SearchHdl)
1055 OUString aSearchText = comphelper::string::strip(aSearchED.GetText(), ' ');
1056 if ( !aSearchText.isEmpty() )
1058 EnterWait();
1059 ClearSearchResults();
1060 RememberSearchText( aSearchText );
1061 OUStringBuffer aSearchURL(HELP_URL);
1062 aSearchURL.append(aFactory);
1063 aSearchURL.append(HELP_SEARCH_TAG);
1064 if ( !aFullWordsCB.IsChecked() )
1065 aSearchText = sfx2::PrepareSearchString( aSearchText, xBreakIterator, true );
1066 aSearchURL.append(aSearchText);
1067 AppendConfigToken(aSearchURL, sal_False);
1068 if ( aScopeCB.IsChecked() )
1069 aSearchURL.append("&Scope=Heading");
1070 std::vector< OUString > aFactories = SfxContentHelper::GetResultSet(aSearchURL.makeStringAndClear());
1071 for (size_t i = 0, n = aFactories.size(); i < n; ++i )
1073 const OUString& rRow = aFactories[i];
1074 sal_Int32 nIdx = 0;
1075 OUString aTitle = rRow.getToken( 0, '\t', nIdx );
1076 nIdx = 0;
1077 OUString* pURL = new OUString( rRow.getToken( 2, '\t', nIdx ) );
1078 sal_uInt16 nPos = aResultsLB.InsertEntry( aTitle );
1079 aResultsLB.SetEntryData( nPos, (void*)(sal_uIntPtr)pURL );
1081 LeaveWait();
1083 if ( aFactories.empty() )
1085 InfoBox aBox( this, SfxResId( RID_INFO_NOSEARCHRESULTS ) );
1086 aBox.SetText( SfxResId( STR_HELP_WINDOW_TITLE ).toString() );
1087 aBox.Execute();
1090 return 0;
1093 // -----------------------------------------------------------------------
1095 IMPL_LINK_NOARG(SearchTabPage_Impl, OpenHdl)
1097 aResultsLB.GetDoubleClickHdl().Call( &aResultsLB );
1098 return 0;
1101 // -----------------------------------------------------------------------
1103 IMPL_LINK_NOARG(SearchTabPage_Impl, ModifyHdl)
1105 OUString aSearchText = comphelper::string::strip(aSearchED.GetText(), ' ');
1106 aSearchBtn.Enable( !aSearchText.isEmpty() );
1107 return 0;
1110 // -----------------------------------------------------------------------
1112 void SearchTabPage_Impl::Resize()
1114 Size a6Size = LogicToPixel( Size( 6, 6 ), MAP_APPFONT );
1115 Size aSize = GetSizePixel();
1116 if ( aSize.Width() < aMinSize.Width() )
1117 aSize.Width() = aMinSize.Width();
1118 Point aPnt = aSearchFT.GetPosPixel();
1119 Size aNewSize = aSearchFT.GetSizePixel();
1120 aNewSize.Width() = aSize.Width() - ( aPnt.X() * 2 );
1121 aSearchFT.SetSizePixel( aNewSize );
1122 aNewSize.Height() = aResultsLB.GetSizePixel().Height();
1123 aResultsLB.SetSizePixel( aNewSize );
1124 aNewSize.Height() = aFullWordsCB.GetSizePixel().Height();
1125 aFullWordsCB.SetSizePixel( aNewSize );
1126 aScopeCB.SetSizePixel( aNewSize );
1127 aNewSize = aSearchED.GetSizePixel();
1128 aNewSize.Width() = aSize.Width() - ( aPnt.X() * 2 ) -
1129 ( aSearchBtn.GetSizePixel().Width() + ( aPnt.X() / 2 ) );
1130 aSearchED.SetSizePixel( aNewSize );
1131 Point aNewPnt = aSearchBtn.GetPosPixel();
1132 aNewPnt.X() = aPnt.X() + aNewSize.Width() + ( aPnt.X() / 2 );
1133 aSearchBtn.SetPosPixel( aNewPnt );
1135 if ( aSize.Height() > aMinSize.Height() )
1137 long n3Height = a6Size.Height() / 2;
1138 Size aBtnSize = aOpenBtn.GetSizePixel();
1139 long nExtraHeight = aBtnSize.Height() + n3Height;
1141 aPnt = aResultsLB.GetPosPixel();
1142 aNewSize = aResultsLB.GetSizePixel();
1143 aNewSize.Height() = aSize.Height() - aPnt.Y();
1144 aNewSize.Height() -= ( nExtraHeight + ( a6Size.Height() * 3 / 2 ) );
1145 aResultsLB.SetSizePixel( aNewSize );
1147 aPnt.X() += ( aNewSize.Width() - aBtnSize.Width() );
1148 aPnt.Y() += aNewSize.Height() + a6Size.Height();
1149 aOpenBtn.SetPosPixel( aPnt );
1153 // -----------------------------------------------------------------------
1155 void SearchTabPage_Impl::ActivatePage()
1157 if ( !m_pIdxWin->WasCursorLeftOrRight() )
1158 aSearchED.GrabFocus();
1161 // -----------------------------------------------------------------------
1163 Control* SearchTabPage_Impl::GetLastFocusControl()
1165 return &aOpenBtn;
1168 // -----------------------------------------------------------------------
1170 void SearchTabPage_Impl::SetDoubleClickHdl( const Link& rLink )
1172 aResultsLB.SetDoubleClickHdl( rLink );
1175 // -----------------------------------------------------------------------
1177 OUString SearchTabPage_Impl::GetSelectEntry() const
1179 OUString aRet;
1180 OUString* pData = (OUString*)(sal_uIntPtr)aResultsLB.GetEntryData( aResultsLB.GetSelectEntryPos() );
1181 if ( pData )
1182 aRet = *pData;
1183 return aRet;
1186 // -----------------------------------------------------------------------
1188 void SearchTabPage_Impl::ClearPage()
1190 ClearSearchResults();
1191 aSearchED.SetText( OUString() );
1194 // -----------------------------------------------------------------------
1196 sal_Bool SearchTabPage_Impl::OpenKeyword( const OUString& rKeyword )
1198 sal_Bool bRet = sal_False;
1199 aSearchED.SetText( rKeyword );
1200 SearchHdl( NULL );
1201 if ( aResultsLB.GetEntryCount() > 0 )
1203 // found keyword -> open it
1204 aResultsLB.SelectEntryPos(0);
1205 OpenHdl( NULL );
1206 bRet = sal_True;
1209 return bRet;
1212 // class BookmarksTabPage_Impl -------------------------------------------
1214 void GetBookmarkEntry_Impl
1216 Sequence< PropertyValue >& aBookmarkEntry,
1217 OUString& rTitle,
1218 OUString& rURL
1221 for ( int i = 0; i < aBookmarkEntry.getLength(); i++ )
1223 PropertyValue aValue = aBookmarkEntry[i];
1224 if ( aValue.Name == HISTORY_PROPERTYNAME_URL )
1225 aValue.Value >>= rURL;
1226 else if ( aValue.Name == HISTORY_PROPERTYNAME_TITLE )
1227 aValue.Value >>= rTitle;
1231 // -----------------------------------------------------------------------
1233 BookmarksBox_Impl::BookmarksBox_Impl( Window* pParent, const ResId& rResId ) :
1235 ListBox( pParent, rResId )
1240 // -----------------------------------------------------------------------
1242 BookmarksBox_Impl::~BookmarksBox_Impl()
1244 // save bookmarks to configuration
1245 SvtHistoryOptions aHistOpt;
1246 aHistOpt.Clear( eHELPBOOKMARKS );
1247 OUString sEmpty;
1248 sal_uInt16 nCount = GetEntryCount();
1249 for ( sal_uInt16 i = 0; i < nCount; ++i )
1251 OUString aTitle = GetEntry(i);
1252 OUString* pURL = (OUString*)(sal_uIntPtr)GetEntryData(i);
1253 aHistOpt.AppendItem( eHELPBOOKMARKS, OUString( *pURL ), sEmpty, OUString( aTitle ), sEmpty );
1254 delete pURL;
1258 // -----------------------------------------------------------------------
1260 void BookmarksBox_Impl::DoAction( sal_uInt16 nAction )
1262 switch ( nAction )
1264 case MID_OPEN :
1265 GetDoubleClickHdl().Call( NULL );
1266 break;
1268 case MID_RENAME :
1270 sal_uInt16 nPos = GetSelectEntryPos();
1271 if ( nPos != LISTBOX_ENTRY_NOTFOUND )
1273 SfxAddHelpBookmarkDialog_Impl aDlg( this, sal_True );
1274 aDlg.SetTitle( GetEntry( nPos ) );
1275 if ( aDlg.Execute() == RET_OK )
1277 OUString* pURL = (OUString*)(sal_uIntPtr)GetEntryData( nPos );
1278 RemoveEntry( nPos );
1279 OUString aImageURL = IMAGE_URL;
1280 aImageURL += INetURLObject( *pURL ).GetHost();
1281 nPos = InsertEntry( aDlg.GetTitle(), SvFileInformationManager::GetImage( INetURLObject(aImageURL), false ) );
1282 SetEntryData( nPos, (void*)(sal_uIntPtr)( new OUString( *pURL ) ) );
1283 SelectEntryPos( nPos );
1284 delete pURL;
1287 break;
1290 case MID_DELETE :
1292 sal_uInt16 nPos = GetSelectEntryPos();
1293 if ( nPos != LISTBOX_ENTRY_NOTFOUND )
1295 RemoveEntry( nPos );
1296 sal_uInt16 nCount = GetEntryCount();
1297 if ( nCount )
1299 if ( nPos >= nCount )
1300 nPos = nCount - 1;
1301 SelectEntryPos( nPos );
1304 break;
1309 // -----------------------------------------------------------------------
1311 long BookmarksBox_Impl::Notify( NotifyEvent& rNEvt )
1313 long nRet = 0;
1314 sal_uInt16 nType = rNEvt.GetType();
1315 if ( EVENT_KEYINPUT == nType )
1317 sal_uInt16 nCode = rNEvt.GetKeyEvent()->GetKeyCode().GetCode();
1318 if ( KEY_DELETE == nCode && GetEntryCount() > 0 )
1320 DoAction( MID_DELETE );
1321 nRet = 1;
1323 else if ( KEY_RETURN == nCode )
1325 GetDoubleClickHdl().Call( NULL );
1326 nRet = 1;
1329 else if ( EVENT_COMMAND == nType )
1331 const CommandEvent* pCEvt = rNEvt.GetCommandEvent();
1332 if ( pCEvt->GetCommand() == COMMAND_CONTEXTMENU )
1334 PopupMenu aMenu( SfxResId( MENU_HELP_BOOKMARKS ) );
1335 sal_uInt16 nId = aMenu.Execute( this, pCEvt->GetMousePosPixel() );
1336 if ( nId != MENU_ITEM_NOTFOUND )
1337 DoAction( nId );
1338 nRet = 1;
1342 return nRet ? nRet : ListBox::Notify( rNEvt );
1345 // class BookmarksTabPage_Impl -------------------------------------------
1347 BookmarksTabPage_Impl::BookmarksTabPage_Impl( Window* pParent, SfxHelpIndexWindow_Impl* _pIdxWin ) :
1349 HelpTabPage_Impl( pParent, _pIdxWin, SfxResId( TP_HELP_BOOKMARKS ) ),
1351 aBookmarksFT ( this, SfxResId( FT_BOOKMARKS ) ),
1352 aBookmarksBox ( this, SfxResId( LB_BOOKMARKS ) ),
1353 aBookmarksPB ( this, SfxResId( PB_BOOKMARKS ) )
1356 FreeResource();
1358 nMinWidth = aBookmarksPB.GetSizePixel().Width();
1360 aBookmarksPB.SetClickHdl( LINK( this, BookmarksTabPage_Impl, OpenHdl ) );
1362 // load bookmarks from configuration
1363 Sequence< Sequence< PropertyValue > > aBookmarkSeq;
1364 aBookmarkSeq = SvtHistoryOptions().GetList( eHELPBOOKMARKS );
1366 OUString aTitle;
1367 OUString aURL;
1369 sal_uInt32 i, nCount = aBookmarkSeq.getLength();
1370 for ( i = 0; i < nCount; ++i )
1372 GetBookmarkEntry_Impl( aBookmarkSeq[i], aTitle, aURL );
1373 AddBookmarks( aTitle, aURL );
1377 // -----------------------------------------------------------------------
1379 IMPL_LINK_NOARG(BookmarksTabPage_Impl, OpenHdl)
1381 aBookmarksBox.GetDoubleClickHdl().Call( &aBookmarksBox );
1382 return 0;
1385 // -----------------------------------------------------------------------
1387 void BookmarksTabPage_Impl::Resize()
1389 Size aSize = GetSizePixel();
1390 if ( aSize.Width() < nMinWidth )
1391 aSize.Width() = nMinWidth;
1392 Point aPnt = aBookmarksFT.GetPosPixel();
1393 Size aNewSize = aBookmarksFT.GetSizePixel();
1394 aNewSize.Width() = aSize.Width() - ( aPnt.X() * 2 );
1395 aBookmarksFT.SetSizePixel( aNewSize );
1397 Size a6Size = LogicToPixel( Size( 6, 6 ), MAP_APPFONT );
1398 Size aBtnSize = aBookmarksPB.GetSizePixel();
1400 aPnt = aBookmarksBox.GetPosPixel();
1401 aNewSize = aBookmarksBox.GetSizePixel();
1402 aNewSize.Width() = aSize.Width() - ( aPnt.X() * 2 );
1403 aNewSize.Height() = aSize.Height() - aPnt.Y();
1404 aNewSize.Height() -= ( aBtnSize.Height() + ( a6Size.Height() * 3 / 2 ) );
1405 aBookmarksBox.SetSizePixel( aNewSize );
1407 aPnt.X() += ( aNewSize.Width() - aBtnSize.Width() );
1408 aPnt.Y() += aNewSize.Height() + ( a6Size.Height() / 2 );
1409 long nMinX = aBookmarksBox.GetPosPixel().X();
1410 if ( aPnt.X() < nMinX )
1411 aPnt.X() = nMinX;
1412 aBookmarksPB.SetPosPixel( aPnt );
1415 // -----------------------------------------------------------------------
1417 void BookmarksTabPage_Impl::ActivatePage()
1419 if ( !m_pIdxWin->WasCursorLeftOrRight() )
1420 SetFocusOnBox();
1423 // -----------------------------------------------------------------------
1425 Control* BookmarksTabPage_Impl::GetLastFocusControl()
1427 return &aBookmarksPB;
1430 // -----------------------------------------------------------------------
1432 void BookmarksTabPage_Impl::SetDoubleClickHdl( const Link& rLink )
1434 aBookmarksBox.SetDoubleClickHdl( rLink );
1437 // -----------------------------------------------------------------------
1439 OUString BookmarksTabPage_Impl::GetSelectEntry() const
1441 OUString aRet;
1442 OUString* pData = (OUString*)(sal_uIntPtr)aBookmarksBox.GetEntryData( aBookmarksBox.GetSelectEntryPos() );
1443 if ( pData )
1444 aRet = *pData;
1445 return aRet;
1448 // -----------------------------------------------------------------------
1450 void BookmarksTabPage_Impl::AddBookmarks( const OUString& rTitle, const OUString& rURL )
1452 OUString aImageURL = IMAGE_URL;
1453 aImageURL += INetURLObject( rURL ).GetHost();
1454 sal_uInt16 nPos = aBookmarksBox.InsertEntry( rTitle, SvFileInformationManager::GetImage( INetURLObject(aImageURL), false ) );
1455 aBookmarksBox.SetEntryData( nPos, (void*)(sal_uIntPtr)( new OUString( rURL ) ) );
1458 OUString SfxHelpWindow_Impl::buildHelpURL(const OUString& sFactory ,
1459 const OUString& sContent ,
1460 const OUString& sAnchor ,
1461 sal_Bool bUseQuestionMark)
1463 OUStringBuffer sHelpURL(256);
1464 sHelpURL.append(HELP_URL);
1465 sHelpURL.append(sFactory);
1466 sHelpURL.append(sContent);
1467 AppendConfigToken(sHelpURL, bUseQuestionMark);
1468 if (!sAnchor.isEmpty())
1469 sHelpURL.append(sAnchor);
1470 return sHelpURL.makeStringAndClear();
1473 void SfxHelpWindow_Impl::loadHelpContent(const OUString& sHelpURL, sal_Bool bAddToHistory)
1475 Reference< XComponentLoader > xLoader(getTextFrame(), UNO_QUERY);
1476 if (!xLoader.is())
1477 return;
1479 // If a print job runs do not open a new page
1480 Reference< XFrame2 > xTextFrame = pTextWin->getFrame();
1481 Reference< XController > xTextController ;
1482 if (xTextFrame.is())
1483 xTextController = xTextFrame->getController ();
1484 if ( xTextController.is() && !xTextController->suspend( sal_True ) )
1486 xTextController->suspend( sal_False );
1487 return;
1490 // save url to history
1491 if (bAddToHistory)
1492 pHelpInterceptor->addURL(sHelpURL);
1494 if ( !IsWait() )
1495 EnterWait();
1496 sal_Bool bSuccess = sal_False;
1497 // TODO implement locale fallback ... see below while(true)
1501 Reference< XComponent > xContent = xLoader->loadComponentFromURL(sHelpURL, "_self", 0, Sequence< PropertyValue >());
1502 if (xContent.is())
1504 bSuccess = sal_True;
1507 catch(const RuntimeException&)
1508 { throw; }
1509 catch(const Exception&)
1510 { /*break;*/ }
1512 /* TODO try next locale ...
1513 no further locale available? => break loop and show error page
1516 openDone(sHelpURL, bSuccess);
1517 if ( IsWait() )
1518 LeaveWait();
1521 SfxHelpIndexWindow_Impl::SfxHelpIndexWindow_Impl( SfxHelpWindow_Impl* _pParent ) :
1523 Window( _pParent, SfxResId( WIN_HELPINDEX ) ),
1525 aActiveLB ( this, SfxResId( LB_ACTIVE ) ),
1526 aActiveLine ( this, SfxResId( FL_ACTIVE ) ),
1527 aTabCtrl ( this, SfxResId( TC_INDEX ) ),
1529 aIndexKeywordLink ( LINK( this, SfxHelpIndexWindow_Impl, KeywordHdl ) ),
1530 pParentWin ( _pParent ),
1532 pCPage ( NULL ),
1533 pIPage ( NULL ),
1534 pSPage ( NULL ),
1535 pBPage ( NULL ),
1537 bWasCursorLeftOrRight( false ),
1538 bIsInitDone ( false )
1541 FreeResource();
1543 sfx2::AddToTaskPaneList( this );
1545 aTabCtrl.SetActivatePageHdl( LINK( this, SfxHelpIndexWindow_Impl, ActivatePageHdl ) );
1546 aTabCtrl.Show();
1548 sal_Int32 nPageId = HELP_INDEX_PAGE_INDEX;
1549 SvtViewOptions aViewOpt( E_TABDIALOG, CONFIGNAME_INDEXWIN );
1550 if ( aViewOpt.Exists() )
1551 nPageId = aViewOpt.GetPageID();
1552 aTabCtrl.SetCurPageId( (sal_uInt16)nPageId );
1553 ActivatePageHdl( &aTabCtrl );
1554 aActiveLB.SetSelectHdl( LINK( this, SfxHelpIndexWindow_Impl, SelectHdl ) );
1555 nMinWidth = ( aActiveLB.GetSizePixel().Width() / 2 );
1557 aTimer.SetTimeoutHdl( LINK( this, SfxHelpIndexWindow_Impl, InitHdl ) );
1558 aTimer.SetTimeout( 200 );
1559 aTimer.Start();
1562 // -----------------------------------------------------------------------
1564 SfxHelpIndexWindow_Impl::~SfxHelpIndexWindow_Impl()
1566 sfx2::RemoveFromTaskPaneList( this );
1568 DELETEZ( pCPage );
1569 DELETEZ( pIPage );
1570 DELETEZ( pSPage );
1571 DELETEZ( pBPage );
1573 for ( sal_uInt16 i = 0; i < aActiveLB.GetEntryCount(); ++i )
1574 delete (OUString*)(sal_uIntPtr)aActiveLB.GetEntryData(i);
1576 SvtViewOptions aViewOpt( E_TABDIALOG, CONFIGNAME_INDEXWIN );
1577 aViewOpt.SetPageID( (sal_Int32)aTabCtrl.GetCurPageId() );
1580 // -----------------------------------------------------------------------
1582 void SfxHelpIndexWindow_Impl::Initialize()
1584 OUStringBuffer aHelpURL(HELP_URL);
1585 AppendConfigToken(aHelpURL, sal_True);
1586 std::vector<OUString> aFactories = SfxContentHelper::GetResultSet(aHelpURL.makeStringAndClear());
1587 for (size_t i = 0, n = aFactories.size(); i < n; ++i )
1589 const OUString& rRow = aFactories[i];
1590 sal_Int32 nIdx = 0;
1591 OUString aTitle = rRow.getToken( 0, '\t', nIdx );
1592 nIdx = 0;
1593 OUString aURL = rRow.getToken( 2, '\t', nIdx );
1594 OUString* pFactory = new OUString( INetURLObject( aURL ).GetHost() );
1595 sal_uInt16 nPos = aActiveLB.InsertEntry( aTitle );
1596 aActiveLB.SetEntryData( nPos, (void*)(sal_uIntPtr)pFactory );
1599 aActiveLB.SetDropDownLineCount( (sal_uInt16)aFactories.size() );
1600 if ( aActiveLB.GetSelectEntryPos() == LISTBOX_ENTRY_NOTFOUND )
1601 SetActiveFactory();
1604 // -----------------------------------------------------------------------
1606 void SfxHelpIndexWindow_Impl::SetActiveFactory()
1608 DBG_ASSERT( pIPage, "index page not initialized" );
1609 if ( !bIsInitDone && !aActiveLB.GetEntryCount() )
1611 aTimer.Stop();
1612 InitHdl( NULL );
1615 for ( sal_uInt16 i = 0; i < aActiveLB.GetEntryCount(); ++i )
1617 OUString* pFactory = (OUString*)(sal_uIntPtr)aActiveLB.GetEntryData(i);
1618 *pFactory = pFactory->toAsciiLowerCase();
1619 if ( *pFactory == pIPage->GetFactory() )
1621 if ( aActiveLB.GetSelectEntryPos() != i )
1623 aActiveLB.SelectEntryPos(i);
1624 aSelectFactoryLink.Call( NULL );
1626 break;
1631 // -----------------------------------------------------------------------
1633 HelpTabPage_Impl* SfxHelpIndexWindow_Impl::GetCurrentPage( sal_uInt16& rCurId )
1635 rCurId = aTabCtrl.GetCurPageId();
1636 HelpTabPage_Impl* pPage = NULL;
1638 switch ( rCurId )
1640 case HELP_INDEX_PAGE_CONTENTS:
1642 pPage = GetContentPage();
1643 break;
1646 case HELP_INDEX_PAGE_INDEX:
1648 pPage = GetIndexPage();
1649 break;
1652 case HELP_INDEX_PAGE_SEARCH:
1654 pPage = GetSearchPage();
1655 break;
1658 case HELP_INDEX_PAGE_BOOKMARKS:
1660 pPage = GetBookmarksPage();
1661 break;
1665 DBG_ASSERT( pPage, "SfxHelpIndexWindow_Impl::GetCurrentPage(): no current page" );
1666 return pPage;
1669 // -----------------------------------------------------------------------
1671 IMPL_LINK( SfxHelpIndexWindow_Impl, ActivatePageHdl, TabControl *, pTabCtrl )
1673 sal_uInt16 nId = 0;
1674 TabPage* pPage = GetCurrentPage( nId );
1675 pTabCtrl->SetTabPage( nId, pPage );
1676 return 0;
1679 // -----------------------------------------------------------------------
1681 IMPL_LINK_NOARG(SfxHelpIndexWindow_Impl, SelectHdl)
1683 aTimer.Start();
1685 return 0;
1688 // -----------------------------------------------------------------------
1690 IMPL_LINK_NOARG(SfxHelpIndexWindow_Impl, InitHdl)
1692 bIsInitDone = true;
1693 Initialize();
1695 // now use the timer for selection
1696 aTimer.SetTimeoutHdl( LINK( this, SfxHelpIndexWindow_Impl, SelectFactoryHdl ) );
1697 aTimer.SetTimeout( 1000 );
1699 return 0;
1702 // -----------------------------------------------------------------------
1704 IMPL_LINK_NOARG(SfxHelpIndexWindow_Impl, SelectFactoryHdl)
1706 OUString* pFactory = (OUString*)(sal_uIntPtr)aActiveLB.GetEntryData( aActiveLB.GetSelectEntryPos() );
1707 if ( pFactory )
1709 SetFactory( OUString( *pFactory ).toAsciiLowerCase(), sal_False );
1710 aSelectFactoryLink.Call( this );
1713 return 0;
1716 // -----------------------------------------------------------------------
1718 IMPL_LINK_NOARG(SfxHelpIndexWindow_Impl, KeywordHdl)
1720 // keyword found on index?
1721 sal_Bool bIndex = pIPage->HasKeyword();
1723 if( !bIndex)
1724 bIndex = pIPage->HasKeywordIgnoreCase();
1725 // then set index or search page as current.
1726 sal_uInt16 nPageId = ( bIndex ) ? HELP_INDEX_PAGE_INDEX : HELP_INDEX_PAGE_SEARCH;
1727 if ( nPageId != aTabCtrl.GetCurPageId() )
1729 aTabCtrl.SetCurPageId( nPageId );
1730 ActivatePageHdl( &aTabCtrl );
1733 // at last we open the keyword
1734 if ( bIndex )
1735 pIPage->OpenKeyword();
1736 else if ( !pSPage->OpenKeyword( sKeyword ) )
1737 pParentWin->ShowStartPage();
1739 return 0;
1742 // -----------------------------------------------------------------------
1744 void SfxHelpIndexWindow_Impl::Resize()
1746 Size aSize = GetOutputSizePixel();
1747 if ( aSize.Width() < nMinWidth )
1748 aSize.Width() = nMinWidth;
1750 Point aPnt = aActiveLB.GetPosPixel();
1751 Size aNewSize = aActiveLB.GetSizePixel();
1752 aNewSize.Width() = aSize.Width() - ( aPnt.X() * 2 );
1753 aActiveLB.SetSizePixel( aNewSize );
1754 aPnt = aActiveLine.GetPosPixel();
1755 aNewSize = aActiveLine.GetSizePixel();
1756 aNewSize.Width() = aSize.Width() - ( aPnt.X() * 2 );
1757 aActiveLine.SetSizePixel( aNewSize );
1758 aPnt = aTabCtrl.GetPosPixel();
1759 aNewSize = aSize;
1760 aSize.Width() -= aPnt.X();
1761 aSize.Height() -= aPnt.Y();
1762 aTabCtrl.SetSizePixel( aSize );
1765 // -----------------------------------------------------------------------
1767 long SfxHelpIndexWindow_Impl::PreNotify( NotifyEvent& rNEvt )
1769 long nDone = 0;
1770 sal_uInt16 nType = rNEvt.GetType();
1771 if ( EVENT_KEYINPUT == nType && rNEvt.GetKeyEvent() )
1773 const KeyCode& rKeyCode = rNEvt.GetKeyEvent()->GetKeyCode();
1774 sal_uInt16 nCode = rKeyCode.GetCode();
1776 if ( KEY_TAB == nCode )
1778 // don't exit index pane with <TAB>
1779 sal_uInt16 nPageId = 0;
1780 HelpTabPage_Impl* pCurPage = GetCurrentPage( nPageId );
1781 Control* pControl = pCurPage->GetLastFocusControl();
1782 sal_Bool bShift = rKeyCode.IsShift();
1783 sal_Bool bCtrl = rKeyCode.IsMod1();
1784 if ( !bCtrl && bShift && aActiveLB.HasChildPathFocus() )
1786 pControl->GrabFocus();
1787 nDone = 1;
1789 else if ( !bCtrl && !bShift && pControl->HasChildPathFocus() )
1791 aActiveLB.GrabFocus();
1792 nDone = 1;
1794 else if ( bCtrl )
1796 // <CTRL><TAB> moves through the pages
1797 if ( nPageId < HELP_INDEX_PAGE_LAST )
1798 nPageId++;
1799 else
1800 nPageId = HELP_INDEX_PAGE_FIRST;
1801 aTabCtrl.SetCurPageId( (sal_uInt16)nPageId );
1802 ActivatePageHdl( &aTabCtrl );
1803 nDone = 1;
1806 else if ( aTabCtrl.HasFocus() && ( KEY_LEFT == nCode || KEY_RIGHT == nCode ) )
1808 bWasCursorLeftOrRight = true;
1812 return nDone ? nDone : Window::PreNotify( rNEvt );
1815 // -----------------------------------------------------------------------
1817 void SfxHelpIndexWindow_Impl::DataChanged( const DataChangedEvent& rDCEvt )
1819 Window::DataChanged( rDCEvt );
1821 if ( ( ( rDCEvt.GetType() == DATACHANGED_SETTINGS ) ||
1822 ( rDCEvt.GetType() == DATACHANGED_DISPLAY ) ) &&
1823 ( rDCEvt.GetFlags() & SETTINGS_STYLE ) )
1825 SetBackground( Wallpaper( GetSettings().GetStyleSettings().GetFaceColor() ) );
1829 // -----------------------------------------------------------------------
1831 void SfxHelpIndexWindow_Impl::SetDoubleClickHdl( const Link& rLink )
1833 aPageDoubleClickLink = rLink;
1834 if ( pCPage )
1835 pCPage->SetOpenHdl( aPageDoubleClickLink );
1836 if ( pIPage )
1837 pIPage->SetDoubleClickHdl( aPageDoubleClickLink );
1838 if ( pSPage )
1839 pSPage->SetDoubleClickHdl( aPageDoubleClickLink );
1840 if ( pBPage )
1841 pBPage->SetDoubleClickHdl( aPageDoubleClickLink );
1844 // -----------------------------------------------------------------------
1846 void SfxHelpIndexWindow_Impl::SetFactory( const OUString& rFactory, sal_Bool bActive )
1848 if ( !rFactory.isEmpty() )
1850 GetIndexPage()->SetFactory( rFactory );
1851 // the index page did a check if rFactory is valid,
1852 // so the index page always returns a valid factory
1853 GetSearchPage()->SetFactory( GetIndexPage()->GetFactory() );
1854 if ( bActive )
1855 SetActiveFactory();
1859 // -----------------------------------------------------------------------
1861 OUString SfxHelpIndexWindow_Impl::GetSelectEntry() const
1863 OUString sRet;
1865 switch ( aTabCtrl.GetCurPageId() )
1867 case HELP_INDEX_PAGE_CONTENTS:
1868 sRet = pCPage->GetSelectEntry();
1869 break;
1871 case HELP_INDEX_PAGE_INDEX:
1872 sRet = pIPage->GetSelectEntry();
1873 break;
1875 case HELP_INDEX_PAGE_SEARCH:
1876 sRet = pSPage->GetSelectEntry();
1877 break;
1879 case HELP_INDEX_PAGE_BOOKMARKS:
1880 sRet = pBPage->GetSelectEntry();
1881 break;
1884 return sRet;
1887 // -----------------------------------------------------------------------
1889 void SfxHelpIndexWindow_Impl::AddBookmarks( const OUString& rTitle, const OUString& rURL )
1891 GetBookmarksPage()->AddBookmarks( rTitle, rURL );
1894 // -----------------------------------------------------------------------
1896 bool SfxHelpIndexWindow_Impl::IsValidFactory( const OUString& _rFactory )
1898 bool bValid = false;
1899 for ( sal_uInt16 i = 0; i < aActiveLB.GetEntryCount(); ++i )
1901 OUString* pFactory = (OUString*)(sal_uIntPtr)aActiveLB.GetEntryData(i);
1902 if ( *pFactory == _rFactory )
1904 bValid = true;
1905 break;
1908 return bValid;
1911 // -----------------------------------------------------------------------
1913 void SfxHelpIndexWindow_Impl::ClearSearchPage()
1915 if ( pSPage )
1916 pSPage->ClearPage();
1919 // -----------------------------------------------------------------------
1921 void SfxHelpIndexWindow_Impl::GrabFocusBack()
1923 if ( aTabCtrl.GetCurPageId() == HELP_INDEX_PAGE_CONTENTS && pCPage )
1924 pCPage->SetFocusOnBox();
1925 else if ( aTabCtrl.GetCurPageId() == HELP_INDEX_PAGE_INDEX && pIPage )
1926 pIPage->SetFocusOnBox();
1927 else if ( aTabCtrl.GetCurPageId() == HELP_INDEX_PAGE_SEARCH && pSPage )
1928 pSPage->SetFocusOnBox();
1929 else if ( aTabCtrl.GetCurPageId() == HELP_INDEX_PAGE_BOOKMARKS && pBPage )
1930 pBPage->SetFocusOnBox();
1933 // -----------------------------------------------------------------------
1935 sal_Bool SfxHelpIndexWindow_Impl::HasFocusOnEdit() const
1937 sal_Bool bRet = sal_False;
1938 if ( aTabCtrl.GetCurPageId() == HELP_INDEX_PAGE_INDEX && pIPage )
1939 bRet = pIPage->HasFocusOnEdit();
1940 else if ( aTabCtrl.GetCurPageId() == HELP_INDEX_PAGE_SEARCH && pSPage )
1941 bRet = pSPage->HasFocusOnEdit();
1942 return bRet;
1945 // -----------------------------------------------------------------------
1947 OUString SfxHelpIndexWindow_Impl::GetSearchText() const
1949 OUString sRet;
1950 if ( aTabCtrl.GetCurPageId() == HELP_INDEX_PAGE_SEARCH && pSPage )
1951 sRet = pSPage->GetSearchText();
1952 return sRet;
1955 // -----------------------------------------------------------------------
1957 sal_Bool SfxHelpIndexWindow_Impl::IsFullWordSearch() const
1959 sal_Bool bRet = sal_False;
1960 if ( aTabCtrl.GetCurPageId() == HELP_INDEX_PAGE_SEARCH && pSPage )
1961 bRet = pSPage->IsFullWordSearch();
1962 return bRet;
1965 // -----------------------------------------------------------------------
1967 void SfxHelpIndexWindow_Impl::OpenKeyword( const OUString& rKeyword )
1969 sKeyword = rKeyword;
1970 DBG_ASSERT( pIPage, "invalid index page" );
1971 pIPage->SetKeyword( sKeyword );
1974 // -----------------------------------------------------------------------
1976 void SfxHelpIndexWindow_Impl::SelectExecutableEntry()
1978 if ( aTabCtrl.GetCurPageId() == HELP_INDEX_PAGE_INDEX && pIPage )
1979 pIPage->SelectExecutableEntry();
1982 // class TextWin_Impl ----------------------------------------------------
1984 TextWin_Impl::TextWin_Impl( Window* p ) : DockingWindow( p, 0 )
1988 TextWin_Impl::~TextWin_Impl()
1992 long TextWin_Impl::Notify( NotifyEvent& rNEvt )
1994 if( ( rNEvt.GetType() == EVENT_KEYINPUT ) && rNEvt.GetKeyEvent()->GetKeyCode().GetCode() == KEY_TAB )
1995 return GetParent()->Notify( rNEvt );
1996 else
1997 return DockingWindow::Notify( rNEvt );
2000 // -----------------------------------------------------------------------
2001 // remove docking area acceptor from layoutmanager, so it will not layout anything further .-)
2002 static void lcl_disableLayoutOfFrame(const Reference< XFrame2 >& xFrame)
2004 xFrame->setLayoutManager( Reference< XLayoutManager >() );
2007 // class SfxHelpTextWindow_Impl ------------------------------------------
2009 SfxHelpTextWindow_Impl::SfxHelpTextWindow_Impl( SfxHelpWindow_Impl* pParent ) :
2011 Window( pParent, WB_CLIPCHILDREN | WB_TABSTOP | WB_DIALOGCONTROL ),
2013 aToolBox ( this, 0 ),
2014 aOnStartupCB ( this, SfxResId( RID_HELP_ONSTARTUP_BOX ) ),
2015 aIndexOnImage ( SfxResId( IMG_HELP_TOOLBOX_INDEX_ON ) ),
2016 aIndexOffImage ( SfxResId( IMG_HELP_TOOLBOX_INDEX_OFF ) ),
2017 aIndexOnText ( SfxResId( STR_HELP_BUTTON_INDEX_ON ).toString() ),
2018 aIndexOffText ( SfxResId( STR_HELP_BUTTON_INDEX_OFF ).toString() ),
2019 aOnStartupText ( SfxResId( RID_HELP_ONSTARTUP_TEXT ).toString() ),
2020 pHelpWin ( pParent ),
2021 pTextWin ( new TextWin_Impl( this ) ),
2022 pSrchDlg ( NULL ),
2023 nMinPos ( 0 ),
2024 bIsDebug ( sal_False ),
2025 bIsIndexOn ( sal_False ),
2026 bIsInClose ( sal_False ),
2027 bIsFullWordSearch ( sal_False )
2030 sfx2::AddToTaskPaneList( &aToolBox );
2032 xFrame = Frame::create( ::comphelper::getProcessComponentContext() );
2033 xFrame->initialize( VCLUnoHelper::GetInterface ( pTextWin ) );
2034 xFrame->setName( "OFFICE_HELP" );
2035 lcl_disableLayoutOfFrame(xFrame);
2037 aToolBox.SetHelpId( HID_HELP_TOOLBOX );
2039 aToolBox.InsertItem( TBI_INDEX, aIndexOffText );
2040 aToolBox.SetHelpId( TBI_INDEX, HID_HELP_TOOLBOXITEM_INDEX );
2041 aToolBox.InsertSeparator();
2042 aToolBox.InsertItem( TBI_BACKWARD, SfxResId( STR_HELP_BUTTON_PREV ).toString() );
2043 aToolBox.SetHelpId( TBI_BACKWARD, HID_HELP_TOOLBOXITEM_BACKWARD );
2044 aToolBox.InsertItem( TBI_FORWARD, SfxResId( STR_HELP_BUTTON_NEXT ).toString() );
2045 aToolBox.SetHelpId( TBI_FORWARD, HID_HELP_TOOLBOXITEM_FORWARD );
2046 aToolBox.InsertItem( TBI_START, SfxResId( STR_HELP_BUTTON_START ).toString() );
2047 aToolBox.SetHelpId( TBI_START, HID_HELP_TOOLBOXITEM_START );
2048 aToolBox.InsertSeparator();
2049 aToolBox.InsertItem( TBI_PRINT, SfxResId( STR_HELP_BUTTON_PRINT ).toString() );
2050 aToolBox.SetHelpId( TBI_PRINT, HID_HELP_TOOLBOXITEM_PRINT );
2051 aToolBox.InsertItem( TBI_BOOKMARKS, SfxResId( STR_HELP_BUTTON_ADDBOOKMARK ).toString() );
2052 aToolBox.SetHelpId( TBI_BOOKMARKS, HID_HELP_TOOLBOXITEM_BOOKMARKS );
2053 aToolBox.InsertItem( TBI_SEARCHDIALOG, SfxResId( STR_HELP_BUTTON_SEARCHDIALOG ).toString() );
2054 aToolBox.SetHelpId( TBI_SEARCHDIALOG, HID_HELP_TOOLBOXITEM_SEARCHDIALOG );
2056 InitToolBoxImages();
2057 aToolBox.Show();
2058 InitOnStartupBox( false );
2059 aOnStartupCB.SetClickHdl( LINK( this, SfxHelpTextWindow_Impl, CheckHdl ) );
2061 aSelectTimer.SetTimeoutHdl( LINK( this, SfxHelpTextWindow_Impl, SelectHdl ) );
2062 aSelectTimer.SetTimeout( 1000 );
2064 char* pEnv = getenv( "help_debug" );
2065 if ( pEnv )
2066 bIsDebug = sal_True;
2068 SvtMiscOptions().AddListenerLink( LINK( this, SfxHelpTextWindow_Impl, NotifyHdl ) );
2070 if ( !aOnStartupCB.GetHelpId().getLength() )
2071 aOnStartupCB.SetHelpId( HID_HELP_ONSTARTUP_BOX );
2074 // -----------------------------------------------------------------------
2076 SfxHelpTextWindow_Impl::~SfxHelpTextWindow_Impl()
2078 sfx2::RemoveFromTaskPaneList( &aToolBox );
2080 bIsInClose = sal_True;
2081 SvtMiscOptions().RemoveListenerLink( LINK( this, SfxHelpTextWindow_Impl, NotifyHdl ) );
2082 delete pSrchDlg;
2085 // -----------------------------------------------------------------------
2087 sal_Bool SfxHelpTextWindow_Impl::HasSelection() const
2089 // is there any selection in the text and not only a cursor?
2090 sal_Bool bRet = sal_False;
2091 Reference < XTextRange > xRange = getCursor();
2092 if ( xRange.is() )
2094 Reference < XText > xText = xRange->getText();
2095 Reference < XTextCursor > xCursor = xText->createTextCursorByRange( xRange );
2096 bRet = !xCursor->isCollapsed();
2099 return bRet;
2102 // -----------------------------------------------------------------------
2104 void SfxHelpTextWindow_Impl::InitToolBoxImages()
2106 sal_Bool bLarge = SvtMiscOptions().AreCurrentSymbolsLarge();
2108 aIndexOnImage = Image( SfxResId( bLarge ? IMG_HELP_TOOLBOX_L_INDEX_ON : IMG_HELP_TOOLBOX_INDEX_ON ) );
2109 aIndexOffImage = Image( SfxResId( bLarge ? IMG_HELP_TOOLBOX_L_INDEX_OFF : IMG_HELP_TOOLBOX_INDEX_OFF ) );
2111 aToolBox.SetItemImage( TBI_INDEX, bIsIndexOn ? aIndexOffImage : aIndexOnImage );
2113 aToolBox.SetItemImage( TBI_BACKWARD,
2114 Image( SfxResId( bLarge ? IMG_HELP_TOOLBOX_L_PREV : IMG_HELP_TOOLBOX_PREV ) )
2117 aToolBox.SetItemImage( TBI_FORWARD,
2118 Image( SfxResId( bLarge ? IMG_HELP_TOOLBOX_L_NEXT : IMG_HELP_TOOLBOX_NEXT ) )
2121 aToolBox.SetItemImage( TBI_START,
2122 Image( SfxResId( bLarge ? IMG_HELP_TOOLBOX_L_START : IMG_HELP_TOOLBOX_START ) )
2125 aToolBox.SetItemImage( TBI_PRINT,
2126 Image( SfxResId( bLarge ? IMG_HELP_TOOLBOX_L_PRINT : IMG_HELP_TOOLBOX_PRINT ) )
2129 aToolBox.SetItemImage( TBI_BOOKMARKS,
2130 Image( SfxResId( bLarge ? IMG_HELP_TOOLBOX_L_BOOKMARKS : IMG_HELP_TOOLBOX_BOOKMARKS ) )
2133 aToolBox.SetItemImage( TBI_SEARCHDIALOG,
2134 Image( SfxResId( bLarge ? IMG_HELP_TOOLBOX_L_SEARCHDIALOG : IMG_HELP_TOOLBOX_SEARCHDIALOG ) )
2137 Size aSize = aToolBox.CalcWindowSizePixel();
2138 aSize.Height() += TOOLBOX_OFFSET;
2139 aToolBox.SetPosSizePixel( Point( 0, TOOLBOX_OFFSET ), aSize );
2141 SvtMiscOptions aMiscOptions;
2142 if ( aMiscOptions.GetToolboxStyle() != aToolBox.GetOutStyle() )
2143 aToolBox.SetOutStyle( aMiscOptions.GetToolboxStyle() );
2146 // -----------------------------------------------------------------------
2148 void SfxHelpTextWindow_Impl::InitOnStartupBox( bool bOnlyText )
2150 sCurrentFactory = SfxHelp::GetCurrentModuleIdentifier();
2152 Reference< XComponentContext > xContext = ::comphelper::getProcessComponentContext();
2153 Reference< XInterface > xConfig;
2154 OUString sPath( PATH_OFFICE_FACTORIES );
2155 sPath += sCurrentFactory;
2156 OUString sKey( KEY_HELP_ON_OPEN );
2158 // Attention: This check boy knows two states:
2159 // 1) Reading of the config key fails with an exception or by getting an empty Any (!) => check box must be hidden
2160 // 2) We read sal_True/sal_False => check box must be shown and enabled/disabled
2162 bool bHideBox = true;
2163 sal_Bool bHelpAtStartup = sal_False;
2166 xConfiguration = ConfigurationHelper::openConfig(
2167 xContext, PACKAGE_SETUP, ConfigurationHelper::E_STANDARD );
2168 if ( xConfiguration.is() )
2170 Any aAny = ConfigurationHelper::readRelativeKey( xConfiguration, sPath, sKey );
2171 if (aAny >>= bHelpAtStartup)
2172 bHideBox = false;
2175 catch( Exception& )
2177 bHideBox = true;
2180 if ( bHideBox )
2181 aOnStartupCB.Hide();
2182 else
2184 // detect module name
2185 OUString sModuleName;
2187 if ( xConfiguration.is() )
2189 OUString sTemp;
2190 sKey = KEY_UI_NAME;
2193 Any aAny = ConfigurationHelper::readRelativeKey( xConfiguration, sPath, sKey );
2194 aAny >>= sTemp;
2196 catch( Exception& )
2198 SAL_WARN( "sfx.appl", "SfxHelpTextWindow_Impl::InitOnStartupBox(): unexpected exception" );
2200 sModuleName = sTemp;
2203 if ( !sModuleName.isEmpty() )
2205 // set module name in checkbox text
2206 OUString sText( aOnStartupText );
2207 sText = sText.replaceFirst( "%MODULENAME", sModuleName );
2208 aOnStartupCB.SetText( sText );
2209 // and show it
2210 aOnStartupCB.Show();
2211 // set check state
2212 aOnStartupCB.Check( bHelpAtStartup );
2213 aOnStartupCB.SaveValue();
2215 // calculate and set optimal width of the onstartup checkbox
2216 OUString sCBText( "XXX" );
2217 sCBText += aOnStartupCB.GetText();
2218 long nTextWidth = aOnStartupCB.GetTextWidth( sCBText );
2219 Size aSize = aOnStartupCB.GetSizePixel();
2220 aSize.Width() = nTextWidth;
2221 aOnStartupCB.SetSizePixel( aSize );
2222 SetOnStartupBoxPosition();
2225 if ( !bOnlyText )
2227 // set position of the checkbox
2228 Size a3Size = LogicToPixel( Size( 3, 3 ), MAP_APPFONT );
2229 Size aTBSize = aToolBox.GetSizePixel();
2230 Size aCBSize = aOnStartupCB.GetSizePixel();
2231 Point aPnt = aToolBox.GetPosPixel();
2232 aPnt.X() += aTBSize.Width() + a3Size.Width();
2233 aPnt.Y() += ( ( aTBSize.Height() - aCBSize.Height() ) / 2 );
2234 aOnStartupCB.SetPosPixel( aPnt );
2235 nMinPos = aPnt.X();
2240 // -----------------------------------------------------------------------
2242 void SfxHelpTextWindow_Impl::SetOnStartupBoxPosition()
2244 long nX = std::max( GetOutputSizePixel().Width() - aOnStartupCB.GetSizePixel().Width(), nMinPos );
2245 Point aPos = aOnStartupCB.GetPosPixel();
2246 aPos.X() = nX;
2247 aOnStartupCB.SetPosPixel( aPos );
2250 // -----------------------------------------------------------------------
2252 Reference< XBreakIterator > SfxHelpTextWindow_Impl::GetBreakIterator()
2254 if ( !xBreakIterator.is() )
2255 xBreakIterator = vcl::unohelper::CreateBreakIterator();
2256 DBG_ASSERT( xBreakIterator.is(), "Could not create BreakIterator" );
2257 return xBreakIterator;
2260 // -----------------------------------------------------------------------
2262 Reference< XTextRange > SfxHelpTextWindow_Impl::getCursor() const
2264 // return the current cursor
2265 Reference< XTextRange > xCursor;
2269 Reference < XSelectionSupplier > xSelSup( xFrame->getController(), UNO_QUERY );
2270 if ( xSelSup.is() )
2272 Any aAny = xSelSup->getSelection();
2273 Reference < XIndexAccess > xSelection;
2274 if ( aAny >>= xSelection )
2276 if ( xSelection->getCount() == 1 )
2278 aAny = xSelection->getByIndex(0);
2279 aAny >>= xCursor;
2284 catch( Exception& )
2286 OSL_FAIL( "SfxHelpTextWindow_Impl::getCursor(): unexpected exception" );
2289 return xCursor;
2292 // -----------------------------------------------------------------------
2294 bool SfxHelpTextWindow_Impl::isHandledKey( const KeyCode& _rKeyCode )
2296 bool bRet = false;
2297 sal_uInt16 nCode = _rKeyCode.GetCode();
2299 // the keys <CTRL><A> (select all), <CTRL><C> (copy),
2300 // <CTRL><F> (find), <CTRL><P> (print) and <CTRL><W> (close window)
2301 // were handled in help
2302 if ( _rKeyCode.IsMod1() &&
2303 ( KEY_A == nCode || KEY_C == nCode || KEY_F == nCode || KEY_P == nCode || KEY_W == nCode ) )
2305 if ( KEY_F == nCode )
2306 DoSearch();
2307 else
2308 bRet = true;
2311 return bRet;
2314 // -----------------------------------------------------------------------
2316 IMPL_LINK_NOARG(SfxHelpTextWindow_Impl, SelectHdl)
2320 // select the words, which are equal to the search text of the search page
2321 Reference < XController > xController = xFrame->getController();
2322 if ( xController.is() )
2324 // get document
2325 Reference < XSearchable > xSearchable( xController->getModel(), UNO_QUERY );
2326 if ( xSearchable.is() )
2328 // create descriptor, set string and find all words
2329 Reference < XSearchDescriptor > xSrchDesc = xSearchable->createSearchDescriptor();
2330 xSrchDesc->setPropertyValue( "SearchRegularExpression",
2331 makeAny( sal_Bool( sal_True ) ) );
2332 if ( bIsFullWordSearch )
2333 xSrchDesc->setPropertyValue( "SearchWords",
2334 makeAny( sal_Bool( sal_True ) ) );
2336 OUString sSearchString = sfx2::PrepareSearchString( aSearchText, GetBreakIterator(), false );
2337 xSrchDesc->setSearchString( sSearchString );
2338 Reference< XIndexAccess > xSelection = xSearchable->findAll( xSrchDesc );
2340 // then select all found words
2341 Reference < XSelectionSupplier > xSelectionSup( xController, UNO_QUERY );
2342 if ( xSelectionSup.is() )
2344 Any aAny;
2345 aAny <<= xSelection;
2346 xSelectionSup->select( aAny );
2351 catch( Exception& )
2353 OSL_FAIL( "SfxHelpTextWindow_Impl::SelectHdl(): unexpected exception" );
2356 return 1;
2359 // -----------------------------------------------------------------------
2361 IMPL_LINK( SfxHelpTextWindow_Impl, NotifyHdl, SvtMiscOptions*, pOptions )
2363 (void)pOptions; // unused variable
2364 InitToolBoxImages();
2365 Resize();
2366 aToolBox.Invalidate();
2367 return 0;
2370 // -----------------------------------------------------------------------
2372 IMPL_LINK( SfxHelpTextWindow_Impl, FindHdl, sfx2::SearchDialog*, pDlg )
2374 bool bWrapAround = ( NULL == pDlg );
2375 if ( bWrapAround )
2376 pDlg = pSrchDlg;
2377 DBG_ASSERT( pDlg, "invalid search dialog" );
2378 OUString sSearchText = pDlg->GetSearchText();
2381 // select the words, which are equal to the search text of the search page
2382 Reference < XController > xController = xFrame->getController();
2383 if ( xController.is() )
2385 // get document
2386 Reference < XSearchable > xSearchable( xController->getModel(), UNO_QUERY );
2387 if ( xSearchable.is() )
2389 // create descriptor, set string and find all words
2390 Reference < XSearchDescriptor > xSrchDesc = xSearchable->createSearchDescriptor();
2391 xSrchDesc->setPropertyValue( "SearchWords", makeAny( sal_Bool( pDlg->IsOnlyWholeWords() != false ) ) );
2392 xSrchDesc->setPropertyValue( "SearchCaseSensitive", makeAny( sal_Bool( pDlg->IsMarchCase() != false ) ) );
2393 xSrchDesc->setPropertyValue( "SearchBackwards", makeAny( sal_Bool( pDlg->IsSearchBackwards() != false ) ) );
2394 xSrchDesc->setSearchString( sSearchText );
2395 Reference< XInterface > xSelection;
2396 Reference< XTextRange > xCursor = getCursor();
2398 if ( xCursor.is() )
2400 if ( pDlg->IsSearchBackwards() )
2401 xCursor = xCursor->getStart();
2402 xSelection = xSearchable->findNext( xCursor, xSrchDesc );
2404 else
2405 xSelection = xSearchable->findFirst( xSrchDesc );
2407 // then select the found word
2408 if ( xSelection.is() )
2410 Reference < XSelectionSupplier > xSelectionSup( xController, UNO_QUERY );
2411 if ( xSelectionSup.is() )
2413 Any aAny;
2414 aAny <<= xSelection;
2415 xSelectionSup->select( aAny );
2418 else if ( pDlg->IsWrapAround() && !bWrapAround )
2420 Reference < text::XTextViewCursorSupplier > xCrsrSupp( xController, uno::UNO_QUERY );
2421 Reference < text::XTextViewCursor > xTVCrsr( xCrsrSupp->getViewCursor(), uno::UNO_QUERY );
2422 if ( xTVCrsr.is() )
2424 Reference < text::XTextDocument > xDoc( xController->getModel(), uno::UNO_QUERY );
2425 Reference < text::XText > xText = xDoc->getText();
2426 if ( xText.is() )
2428 if ( pDlg->IsSearchBackwards() )
2429 xTVCrsr->gotoRange( xText->getEnd(), sal_False );
2430 else
2431 xTVCrsr->gotoRange( xText->getStart(), sal_False );
2432 FindHdl( NULL );
2436 else
2438 DBG_ASSERT( pSrchDlg, "no search dialog" );
2439 InfoBox aBox( pSrchDlg, SfxResId( RID_INFO_NOSEARCHTEXTFOUND ) );
2440 aBox.Execute();
2441 pSrchDlg->SetFocusOnEdit();
2446 catch( Exception& )
2448 OSL_FAIL( "SfxHelpTextWindow_Impl::SelectHdl(): unexpected exception" );
2451 return 0;
2454 // -----------------------------------------------------------------------
2456 IMPL_LINK( SfxHelpTextWindow_Impl, CloseHdl, sfx2::SearchDialog*, pDlg )
2458 if ( pDlg )
2459 delete pSrchDlg;
2460 pSrchDlg = NULL;
2461 return 0;
2464 // -----------------------------------------------------------------------
2466 IMPL_LINK( SfxHelpTextWindow_Impl, CheckHdl, CheckBox*, pBox )
2468 if ( xConfiguration.is() )
2470 sal_Bool bChecked = pBox->IsChecked();
2471 OUString sPath( PATH_OFFICE_FACTORIES );
2472 sPath += sCurrentFactory;
2475 ConfigurationHelper::writeRelativeKey(
2476 xConfiguration, sPath, KEY_HELP_ON_OPEN, makeAny( bChecked ) );
2477 ConfigurationHelper::flush( xConfiguration );
2479 catch( Exception& )
2481 SAL_WARN( "sfx.appl", "SfxHelpTextWindow_Impl::CheckHdl(): unexpected exception" );
2485 return 0;
2488 // -----------------------------------------------------------------------
2490 void SfxHelpTextWindow_Impl::Resize()
2492 Size aSize = GetOutputSizePixel();
2493 long nToolBoxHeight = aToolBox.GetSizePixel().Height() + TOOLBOX_OFFSET;
2494 aSize.Height() -= nToolBoxHeight;
2495 pTextWin->SetPosSizePixel( Point( 0, nToolBoxHeight ), aSize );
2496 SetOnStartupBoxPosition();
2499 // -----------------------------------------------------------------------
2501 long SfxHelpTextWindow_Impl::PreNotify( NotifyEvent& rNEvt )
2503 long nDone = 0;
2504 sal_uInt16 nType = rNEvt.GetType();
2505 if ( EVENT_COMMAND == nType && rNEvt.GetCommandEvent() )
2507 const CommandEvent* pCmdEvt = rNEvt.GetCommandEvent();
2508 Window* pCmdWin = rNEvt.GetWindow();
2510 if ( pCmdEvt->GetCommand() == COMMAND_CONTEXTMENU && pCmdWin != this && pCmdWin != &aToolBox )
2512 Point aPos;
2513 if ( pCmdEvt->IsMouseEvent() )
2514 aPos = pCmdEvt->GetMousePosPixel();
2515 else
2516 aPos = Point( pTextWin->GetPosPixel().X() + 20, 20 );
2517 aPos.Y() += pTextWin->GetPosPixel().Y();
2518 PopupMenu aMenu;
2519 if ( bIsIndexOn )
2520 aMenu.InsertItem( TBI_INDEX, aIndexOffText, Image( SfxResId( IMG_HELP_TOOLBOX_INDEX_OFF ) ) );
2521 else
2522 aMenu.InsertItem( TBI_INDEX, aIndexOnText, Image( SfxResId( IMG_HELP_TOOLBOX_INDEX_ON ) ) );
2524 aMenu.SetHelpId( TBI_INDEX, HID_HELP_TOOLBOXITEM_INDEX );
2525 aMenu.InsertSeparator();
2526 aMenu.InsertItem( TBI_BACKWARD,
2527 SfxResId( STR_HELP_BUTTON_PREV ).toString(),
2528 Image( SfxResId( IMG_HELP_TOOLBOX_PREV ) )
2530 aMenu.SetHelpId( TBI_BACKWARD, HID_HELP_TOOLBOXITEM_BACKWARD );
2531 aMenu.EnableItem( TBI_BACKWARD, pHelpWin->HasHistoryPredecessor() );
2532 aMenu.InsertItem( TBI_FORWARD,
2533 SfxResId( STR_HELP_BUTTON_NEXT ).toString(),
2534 Image( SfxResId( IMG_HELP_TOOLBOX_NEXT ) )
2536 aMenu.SetHelpId( TBI_FORWARD, HID_HELP_TOOLBOXITEM_FORWARD );
2537 aMenu.EnableItem( TBI_FORWARD, pHelpWin->HasHistorySuccessor() );
2538 aMenu.InsertItem( TBI_START,
2539 SfxResId( STR_HELP_BUTTON_START ).toString(),
2540 Image( SfxResId( IMG_HELP_TOOLBOX_START ) )
2542 aMenu.SetHelpId( TBI_START, HID_HELP_TOOLBOXITEM_START );
2543 aMenu.InsertSeparator();
2544 aMenu.InsertItem( TBI_PRINT,
2545 SfxResId( STR_HELP_BUTTON_PRINT ).toString(),
2546 Image( SfxResId( IMG_HELP_TOOLBOX_PRINT ) )
2548 aMenu.SetHelpId( TBI_PRINT, HID_HELP_TOOLBOXITEM_PRINT );
2549 aMenu.InsertItem( TBI_BOOKMARKS,
2550 SfxResId( STR_HELP_BUTTON_ADDBOOKMARK ).toString(),
2551 Image( SfxResId( IMG_HELP_TOOLBOX_BOOKMARKS ) )
2553 aMenu.SetHelpId( TBI_BOOKMARKS, HID_HELP_TOOLBOXITEM_BOOKMARKS );
2554 aMenu.InsertItem( TBI_SEARCHDIALOG,
2555 SfxResId( STR_HELP_BUTTON_SEARCHDIALOG ).toString(),
2556 Image( SfxResId( IMG_HELP_TOOLBOX_SEARCHDIALOG ) )
2558 aMenu.SetHelpId( TBI_SEARCHDIALOG, HID_HELP_TOOLBOXITEM_SEARCHDIALOG );
2559 aMenu.InsertSeparator();
2560 aMenu.InsertItem( TBI_SELECTIONMODE, SfxResId( STR_HELP_MENU_TEXT_SELECTION_MODE ).toString() );
2561 aMenu.SetHelpId( TBI_SELECTIONMODE, HID_HELP_TEXT_SELECTION_MODE );
2562 URL aURL;
2563 aURL.Complete = ".uno:SelectTextMode";
2564 PARSE_URL( aURL );
2565 Reference < XDispatch > xDisp = xFrame->queryDispatch( aURL, OUString(), 0 );
2566 if(xDisp.is())
2568 HelpStatusListener_Impl* pStateListener;
2569 Reference<XStatusListener>xStateListener = pStateListener =
2570 new HelpStatusListener_Impl(xDisp, aURL );
2571 FeatureStateEvent rEvent = pStateListener->GetStateEvent();
2572 sal_Bool bCheck = sal_False;
2573 rEvent.State >>= bCheck;
2574 aMenu.CheckItem(TBI_SELECTIONMODE, bCheck);
2576 aMenu.InsertSeparator();
2577 aMenu.InsertItem( TBI_COPY,
2578 SfxResId(STR_HELP_MENU_TEXT_COPY).toString(),
2579 Image( SfxResId( IMG_HELP_TOOLBOX_COPY ) )
2581 aMenu.SetHelpId( TBI_COPY, ".uno:Copy" );
2582 aMenu.EnableItem( TBI_COPY, HasSelection() );
2584 if ( bIsDebug )
2586 aMenu.InsertSeparator();
2587 aMenu.InsertItem( TBI_SOURCEVIEW, SfxResId(STR_HELP_BUTTON_SOURCEVIEW).toString() );
2590 if( SvtMenuOptions().IsEntryHidingEnabled() == sal_False )
2591 aMenu.SetMenuFlags( aMenu.GetMenuFlags() | MENU_FLAG_HIDEDISABLEDENTRIES );
2593 sal_uInt16 nId = aMenu.Execute( this, aPos );
2594 pHelpWin->DoAction( nId );
2595 nDone = 1;
2598 else if ( EVENT_KEYINPUT == nType && rNEvt.GetKeyEvent() )
2600 const KeyEvent* pKEvt = rNEvt.GetKeyEvent();
2601 const KeyCode& rKeyCode = pKEvt->GetKeyCode();
2602 sal_uInt16 nKeyGroup = rKeyCode.GetGroup();
2603 sal_uInt16 nKey = rKeyCode.GetCode();
2604 if ( KEYGROUP_ALPHA == nKeyGroup && !isHandledKey( rKeyCode ) )
2606 // do nothing disables the writer accelerators
2607 nDone = 1;
2609 else if ( rKeyCode.IsMod1() && ( KEY_F4 == nKey || KEY_W == nKey ) )
2611 // <CTRL><F4> or <CTRL><W> -> close top frame
2612 pHelpWin->CloseWindow();
2613 nDone = 1;
2615 else if ( KEY_TAB == nKey && aOnStartupCB.HasChildPathFocus() )
2617 aToolBox.GrabFocus();
2618 nDone = 1;
2622 return nDone ? nDone : Window::PreNotify( rNEvt );
2625 // -----------------------------------------------------------------------
2627 void SfxHelpTextWindow_Impl::GetFocus()
2629 if ( !bIsInClose )
2633 if( xFrame.is() )
2635 Reference< ::com::sun::star::awt::XWindow > xWindow = xFrame->getComponentWindow();
2636 if( xWindow.is() )
2637 xWindow->setFocus();
2640 catch( Exception& )
2642 SAL_WARN( "sfx.appl", "SfxHelpTextWindow_Impl::GetFocus(): unexpected exception" );
2647 // -----------------------------------------------------------------------
2649 void SfxHelpTextWindow_Impl::DataChanged( const DataChangedEvent& rDCEvt )
2651 Window::DataChanged( rDCEvt );
2653 if ( ( ( rDCEvt.GetType() == DATACHANGED_SETTINGS ) ||
2654 ( rDCEvt.GetType() == DATACHANGED_DISPLAY ) ) &&
2655 ( rDCEvt.GetFlags() & SETTINGS_STYLE ) )
2657 SetBackground( Wallpaper( GetSettings().GetStyleSettings().GetFaceColor() ) );
2658 InitToolBoxImages();
2662 // -----------------------------------------------------------------------
2664 void SfxHelpTextWindow_Impl::ToggleIndex( sal_Bool bOn )
2666 bIsIndexOn = bOn;
2667 if ( bIsIndexOn )
2669 aToolBox.SetItemImage( TBI_INDEX, aIndexOffImage );
2670 aToolBox.SetItemText( TBI_INDEX, aIndexOffText );
2672 else
2674 aToolBox.SetItemImage( TBI_INDEX, aIndexOnImage );
2675 aToolBox.SetItemText( TBI_INDEX, aIndexOnText );
2679 // -----------------------------------------------------------------------
2681 void SfxHelpTextWindow_Impl::SelectSearchText( const OUString& rSearchText, sal_Bool _bIsFullWordSearch )
2683 aSearchText = rSearchText;
2684 bIsFullWordSearch = _bIsFullWordSearch;
2685 aSelectTimer.Start();
2688 // -----------------------------------------------------------------------
2690 void SfxHelpTextWindow_Impl::SetPageStyleHeaderOff() const
2692 #ifdef DBG_UTIL
2693 sal_Bool bSetOff = sal_False;
2694 #endif
2695 // set off the pagestyle header to prevent print output of the help URL
2698 Reference < XController > xController = xFrame->getController();
2699 Reference < XSelectionSupplier > xSelSup( xController, UNO_QUERY );
2700 if ( xSelSup.is() )
2702 Reference < XIndexAccess > xSelection;
2703 if ( xSelSup->getSelection() >>= xSelection )
2705 Reference < XTextRange > xRange;
2706 if ( xSelection->getByIndex(0) >>= xRange )
2708 Reference < XText > xText = xRange->getText();
2709 Reference < XPropertySet > xProps( xText->createTextCursorByRange( xRange ), UNO_QUERY );
2710 OUString sStyleName;
2711 if ( xProps->getPropertyValue( "PageStyleName" ) >>= sStyleName )
2713 Reference < XStyleFamiliesSupplier > xStyles( xController->getModel(), UNO_QUERY );
2714 Reference < XNameContainer > xContainer;
2715 if ( xStyles->getStyleFamilies()->getByName( "PageStyles" )
2716 >>= xContainer )
2718 Reference < XStyle > xStyle;
2719 if ( xContainer->getByName( sStyleName ) >>= xStyle )
2721 Reference < XPropertySet > xPropSet( xStyle, UNO_QUERY );
2722 xPropSet->setPropertyValue( "HeaderIsOn",
2723 makeAny( sal_Bool( sal_False ) ) );
2725 Reference< XModifiable > xReset(xStyles, UNO_QUERY);
2726 xReset->setModified(sal_False);
2727 #ifdef DBG_UTIL
2728 bSetOff = sal_True;
2729 #endif
2737 catch( Exception& )
2739 SAL_WARN( "sfx.appl", "SfxHelpTextWindow_Impl::SetPageStyleHeaderOff(): unexpected exception" );
2742 #ifdef DBG_UTIL
2743 if ( !bSetOff )
2745 SAL_WARN( "sfx.appl", "SfxHelpTextWindow_Impl::SetPageStyleHeaderOff(): set off failed" );
2747 #endif
2750 // -----------------------------------------------------------------------
2752 void SfxHelpTextWindow_Impl::CloseFrame()
2754 bIsInClose = sal_True;
2757 ::com::sun::star::uno::Reference< ::com::sun::star::util::XCloseable > xCloseable ( xFrame, ::com::sun::star::uno::UNO_QUERY );
2758 if (xCloseable.is())
2759 xCloseable->close(sal_True);
2761 catch( ::com::sun::star::util::CloseVetoException& )
2766 // -----------------------------------------------------------------------
2768 void SfxHelpTextWindow_Impl::DoSearch()
2770 if ( !pSrchDlg )
2772 // create the search dialog
2773 pSrchDlg = new sfx2::SearchDialog( pTextWin, "HelpSearchDialog" );
2774 // set handler
2775 pSrchDlg->SetFindHdl( LINK( this, SfxHelpTextWindow_Impl, FindHdl ) );
2776 pSrchDlg->SetCloseHdl( LINK( this, SfxHelpTextWindow_Impl, CloseHdl ) );
2777 // get selected text of the help page to set it as the search text
2778 Reference< XTextRange > xCursor = getCursor();
2779 if ( xCursor.is() )
2781 OUString sText = xCursor->getString();
2782 if ( !sText.isEmpty() )
2783 pSrchDlg->SetSearchText( sText );
2785 pSrchDlg->Show();
2789 // class SfxHelpWindow_Impl ----------------------------------------------
2791 void SfxHelpWindow_Impl::Resize()
2793 SplitWindow::Resize();
2794 InitSizes();
2797 // -----------------------------------------------------------------------
2799 void SfxHelpWindow_Impl::Split()
2801 static long nMinSplitSize = 5;
2802 static long nMaxSplitSize = 99 - nMinSplitSize;
2804 SplitWindow::Split();
2806 nIndexSize = GetItemSize( INDEXWIN_ID );
2807 nTextSize = GetItemSize( TEXTWIN_ID );
2809 sal_Bool bMod = sal_False;
2810 if( nIndexSize < nMinSplitSize )
2812 nIndexSize = nMinSplitSize;
2813 nTextSize = nMaxSplitSize;
2815 bMod = sal_True;
2817 else if( nTextSize < nMinSplitSize )
2819 nTextSize = nMinSplitSize;
2820 nIndexSize = nMaxSplitSize;
2822 bMod = sal_True;
2824 else
2825 bMod = sal_False;
2827 if( bMod )
2829 SetItemSize( INDEXWIN_ID, nIndexSize );
2830 SetItemSize( TEXTWIN_ID, nTextSize );
2833 InitSizes();
2836 // -----------------------------------------------------------------------
2838 void SfxHelpWindow_Impl::GetFocus()
2840 pTextWin->GrabFocus();
2843 // -----------------------------------------------------------------------
2845 void SfxHelpWindow_Impl::MakeLayout()
2847 if ( nHeight > 0 && xWindow.is() )
2849 Window* pScreenWin = VCLUnoHelper::GetWindow( xWindow );
2851 /* #i55528#
2852 Hide() / Show() will produce starnge effects.
2853 The returned size (used later to be written back into the configuration)
2854 isnt the right after a resize during the window is hidden.
2855 If this resize is done if the window is visible evyrthing works as aspected.
2856 Some VCL-patches could not solve this problem so I've established the
2857 workaround: resize the help window if it's visible .-)
2860 ::com::sun::star::awt::Rectangle aRect = xWindow->getPosSize();
2861 sal_Int32 nOldWidth = bIndex ? nCollapseWidth : nExpandWidth;
2862 sal_Int32 nWidth = bIndex ? nExpandWidth : nCollapseWidth;
2863 xWindow->setPosSize( aRect.X, aRect.Y, nWidth, nHeight, ::com::sun::star::awt::PosSize::SIZE );
2865 if ( aRect.Width > 0 && aRect.Height > 0 )
2867 Rectangle aScreenRect = pScreenWin->GetClientWindowExtentsRelative( NULL );
2868 Point aNewPos = aScreenRect.TopLeft();
2869 sal_Int32 nDiffWidth = nOldWidth - nWidth;
2870 aNewPos.X() += nDiffWidth;
2871 pScreenWin->SetPosPixel( aNewPos );
2873 else if ( aWinPos.X() > 0 && aWinPos.Y() > 0 )
2874 pScreenWin->SetPosPixel( aWinPos );
2877 Clear();
2879 if ( bIndex )
2881 pIndexWin->Show();
2882 InsertItem( COLSET_ID, 100, SPLITWINDOW_APPEND, SPLITSET_ID, SWIB_PERCENTSIZE | SWIB_COLSET );
2883 InsertItem( INDEXWIN_ID, pIndexWin, nIndexSize, SPLITWINDOW_APPEND, COLSET_ID, SWIB_PERCENTSIZE );
2884 InsertItem( TEXTWIN_ID, pTextWin, nTextSize, SPLITWINDOW_APPEND, COLSET_ID, SWIB_PERCENTSIZE );
2886 else
2888 pIndexWin->Hide();
2889 InsertItem( COLSET_ID, 100, SPLITWINDOW_APPEND, SPLITSET_ID, SWIB_PERCENTSIZE | SWIB_COLSET );
2890 InsertItem( TEXTWIN_ID, pTextWin, 100, SPLITWINDOW_APPEND, 1, SWIB_PERCENTSIZE );
2894 // -----------------------------------------------------------------------
2896 void SfxHelpWindow_Impl::InitSizes()
2898 if ( xWindow.is() )
2900 ::com::sun::star::awt::Rectangle aRect = xWindow->getPosSize();
2901 nHeight = aRect.Height;
2903 if ( bIndex )
2905 nExpandWidth = aRect.Width;
2906 nCollapseWidth = nExpandWidth * nTextSize / 100;
2908 else
2910 nCollapseWidth = aRect.Width;
2911 nExpandWidth = nCollapseWidth * 100 / nTextSize;
2916 // -----------------------------------------------------------------------
2918 void SfxHelpWindow_Impl::LoadConfig()
2920 SvtViewOptions aViewOpt( E_WINDOW, CONFIGNAME_HELPWIN );
2921 if ( aViewOpt.Exists() )
2923 bIndex = aViewOpt.IsVisible();
2924 OUString aUserData;
2925 Any aUserItem = aViewOpt.GetUserItem( USERITEM_NAME );
2926 OUString aTemp;
2927 if ( aUserItem >>= aTemp )
2929 aUserData = aTemp;
2930 DBG_ASSERT( comphelper::string::getTokenCount(aUserData, ';') == 6, "invalid user data" );
2931 sal_Int32 nIdx = 0;
2932 nIndexSize = aUserData.getToken( 0, ';', nIdx ).toInt32();
2933 nTextSize = aUserData.getToken( 0, ';', nIdx ).toInt32();
2934 sal_Int32 nWidth = aUserData.getToken( 0, ';', nIdx ).toInt32();
2935 nHeight = aUserData.getToken( 0, ';', nIdx ).toInt32();
2936 aWinPos.X() = aUserData.getToken( 0, ';', nIdx ).toInt32();
2937 aWinPos.Y() = aUserData.getToken( 0, ';', nIdx ).toInt32();
2938 if ( bIndex )
2940 nExpandWidth = nWidth;
2941 nCollapseWidth = nExpandWidth * nTextSize / 100;
2943 else
2945 nCollapseWidth = nWidth;
2946 nExpandWidth = nCollapseWidth * 100 / nTextSize;
2950 pTextWin->ToggleIndex( bIndex );
2954 // -----------------------------------------------------------------------
2956 void SfxHelpWindow_Impl::SaveConfig()
2958 SvtViewOptions aViewOpt( E_WINDOW, CONFIGNAME_HELPWIN );
2959 sal_Int32 nW = 0, nH = 0;
2961 if ( xWindow.is() )
2963 ::com::sun::star::awt::Rectangle aRect = xWindow->getPosSize();
2964 nW = aRect.Width;
2965 nH = aRect.Height;
2968 aViewOpt.SetVisible( bIndex );
2969 OUString aUserData = OUString::number( nIndexSize );
2970 aUserData += ";";
2971 aUserData += OUString::number( nTextSize );
2972 aUserData += ";";
2973 aUserData += OUString::number( nW );
2974 aUserData += ";";
2975 aUserData += OUString::number( nH );
2977 Window* pScreenWin = VCLUnoHelper::GetWindow( xWindow );
2978 aWinPos = pScreenWin->GetWindowExtentsRelative( NULL ).TopLeft();
2979 aUserData += ";";
2980 aUserData += OUString::number( aWinPos.X() );
2981 aUserData += ";";
2982 aUserData += OUString::number( aWinPos.Y() );
2984 aViewOpt.SetUserItem( USERITEM_NAME, makeAny( OUString( aUserData ) ) );
2987 // -----------------------------------------------------------------------
2989 void SfxHelpWindow_Impl::ShowStartPage()
2991 OUString sHelpURL = SfxHelpWindow_Impl::buildHelpURL(pIndexWin->GetFactory(),
2992 "/start",
2993 OUString(),
2994 sal_True);
2995 loadHelpContent(sHelpURL);
2998 // -----------------------------------------------------------------------
3000 IMPL_LINK( SfxHelpWindow_Impl, SelectHdl, ToolBox* , pToolBox )
3002 if ( pToolBox )
3004 bGrabFocusToToolBox = pToolBox->HasChildPathFocus();
3005 DoAction( pToolBox->GetCurItemId() );
3008 return 1;
3011 //-------------------------------------------------------------------------
3013 IMPL_LINK_NOARG(SfxHelpWindow_Impl, OpenHdl)
3015 pIndexWin->SelectExecutableEntry();
3016 OUString aEntry = pIndexWin->GetSelectEntry();
3018 if ( aEntry.isEmpty() )
3019 return 0;
3021 OUString sHelpURL;
3023 bool bComplete = OUString(aEntry).toAsciiLowerCase().match("vnd.sun.star.help");
3025 if (bComplete)
3026 sHelpURL = OUString(aEntry);
3027 else
3029 OUString aId;
3030 OUString aAnchor = OUString('#');
3031 if ( comphelper::string::getTokenCount(aEntry, '#') == 2 )
3033 aId = aEntry.getToken( 0, '#' );
3034 aAnchor += aEntry.getToken( 1, '#' );
3036 else
3037 aId = aEntry;
3039 aEntry = "/";
3040 aEntry += aId;
3042 sHelpURL = SfxHelpWindow_Impl::buildHelpURL(pIndexWin->GetFactory(),
3043 aEntry,
3044 aAnchor,
3045 sal_True);
3048 loadHelpContent(sHelpURL);
3050 return 0;
3053 //-------------------------------------------------------------------------
3055 IMPL_LINK( SfxHelpWindow_Impl, SelectFactoryHdl, SfxHelpIndexWindow_Impl* , pWin )
3057 if ( sTitle.isEmpty() )
3058 sTitle = GetParent()->GetText();
3060 OUString aNewTitle = sTitle + " - " + pIndexWin->GetActiveFactoryTitle();
3062 Reference< XTitle > xTitle(xFrame, UNO_QUERY);
3063 if (xTitle.is ())
3064 xTitle->setTitle (aNewTitle);
3066 if ( pWin )
3067 ShowStartPage();
3068 pIndexWin->ClearSearchPage();
3070 return 0;
3073 // -----------------------------------------------------------------------
3075 IMPL_LINK( SfxHelpWindow_Impl, ChangeHdl, HelpListener_Impl*, pListener )
3077 SetFactory( pListener->GetFactory() );
3078 return 0;
3081 // -----------------------------------------------------------------------
3083 void SfxHelpWindow_Impl::openDone(const OUString& sURL ,
3084 sal_Bool bSuccess)
3086 INetURLObject aObj( sURL );
3087 if ( aObj.GetProtocol() == INET_PROT_VND_SUN_STAR_HELP )
3088 SetFactory( aObj.GetHost() );
3089 if ( IsWait() )
3090 LeaveWait();
3091 if ( bGrabFocusToToolBox )
3093 pTextWin->GetToolBox().GrabFocus();
3094 bGrabFocusToToolBox = sal_False;
3096 else
3097 pIndexWin->GrabFocusBack();
3098 if ( bSuccess )
3100 // set some view settings: "prevent help tips" and "helpid == 68245"
3103 Reference < XController > xController = pTextWin->getFrame()->getController();
3104 if ( xController.is() )
3106 Reference < XViewSettingsSupplier > xSettings( xController, UNO_QUERY );
3107 Reference < XPropertySet > xViewProps = xSettings->getViewSettings();
3108 Reference< XPropertySetInfo > xInfo = xViewProps->getPropertySetInfo();
3109 Any aBoolAny = makeAny( sal_Bool( sal_True ) );
3110 xViewProps->setPropertyValue( "ShowContentTips", makeAny( sal_Bool( sal_False ) ) );
3111 xViewProps->setPropertyValue( "ShowGraphics", aBoolAny );
3112 xViewProps->setPropertyValue( "ShowTables", aBoolAny );
3113 xViewProps->setPropertyValue( "HelpURL", makeAny( OUString("HID:SFX2_HID_HELP_ONHELP") ) );
3114 OUString sProperty( "IsExecuteHyperlinks" );
3115 if ( xInfo->hasPropertyByName( sProperty ) )
3116 xViewProps->setPropertyValue( sProperty, aBoolAny );
3117 xController->restoreViewData(pHelpInterceptor->GetViewData());
3120 catch( Exception& )
3122 OSL_FAIL( "SfxHelpWindow_Impl::OpenDoneHdl(): unexpected exception" );
3125 // When the SearchPage opens the help doc, then select all words, which are equal to its text
3126 OUString sSearchText = comphelper::string::strip(pIndexWin->GetSearchText(), ' ');
3127 if ( !sSearchText.isEmpty() )
3128 pTextWin->SelectSearchText( sSearchText, pIndexWin->IsFullWordSearch() );
3130 // no page style header -> this prevents a print output of the URL
3131 pTextWin->SetPageStyleHeaderOff();
3135 // -----------------------------------------------------------------------
3137 SfxHelpWindow_Impl::SfxHelpWindow_Impl(
3138 const ::com::sun::star::uno::Reference < ::com::sun::star::frame::XFrame2 >& rFrame,
3139 Window* pParent, WinBits ) :
3141 SplitWindow( pParent, WB_3DLOOK | WB_NOSPLITDRAW ),
3143 xFrame ( rFrame ),
3144 pIndexWin ( NULL ),
3145 pTextWin ( NULL ),
3146 pHelpInterceptor ( new HelpInterceptor_Impl() ),
3147 pHelpListener ( new HelpListener_Impl( pHelpInterceptor ) ),
3148 nExpandWidth ( 0 ),
3149 nCollapseWidth ( 0 ),
3150 nHeight ( 0 ),
3151 nIndexSize ( 40 ),
3152 nTextSize ( 60 ),
3153 bIndex ( sal_True ),
3154 bGrabFocusToToolBox ( sal_False ),
3155 aWinPos ( 0, 0 ),
3156 sTitle ( pParent->GetText() )
3158 SetHelpId( HID_HELP_WINDOW );
3159 SetStyle( GetStyle() | WB_DIALOGCONTROL );
3161 pHelpInterceptor->InitWaiter( this );
3162 pIndexWin = new SfxHelpIndexWindow_Impl( this );
3163 pIndexWin->SetDoubleClickHdl( LINK( this, SfxHelpWindow_Impl, OpenHdl ) );
3164 pIndexWin->SetSelectFactoryHdl( LINK( this, SfxHelpWindow_Impl, SelectFactoryHdl ) );
3165 pIndexWin->Show();
3166 pTextWin = new SfxHelpTextWindow_Impl( this );
3167 Reference < XFrames > xFrames = rFrame->getFrames();
3168 xFrames->append( Reference<XFrame>(pTextWin->getFrame(), UNO_QUERY_THROW) );
3169 pTextWin->SetSelectHdl( LINK( this, SfxHelpWindow_Impl, SelectHdl ) );
3170 pTextWin->Show();
3171 pHelpInterceptor->setInterception( Reference<XFrame>(pTextWin->getFrame(), UNO_QUERY_THROW) );
3172 pHelpListener->SetChangeHdl( LINK( this, SfxHelpWindow_Impl, ChangeHdl ) );
3173 LoadConfig();
3176 // -----------------------------------------------------------------------
3178 SfxHelpWindow_Impl::~SfxHelpWindow_Impl()
3180 SaveConfig();
3181 Window* pDel = pIndexWin;
3182 pIndexWin = NULL;
3183 delete pDel;
3185 pTextWin->CloseFrame();
3186 delete pTextWin;
3189 // -----------------------------------------------------------------------
3191 long SfxHelpWindow_Impl::PreNotify( NotifyEvent& rNEvt )
3193 sal_Bool bHandled = sal_False;
3194 if ( rNEvt.GetType() == EVENT_KEYINPUT )
3196 // Backward == <ALT><LEFT> or <BACKSPACE> Forward == <ALT><RIGHT>
3197 const KeyCode& rKeyCode = rNEvt.GetKeyEvent()->GetKeyCode();
3198 sal_uInt16 nKey = rKeyCode.GetCode();
3199 if ( ( rKeyCode.IsMod2() && ( KEY_LEFT == nKey || KEY_RIGHT == nKey ) ) ||
3200 ( !rKeyCode.GetModifier() && KEY_BACKSPACE == nKey && !pIndexWin->HasFocusOnEdit() ) )
3202 DoAction( rKeyCode.GetCode() == KEY_RIGHT ? TBI_FORWARD : TBI_BACKWARD );
3203 bHandled = sal_True;
3205 else if ( rKeyCode.IsMod1() && ( KEY_F4 == nKey || KEY_W == nKey ) )
3207 // <CTRL><F4> or <CTRL><W> -> close top frame
3208 CloseWindow();
3209 bHandled = sal_True;
3212 return bHandled ? 1 : Window::PreNotify( rNEvt );
3215 // -----------------------------------------------------------------------
3217 void SfxHelpWindow_Impl::setContainerWindow( Reference < ::com::sun::star::awt::XWindow > xWin )
3219 xWindow = xWin;
3220 MakeLayout();
3223 // -----------------------------------------------------------------------
3225 void SfxHelpWindow_Impl::SetFactory( const OUString& rFactory )
3227 pIndexWin->SetFactory( rFactory, sal_True );
3230 // -----------------------------------------------------------------------
3232 void SfxHelpWindow_Impl::SetHelpURL( const OUString& rURL )
3234 INetURLObject aObj( rURL );
3235 if ( aObj.GetProtocol() == INET_PROT_VND_SUN_STAR_HELP )
3236 SetFactory( aObj.GetHost() );
3239 // -----------------------------------------------------------------------
3241 void SfxHelpWindow_Impl::DoAction( sal_uInt16 nActionId )
3243 switch ( nActionId )
3245 case TBI_INDEX :
3247 bIndex = !bIndex;
3248 MakeLayout();
3249 pTextWin->ToggleIndex( bIndex );
3250 break;
3253 case TBI_START :
3255 ShowStartPage();
3256 break;
3259 case TBI_BACKWARD :
3260 case TBI_FORWARD :
3262 URL aURL;
3263 aURL.Complete = ".uno:Backward";
3264 if ( TBI_FORWARD == nActionId )
3265 aURL.Complete = ".uno:Forward";
3266 PARSE_URL( aURL );
3267 pHelpInterceptor->dispatch( aURL, Sequence < PropertyValue >() );
3268 break;
3271 case TBI_SEARCHDIALOG :
3273 pTextWin->DoSearch();
3274 break;
3277 case TBI_PRINT :
3278 case TBI_SOURCEVIEW :
3279 case TBI_COPY :
3280 case TBI_SELECTIONMODE:
3282 Reference < XDispatchProvider > xProv( pTextWin->getFrame(), UNO_QUERY );
3283 if ( xProv.is() )
3285 URL aURL;
3286 if ( TBI_PRINT == nActionId )
3287 aURL.Complete = ".uno:Print";
3288 else if ( TBI_SOURCEVIEW == nActionId )
3289 aURL.Complete = ".uno:SourceView";
3290 else if ( TBI_COPY == nActionId )
3291 aURL.Complete = ".uno:Copy";
3292 else if ( TBI_SELECTIONMODE == nActionId )
3293 aURL.Complete = ".uno:SelectTextMode";
3294 else
3295 aURL.Complete = ".uno:SearchDialog";
3296 PARSE_URL( aURL );
3297 Reference < XDispatch > xDisp = xProv->queryDispatch( aURL, OUString(), 0 );
3298 if ( xDisp.is() )
3299 xDisp->dispatch( aURL, Sequence < PropertyValue >() );
3301 break;
3304 case TBI_BOOKMARKS :
3306 OUString aURL = pHelpInterceptor->GetCurrentURL();
3307 if ( !aURL.isEmpty() )
3311 Content aCnt( aURL, Reference< ::com::sun::star::ucb::XCommandEnvironment >(), comphelper::getProcessComponentContext() );
3312 ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > xInfo = aCnt.getProperties();
3313 if ( xInfo->hasPropertyByName( PROPERTY_TITLE ) )
3315 ::com::sun::star::uno::Any aAny = aCnt.getPropertyValue( PROPERTY_TITLE );
3316 OUString aValue;
3317 if ( aAny >>= aValue )
3319 OUString aTitle( aValue );
3320 SfxAddHelpBookmarkDialog_Impl aDlg( this, sal_False );
3321 aDlg.SetTitle( aTitle );
3322 if ( aDlg.Execute() == RET_OK )
3324 aTitle = aDlg.GetTitle();
3325 pIndexWin->AddBookmarks( aTitle, aURL );
3330 catch( Exception& )
3332 OSL_FAIL( "SfxHelpWindow_Impl::DoAction(): unexpected exception" );
3335 break;
3340 // -----------------------------------------------------------------------
3342 void SfxHelpWindow_Impl::CloseWindow()
3346 // search for top frame
3347 Reference< XFramesSupplier > xCreator = getTextFrame()->getCreator();
3348 while ( xCreator.is() && !xCreator->isTop() )
3350 xCreator = xCreator->getCreator();
3353 // when found, close it
3354 if ( xCreator.is() && xCreator->isTop() )
3356 Reference < XCloseable > xCloser( xCreator, UNO_QUERY );
3357 if ( xCloser.is() )
3358 xCloser->close( sal_False );
3361 catch( Exception& )
3363 SAL_WARN( "sfx.appl", "SfxHelpWindow_Impl::CloseWindow(): caught an exception" );
3367 // -----------------------------------------------------------------------
3369 void SfxHelpWindow_Impl::UpdateToolbox()
3371 pTextWin->GetToolBox().EnableItem( TBI_BACKWARD, pHelpInterceptor->HasHistoryPred() );
3372 pTextWin->GetToolBox().EnableItem( TBI_FORWARD, pHelpInterceptor->HasHistorySucc() );
3375 // -----------------------------------------------------------------------
3377 sal_Bool SfxHelpWindow_Impl::HasHistoryPredecessor() const
3379 return pHelpInterceptor->HasHistoryPred();
3382 // -----------------------------------------------------------------------
3384 sal_Bool SfxHelpWindow_Impl::HasHistorySuccessor() const
3386 return pHelpInterceptor->HasHistorySucc();
3389 // class SfxAddHelpBookmarkDialog_Impl -----------------------------------
3391 SfxAddHelpBookmarkDialog_Impl::SfxAddHelpBookmarkDialog_Impl( Window* pParent, sal_Bool bRename ) :
3393 ModalDialog( pParent, SfxResId( DLG_HELP_ADDBOOKMARK ) ),
3395 aTitleFT ( this, SfxResId( FT_BOOKMARK_TITLE ) ),
3396 aTitleED ( this, SfxResId( ED_BOOKMARK_TITLE ) ),
3397 aOKBtn ( this, SfxResId( PB_BOOKMARK_OK ) ),
3398 aEscBtn ( this, SfxResId( PB_BOOKMARK_CANCEL ) ),
3399 aHelpBtn ( this, SfxResId( PB_BOOKMARK_HELP ) )
3402 if ( bRename )
3403 SetText( SfxResId(STR_BOOKMARK_RENAME).toString() );
3405 FreeResource();
3408 // -----------------------------------------------------------------------
3410 SfxAddHelpBookmarkDialog_Impl::~SfxAddHelpBookmarkDialog_Impl()
3414 // -----------------------------------------------------------------------
3416 void SfxAddHelpBookmarkDialog_Impl::SetTitle( const OUString& rTitle )
3418 aTitleED.SetText( rTitle );
3419 aTitleED.SetSelection( Selection( 0, rTitle.getLength() ) );
3422 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */