bump product version to 4.1.6.2
[LibreOffice.git] / sfx2 / source / appl / newhelp.cxx
blobcf1ba0403df622b92456436f5c9445fe482ba2c9
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 String PrepareSearchString( const String& rSearchString,
205 Reference< XBreakIterator > xBreak, bool bForSearch )
207 String 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 String sSearchToken( rSearchString.Copy(
217 (sal_uInt16)aBoundary.startPos, (sal_uInt16)aBoundary.endPos - (sal_uInt16)aBoundary.startPos ) );
218 if ( sSearchToken.Len() > 0 && ( sSearchToken.Len() > 1 || sSearchToken.GetChar(0) != '.' ) )
220 if ( bForSearch && sSearchToken.GetChar( sSearchToken.Len() - 1 ) != '*' )
221 sSearchToken += '*';
223 if ( sSearchToken.Len() > 1 ||
224 ( sSearchToken.Len() > 0 && sSearchToken.GetChar( 0 ) != '*' ) )
226 if ( sSearchStr.Len() > 0 )
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 String m_aURL;
254 IndexEntry_Impl( const String& rURL, sal_Bool bSubEntry ) :
255 m_bSubEntry( bSubEntry ), m_aURL( rURL ) {}
258 #define NEW_ENTRY( url, bool ) \
259 (void*)(sal_uIntPtr)( new IndexEntry_Impl( url, bool ) )
261 // struct ContentEntry_Impl ----------------------------------------------
263 struct ContentEntry_Impl
265 String aURL;
266 sal_Bool bIsFolder;
268 ContentEntry_Impl( const String& rURL, sal_Bool bFolder ) :
269 aURL( rURL ), bIsFolder( bFolder ) {}
272 // ContentListBox_Impl ---------------------------------------------------
274 ContentListBox_Impl::ContentListBox_Impl( Window* pParent, const ResId& rResId ) :
276 SvTreeListBox( pParent, rResId ),
278 aOpenBookImage ( SfxResId( IMG_HELP_CONTENT_BOOK_OPEN ) ),
279 aClosedBookImage ( SfxResId( IMG_HELP_CONTENT_BOOK_CLOSED ) ),
280 aDocumentImage ( SfxResId( IMG_HELP_CONTENT_DOC ) )
283 SetStyle( GetStyle() | WB_HIDESELECTION | WB_HSCROLL );
285 SetEntryHeight( 16 );
286 SetSelectionMode( SINGLE_SELECTION );
287 SetSpaceBetweenEntries( 2 );
288 SetNodeBitmaps( aClosedBookImage, aOpenBookImage );
290 SetSublistOpenWithReturn();
291 SetSublistOpenWithLeftRight();
293 InitRoot();
296 // -----------------------------------------------------------------------
298 ContentListBox_Impl::~ContentListBox_Impl()
300 sal_uInt16 nPos = 0;
301 SvTreeListEntry* pEntry = GetEntry( nPos++ );
302 while ( pEntry )
304 ClearChildren( pEntry );
305 delete (ContentEntry_Impl*)pEntry->GetUserData();
306 pEntry = GetEntry( nPos++ );
310 // -----------------------------------------------------------------------
312 void ContentListBox_Impl::InitRoot()
314 OUString aHelpTreeviewURL( "vnd.sun.star.hier://com.sun.star.help.TreeView/" );
315 std::vector< OUString > aList =
316 SfxContentHelper::GetHelpTreeViewContents( aHelpTreeviewURL );
318 for(size_t i = 0, n = aList.size(); i < n; ++i )
320 const OUString& aRow = aList[i];
321 sal_Int32 nIdx = 0;
322 OUString aTitle = aRow.getToken( 0, '\t', nIdx );
323 OUString aURL = aRow.getToken( 0, '\t', nIdx );
324 sal_Unicode cFolder = aRow.getToken( 0, '\t', nIdx )[0];
325 bool bIsFolder = ( '1' == cFolder );
326 SvTreeListEntry* pEntry = InsertEntry( aTitle, aOpenBookImage, aClosedBookImage, NULL, sal_True );
327 if ( bIsFolder )
328 pEntry->SetUserData( new ContentEntry_Impl( aURL, sal_True ) );
332 // -----------------------------------------------------------------------
334 void ContentListBox_Impl::ClearChildren( SvTreeListEntry* pParent )
336 SvTreeListEntry* pEntry = FirstChild( pParent );
337 while ( pEntry )
339 ClearChildren( pEntry );
340 delete (ContentEntry_Impl*)pEntry->GetUserData();
341 pEntry = NextSibling( pEntry );
345 // -----------------------------------------------------------------------
347 void ContentListBox_Impl::RequestingChildren( SvTreeListEntry* pParent )
351 if ( !pParent->HasChildren() )
353 if ( pParent->GetUserData() )
355 String aTmpURL( ( (ContentEntry_Impl*)pParent->GetUserData() )->aURL );
356 std::vector<OUString > aList =
357 SfxContentHelper::GetHelpTreeViewContents( aTmpURL );
359 for (size_t i = 0,n = aList.size(); i < n; ++i )
361 const OUString& aRow = aList[i];
362 sal_Int32 nIdx = 0;
363 OUString aTitle = aRow.getToken( 0, '\t', nIdx );
364 OUString aURL = aRow.getToken( 0, '\t', nIdx );
365 sal_Unicode cFolder = aRow.getToken( 0, '\t', nIdx )[0];
366 bool bIsFolder = ( '1' == cFolder );
367 SvTreeListEntry* pEntry = NULL;
368 if ( bIsFolder )
370 pEntry = InsertEntry( aTitle, aOpenBookImage, aClosedBookImage, pParent, sal_True );
371 pEntry->SetUserData( new ContentEntry_Impl( aURL, sal_True ) );
373 else
375 pEntry = InsertEntry( aTitle, aDocumentImage, aDocumentImage, pParent );
376 Any aAny( ::utl::UCBContentHelper::GetProperty( aURL, String("TargetURL" ) ) );
377 OUString aTargetURL;
378 if ( aAny >>= aTargetURL )
379 pEntry->SetUserData( new ContentEntry_Impl( aTargetURL, sal_False ) );
385 catch( Exception& )
387 OSL_FAIL( "ContentListBox_Impl::RequestingChildren(): unexpected exception" );
391 // -----------------------------------------------------------------------
393 long ContentListBox_Impl::Notify( NotifyEvent& rNEvt )
395 sal_Bool bHandled = sal_False;
396 if ( rNEvt.GetType() == EVENT_KEYINPUT &&
397 KEY_RETURN == rNEvt.GetKeyEvent()->GetKeyCode().GetCode() )
399 GetDoubleClickHdl().Call( NULL );
400 bHandled = sal_True;
403 return bHandled ? 1 : SvTreeListBox::Notify( rNEvt );
406 // -----------------------------------------------------------------------
408 String ContentListBox_Impl::GetSelectEntry() const
410 String aRet;
411 SvTreeListEntry* pEntry = FirstSelected();
412 if ( pEntry && !( (ContentEntry_Impl*)pEntry->GetUserData() )->bIsFolder )
413 aRet = ( (ContentEntry_Impl*)pEntry->GetUserData() )->aURL;
414 return aRet;
417 // class HelpTabPage_Impl ------------------------------------------------
419 HelpTabPage_Impl::HelpTabPage_Impl(
420 Window* pParent, SfxHelpIndexWindow_Impl* _pIdxWin, const ResId& rResId ) :
422 TabPage( pParent, rResId ),
424 m_pIdxWin( _pIdxWin )
429 // class ContentTabPage_Impl ---------------------------------------------
431 ContentTabPage_Impl::ContentTabPage_Impl( Window* pParent, SfxHelpIndexWindow_Impl* _pIdxWin ) :
433 HelpTabPage_Impl( pParent, _pIdxWin, SfxResId( TP_HELP_CONTENT ) ),
435 aContentBox( this, SfxResId( LB_CONTENTS ) )
438 FreeResource();
440 aContentBox.Show();
443 // -----------------------------------------------------------------------
445 void ContentTabPage_Impl::Resize()
447 Size aSize = GetOutputSizePixel();
448 aSize.Width() -= 8;
449 aSize.Height() -= 8;
450 aContentBox.SetPosSizePixel( Point( 4, 4 ), aSize );
453 // -----------------------------------------------------------------------
455 void ContentTabPage_Impl::ActivatePage()
457 if ( !m_pIdxWin->WasCursorLeftOrRight() )
458 SetFocusOnBox();
461 // -----------------------------------------------------------------------
463 Control* ContentTabPage_Impl::GetLastFocusControl()
465 return &aContentBox;
468 // class IndexBox_Impl ---------------------------------------------------
470 IndexBox_Impl::IndexBox_Impl( Window* pParent, const ResId& rResId ) :
472 ComboBox( pParent, rResId )
475 EnableAutocomplete( sal_True );
476 EnableUserDraw( sal_True );
479 // -----------------------------------------------------------------------
481 void IndexBox_Impl::UserDraw( const UserDrawEvent& rUDEvt )
483 IndexEntry_Impl* pEntry = (IndexEntry_Impl*)(sal_uIntPtr)GetEntryData( rUDEvt.GetItemId() );
484 if ( pEntry && pEntry->m_bSubEntry )
486 // indent sub entries
487 Point aPos( rUDEvt.GetRect().TopLeft() );
488 aPos.X() += 8;
489 aPos.Y() += ( rUDEvt.GetRect().GetHeight() - rUDEvt.GetDevice()->GetTextHeight() ) / 2;
490 String aEntry( GetEntry( rUDEvt.GetItemId() ) );
491 sal_uInt16 nPos = aEntry.Search( ';' );
492 rUDEvt.GetDevice()->DrawText( aPos, ( nPos != STRING_NOTFOUND ) ? aEntry.Copy( nPos + 1 ) : aEntry );
494 else
495 DrawEntry( rUDEvt, sal_False, sal_True, sal_True );
498 // -----------------------------------------------------------------------
500 long IndexBox_Impl::Notify( NotifyEvent& rNEvt )
502 sal_Bool bHandled = sal_False;
503 if ( rNEvt.GetType() == EVENT_KEYINPUT &&
504 KEY_RETURN == rNEvt.GetKeyEvent()->GetKeyCode().GetCode() )
506 GetDoubleClickHdl().Call( NULL );
507 bHandled = sal_True;
510 return bHandled ? 1 : ComboBox::Notify( rNEvt );
513 // -----------------------------------------------------------------------
515 void IndexBox_Impl::SelectExecutableEntry()
517 sal_uInt16 nPos = GetEntryPos( GetText() );
518 if ( nPos != COMBOBOX_ENTRY_NOTFOUND )
520 sal_uInt16 nOldPos = nPos;
521 String aEntryText;
522 IndexEntry_Impl* pEntry = (IndexEntry_Impl*)(sal_uIntPtr)GetEntryData( nPos );
523 sal_uInt16 nCount = GetEntryCount();
524 while ( nPos < nCount && ( !pEntry || pEntry->m_aURL.Len() == 0 ) )
526 pEntry = (IndexEntry_Impl*)(sal_uIntPtr)GetEntryData( ++nPos );
527 aEntryText = GetEntry( nPos );
530 if ( nOldPos != nPos )
531 SetText( aEntryText );
535 // class IndexTabPage_Impl -----------------------------------------------
537 IndexTabPage_Impl::IndexTabPage_Impl( Window* pParent, SfxHelpIndexWindow_Impl* _pIdxWin ) :
539 HelpTabPage_Impl( pParent, _pIdxWin, SfxResId( TP_HELP_INDEX ) ),
541 aExpressionFT ( this, SfxResId( FT_EXPRESSION ) ),
542 aIndexCB ( this, SfxResId( CB_INDEX ) ),
543 aOpenBtn ( this, SfxResId( PB_OPEN_INDEX ) ),
545 bIsActivated ( sal_False )
548 FreeResource();
550 aOpenBtn.SetClickHdl( LINK( this, IndexTabPage_Impl, OpenHdl ) );
551 Link aTimeoutLink = LINK( this, IndexTabPage_Impl, TimeoutHdl );
552 aFactoryTimer.SetTimeoutHdl( aTimeoutLink );
553 aFactoryTimer.SetTimeout( 300 );
554 aKeywordTimer.SetTimeoutHdl( aTimeoutLink );
555 aFactoryTimer.SetTimeout( 300 );
557 nMinWidth = aOpenBtn.GetSizePixel().Width();
560 // -----------------------------------------------------------------------
562 IndexTabPage_Impl::~IndexTabPage_Impl()
564 ClearIndex();
567 // -----------------------------------------------------------------------
569 namespace sfx2 {
571 struct equalOUString
573 bool operator()( const OUString& rKey1, const OUString& rKey2 ) const
575 return !!( rKey1 == rKey2 );
580 struct hashOUString
582 size_t operator()( const OUString& rName ) const
584 return rName.hashCode();
588 typedef ::boost::unordered_map< OUString, int, hashOUString, equalOUString > KeywordInfo;
591 #define UNIFY_AND_INSERT_TOKEN( aToken ) \
592 it = \
593 aInfo.insert( sfx2::KeywordInfo::value_type( aToken, 0 ) ).first; \
594 if ( ( tmp = it->second++ ) != 0 ) \
595 nPos = aIndexCB.InsertEntry( aToken + OUString( append, tmp ) ); \
596 else \
597 nPos = aIndexCB.InsertEntry( aToken )
599 #define INSERT_DATA( j ) \
600 if ( aAnchorList[j].getLength() > 0 ) \
602 aData.append( aRefList[j] ).append( sal_Unicode('#') ).append( aAnchorList[j] ); \
603 aIndexCB.SetEntryData( nPos, NEW_ENTRY( aData.makeStringAndClear(), insert ) ); \
605 else \
606 aIndexCB.SetEntryData( nPos, NEW_ENTRY( aRefList[j], insert ) );
608 // -----------------------------------------------------------------------
610 void IndexTabPage_Impl::InitializeIndex()
612 WaitObject aWaitCursor( this );
614 // By now more than 256 equal entries are not allowed
615 sal_Unicode append[256];
616 for( int k = 0; k < 256; ++k )
617 append[k] = sal_Unicode( ' ' );
619 sfx2::KeywordInfo aInfo;
620 aIndexCB.SetUpdateMode( sal_False );
624 OUStringBuffer aURL = HELP_URL;
625 aURL.append(sFactory);
626 AppendConfigToken(aURL, sal_True);
628 Content aCnt( aURL.makeStringAndClear(), Reference< ::com::sun::star::ucb::XCommandEnvironment >(), comphelper::getProcessComponentContext() );
629 ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > xInfo = aCnt.getProperties();
630 if ( xInfo->hasPropertyByName( PROPERTY_ANCHORREF ) )
632 ::com::sun::star::uno::Sequence< OUString > aPropSeq( 4 );
633 aPropSeq[0] = PROPERTY_KEYWORDLIST;
634 aPropSeq[1] = PROPERTY_KEYWORDREF;
635 aPropSeq[2] = PROPERTY_ANCHORREF;
636 aPropSeq[3] = PROPERTY_TITLEREF;
638 // abi: use one possibly remote call only
639 ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any > aAnySeq =
640 aCnt.getPropertyValues( aPropSeq );
642 ::com::sun::star::uno::Sequence< OUString > aKeywordList;
643 ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< OUString > > aKeywordRefList;
644 ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< OUString > > aAnchorRefList;
645 ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< OUString > > aTitleRefList;
647 if ( ( aAnySeq[0] >>= aKeywordList ) && ( aAnySeq[1] >>= aKeywordRefList ) &&
648 ( aAnySeq[2] >>= aAnchorRefList ) && ( aAnySeq[3] >>= aTitleRefList ) )
650 sal_Bool insert;
651 sal_uInt16 nPos;
652 int ndx,tmp;
653 OUString aIndex, aTempString;
654 OUStringBuffer aData( 128 ); // Capacity of up to 128 characters
655 sfx2::KeywordInfo::iterator it;
657 for ( int i = 0; i < aKeywordList.getLength(); ++i )
659 // abi: Do not copy, but use references
660 const OUString& aKeywordPair = aKeywordList[i];
661 DBG_ASSERT( !aKeywordPair.isEmpty(), "invalid help index" );
662 const ::com::sun::star::uno::Sequence< OUString >& aRefList = aKeywordRefList[i];
663 const ::com::sun::star::uno::Sequence< OUString >& aAnchorList = aAnchorRefList[i];
664 const ::com::sun::star::uno::Sequence< OUString >& aTitleList = aTitleRefList[i];
666 DBG_ASSERT( aRefList.getLength() == aAnchorList.getLength(),"reference list and title list of different length" );
668 insert = ( ( ndx = aKeywordPair.indexOf( sal_Unicode( ';' ) ) ) == -1 ? sal_False : sal_True );
670 if ( insert )
672 aTempString = aKeywordPair.copy( 0, ndx );
673 if ( aIndex != aTempString )
675 aIndex = aTempString;
676 UNIFY_AND_INSERT_TOKEN( aTempString );
679 else
680 aIndex = OUString();
682 // Assume the token is trimed
683 UNIFY_AND_INSERT_TOKEN( aKeywordPair );
685 sal_uInt32 nRefListLen = aRefList.getLength();
687 DBG_ASSERT( aAnchorList.getLength(), "*IndexTabPage_Impl::InitializeIndex(): AnchorList is empty!" ); \
688 DBG_ASSERT( nRefListLen, "*IndexTabPage_Impl::InitializeIndex(): RefList is empty!" ); \
690 if ( aAnchorList.getLength() && nRefListLen )
692 INSERT_DATA( 0 );
695 for ( sal_uInt32 j = 1; j < nRefListLen ; ++j )
697 aData
698 .append( aKeywordPair )
699 .append( sal_Unicode(' ') )
700 .append( sal_Unicode('-') )
701 .append( sal_Unicode(' ') )
702 .append( aTitleList[j] );
704 aTempString = aData.makeStringAndClear();
705 UNIFY_AND_INSERT_TOKEN( aTempString );
706 INSERT_DATA( j );
712 catch( Exception& )
714 OSL_FAIL( "IndexTabPage_Impl::InitializeIndex(): unexpected exception" );
717 aIndexCB.SetUpdateMode( sal_True );
719 if ( sKeyword.Len() > 0 )
720 aKeywordLink.Call( this );
723 #undef INSERT_DATA
724 #undef UNIFY_AND_INSERT_TOKEN
726 // -----------------------------------------------------------------------
728 void IndexTabPage_Impl::ClearIndex()
730 sal_uInt16 nCount = aIndexCB.GetEntryCount();
731 for ( sal_uInt16 i = 0; i < nCount; ++i )
732 delete (IndexEntry_Impl*)(sal_uIntPtr)aIndexCB.GetEntryData(i);
733 aIndexCB.Clear();
736 // -----------------------------------------------------------------------
738 IMPL_LINK_NOARG(IndexTabPage_Impl, OpenHdl)
740 aIndexCB.GetDoubleClickHdl().Call( &aIndexCB );
741 return 0;
744 // -----------------------------------------------------------------------
746 IMPL_LINK( IndexTabPage_Impl, TimeoutHdl, Timer*, pTimer )
748 if ( &aFactoryTimer == pTimer )
749 InitializeIndex();
750 else if ( &aKeywordTimer == pTimer && sKeyword.Len() > 0 )
751 aKeywordLink.Call( this );
752 return 0;
755 // -----------------------------------------------------------------------
757 void IndexTabPage_Impl::Resize()
759 Size aSize = GetSizePixel();
760 if ( aSize.Width() < nMinWidth )
761 aSize.Width() = nMinWidth;
762 Point aPnt = aExpressionFT.GetPosPixel();
763 Size aNewSize = aExpressionFT.GetSizePixel();
764 aNewSize.Width() = aSize.Width() - ( aPnt.X() * 2 );
765 aExpressionFT.SetSizePixel( aNewSize );
767 Size a6Size = LogicToPixel( Size( 6, 6 ), MAP_APPFONT );
768 Size aBtnSize = aOpenBtn.GetSizePixel();
770 aPnt = aIndexCB.GetPosPixel();
771 aNewSize = aIndexCB.GetSizePixel();
772 aNewSize.Width() = aSize.Width() - ( aPnt.X() * 2 );
773 aNewSize.Height() = aSize.Height() - aPnt.Y();
774 aNewSize.Height() -= ( aBtnSize.Height() + ( a6Size.Height() * 3 / 2 ) );
775 aIndexCB.SetSizePixel( aNewSize );
777 aPnt.X() += ( aNewSize.Width() - aBtnSize.Width() );
778 aPnt.Y() += aNewSize.Height() + ( a6Size.Height() / 2 );
779 long nMinX = aIndexCB.GetPosPixel().X();
780 if ( aPnt.X() < nMinX )
781 aPnt.X() = nMinX;
782 aOpenBtn.SetPosPixel( aPnt );
785 // -----------------------------------------------------------------------
787 void IndexTabPage_Impl::ActivatePage()
789 if ( !bIsActivated )
791 bIsActivated = sal_True;
792 aFactoryTimer.Start();
795 if ( !m_pIdxWin->WasCursorLeftOrRight() )
796 SetFocusOnBox();
799 // -----------------------------------------------------------------------
801 Control* IndexTabPage_Impl::GetLastFocusControl()
803 return &aOpenBtn;
806 // -----------------------------------------------------------------------
808 void IndexTabPage_Impl::SetDoubleClickHdl( const Link& rLink )
810 aIndexCB.SetDoubleClickHdl( rLink );
813 // -----------------------------------------------------------------------
815 void IndexTabPage_Impl::SetFactory( const String& rFactory )
817 String sNewFactory( rFactory );
818 DBG_ASSERT( sNewFactory.Len() > 0, "empty factory" );
819 bool bValid = m_pIdxWin->IsValidFactory( rFactory );
821 if ( sFactory.Len() == 0 && !bValid )
823 sNewFactory = SfxHelp::GetDefaultHelpModule();
824 bValid = true;
827 if ( sNewFactory != sFactory && bValid )
829 sFactory = sNewFactory;
830 ClearIndex();
831 if ( bIsActivated )
832 aFactoryTimer.Start();
836 // -----------------------------------------------------------------------
838 String IndexTabPage_Impl::GetSelectEntry() const
840 String aRet;
841 IndexEntry_Impl* pEntry = (IndexEntry_Impl*)(sal_uIntPtr)aIndexCB.GetEntryData( aIndexCB.GetEntryPos( aIndexCB.GetText() ) );
842 if ( pEntry )
843 aRet = pEntry->m_aURL;
844 return aRet;
847 // -----------------------------------------------------------------------
849 void IndexTabPage_Impl::SetKeyword( const String& rKeyword )
851 sKeyword = rKeyword;
853 if ( aIndexCB.GetEntryCount() > 0 )
854 aKeywordTimer.Start();
855 else if ( !bIsActivated )
856 aFactoryTimer.Start();
859 // -----------------------------------------------------------------------
861 sal_Bool IndexTabPage_Impl::HasKeyword() const
863 sal_Bool bRet = sal_False;
864 if ( sKeyword.Len() > 0 )
866 sal_uInt16 nPos = aIndexCB.GetEntryPos( sKeyword );
867 bRet = ( nPos != LISTBOX_ENTRY_NOTFOUND );
870 return bRet;
873 // -----------------------------------------------------------------------
875 sal_Bool IndexTabPage_Impl::HasKeywordIgnoreCase()
877 sal_Bool bRet = sal_False;
878 if ( sKeyword.Len() > 0 )
880 sal_uInt16 nEntries = aIndexCB.GetEntryCount();
881 String sIndexItem;
882 const vcl::I18nHelper& rI18nHelper = GetSettings().GetLocaleI18nHelper();
883 for ( sal_uInt16 n = 0; n < nEntries; n++)
885 sIndexItem = aIndexCB.GetEntry( n );
886 if (rI18nHelper.MatchString( sIndexItem, sKeyword ))
888 sKeyword = sIndexItem;
889 bRet = sal_True;
894 return bRet;
897 // -----------------------------------------------------------------------
899 void IndexTabPage_Impl::OpenKeyword()
901 if ( sKeyword.Len() > 0 )
903 aIndexCB.SetText( sKeyword );
904 aIndexCB.GetDoubleClickHdl().Call( NULL );
905 sKeyword.Erase();
909 // class SearchBox_Impl --------------------------------------------------
911 long SearchBox_Impl::PreNotify( NotifyEvent& rNEvt )
913 sal_Bool bHandled = sal_False;
914 if ( !IsInDropDown() &&
915 rNEvt.GetWindow() == GetSubEdit() &&
916 rNEvt.GetType() == EVENT_KEYINPUT &&
917 KEY_RETURN == rNEvt.GetKeyEvent()->GetKeyCode().GetCode() )
919 aSearchLink.Call( NULL );
920 bHandled = sal_True;
922 return bHandled ? 1 : ComboBox::PreNotify( rNEvt );
925 // -----------------------------------------------------------------------
927 void SearchBox_Impl::Select()
929 if ( !IsTravelSelect() )
930 aSearchLink.Call( NULL );
933 // class SearchResultsBox_Impl -------------------------------------------
935 long SearchResultsBox_Impl::Notify( NotifyEvent& rNEvt )
937 sal_Bool bHandled = sal_False;
938 if ( rNEvt.GetType() == EVENT_KEYINPUT &&
939 KEY_RETURN == rNEvt.GetKeyEvent()->GetKeyCode().GetCode() )
941 GetDoubleClickHdl().Call( NULL );
942 bHandled = sal_True;
945 return bHandled ? 1 : ListBox::Notify( rNEvt );
948 // class SearchTabPage_Impl ----------------------------------------------
950 SearchTabPage_Impl::SearchTabPage_Impl( Window* pParent, SfxHelpIndexWindow_Impl* _pIdxWin ) :
952 HelpTabPage_Impl( pParent, _pIdxWin, SfxResId( TP_HELP_SEARCH ) ),
954 aSearchFT ( this, SfxResId( FT_SEARCH ) ),
955 aSearchED ( this, SfxResId( ED_SEARCH ) ),
956 aSearchBtn ( this, SfxResId( PB_SEARCH ) ),
957 aFullWordsCB ( this, SfxResId( CB_FULLWORDS ) ),
958 aScopeCB ( this, SfxResId( CB_SCOPE ) ),
959 aResultsLB ( this, SfxResId( LB_RESULT ) ),
960 aOpenBtn ( this, SfxResId( PB_OPEN_SEARCH ) ),
961 xBreakIterator ( vcl::unohelper::CreateBreakIterator() )
964 FreeResource();
966 Link aLink = LINK( this, SearchTabPage_Impl, SearchHdl );
967 aSearchED.SetSearchLink( aLink );
968 aSearchBtn.SetClickHdl( aLink );
969 aSearchED.SetModifyHdl( LINK( this, SearchTabPage_Impl, ModifyHdl ) );
970 aOpenBtn.SetClickHdl( LINK( this, SearchTabPage_Impl, OpenHdl ) );
972 aMinSize = GetSizePixel();
974 SvtViewOptions aViewOpt( E_TABPAGE, CONFIGNAME_SEARCHPAGE );
975 if ( aViewOpt.Exists() )
977 String aUserData;
978 Any aUserItem = aViewOpt.GetUserItem( USERITEM_NAME );
979 OUString aTemp;
980 if ( aUserItem >>= aTemp )
982 aUserData = String( aTemp );
983 sal_Bool bChecked = ( 1 == aUserData.GetToken(0).ToInt32() ) ? sal_True : sal_False;
984 aFullWordsCB.Check( bChecked );
985 bChecked = ( 1 == aUserData.GetToken(1).ToInt32() ) ? sal_True : sal_False;
986 aScopeCB.Check( bChecked );
988 for ( sal_uInt16 i = 2; i < comphelper::string::getTokenCount(aUserData, ';'); ++i )
990 String aToken = aUserData.GetToken(i, ';');
991 aSearchED.InsertEntry( INetURLObject::decode(
992 aToken, '%', INetURLObject::DECODE_WITH_CHARSET ) );
997 ModifyHdl( &aSearchED );
1000 // -----------------------------------------------------------------------
1002 SearchTabPage_Impl::~SearchTabPage_Impl()
1004 SvtViewOptions aViewOpt( E_TABPAGE, CONFIGNAME_SEARCHPAGE );
1005 sal_Int32 nChecked = aFullWordsCB.IsChecked() ? 1 : 0;
1006 String aUserData = OUString::number( nChecked );
1007 aUserData += ';';
1008 nChecked = aScopeCB.IsChecked() ? 1 : 0;
1009 aUserData += OUString::number( nChecked );
1010 aUserData += ';';
1011 sal_uInt16 nCount = std::min( aSearchED.GetEntryCount(), (sal_uInt16)10 ); // save only 10 entries
1013 for ( sal_uInt16 i = 0; i < nCount; ++i )
1015 OUString aText = aSearchED.GetEntry(i);
1016 aUserData += String(INetURLObject::encode(
1017 aText, INetURLObject::PART_UNO_PARAM_VALUE, '%',
1018 INetURLObject::ENCODE_ALL ));
1019 aUserData += ';';
1022 aUserData = comphelper::string::stripEnd(aUserData, ';');
1023 Any aUserItem = makeAny( OUString( aUserData ) );
1024 aViewOpt.SetUserItem( USERITEM_NAME, aUserItem );
1027 // -----------------------------------------------------------------------
1029 void SearchTabPage_Impl::ClearSearchResults()
1031 sal_uInt16 nCount = aResultsLB.GetEntryCount();
1032 for ( sal_uInt16 i = 0; i < nCount; ++i )
1033 delete (String*)(sal_uIntPtr)aResultsLB.GetEntryData(i);
1034 aResultsLB.Clear();
1035 aResultsLB.Update();
1038 // -----------------------------------------------------------------------
1040 void SearchTabPage_Impl::RememberSearchText( const String& rSearchText )
1042 for ( sal_uInt16 i = 0; i < aSearchED.GetEntryCount(); ++i )
1044 if ( rSearchText == aSearchED.GetEntry(i) )
1046 aSearchED.RemoveEntry(i);
1047 break;
1051 aSearchED.InsertEntry( rSearchText, 0 );
1054 // -----------------------------------------------------------------------
1056 IMPL_LINK_NOARG(SearchTabPage_Impl, SearchHdl)
1058 String aSearchText = comphelper::string::strip(aSearchED.GetText(), ' ');
1059 if ( aSearchText.Len() > 0 )
1061 EnterWait();
1062 ClearSearchResults();
1063 RememberSearchText( aSearchText );
1064 OUStringBuffer aSearchURL(HELP_URL);
1065 aSearchURL.append(aFactory);
1066 aSearchURL.append(HELP_SEARCH_TAG);
1067 if ( !aFullWordsCB.IsChecked() )
1068 aSearchText = sfx2::PrepareSearchString( aSearchText, xBreakIterator, true );
1069 aSearchURL.append(aSearchText);
1070 AppendConfigToken(aSearchURL, sal_False);
1071 if ( aScopeCB.IsChecked() )
1072 aSearchURL.append("&Scope=Heading");
1073 std::vector< OUString > aFactories = SfxContentHelper::GetResultSet(aSearchURL.makeStringAndClear());
1074 for (size_t i = 0, n = aFactories.size(); i < n; ++i )
1076 const OUString& rRow = aFactories[i];
1077 sal_Int32 nIdx = 0;
1078 OUString aTitle = rRow.getToken( 0, '\t', nIdx );
1079 nIdx = 0;
1080 String* pURL = new String( rRow.getToken( 2, '\t', nIdx ) );
1081 sal_uInt16 nPos = aResultsLB.InsertEntry( aTitle );
1082 aResultsLB.SetEntryData( nPos, (void*)(sal_uIntPtr)pURL );
1084 LeaveWait();
1086 if ( aFactories.empty() )
1088 InfoBox aBox( this, SfxResId( RID_INFO_NOSEARCHRESULTS ) );
1089 aBox.SetText( SfxResId( STR_HELP_WINDOW_TITLE ).toString() );
1090 aBox.Execute();
1093 return 0;
1096 // -----------------------------------------------------------------------
1098 IMPL_LINK_NOARG(SearchTabPage_Impl, OpenHdl)
1100 aResultsLB.GetDoubleClickHdl().Call( &aResultsLB );
1101 return 0;
1104 // -----------------------------------------------------------------------
1106 IMPL_LINK_NOARG(SearchTabPage_Impl, ModifyHdl)
1108 String aSearchText = comphelper::string::strip(aSearchED.GetText(), ' ');
1109 aSearchBtn.Enable( aSearchText.Len() > 0 );
1110 return 0;
1113 // -----------------------------------------------------------------------
1115 void SearchTabPage_Impl::Resize()
1117 Size a6Size = LogicToPixel( Size( 6, 6 ), MAP_APPFONT );
1118 Size aSize = GetSizePixel();
1119 if ( aSize.Width() < aMinSize.Width() )
1120 aSize.Width() = aMinSize.Width();
1121 Point aPnt = aSearchFT.GetPosPixel();
1122 Size aNewSize = aSearchFT.GetSizePixel();
1123 aNewSize.Width() = aSize.Width() - ( aPnt.X() * 2 );
1124 aSearchFT.SetSizePixel( aNewSize );
1125 aNewSize.Height() = aResultsLB.GetSizePixel().Height();
1126 aResultsLB.SetSizePixel( aNewSize );
1127 aNewSize.Height() = aFullWordsCB.GetSizePixel().Height();
1128 aFullWordsCB.SetSizePixel( aNewSize );
1129 aScopeCB.SetSizePixel( aNewSize );
1130 aNewSize = aSearchED.GetSizePixel();
1131 aNewSize.Width() = aSize.Width() - ( aPnt.X() * 2 ) -
1132 ( aSearchBtn.GetSizePixel().Width() + ( aPnt.X() / 2 ) );
1133 aSearchED.SetSizePixel( aNewSize );
1134 Point aNewPnt = aSearchBtn.GetPosPixel();
1135 aNewPnt.X() = aPnt.X() + aNewSize.Width() + ( aPnt.X() / 2 );
1136 aSearchBtn.SetPosPixel( aNewPnt );
1138 if ( aSize.Height() > aMinSize.Height() )
1140 long n3Height = a6Size.Height() / 2;
1141 Size aBtnSize = aOpenBtn.GetSizePixel();
1142 long nExtraHeight = aBtnSize.Height() + n3Height;
1144 aPnt = aResultsLB.GetPosPixel();
1145 aNewSize = aResultsLB.GetSizePixel();
1146 aNewSize.Height() = aSize.Height() - aPnt.Y();
1147 aNewSize.Height() -= ( nExtraHeight + ( a6Size.Height() * 3 / 2 ) );
1148 aResultsLB.SetSizePixel( aNewSize );
1150 aPnt.X() += ( aNewSize.Width() - aBtnSize.Width() );
1151 aPnt.Y() += aNewSize.Height() + a6Size.Height();
1152 aOpenBtn.SetPosPixel( aPnt );
1156 // -----------------------------------------------------------------------
1158 void SearchTabPage_Impl::ActivatePage()
1160 if ( !m_pIdxWin->WasCursorLeftOrRight() )
1161 aSearchED.GrabFocus();
1164 // -----------------------------------------------------------------------
1166 Control* SearchTabPage_Impl::GetLastFocusControl()
1168 return &aOpenBtn;
1171 // -----------------------------------------------------------------------
1173 void SearchTabPage_Impl::SetDoubleClickHdl( const Link& rLink )
1175 aResultsLB.SetDoubleClickHdl( rLink );
1178 // -----------------------------------------------------------------------
1180 String SearchTabPage_Impl::GetSelectEntry() const
1182 String aRet;
1183 String* pData = (String*)(sal_uIntPtr)aResultsLB.GetEntryData( aResultsLB.GetSelectEntryPos() );
1184 if ( pData )
1185 aRet = String( *pData );
1186 return aRet;
1189 // -----------------------------------------------------------------------
1191 void SearchTabPage_Impl::ClearPage()
1193 ClearSearchResults();
1194 aSearchED.SetText( OUString() );
1197 // -----------------------------------------------------------------------
1199 sal_Bool SearchTabPage_Impl::OpenKeyword( const String& rKeyword )
1201 sal_Bool bRet = sal_False;
1202 aSearchED.SetText( rKeyword );
1203 SearchHdl( NULL );
1204 if ( aResultsLB.GetEntryCount() > 0 )
1206 // found keyword -> open it
1207 aResultsLB.SelectEntryPos(0);
1208 OpenHdl( NULL );
1209 bRet = sal_True;
1212 return bRet;
1215 // class BookmarksTabPage_Impl -------------------------------------------
1217 void GetBookmarkEntry_Impl
1219 Sequence< PropertyValue >& aBookmarkEntry,
1220 OUString& rTitle,
1221 OUString& rURL
1224 for ( int i = 0; i < aBookmarkEntry.getLength(); i++ )
1226 PropertyValue aValue = aBookmarkEntry[i];
1227 if ( aValue.Name == HISTORY_PROPERTYNAME_URL )
1228 aValue.Value >>= rURL;
1229 else if ( aValue.Name == HISTORY_PROPERTYNAME_TITLE )
1230 aValue.Value >>= rTitle;
1234 // -----------------------------------------------------------------------
1236 BookmarksBox_Impl::BookmarksBox_Impl( Window* pParent, const ResId& rResId ) :
1238 ListBox( pParent, rResId )
1243 // -----------------------------------------------------------------------
1245 BookmarksBox_Impl::~BookmarksBox_Impl()
1247 // save bookmarks to configuration
1248 SvtHistoryOptions aHistOpt;
1249 aHistOpt.Clear( eHELPBOOKMARKS );
1250 OUString sEmpty;
1251 sal_uInt16 nCount = GetEntryCount();
1252 for ( sal_uInt16 i = 0; i < nCount; ++i )
1254 String aTitle = GetEntry(i);
1255 String* pURL = (String*)(sal_uIntPtr)GetEntryData(i);
1256 aHistOpt.AppendItem( eHELPBOOKMARKS, OUString( *pURL ), sEmpty, OUString( aTitle ), sEmpty );
1257 delete pURL;
1261 // -----------------------------------------------------------------------
1263 void BookmarksBox_Impl::DoAction( sal_uInt16 nAction )
1265 switch ( nAction )
1267 case MID_OPEN :
1268 GetDoubleClickHdl().Call( NULL );
1269 break;
1271 case MID_RENAME :
1273 sal_uInt16 nPos = GetSelectEntryPos();
1274 if ( nPos != LISTBOX_ENTRY_NOTFOUND )
1276 SfxAddHelpBookmarkDialog_Impl aDlg( this, sal_True );
1277 aDlg.SetTitle( GetEntry( nPos ) );
1278 if ( aDlg.Execute() == RET_OK )
1280 String* pURL = (String*)(sal_uIntPtr)GetEntryData( nPos );
1281 RemoveEntry( nPos );
1282 OUString aImageURL = IMAGE_URL;
1283 aImageURL += INetURLObject( *pURL ).GetHost();
1284 nPos = InsertEntry( aDlg.GetTitle(), SvFileInformationManager::GetImage( aImageURL, false ) );
1285 SetEntryData( nPos, (void*)(sal_uIntPtr)( new String( *pURL ) ) );
1286 SelectEntryPos( nPos );
1287 delete pURL;
1290 break;
1293 case MID_DELETE :
1295 sal_uInt16 nPos = GetSelectEntryPos();
1296 if ( nPos != LISTBOX_ENTRY_NOTFOUND )
1298 RemoveEntry( nPos );
1299 sal_uInt16 nCount = GetEntryCount();
1300 if ( nCount )
1302 if ( nPos >= nCount )
1303 nPos = nCount - 1;
1304 SelectEntryPos( nPos );
1307 break;
1312 // -----------------------------------------------------------------------
1314 long BookmarksBox_Impl::Notify( NotifyEvent& rNEvt )
1316 long nRet = 0;
1317 sal_uInt16 nType = rNEvt.GetType();
1318 if ( EVENT_KEYINPUT == nType )
1320 sal_uInt16 nCode = rNEvt.GetKeyEvent()->GetKeyCode().GetCode();
1321 if ( KEY_DELETE == nCode && GetEntryCount() > 0 )
1323 DoAction( MID_DELETE );
1324 nRet = 1;
1326 else if ( KEY_RETURN == nCode )
1328 GetDoubleClickHdl().Call( NULL );
1329 nRet = 1;
1332 else if ( EVENT_COMMAND == nType )
1334 const CommandEvent* pCEvt = rNEvt.GetCommandEvent();
1335 if ( pCEvt->GetCommand() == COMMAND_CONTEXTMENU )
1337 PopupMenu aMenu( SfxResId( MENU_HELP_BOOKMARKS ) );
1338 sal_uInt16 nId = aMenu.Execute( this, pCEvt->GetMousePosPixel() );
1339 if ( nId != MENU_ITEM_NOTFOUND )
1340 DoAction( nId );
1341 nRet = 1;
1345 return nRet ? nRet : ListBox::Notify( rNEvt );
1348 // class BookmarksTabPage_Impl -------------------------------------------
1350 BookmarksTabPage_Impl::BookmarksTabPage_Impl( Window* pParent, SfxHelpIndexWindow_Impl* _pIdxWin ) :
1352 HelpTabPage_Impl( pParent, _pIdxWin, SfxResId( TP_HELP_BOOKMARKS ) ),
1354 aBookmarksFT ( this, SfxResId( FT_BOOKMARKS ) ),
1355 aBookmarksBox ( this, SfxResId( LB_BOOKMARKS ) ),
1356 aBookmarksPB ( this, SfxResId( PB_BOOKMARKS ) )
1359 FreeResource();
1361 nMinWidth = aBookmarksPB.GetSizePixel().Width();
1363 aBookmarksPB.SetClickHdl( LINK( this, BookmarksTabPage_Impl, OpenHdl ) );
1365 // load bookmarks from configuration
1366 Sequence< Sequence< PropertyValue > > aBookmarkSeq;
1367 aBookmarkSeq = SvtHistoryOptions().GetList( eHELPBOOKMARKS );
1369 OUString aTitle;
1370 OUString aURL;
1372 sal_uInt32 i, nCount = aBookmarkSeq.getLength();
1373 for ( i = 0; i < nCount; ++i )
1375 GetBookmarkEntry_Impl( aBookmarkSeq[i], aTitle, aURL );
1376 AddBookmarks( aTitle, aURL );
1380 // -----------------------------------------------------------------------
1382 IMPL_LINK_NOARG(BookmarksTabPage_Impl, OpenHdl)
1384 aBookmarksBox.GetDoubleClickHdl().Call( &aBookmarksBox );
1385 return 0;
1388 // -----------------------------------------------------------------------
1390 void BookmarksTabPage_Impl::Resize()
1392 Size aSize = GetSizePixel();
1393 if ( aSize.Width() < nMinWidth )
1394 aSize.Width() = nMinWidth;
1395 Point aPnt = aBookmarksFT.GetPosPixel();
1396 Size aNewSize = aBookmarksFT.GetSizePixel();
1397 aNewSize.Width() = aSize.Width() - ( aPnt.X() * 2 );
1398 aBookmarksFT.SetSizePixel( aNewSize );
1400 Size a6Size = LogicToPixel( Size( 6, 6 ), MAP_APPFONT );
1401 Size aBtnSize = aBookmarksPB.GetSizePixel();
1403 aPnt = aBookmarksBox.GetPosPixel();
1404 aNewSize = aBookmarksBox.GetSizePixel();
1405 aNewSize.Width() = aSize.Width() - ( aPnt.X() * 2 );
1406 aNewSize.Height() = aSize.Height() - aPnt.Y();
1407 aNewSize.Height() -= ( aBtnSize.Height() + ( a6Size.Height() * 3 / 2 ) );
1408 aBookmarksBox.SetSizePixel( aNewSize );
1410 aPnt.X() += ( aNewSize.Width() - aBtnSize.Width() );
1411 aPnt.Y() += aNewSize.Height() + ( a6Size.Height() / 2 );
1412 long nMinX = aBookmarksBox.GetPosPixel().X();
1413 if ( aPnt.X() < nMinX )
1414 aPnt.X() = nMinX;
1415 aBookmarksPB.SetPosPixel( aPnt );
1418 // -----------------------------------------------------------------------
1420 void BookmarksTabPage_Impl::ActivatePage()
1422 if ( !m_pIdxWin->WasCursorLeftOrRight() )
1423 SetFocusOnBox();
1426 // -----------------------------------------------------------------------
1428 Control* BookmarksTabPage_Impl::GetLastFocusControl()
1430 return &aBookmarksPB;
1433 // -----------------------------------------------------------------------
1435 void BookmarksTabPage_Impl::SetDoubleClickHdl( const Link& rLink )
1437 aBookmarksBox.SetDoubleClickHdl( rLink );
1440 // -----------------------------------------------------------------------
1442 String BookmarksTabPage_Impl::GetSelectEntry() const
1444 String aRet;
1445 String* pData = (String*)(sal_uIntPtr)aBookmarksBox.GetEntryData( aBookmarksBox.GetSelectEntryPos() );
1446 if ( pData )
1447 aRet = String( *pData );
1448 return aRet;
1451 // -----------------------------------------------------------------------
1453 void BookmarksTabPage_Impl::AddBookmarks( const String& rTitle, const String& rURL )
1455 OUString aImageURL = IMAGE_URL;
1456 aImageURL += INetURLObject( rURL ).GetHost();
1457 sal_uInt16 nPos = aBookmarksBox.InsertEntry( rTitle, SvFileInformationManager::GetImage( aImageURL, false ) );
1458 aBookmarksBox.SetEntryData( nPos, (void*)(sal_uIntPtr)( new String( rURL ) ) );
1461 OUString SfxHelpWindow_Impl::buildHelpURL(const OUString& sFactory ,
1462 const OUString& sContent ,
1463 const OUString& sAnchor ,
1464 sal_Bool bUseQuestionMark)
1466 OUStringBuffer sHelpURL(256);
1467 sHelpURL.append(HELP_URL);
1468 sHelpURL.append(sFactory);
1469 sHelpURL.append(sContent);
1470 AppendConfigToken(sHelpURL, bUseQuestionMark);
1471 if (!sAnchor.isEmpty())
1472 sHelpURL.append(sAnchor);
1473 return sHelpURL.makeStringAndClear();
1476 void SfxHelpWindow_Impl::loadHelpContent(const OUString& sHelpURL, sal_Bool bAddToHistory)
1478 Reference< XComponentLoader > xLoader(getTextFrame(), UNO_QUERY);
1479 if (!xLoader.is())
1480 return;
1482 // If a print job runs do not open a new page
1483 Reference< XFrame2 > xTextFrame = pTextWin->getFrame();
1484 Reference< XController > xTextController ;
1485 if (xTextFrame.is())
1486 xTextController = xTextFrame->getController ();
1487 if ( xTextController.is() && !xTextController->suspend( sal_True ) )
1489 xTextController->suspend( sal_False );
1490 return;
1493 // save url to history
1494 if (bAddToHistory)
1495 pHelpInterceptor->addURL(sHelpURL);
1497 if ( !IsWait() )
1498 EnterWait();
1499 sal_Bool bSuccess = sal_False;
1500 // TODO implement locale fallback ... see below while(true)
1504 Reference< XComponent > xContent = xLoader->loadComponentFromURL(sHelpURL, "_self", 0, Sequence< PropertyValue >());
1505 if (xContent.is())
1507 bSuccess = sal_True;
1510 catch(const RuntimeException&)
1511 { throw; }
1512 catch(const Exception&)
1513 { /*break;*/ }
1515 /* TODO try next locale ...
1516 no further locale available? => break loop and show error page
1519 openDone(sHelpURL, bSuccess);
1520 if ( IsWait() )
1521 LeaveWait();
1524 SfxHelpIndexWindow_Impl::SfxHelpIndexWindow_Impl( SfxHelpWindow_Impl* _pParent ) :
1526 Window( _pParent, SfxResId( WIN_HELPINDEX ) ),
1528 aActiveLB ( this, SfxResId( LB_ACTIVE ) ),
1529 aActiveLine ( this, SfxResId( FL_ACTIVE ) ),
1530 aTabCtrl ( this, SfxResId( TC_INDEX ) ),
1532 aIndexKeywordLink ( LINK( this, SfxHelpIndexWindow_Impl, KeywordHdl ) ),
1533 pParentWin ( _pParent ),
1535 pCPage ( NULL ),
1536 pIPage ( NULL ),
1537 pSPage ( NULL ),
1538 pBPage ( NULL ),
1540 bWasCursorLeftOrRight( false ),
1541 bIsInitDone ( false )
1544 FreeResource();
1546 sfx2::AddToTaskPaneList( this );
1548 aTabCtrl.SetActivatePageHdl( LINK( this, SfxHelpIndexWindow_Impl, ActivatePageHdl ) );
1549 aTabCtrl.Show();
1551 sal_Int32 nPageId = HELP_INDEX_PAGE_INDEX;
1552 SvtViewOptions aViewOpt( E_TABDIALOG, CONFIGNAME_INDEXWIN );
1553 if ( aViewOpt.Exists() )
1554 nPageId = aViewOpt.GetPageID();
1555 aTabCtrl.SetCurPageId( (sal_uInt16)nPageId );
1556 ActivatePageHdl( &aTabCtrl );
1557 aActiveLB.SetSelectHdl( LINK( this, SfxHelpIndexWindow_Impl, SelectHdl ) );
1558 nMinWidth = ( aActiveLB.GetSizePixel().Width() / 2 );
1560 aTimer.SetTimeoutHdl( LINK( this, SfxHelpIndexWindow_Impl, InitHdl ) );
1561 aTimer.SetTimeout( 200 );
1562 aTimer.Start();
1565 // -----------------------------------------------------------------------
1567 SfxHelpIndexWindow_Impl::~SfxHelpIndexWindow_Impl()
1569 sfx2::RemoveFromTaskPaneList( this );
1571 DELETEZ( pCPage );
1572 DELETEZ( pIPage );
1573 DELETEZ( pSPage );
1574 DELETEZ( pBPage );
1576 for ( sal_uInt16 i = 0; i < aActiveLB.GetEntryCount(); ++i )
1577 delete (String*)(sal_uIntPtr)aActiveLB.GetEntryData(i);
1579 SvtViewOptions aViewOpt( E_TABDIALOG, CONFIGNAME_INDEXWIN );
1580 aViewOpt.SetPageID( (sal_Int32)aTabCtrl.GetCurPageId() );
1583 // -----------------------------------------------------------------------
1585 void SfxHelpIndexWindow_Impl::Initialize()
1587 OUStringBuffer aHelpURL(HELP_URL);
1588 AppendConfigToken(aHelpURL, sal_True);
1589 std::vector<OUString> aFactories = SfxContentHelper::GetResultSet(aHelpURL.makeStringAndClear());
1590 for (size_t i = 0, n = aFactories.size(); i < n; ++i )
1592 const OUString& rRow = aFactories[i];
1593 sal_Int32 nIdx = 0;
1594 OUString aTitle = rRow.getToken( 0, '\t', nIdx );
1595 nIdx = 0;
1596 OUString aURL = rRow.getToken( 2, '\t', nIdx );
1597 String* pFactory = new String( INetURLObject( aURL ).GetHost() );
1598 sal_uInt16 nPos = aActiveLB.InsertEntry( aTitle );
1599 aActiveLB.SetEntryData( nPos, (void*)(sal_uIntPtr)pFactory );
1602 aActiveLB.SetDropDownLineCount( (sal_uInt16)aFactories.size() );
1603 if ( aActiveLB.GetSelectEntryPos() == LISTBOX_ENTRY_NOTFOUND )
1604 SetActiveFactory();
1607 // -----------------------------------------------------------------------
1609 void SfxHelpIndexWindow_Impl::SetActiveFactory()
1611 DBG_ASSERT( pIPage, "index page not initialized" );
1612 if ( !bIsInitDone && !aActiveLB.GetEntryCount() )
1614 aTimer.Stop();
1615 InitHdl( NULL );
1618 for ( sal_uInt16 i = 0; i < aActiveLB.GetEntryCount(); ++i )
1620 String* pFactory = (String*)(sal_uIntPtr)aActiveLB.GetEntryData(i);
1621 pFactory->ToLowerAscii();
1622 if ( *pFactory == pIPage->GetFactory() )
1624 if ( aActiveLB.GetSelectEntryPos() != i )
1626 aActiveLB.SelectEntryPos(i);
1627 aSelectFactoryLink.Call( NULL );
1629 break;
1634 // -----------------------------------------------------------------------
1636 HelpTabPage_Impl* SfxHelpIndexWindow_Impl::GetCurrentPage( sal_uInt16& rCurId )
1638 rCurId = aTabCtrl.GetCurPageId();
1639 HelpTabPage_Impl* pPage = NULL;
1641 switch ( rCurId )
1643 case HELP_INDEX_PAGE_CONTENTS:
1645 pPage = GetContentPage();
1646 break;
1649 case HELP_INDEX_PAGE_INDEX:
1651 pPage = GetIndexPage();
1652 break;
1655 case HELP_INDEX_PAGE_SEARCH:
1657 pPage = GetSearchPage();
1658 break;
1661 case HELP_INDEX_PAGE_BOOKMARKS:
1663 pPage = GetBookmarksPage();
1664 break;
1668 DBG_ASSERT( pPage, "SfxHelpIndexWindow_Impl::GetCurrentPage(): no current page" );
1669 return pPage;
1672 // -----------------------------------------------------------------------
1674 IMPL_LINK( SfxHelpIndexWindow_Impl, ActivatePageHdl, TabControl *, pTabCtrl )
1676 sal_uInt16 nId = 0;
1677 TabPage* pPage = GetCurrentPage( nId );
1678 pTabCtrl->SetTabPage( nId, pPage );
1679 return 0;
1682 // -----------------------------------------------------------------------
1684 IMPL_LINK_NOARG(SfxHelpIndexWindow_Impl, SelectHdl)
1686 aTimer.Start();
1688 return 0;
1691 // -----------------------------------------------------------------------
1693 IMPL_LINK_NOARG(SfxHelpIndexWindow_Impl, InitHdl)
1695 bIsInitDone = true;
1696 Initialize();
1698 // now use the timer for selection
1699 aTimer.SetTimeoutHdl( LINK( this, SfxHelpIndexWindow_Impl, SelectFactoryHdl ) );
1700 aTimer.SetTimeout( 1000 );
1702 return 0;
1705 // -----------------------------------------------------------------------
1707 IMPL_LINK_NOARG(SfxHelpIndexWindow_Impl, SelectFactoryHdl)
1709 String* pFactory = (String*)(sal_uIntPtr)aActiveLB.GetEntryData( aActiveLB.GetSelectEntryPos() );
1710 if ( pFactory )
1712 String aFactory( *pFactory );
1713 aFactory.ToLowerAscii();
1714 SetFactory( aFactory, sal_False );
1715 aSelectFactoryLink.Call( this );
1718 return 0;
1721 // -----------------------------------------------------------------------
1723 IMPL_LINK_NOARG(SfxHelpIndexWindow_Impl, KeywordHdl)
1725 // keyword found on index?
1726 sal_Bool bIndex = pIPage->HasKeyword();
1728 if( !bIndex)
1729 bIndex = pIPage->HasKeywordIgnoreCase();
1730 // then set index or search page as current.
1731 sal_uInt16 nPageId = ( bIndex ) ? HELP_INDEX_PAGE_INDEX : HELP_INDEX_PAGE_SEARCH;
1732 if ( nPageId != aTabCtrl.GetCurPageId() )
1734 aTabCtrl.SetCurPageId( nPageId );
1735 ActivatePageHdl( &aTabCtrl );
1738 // at last we open the keyword
1739 if ( bIndex )
1740 pIPage->OpenKeyword();
1741 else if ( !pSPage->OpenKeyword( sKeyword ) )
1742 pParentWin->ShowStartPage();
1744 return 0;
1747 // -----------------------------------------------------------------------
1749 void SfxHelpIndexWindow_Impl::Resize()
1751 Size aSize = GetOutputSizePixel();
1752 if ( aSize.Width() < nMinWidth )
1753 aSize.Width() = nMinWidth;
1755 Point aPnt = aActiveLB.GetPosPixel();
1756 Size aNewSize = aActiveLB.GetSizePixel();
1757 aNewSize.Width() = aSize.Width() - ( aPnt.X() * 2 );
1758 aActiveLB.SetSizePixel( aNewSize );
1759 aPnt = aActiveLine.GetPosPixel();
1760 aNewSize = aActiveLine.GetSizePixel();
1761 aNewSize.Width() = aSize.Width() - ( aPnt.X() * 2 );
1762 aActiveLine.SetSizePixel( aNewSize );
1763 aPnt = aTabCtrl.GetPosPixel();
1764 aNewSize = aSize;
1765 aSize.Width() -= aPnt.X();
1766 aSize.Height() -= aPnt.Y();
1767 aTabCtrl.SetSizePixel( aSize );
1770 // -----------------------------------------------------------------------
1772 long SfxHelpIndexWindow_Impl::PreNotify( NotifyEvent& rNEvt )
1774 long nDone = 0;
1775 sal_uInt16 nType = rNEvt.GetType();
1776 if ( EVENT_KEYINPUT == nType && rNEvt.GetKeyEvent() )
1778 const KeyCode& rKeyCode = rNEvt.GetKeyEvent()->GetKeyCode();
1779 sal_uInt16 nCode = rKeyCode.GetCode();
1781 if ( KEY_TAB == nCode )
1783 // don't exit index pane with <TAB>
1784 sal_uInt16 nPageId = 0;
1785 HelpTabPage_Impl* pCurPage = GetCurrentPage( nPageId );
1786 Control* pControl = pCurPage->GetLastFocusControl();
1787 sal_Bool bShift = rKeyCode.IsShift();
1788 sal_Bool bCtrl = rKeyCode.IsMod1();
1789 if ( !bCtrl && bShift && aActiveLB.HasChildPathFocus() )
1791 pControl->GrabFocus();
1792 nDone = 1;
1794 else if ( !bCtrl && !bShift && pControl->HasChildPathFocus() )
1796 aActiveLB.GrabFocus();
1797 nDone = 1;
1799 else if ( bCtrl )
1801 // <CTRL><TAB> moves through the pages
1802 if ( nPageId < HELP_INDEX_PAGE_LAST )
1803 nPageId++;
1804 else
1805 nPageId = HELP_INDEX_PAGE_FIRST;
1806 aTabCtrl.SetCurPageId( (sal_uInt16)nPageId );
1807 ActivatePageHdl( &aTabCtrl );
1808 nDone = 1;
1811 else if ( aTabCtrl.HasFocus() && ( KEY_LEFT == nCode || KEY_RIGHT == nCode ) )
1813 bWasCursorLeftOrRight = true;
1817 return nDone ? nDone : Window::PreNotify( rNEvt );
1820 // -----------------------------------------------------------------------
1822 void SfxHelpIndexWindow_Impl::DataChanged( const DataChangedEvent& rDCEvt )
1824 Window::DataChanged( rDCEvt );
1826 if ( ( ( rDCEvt.GetType() == DATACHANGED_SETTINGS ) ||
1827 ( rDCEvt.GetType() == DATACHANGED_DISPLAY ) ) &&
1828 ( rDCEvt.GetFlags() & SETTINGS_STYLE ) )
1830 SetBackground( Wallpaper( GetSettings().GetStyleSettings().GetFaceColor() ) );
1834 // -----------------------------------------------------------------------
1836 void SfxHelpIndexWindow_Impl::SetDoubleClickHdl( const Link& rLink )
1838 aPageDoubleClickLink = rLink;
1839 if ( pCPage )
1840 pCPage->SetOpenHdl( aPageDoubleClickLink );
1841 if ( pIPage )
1842 pIPage->SetDoubleClickHdl( aPageDoubleClickLink );
1843 if ( pSPage )
1844 pSPage->SetDoubleClickHdl( aPageDoubleClickLink );
1845 if ( pBPage )
1846 pBPage->SetDoubleClickHdl( aPageDoubleClickLink );
1849 // -----------------------------------------------------------------------
1851 void SfxHelpIndexWindow_Impl::SetFactory( const String& rFactory, sal_Bool bActive )
1853 if ( rFactory.Len() > 0 )
1855 GetIndexPage()->SetFactory( rFactory );
1856 // the index page did a check if rFactory is valid,
1857 // so the index page always returns a valid factory
1858 GetSearchPage()->SetFactory( GetIndexPage()->GetFactory() );
1859 if ( bActive )
1860 SetActiveFactory();
1864 // -----------------------------------------------------------------------
1866 String SfxHelpIndexWindow_Impl::GetSelectEntry() const
1868 String sRet;
1870 switch ( aTabCtrl.GetCurPageId() )
1872 case HELP_INDEX_PAGE_CONTENTS:
1873 sRet = pCPage->GetSelectEntry();
1874 break;
1876 case HELP_INDEX_PAGE_INDEX:
1877 sRet = pIPage->GetSelectEntry();
1878 break;
1880 case HELP_INDEX_PAGE_SEARCH:
1881 sRet = pSPage->GetSelectEntry();
1882 break;
1884 case HELP_INDEX_PAGE_BOOKMARKS:
1885 sRet = pBPage->GetSelectEntry();
1886 break;
1889 return sRet;
1892 // -----------------------------------------------------------------------
1894 void SfxHelpIndexWindow_Impl::AddBookmarks( const String& rTitle, const String& rURL )
1896 GetBookmarksPage()->AddBookmarks( rTitle, rURL );
1899 // -----------------------------------------------------------------------
1901 bool SfxHelpIndexWindow_Impl::IsValidFactory( const String& _rFactory )
1903 bool bValid = false;
1904 for ( sal_uInt16 i = 0; i < aActiveLB.GetEntryCount(); ++i )
1906 String* pFactory = (String*)(sal_uIntPtr)aActiveLB.GetEntryData(i);
1907 if ( *pFactory == _rFactory )
1909 bValid = true;
1910 break;
1913 return bValid;
1916 // -----------------------------------------------------------------------
1918 void SfxHelpIndexWindow_Impl::ClearSearchPage()
1920 if ( pSPage )
1921 pSPage->ClearPage();
1924 // -----------------------------------------------------------------------
1926 void SfxHelpIndexWindow_Impl::GrabFocusBack()
1928 if ( aTabCtrl.GetCurPageId() == HELP_INDEX_PAGE_CONTENTS && pCPage )
1929 pCPage->SetFocusOnBox();
1930 else if ( aTabCtrl.GetCurPageId() == HELP_INDEX_PAGE_INDEX && pIPage )
1931 pIPage->SetFocusOnBox();
1932 else if ( aTabCtrl.GetCurPageId() == HELP_INDEX_PAGE_SEARCH && pSPage )
1933 pSPage->SetFocusOnBox();
1934 else if ( aTabCtrl.GetCurPageId() == HELP_INDEX_PAGE_BOOKMARKS && pBPage )
1935 pBPage->SetFocusOnBox();
1938 // -----------------------------------------------------------------------
1940 sal_Bool SfxHelpIndexWindow_Impl::HasFocusOnEdit() const
1942 sal_Bool bRet = sal_False;
1943 if ( aTabCtrl.GetCurPageId() == HELP_INDEX_PAGE_INDEX && pIPage )
1944 bRet = pIPage->HasFocusOnEdit();
1945 else if ( aTabCtrl.GetCurPageId() == HELP_INDEX_PAGE_SEARCH && pSPage )
1946 bRet = pSPage->HasFocusOnEdit();
1947 return bRet;
1950 // -----------------------------------------------------------------------
1952 String SfxHelpIndexWindow_Impl::GetSearchText() const
1954 String sRet;
1955 if ( aTabCtrl.GetCurPageId() == HELP_INDEX_PAGE_SEARCH && pSPage )
1956 sRet = pSPage->GetSearchText();
1957 return sRet;
1960 // -----------------------------------------------------------------------
1962 sal_Bool SfxHelpIndexWindow_Impl::IsFullWordSearch() const
1964 sal_Bool bRet = sal_False;
1965 if ( aTabCtrl.GetCurPageId() == HELP_INDEX_PAGE_SEARCH && pSPage )
1966 bRet = pSPage->IsFullWordSearch();
1967 return bRet;
1970 // -----------------------------------------------------------------------
1972 void SfxHelpIndexWindow_Impl::OpenKeyword( const String& rKeyword )
1974 sKeyword = rKeyword;
1975 DBG_ASSERT( pIPage, "invalid index page" );
1976 pIPage->SetKeyword( sKeyword );
1979 // -----------------------------------------------------------------------
1981 void SfxHelpIndexWindow_Impl::SelectExecutableEntry()
1983 if ( aTabCtrl.GetCurPageId() == HELP_INDEX_PAGE_INDEX && pIPage )
1984 pIPage->SelectExecutableEntry();
1987 // class TextWin_Impl ----------------------------------------------------
1989 TextWin_Impl::TextWin_Impl( Window* p ) : DockingWindow( p, 0 )
1993 TextWin_Impl::~TextWin_Impl()
1997 long TextWin_Impl::Notify( NotifyEvent& rNEvt )
1999 if( ( rNEvt.GetType() == EVENT_KEYINPUT ) && rNEvt.GetKeyEvent()->GetKeyCode().GetCode() == KEY_TAB )
2000 return GetParent()->Notify( rNEvt );
2001 else
2002 return DockingWindow::Notify( rNEvt );
2005 // -----------------------------------------------------------------------
2006 // remove docking area acceptor from layoutmanager, so it will not layout anything further .-)
2007 static void lcl_disableLayoutOfFrame(const Reference< XFrame2 >& xFrame)
2009 xFrame->setLayoutManager( Reference< XLayoutManager >() );
2012 // class SfxHelpTextWindow_Impl ------------------------------------------
2014 SfxHelpTextWindow_Impl::SfxHelpTextWindow_Impl( SfxHelpWindow_Impl* pParent ) :
2016 Window( pParent, WB_CLIPCHILDREN | WB_TABSTOP | WB_DIALOGCONTROL ),
2018 aToolBox ( this, 0 ),
2019 aOnStartupCB ( this, SfxResId( RID_HELP_ONSTARTUP_BOX ) ),
2020 aIndexOnImage ( SfxResId( IMG_HELP_TOOLBOX_INDEX_ON ) ),
2021 aIndexOffImage ( SfxResId( IMG_HELP_TOOLBOX_INDEX_OFF ) ),
2022 aIndexOnText ( SfxResId( STR_HELP_BUTTON_INDEX_ON ).toString() ),
2023 aIndexOffText ( SfxResId( STR_HELP_BUTTON_INDEX_OFF ).toString() ),
2024 aOnStartupText ( SfxResId( RID_HELP_ONSTARTUP_TEXT ).toString() ),
2025 pHelpWin ( pParent ),
2026 pTextWin ( new TextWin_Impl( this ) ),
2027 pSrchDlg ( NULL ),
2028 nMinPos ( 0 ),
2029 bIsDebug ( sal_False ),
2030 bIsIndexOn ( sal_False ),
2031 bIsInClose ( sal_False ),
2032 bIsFullWordSearch ( sal_False )
2035 sfx2::AddToTaskPaneList( &aToolBox );
2037 xFrame = Frame::create( ::comphelper::getProcessComponentContext() );
2038 xFrame->initialize( VCLUnoHelper::GetInterface ( pTextWin ) );
2039 xFrame->setName( "OFFICE_HELP" );
2040 lcl_disableLayoutOfFrame(xFrame);
2042 aToolBox.SetHelpId( HID_HELP_TOOLBOX );
2044 aToolBox.InsertItem( TBI_INDEX, aIndexOffText );
2045 aToolBox.SetHelpId( TBI_INDEX, HID_HELP_TOOLBOXITEM_INDEX );
2046 aToolBox.InsertSeparator();
2047 aToolBox.InsertItem( TBI_BACKWARD, SfxResId( STR_HELP_BUTTON_PREV ).toString() );
2048 aToolBox.SetHelpId( TBI_BACKWARD, HID_HELP_TOOLBOXITEM_BACKWARD );
2049 aToolBox.InsertItem( TBI_FORWARD, SfxResId( STR_HELP_BUTTON_NEXT ).toString() );
2050 aToolBox.SetHelpId( TBI_FORWARD, HID_HELP_TOOLBOXITEM_FORWARD );
2051 aToolBox.InsertItem( TBI_START, SfxResId( STR_HELP_BUTTON_START ).toString() );
2052 aToolBox.SetHelpId( TBI_START, HID_HELP_TOOLBOXITEM_START );
2053 aToolBox.InsertSeparator();
2054 aToolBox.InsertItem( TBI_PRINT, SfxResId( STR_HELP_BUTTON_PRINT ).toString() );
2055 aToolBox.SetHelpId( TBI_PRINT, HID_HELP_TOOLBOXITEM_PRINT );
2056 aToolBox.InsertItem( TBI_BOOKMARKS, SfxResId( STR_HELP_BUTTON_ADDBOOKMARK ).toString() );
2057 aToolBox.SetHelpId( TBI_BOOKMARKS, HID_HELP_TOOLBOXITEM_BOOKMARKS );
2058 aToolBox.InsertItem( TBI_SEARCHDIALOG, SfxResId( STR_HELP_BUTTON_SEARCHDIALOG ).toString() );
2059 aToolBox.SetHelpId( TBI_SEARCHDIALOG, HID_HELP_TOOLBOXITEM_SEARCHDIALOG );
2061 InitToolBoxImages();
2062 aToolBox.Show();
2063 InitOnStartupBox( false );
2064 aOnStartupCB.SetClickHdl( LINK( this, SfxHelpTextWindow_Impl, CheckHdl ) );
2066 aSelectTimer.SetTimeoutHdl( LINK( this, SfxHelpTextWindow_Impl, SelectHdl ) );
2067 aSelectTimer.SetTimeout( 1000 );
2069 char* pEnv = getenv( "help_debug" );
2070 if ( pEnv )
2071 bIsDebug = sal_True;
2073 SvtMiscOptions().AddListenerLink( LINK( this, SfxHelpTextWindow_Impl, NotifyHdl ) );
2075 if ( !aOnStartupCB.GetHelpId().getLength() )
2076 aOnStartupCB.SetHelpId( HID_HELP_ONSTARTUP_BOX );
2079 // -----------------------------------------------------------------------
2081 SfxHelpTextWindow_Impl::~SfxHelpTextWindow_Impl()
2083 sfx2::RemoveFromTaskPaneList( &aToolBox );
2085 bIsInClose = sal_True;
2086 SvtMiscOptions().RemoveListenerLink( LINK( this, SfxHelpTextWindow_Impl, NotifyHdl ) );
2087 delete pSrchDlg;
2090 // -----------------------------------------------------------------------
2092 sal_Bool SfxHelpTextWindow_Impl::HasSelection() const
2094 // is there any selection in the text and not only a cursor?
2095 sal_Bool bRet = sal_False;
2096 Reference < XTextRange > xRange = getCursor();
2097 if ( xRange.is() )
2099 Reference < XText > xText = xRange->getText();
2100 Reference < XTextCursor > xCursor = xText->createTextCursorByRange( xRange );
2101 bRet = !xCursor->isCollapsed();
2104 return bRet;
2107 // -----------------------------------------------------------------------
2109 void SfxHelpTextWindow_Impl::InitToolBoxImages()
2111 sal_Bool bLarge = SvtMiscOptions().AreCurrentSymbolsLarge();
2113 aIndexOnImage = Image( SfxResId( bLarge ? IMG_HELP_TOOLBOX_L_INDEX_ON : IMG_HELP_TOOLBOX_INDEX_ON ) );
2114 aIndexOffImage = Image( SfxResId( bLarge ? IMG_HELP_TOOLBOX_L_INDEX_OFF : IMG_HELP_TOOLBOX_INDEX_OFF ) );
2116 aToolBox.SetItemImage( TBI_INDEX, bIsIndexOn ? aIndexOffImage : aIndexOnImage );
2118 aToolBox.SetItemImage( TBI_BACKWARD,
2119 Image( SfxResId( bLarge ? IMG_HELP_TOOLBOX_L_PREV : IMG_HELP_TOOLBOX_PREV ) )
2122 aToolBox.SetItemImage( TBI_FORWARD,
2123 Image( SfxResId( bLarge ? IMG_HELP_TOOLBOX_L_NEXT : IMG_HELP_TOOLBOX_NEXT ) )
2126 aToolBox.SetItemImage( TBI_START,
2127 Image( SfxResId( bLarge ? IMG_HELP_TOOLBOX_L_START : IMG_HELP_TOOLBOX_START ) )
2130 aToolBox.SetItemImage( TBI_PRINT,
2131 Image( SfxResId( bLarge ? IMG_HELP_TOOLBOX_L_PRINT : IMG_HELP_TOOLBOX_PRINT ) )
2134 aToolBox.SetItemImage( TBI_BOOKMARKS,
2135 Image( SfxResId( bLarge ? IMG_HELP_TOOLBOX_L_BOOKMARKS : IMG_HELP_TOOLBOX_BOOKMARKS ) )
2138 aToolBox.SetItemImage( TBI_SEARCHDIALOG,
2139 Image( SfxResId( bLarge ? IMG_HELP_TOOLBOX_L_SEARCHDIALOG : IMG_HELP_TOOLBOX_SEARCHDIALOG ) )
2142 Size aSize = aToolBox.CalcWindowSizePixel();
2143 aSize.Height() += TOOLBOX_OFFSET;
2144 aToolBox.SetPosSizePixel( Point( 0, TOOLBOX_OFFSET ), aSize );
2146 SvtMiscOptions aMiscOptions;
2147 if ( aMiscOptions.GetToolboxStyle() != aToolBox.GetOutStyle() )
2148 aToolBox.SetOutStyle( aMiscOptions.GetToolboxStyle() );
2151 // -----------------------------------------------------------------------
2153 void SfxHelpTextWindow_Impl::InitOnStartupBox( bool bOnlyText )
2155 sCurrentFactory = SfxHelp::GetCurrentModuleIdentifier();
2157 Reference< XComponentContext > xContext = ::comphelper::getProcessComponentContext();
2158 Reference< XInterface > xConfig;
2159 OUString sPath( PATH_OFFICE_FACTORIES );
2160 sPath += sCurrentFactory;
2161 OUString sKey( KEY_HELP_ON_OPEN );
2163 // Attention: This check boy knows two states:
2164 // 1) Reading of the config key fails with an exception or by getting an empty Any (!) => check box must be hidden
2165 // 2) We read sal_True/sal_False => check box must be shown and enabled/disabled
2167 bool bHideBox = true;
2168 sal_Bool bHelpAtStartup = sal_False;
2171 xConfiguration = ConfigurationHelper::openConfig(
2172 xContext, PACKAGE_SETUP, ConfigurationHelper::E_STANDARD );
2173 if ( xConfiguration.is() )
2175 Any aAny = ConfigurationHelper::readRelativeKey( xConfiguration, sPath, sKey );
2176 if (aAny >>= bHelpAtStartup)
2177 bHideBox = false;
2180 catch( Exception& )
2182 bHideBox = true;
2185 if ( bHideBox )
2186 aOnStartupCB.Hide();
2187 else
2189 // detect module name
2190 String sModuleName;
2192 if ( xConfiguration.is() )
2194 OUString sTemp;
2195 sKey = KEY_UI_NAME;
2198 Any aAny = ConfigurationHelper::readRelativeKey( xConfiguration, sPath, sKey );
2199 aAny >>= sTemp;
2201 catch( Exception& )
2203 SAL_WARN( "sfx2.appl", "SfxHelpTextWindow_Impl::InitOnStartupBox(): unexpected exception" );
2205 sModuleName = String( sTemp );
2208 if ( sModuleName.Len() > 0 )
2210 // set module name in checkbox text
2211 String sText( aOnStartupText );
2212 sText.SearchAndReplace( OUString("%MODULENAME"), sModuleName );
2213 aOnStartupCB.SetText( sText );
2214 // and show it
2215 aOnStartupCB.Show();
2216 // set check state
2217 aOnStartupCB.Check( bHelpAtStartup );
2218 aOnStartupCB.SaveValue();
2220 // calculate and set optimal width of the onstartup checkbox
2221 String sCBText( "XXX" );
2222 sCBText += aOnStartupCB.GetText();
2223 long nTextWidth = aOnStartupCB.GetTextWidth( sCBText );
2224 Size aSize = aOnStartupCB.GetSizePixel();
2225 aSize.Width() = nTextWidth;
2226 aOnStartupCB.SetSizePixel( aSize );
2227 SetOnStartupBoxPosition();
2230 if ( !bOnlyText )
2232 // set position of the checkbox
2233 Size a3Size = LogicToPixel( Size( 3, 3 ), MAP_APPFONT );
2234 Size aTBSize = aToolBox.GetSizePixel();
2235 Size aCBSize = aOnStartupCB.GetSizePixel();
2236 Point aPnt = aToolBox.GetPosPixel();
2237 aPnt.X() += aTBSize.Width() + a3Size.Width();
2238 aPnt.Y() += ( ( aTBSize.Height() - aCBSize.Height() ) / 2 );
2239 aOnStartupCB.SetPosPixel( aPnt );
2240 nMinPos = aPnt.X();
2245 // -----------------------------------------------------------------------
2247 void SfxHelpTextWindow_Impl::SetOnStartupBoxPosition()
2249 long nX = std::max( GetOutputSizePixel().Width() - aOnStartupCB.GetSizePixel().Width(), nMinPos );
2250 Point aPos = aOnStartupCB.GetPosPixel();
2251 aPos.X() = nX;
2252 aOnStartupCB.SetPosPixel( aPos );
2255 // -----------------------------------------------------------------------
2257 Reference< XBreakIterator > SfxHelpTextWindow_Impl::GetBreakIterator()
2259 if ( !xBreakIterator.is() )
2260 xBreakIterator = vcl::unohelper::CreateBreakIterator();
2261 DBG_ASSERT( xBreakIterator.is(), "Could not create BreakIterator" );
2262 return xBreakIterator;
2265 // -----------------------------------------------------------------------
2267 Reference< XTextRange > SfxHelpTextWindow_Impl::getCursor() const
2269 // return the current cursor
2270 Reference< XTextRange > xCursor;
2274 Reference < XSelectionSupplier > xSelSup( xFrame->getController(), UNO_QUERY );
2275 if ( xSelSup.is() )
2277 Any aAny = xSelSup->getSelection();
2278 Reference < XIndexAccess > xSelection;
2279 if ( aAny >>= xSelection )
2281 if ( xSelection->getCount() == 1 )
2283 aAny = xSelection->getByIndex(0);
2284 aAny >>= xCursor;
2289 catch( Exception& )
2291 OSL_FAIL( "SfxHelpTextWindow_Impl::getCursor(): unexpected exception" );
2294 return xCursor;
2297 // -----------------------------------------------------------------------
2299 bool SfxHelpTextWindow_Impl::isHandledKey( const KeyCode& _rKeyCode )
2301 bool bRet = false;
2302 sal_uInt16 nCode = _rKeyCode.GetCode();
2304 // the keys <CTRL><A> (select all), <CTRL><C> (copy),
2305 // <CTRL><F> (find), <CTRL><P> (print) and <CTRL><W> (close window)
2306 // were handled in help
2307 if ( _rKeyCode.IsMod1() &&
2308 ( KEY_A == nCode || KEY_C == nCode || KEY_F == nCode || KEY_P == nCode || KEY_W == nCode ) )
2310 if ( KEY_F == nCode )
2311 DoSearch();
2312 else
2313 bRet = true;
2316 return bRet;
2319 // -----------------------------------------------------------------------
2321 IMPL_LINK_NOARG(SfxHelpTextWindow_Impl, SelectHdl)
2325 // select the words, which are equal to the search text of the search page
2326 Reference < XController > xController = xFrame->getController();
2327 if ( xController.is() )
2329 // get document
2330 Reference < XSearchable > xSearchable( xController->getModel(), UNO_QUERY );
2331 if ( xSearchable.is() )
2333 // create descriptor, set string and find all words
2334 Reference < XSearchDescriptor > xSrchDesc = xSearchable->createSearchDescriptor();
2335 Reference < XPropertySet > xPropSet( xSrchDesc, UNO_QUERY );
2336 xPropSet->setPropertyValue( "SearchRegularExpression",
2337 makeAny( sal_Bool( sal_True ) ) );
2338 if ( bIsFullWordSearch )
2339 xPropSet->setPropertyValue( "SearchWords",
2340 makeAny( sal_Bool( sal_True ) ) );
2342 String sSearchString = sfx2::PrepareSearchString( aSearchText, GetBreakIterator(), false );
2343 xSrchDesc->setSearchString( sSearchString );
2344 Reference< XIndexAccess > xSelection = xSearchable->findAll( xSrchDesc );
2346 // then select all found words
2347 Reference < XSelectionSupplier > xSelectionSup( xController, UNO_QUERY );
2348 if ( xSelectionSup.is() )
2350 Any aAny;
2351 aAny <<= xSelection;
2352 xSelectionSup->select( aAny );
2357 catch( Exception& )
2359 OSL_FAIL( "SfxHelpTextWindow_Impl::SelectHdl(): unexpected exception" );
2362 return 1;
2365 // -----------------------------------------------------------------------
2367 IMPL_LINK( SfxHelpTextWindow_Impl, NotifyHdl, SvtMiscOptions*, pOptions )
2369 (void)pOptions; // unused variable
2370 InitToolBoxImages();
2371 Resize();
2372 aToolBox.Invalidate();
2373 return 0;
2376 // -----------------------------------------------------------------------
2378 IMPL_LINK( SfxHelpTextWindow_Impl, FindHdl, sfx2::SearchDialog*, pDlg )
2380 bool bWrapAround = ( NULL == pDlg );
2381 if ( bWrapAround )
2382 pDlg = pSrchDlg;
2383 DBG_ASSERT( pDlg, "invalid search dialog" );
2384 String sSearchText = pDlg->GetSearchText();
2387 // select the words, which are equal to the search text of the search page
2388 Reference < XController > xController = xFrame->getController();
2389 if ( xController.is() )
2391 // get document
2392 Reference < XSearchable > xSearchable( xController->getModel(), UNO_QUERY );
2393 if ( xSearchable.is() )
2395 // create descriptor, set string and find all words
2396 Reference < XSearchDescriptor > xSrchDesc = xSearchable->createSearchDescriptor();
2397 Reference < XPropertySet > xPropSet( xSrchDesc, UNO_QUERY );
2398 xPropSet->setPropertyValue( "SearchWords", makeAny( sal_Bool( pDlg->IsOnlyWholeWords() != false ) ) );
2399 xPropSet->setPropertyValue( "SearchCaseSensitive", makeAny( sal_Bool( pDlg->IsMarchCase() != false ) ) );
2400 xPropSet->setPropertyValue( "SearchBackwards", makeAny( sal_Bool( pDlg->IsSearchBackwards() != false ) ) );
2401 xSrchDesc->setSearchString( sSearchText );
2402 Reference< XInterface > xSelection;
2403 Reference< XTextRange > xCursor = getCursor();
2405 if ( xCursor.is() )
2407 if ( pDlg->IsSearchBackwards() )
2408 xCursor = xCursor->getStart();
2409 xSelection = xSearchable->findNext( xCursor, xSrchDesc );
2411 else
2412 xSelection = xSearchable->findFirst( xSrchDesc );
2414 // then select the found word
2415 if ( xSelection.is() )
2417 Reference < XSelectionSupplier > xSelectionSup( xController, UNO_QUERY );
2418 if ( xSelectionSup.is() )
2420 Any aAny;
2421 aAny <<= xSelection;
2422 xSelectionSup->select( aAny );
2425 else if ( pDlg->IsWrapAround() && !bWrapAround )
2427 Reference < text::XTextViewCursorSupplier > xCrsrSupp( xController, uno::UNO_QUERY );
2428 Reference < text::XTextViewCursor > xTVCrsr( xCrsrSupp->getViewCursor(), uno::UNO_QUERY );
2429 if ( xTVCrsr.is() )
2431 Reference < text::XTextDocument > xDoc( xController->getModel(), uno::UNO_QUERY );
2432 Reference < text::XText > xText = xDoc->getText();
2433 if ( xText.is() )
2435 if ( pDlg->IsSearchBackwards() )
2436 xTVCrsr->gotoRange( xText->getEnd(), sal_False );
2437 else
2438 xTVCrsr->gotoRange( xText->getStart(), sal_False );
2439 FindHdl( NULL );
2443 else
2445 DBG_ASSERT( pSrchDlg, "no search dialog" );
2446 InfoBox aBox( pSrchDlg, SfxResId( RID_INFO_NOSEARCHTEXTFOUND ) );
2447 aBox.Execute();
2448 pSrchDlg->SetFocusOnEdit();
2453 catch( Exception& )
2455 OSL_FAIL( "SfxHelpTextWindow_Impl::SelectHdl(): unexpected exception" );
2458 return 0;
2461 // -----------------------------------------------------------------------
2463 IMPL_LINK( SfxHelpTextWindow_Impl, CloseHdl, sfx2::SearchDialog*, pDlg )
2465 if ( pDlg )
2466 delete pSrchDlg;
2467 pSrchDlg = NULL;
2468 return 0;
2471 // -----------------------------------------------------------------------
2473 IMPL_LINK( SfxHelpTextWindow_Impl, CheckHdl, CheckBox*, pBox )
2475 if ( xConfiguration.is() )
2477 sal_Bool bChecked = pBox->IsChecked();
2478 OUString sPath( PATH_OFFICE_FACTORIES );
2479 sPath += sCurrentFactory;
2482 ConfigurationHelper::writeRelativeKey(
2483 xConfiguration, sPath, KEY_HELP_ON_OPEN, makeAny( bChecked ) );
2484 ConfigurationHelper::flush( xConfiguration );
2486 catch( Exception& )
2488 SAL_WARN( "sfx2.appl", "SfxHelpTextWindow_Impl::CheckHdl(): unexpected exception" );
2492 return 0;
2495 // -----------------------------------------------------------------------
2497 void SfxHelpTextWindow_Impl::Resize()
2499 Size aSize = GetOutputSizePixel();
2500 long nToolBoxHeight = aToolBox.GetSizePixel().Height() + TOOLBOX_OFFSET;
2501 aSize.Height() -= nToolBoxHeight;
2502 pTextWin->SetPosSizePixel( Point( 0, nToolBoxHeight ), aSize );
2503 SetOnStartupBoxPosition();
2506 // -----------------------------------------------------------------------
2508 long SfxHelpTextWindow_Impl::PreNotify( NotifyEvent& rNEvt )
2510 long nDone = 0;
2511 sal_uInt16 nType = rNEvt.GetType();
2512 if ( EVENT_COMMAND == nType && rNEvt.GetCommandEvent() )
2514 const CommandEvent* pCmdEvt = rNEvt.GetCommandEvent();
2515 Window* pCmdWin = rNEvt.GetWindow();
2517 if ( pCmdEvt->GetCommand() == COMMAND_CONTEXTMENU && pCmdWin != this && pCmdWin != &aToolBox )
2519 Point aPos;
2520 if ( pCmdEvt->IsMouseEvent() )
2521 aPos = pCmdEvt->GetMousePosPixel();
2522 else
2523 aPos = Point( pTextWin->GetPosPixel().X() + 20, 20 );
2524 aPos.Y() += pTextWin->GetPosPixel().Y();
2525 PopupMenu aMenu;
2526 if ( bIsIndexOn )
2527 aMenu.InsertItem( TBI_INDEX, aIndexOffText, Image( SfxResId( IMG_HELP_TOOLBOX_INDEX_OFF ) ) );
2528 else
2529 aMenu.InsertItem( TBI_INDEX, aIndexOnText, Image( SfxResId( IMG_HELP_TOOLBOX_INDEX_ON ) ) );
2531 aMenu.SetHelpId( TBI_INDEX, HID_HELP_TOOLBOXITEM_INDEX );
2532 aMenu.InsertSeparator();
2533 aMenu.InsertItem( TBI_BACKWARD,
2534 SfxResId( STR_HELP_BUTTON_PREV ).toString(),
2535 Image( SfxResId( IMG_HELP_TOOLBOX_PREV ) )
2537 aMenu.SetHelpId( TBI_BACKWARD, HID_HELP_TOOLBOXITEM_BACKWARD );
2538 aMenu.EnableItem( TBI_BACKWARD, pHelpWin->HasHistoryPredecessor() );
2539 aMenu.InsertItem( TBI_FORWARD,
2540 SfxResId( STR_HELP_BUTTON_NEXT ).toString(),
2541 Image( SfxResId( IMG_HELP_TOOLBOX_NEXT ) )
2543 aMenu.SetHelpId( TBI_FORWARD, HID_HELP_TOOLBOXITEM_FORWARD );
2544 aMenu.EnableItem( TBI_FORWARD, pHelpWin->HasHistorySuccessor() );
2545 aMenu.InsertItem( TBI_START,
2546 SfxResId( STR_HELP_BUTTON_START ).toString(),
2547 Image( SfxResId( IMG_HELP_TOOLBOX_START ) )
2549 aMenu.SetHelpId( TBI_START, HID_HELP_TOOLBOXITEM_START );
2550 aMenu.InsertSeparator();
2551 aMenu.InsertItem( TBI_PRINT,
2552 SfxResId( STR_HELP_BUTTON_PRINT ).toString(),
2553 Image( SfxResId( IMG_HELP_TOOLBOX_PRINT ) )
2555 aMenu.SetHelpId( TBI_PRINT, HID_HELP_TOOLBOXITEM_PRINT );
2556 aMenu.InsertItem( TBI_BOOKMARKS,
2557 SfxResId( STR_HELP_BUTTON_ADDBOOKMARK ).toString(),
2558 Image( SfxResId( IMG_HELP_TOOLBOX_BOOKMARKS ) )
2560 aMenu.SetHelpId( TBI_BOOKMARKS, HID_HELP_TOOLBOXITEM_BOOKMARKS );
2561 aMenu.InsertItem( TBI_SEARCHDIALOG,
2562 SfxResId( STR_HELP_BUTTON_SEARCHDIALOG ).toString(),
2563 Image( SfxResId( IMG_HELP_TOOLBOX_SEARCHDIALOG ) )
2565 aMenu.SetHelpId( TBI_SEARCHDIALOG, HID_HELP_TOOLBOXITEM_SEARCHDIALOG );
2566 aMenu.InsertSeparator();
2567 aMenu.InsertItem( TBI_SELECTIONMODE, SfxResId( STR_HELP_MENU_TEXT_SELECTION_MODE ).toString() );
2568 aMenu.SetHelpId( TBI_SELECTIONMODE, HID_HELP_TEXT_SELECTION_MODE );
2569 URL aURL;
2570 aURL.Complete = ".uno:SelectTextMode";
2571 PARSE_URL( aURL );
2572 Reference < XDispatch > xDisp = xFrame->queryDispatch( aURL, OUString(), 0 );
2573 if(xDisp.is())
2575 HelpStatusListener_Impl* pStateListener;
2576 Reference<XStatusListener>xStateListener = pStateListener =
2577 new HelpStatusListener_Impl(xDisp, aURL );
2578 FeatureStateEvent rEvent = pStateListener->GetStateEvent();
2579 sal_Bool bCheck = sal_False;
2580 rEvent.State >>= bCheck;
2581 aMenu.CheckItem(TBI_SELECTIONMODE, bCheck);
2583 aMenu.InsertSeparator();
2584 aMenu.InsertItem( TBI_COPY,
2585 SfxResId(STR_HELP_MENU_TEXT_COPY).toString(),
2586 Image( SfxResId( IMG_HELP_TOOLBOX_COPY ) )
2588 aMenu.SetHelpId( TBI_COPY, ".uno:Copy" );
2589 aMenu.EnableItem( TBI_COPY, HasSelection() );
2591 if ( bIsDebug )
2593 aMenu.InsertSeparator();
2594 aMenu.InsertItem( TBI_SOURCEVIEW, SfxResId(STR_HELP_BUTTON_SOURCEVIEW).toString() );
2597 if( SvtMenuOptions().IsEntryHidingEnabled() == sal_False )
2598 aMenu.SetMenuFlags( aMenu.GetMenuFlags() | MENU_FLAG_HIDEDISABLEDENTRIES );
2600 sal_uInt16 nId = aMenu.Execute( this, aPos );
2601 pHelpWin->DoAction( nId );
2602 nDone = 1;
2605 else if ( EVENT_KEYINPUT == nType && rNEvt.GetKeyEvent() )
2607 const KeyEvent* pKEvt = rNEvt.GetKeyEvent();
2608 const KeyCode& rKeyCode = pKEvt->GetKeyCode();
2609 sal_uInt16 nKeyGroup = rKeyCode.GetGroup();
2610 sal_uInt16 nKey = rKeyCode.GetCode();
2611 if ( KEYGROUP_ALPHA == nKeyGroup && !isHandledKey( rKeyCode ) )
2613 // do nothing disables the writer accelerators
2614 nDone = 1;
2616 else if ( rKeyCode.IsMod1() && ( KEY_F4 == nKey || KEY_W == nKey ) )
2618 // <CTRL><F4> or <CTRL><W> -> close top frame
2619 pHelpWin->CloseWindow();
2620 nDone = 1;
2622 else if ( KEY_TAB == nKey && aOnStartupCB.HasChildPathFocus() )
2624 aToolBox.GrabFocus();
2625 nDone = 1;
2629 return nDone ? nDone : Window::PreNotify( rNEvt );
2632 // -----------------------------------------------------------------------
2634 void SfxHelpTextWindow_Impl::GetFocus()
2636 if ( !bIsInClose )
2640 if( xFrame.is() )
2642 Reference< ::com::sun::star::awt::XWindow > xWindow = xFrame->getComponentWindow();
2643 if( xWindow.is() )
2644 xWindow->setFocus();
2647 catch( Exception& )
2649 SAL_WARN( "sfx2.appl", "SfxHelpTextWindow_Impl::GetFocus(): unexpected exception" );
2654 // -----------------------------------------------------------------------
2656 void SfxHelpTextWindow_Impl::DataChanged( const DataChangedEvent& rDCEvt )
2658 Window::DataChanged( rDCEvt );
2660 if ( ( ( rDCEvt.GetType() == DATACHANGED_SETTINGS ) ||
2661 ( rDCEvt.GetType() == DATACHANGED_DISPLAY ) ) &&
2662 ( rDCEvt.GetFlags() & SETTINGS_STYLE ) )
2664 SetBackground( Wallpaper( GetSettings().GetStyleSettings().GetFaceColor() ) );
2665 InitToolBoxImages();
2669 // -----------------------------------------------------------------------
2671 void SfxHelpTextWindow_Impl::ToggleIndex( sal_Bool bOn )
2673 bIsIndexOn = bOn;
2674 if ( bIsIndexOn )
2676 aToolBox.SetItemImage( TBI_INDEX, aIndexOffImage );
2677 aToolBox.SetItemText( TBI_INDEX, aIndexOffText );
2679 else
2681 aToolBox.SetItemImage( TBI_INDEX, aIndexOnImage );
2682 aToolBox.SetItemText( TBI_INDEX, aIndexOnText );
2686 // -----------------------------------------------------------------------
2688 void SfxHelpTextWindow_Impl::SelectSearchText( const String& rSearchText, sal_Bool _bIsFullWordSearch )
2690 aSearchText = rSearchText;
2691 bIsFullWordSearch = _bIsFullWordSearch;
2692 aSelectTimer.Start();
2695 // -----------------------------------------------------------------------
2697 void SfxHelpTextWindow_Impl::SetPageStyleHeaderOff() const
2699 #ifdef DBG_UTIL
2700 sal_Bool bSetOff = sal_False;
2701 #endif
2702 // set off the pagestyle header to prevent print output of the help URL
2705 Reference < XController > xController = xFrame->getController();
2706 Reference < XSelectionSupplier > xSelSup( xController, UNO_QUERY );
2707 if ( xSelSup.is() )
2709 Reference < XIndexAccess > xSelection;
2710 if ( xSelSup->getSelection() >>= xSelection )
2712 Reference < XTextRange > xRange;
2713 if ( xSelection->getByIndex(0) >>= xRange )
2715 Reference < XText > xText = xRange->getText();
2716 Reference < XPropertySet > xProps( xText->createTextCursorByRange( xRange ), UNO_QUERY );
2717 OUString sStyleName;
2718 if ( xProps->getPropertyValue( "PageStyleName" ) >>= sStyleName )
2720 Reference < XStyleFamiliesSupplier > xStyles( xController->getModel(), UNO_QUERY );
2721 Reference < XNameContainer > xContainer;
2722 if ( xStyles->getStyleFamilies()->getByName( "PageStyles" )
2723 >>= xContainer )
2725 Reference < XStyle > xStyle;
2726 if ( xContainer->getByName( sStyleName ) >>= xStyle )
2728 Reference < XPropertySet > xPropSet( xStyle, UNO_QUERY );
2729 xPropSet->setPropertyValue( "HeaderIsOn",
2730 makeAny( sal_Bool( sal_False ) ) );
2732 Reference< XModifiable > xReset(xStyles, UNO_QUERY);
2733 xReset->setModified(sal_False);
2734 #ifdef DBG_UTIL
2735 bSetOff = sal_True;
2736 #endif
2744 catch( Exception& )
2746 SAL_WARN( "sfx2.appl", "SfxHelpTextWindow_Impl::SetPageStyleHeaderOff(): unexpected exception" );
2749 #ifdef DBG_UTIL
2750 if ( !bSetOff )
2752 SAL_WARN( "sfx2.appl", "SfxHelpTextWindow_Impl::SetPageStyleHeaderOff(): set off failed" );
2754 #endif
2757 // -----------------------------------------------------------------------
2759 void SfxHelpTextWindow_Impl::CloseFrame()
2761 bIsInClose = sal_True;
2764 ::com::sun::star::uno::Reference< ::com::sun::star::util::XCloseable > xCloseable ( xFrame, ::com::sun::star::uno::UNO_QUERY );
2765 if (xCloseable.is())
2766 xCloseable->close(sal_True);
2768 catch( ::com::sun::star::util::CloseVetoException& )
2773 // -----------------------------------------------------------------------
2775 void SfxHelpTextWindow_Impl::DoSearch()
2777 if ( !pSrchDlg )
2779 // create the search dialog
2780 pSrchDlg = new sfx2::SearchDialog( pTextWin, "HelpSearchDialog" );
2781 // set handler
2782 pSrchDlg->SetFindHdl( LINK( this, SfxHelpTextWindow_Impl, FindHdl ) );
2783 pSrchDlg->SetCloseHdl( LINK( this, SfxHelpTextWindow_Impl, CloseHdl ) );
2784 // get selected text of the help page to set it as the search text
2785 Reference< XTextRange > xCursor = getCursor();
2786 if ( xCursor.is() )
2788 String sText = xCursor->getString();
2789 if ( sText.Len() > 0 )
2790 pSrchDlg->SetSearchText( sText );
2792 pSrchDlg->Show();
2796 // class SfxHelpWindow_Impl ----------------------------------------------
2798 void SfxHelpWindow_Impl::Resize()
2800 SplitWindow::Resize();
2801 InitSizes();
2804 // -----------------------------------------------------------------------
2806 void SfxHelpWindow_Impl::Split()
2808 static long nMinSplitSize = 5;
2809 static long nMaxSplitSize = 99 - nMinSplitSize;
2811 SplitWindow::Split();
2813 nIndexSize = GetItemSize( INDEXWIN_ID );
2814 nTextSize = GetItemSize( TEXTWIN_ID );
2816 sal_Bool bMod = sal_False;
2817 if( nIndexSize < nMinSplitSize )
2819 nIndexSize = nMinSplitSize;
2820 nTextSize = nMaxSplitSize;
2822 bMod = sal_True;
2824 else if( nTextSize < nMinSplitSize )
2826 nTextSize = nMinSplitSize;
2827 nIndexSize = nMaxSplitSize;
2829 bMod = sal_True;
2831 else
2832 bMod = sal_False;
2834 if( bMod )
2836 SetItemSize( INDEXWIN_ID, nIndexSize );
2837 SetItemSize( TEXTWIN_ID, nTextSize );
2840 InitSizes();
2843 // -----------------------------------------------------------------------
2845 void SfxHelpWindow_Impl::GetFocus()
2847 pTextWin->GrabFocus();
2850 // -----------------------------------------------------------------------
2852 void SfxHelpWindow_Impl::MakeLayout()
2854 if ( nHeight > 0 && xWindow.is() )
2856 Window* pScreenWin = VCLUnoHelper::GetWindow( xWindow );
2858 /* #i55528#
2859 Hide() / Show() will produce starnge effects.
2860 The returned size (used later to be written back into the configuration)
2861 isnt the right after a resize during the window is hidden.
2862 If this resize is done if the window is visible evyrthing works as aspected.
2863 Some VCL-patches could not solve this problem so I've established the
2864 workaround: resize the help window if it's visible .-)
2867 ::com::sun::star::awt::Rectangle aRect = xWindow->getPosSize();
2868 sal_Int32 nOldWidth = bIndex ? nCollapseWidth : nExpandWidth;
2869 sal_Int32 nWidth = bIndex ? nExpandWidth : nCollapseWidth;
2870 xWindow->setPosSize( aRect.X, aRect.Y, nWidth, nHeight, ::com::sun::star::awt::PosSize::SIZE );
2872 if ( aRect.Width > 0 && aRect.Height > 0 )
2874 Rectangle aScreenRect = pScreenWin->GetClientWindowExtentsRelative( NULL );
2875 Point aNewPos = aScreenRect.TopLeft();
2876 sal_Int32 nDiffWidth = nOldWidth - nWidth;
2877 aNewPos.X() += nDiffWidth;
2878 pScreenWin->SetPosPixel( aNewPos );
2880 else if ( aWinPos.X() > 0 && aWinPos.Y() > 0 )
2881 pScreenWin->SetPosPixel( aWinPos );
2884 Clear();
2886 if ( bIndex )
2888 pIndexWin->Show();
2889 InsertItem( COLSET_ID, 100, SPLITWINDOW_APPEND, SPLITSET_ID, SWIB_PERCENTSIZE | SWIB_COLSET );
2890 InsertItem( INDEXWIN_ID, pIndexWin, nIndexSize, SPLITWINDOW_APPEND, COLSET_ID, SWIB_PERCENTSIZE );
2891 InsertItem( TEXTWIN_ID, pTextWin, nTextSize, SPLITWINDOW_APPEND, COLSET_ID, SWIB_PERCENTSIZE );
2893 else
2895 pIndexWin->Hide();
2896 InsertItem( COLSET_ID, 100, SPLITWINDOW_APPEND, SPLITSET_ID, SWIB_PERCENTSIZE | SWIB_COLSET );
2897 InsertItem( TEXTWIN_ID, pTextWin, 100, SPLITWINDOW_APPEND, 1, SWIB_PERCENTSIZE );
2901 // -----------------------------------------------------------------------
2903 void SfxHelpWindow_Impl::InitSizes()
2905 if ( xWindow.is() )
2907 ::com::sun::star::awt::Rectangle aRect = xWindow->getPosSize();
2908 nHeight = aRect.Height;
2910 if ( bIndex )
2912 nExpandWidth = aRect.Width;
2913 nCollapseWidth = nExpandWidth * nTextSize / 100;
2915 else
2917 nCollapseWidth = aRect.Width;
2918 nExpandWidth = nCollapseWidth * 100 / nTextSize;
2923 // -----------------------------------------------------------------------
2925 void SfxHelpWindow_Impl::LoadConfig()
2927 SvtViewOptions aViewOpt( E_WINDOW, CONFIGNAME_HELPWIN );
2928 if ( aViewOpt.Exists() )
2930 bIndex = aViewOpt.IsVisible();
2931 String aUserData;
2932 Any aUserItem = aViewOpt.GetUserItem( USERITEM_NAME );
2933 OUString aTemp;
2934 if ( aUserItem >>= aTemp )
2936 aUserData = String( aTemp );
2937 DBG_ASSERT( comphelper::string::getTokenCount(aUserData, ';') == 6, "invalid user data" );
2938 sal_Int32 nIdx = 0;
2939 nIndexSize = aUserData.GetToken( 0, ';', nIdx ).ToInt32();
2940 nTextSize = aUserData.GetToken( 0, ';', nIdx ).ToInt32();
2941 sal_Int32 nWidth = aUserData.GetToken( 0, ';', nIdx ).ToInt32();
2942 nHeight = aUserData.GetToken( 0, ';', nIdx ).ToInt32();
2943 aWinPos.X() = aUserData.GetToken( 0, ';', nIdx ).ToInt32();
2944 aWinPos.Y() = aUserData.GetToken( 0, ';', nIdx ).ToInt32();
2945 if ( bIndex )
2947 nExpandWidth = nWidth;
2948 nCollapseWidth = nExpandWidth * nTextSize / 100;
2950 else
2952 nCollapseWidth = nWidth;
2953 nExpandWidth = nCollapseWidth * 100 / nTextSize;
2957 pTextWin->ToggleIndex( bIndex );
2961 // -----------------------------------------------------------------------
2963 void SfxHelpWindow_Impl::SaveConfig()
2965 SvtViewOptions aViewOpt( E_WINDOW, CONFIGNAME_HELPWIN );
2966 sal_Int32 nW = 0, nH = 0;
2968 if ( xWindow.is() )
2970 ::com::sun::star::awt::Rectangle aRect = xWindow->getPosSize();
2971 nW = aRect.Width;
2972 nH = aRect.Height;
2975 aViewOpt.SetVisible( bIndex );
2976 String aUserData = OUString::number( nIndexSize );
2977 aUserData += ';';
2978 aUserData += OUString::number( nTextSize );
2979 aUserData += ';';
2980 aUserData += OUString::number( nW );
2981 aUserData += ';';
2982 aUserData += OUString::number( nH );
2984 Window* pScreenWin = VCLUnoHelper::GetWindow( xWindow );
2985 aWinPos = pScreenWin->GetWindowExtentsRelative( NULL ).TopLeft();
2986 aUserData += ';';
2987 aUserData += OUString::number( aWinPos.X() );
2988 aUserData += ';';
2989 aUserData += OUString::number( aWinPos.Y() );
2991 aViewOpt.SetUserItem( USERITEM_NAME, makeAny( OUString( aUserData ) ) );
2994 // -----------------------------------------------------------------------
2996 void SfxHelpWindow_Impl::ShowStartPage()
2998 OUString sHelpURL = SfxHelpWindow_Impl::buildHelpURL(pIndexWin->GetFactory(),
2999 "/start",
3000 OUString(),
3001 sal_True);
3002 loadHelpContent(sHelpURL);
3005 // -----------------------------------------------------------------------
3007 IMPL_LINK( SfxHelpWindow_Impl, SelectHdl, ToolBox* , pToolBox )
3009 if ( pToolBox )
3011 bGrabFocusToToolBox = pToolBox->HasChildPathFocus();
3012 DoAction( pToolBox->GetCurItemId() );
3015 return 1;
3018 //-------------------------------------------------------------------------
3020 IMPL_LINK_NOARG(SfxHelpWindow_Impl, OpenHdl)
3022 pIndexWin->SelectExecutableEntry();
3023 String aEntry = pIndexWin->GetSelectEntry();
3025 if ( aEntry.Len() < 1 )
3026 return 0;
3028 OUString sHelpURL;
3030 bool bComplete = OUString(aEntry).toAsciiLowerCase().match(OUString("vnd.sun.star.help"),0);
3032 if (bComplete)
3033 sHelpURL = OUString(aEntry);
3034 else
3036 String aId;
3037 String aAnchor = OUString('#');
3038 if ( comphelper::string::getTokenCount(aEntry, '#') == 2 )
3040 aId = aEntry.GetToken( 0, '#' );
3041 aAnchor += aEntry.GetToken( 1, '#' );
3043 else
3044 aId = aEntry;
3046 aEntry = '/';
3047 aEntry += aId;
3049 sHelpURL = SfxHelpWindow_Impl::buildHelpURL(pIndexWin->GetFactory(),
3050 aEntry,
3051 aAnchor,
3052 sal_True);
3055 loadHelpContent(sHelpURL);
3057 return 0;
3060 //-------------------------------------------------------------------------
3062 IMPL_LINK( SfxHelpWindow_Impl, SelectFactoryHdl, SfxHelpIndexWindow_Impl* , pWin )
3064 if ( sTitle.isEmpty() )
3065 sTitle = GetParent()->GetText();
3067 OUString aNewTitle = sTitle + " - " + pIndexWin->GetActiveFactoryTitle();
3069 Reference< XTitle > xTitle(xFrame, UNO_QUERY);
3070 if (xTitle.is ())
3071 xTitle->setTitle (aNewTitle);
3073 if ( pWin )
3074 ShowStartPage();
3075 pIndexWin->ClearSearchPage();
3077 return 0;
3080 // -----------------------------------------------------------------------
3082 IMPL_LINK( SfxHelpWindow_Impl, ChangeHdl, HelpListener_Impl*, pListener )
3084 SetFactory( pListener->GetFactory() );
3085 return 0;
3088 // -----------------------------------------------------------------------
3090 void SfxHelpWindow_Impl::openDone(const OUString& sURL ,
3091 sal_Bool bSuccess)
3093 INetURLObject aObj( sURL );
3094 if ( aObj.GetProtocol() == INET_PROT_VND_SUN_STAR_HELP )
3095 SetFactory( aObj.GetHost() );
3096 if ( IsWait() )
3097 LeaveWait();
3098 if ( bGrabFocusToToolBox )
3100 pTextWin->GetToolBox().GrabFocus();
3101 bGrabFocusToToolBox = sal_False;
3103 else
3104 pIndexWin->GrabFocusBack();
3105 if ( bSuccess )
3107 // set some view settings: "prevent help tips" and "helpid == 68245"
3110 Reference < XController > xController = pTextWin->getFrame()->getController();
3111 if ( xController.is() )
3113 Reference < XViewSettingsSupplier > xSettings( xController, UNO_QUERY );
3114 Reference < XPropertySet > xViewProps = xSettings->getViewSettings();
3115 Reference< XPropertySetInfo > xInfo = xViewProps->getPropertySetInfo();
3116 Any aBoolAny = makeAny( sal_Bool( sal_True ) );
3117 xViewProps->setPropertyValue( "ShowContentTips", makeAny( sal_Bool( sal_False ) ) );
3118 xViewProps->setPropertyValue( "ShowGraphics", aBoolAny );
3119 xViewProps->setPropertyValue( "ShowTables", aBoolAny );
3120 xViewProps->setPropertyValue( "HelpURL", makeAny( OUString("HID:SFX2_HID_HELP_ONHELP") ) );
3121 OUString sProperty( "IsExecuteHyperlinks" );
3122 if ( xInfo->hasPropertyByName( sProperty ) )
3123 xViewProps->setPropertyValue( sProperty, aBoolAny );
3124 xController->restoreViewData(pHelpInterceptor->GetViewData());
3127 catch( Exception& )
3129 OSL_FAIL( "SfxHelpWindow_Impl::OpenDoneHdl(): unexpected exception" );
3132 // When the SearchPage opens the help doc, then select all words, which are equal to its text
3133 String sSearchText = comphelper::string::strip(pIndexWin->GetSearchText(), ' ');
3134 if ( sSearchText.Len() > 0 )
3135 pTextWin->SelectSearchText( sSearchText, pIndexWin->IsFullWordSearch() );
3137 // no page style header -> this prevents a print output of the URL
3138 pTextWin->SetPageStyleHeaderOff();
3142 // -----------------------------------------------------------------------
3144 SfxHelpWindow_Impl::SfxHelpWindow_Impl(
3145 const ::com::sun::star::uno::Reference < ::com::sun::star::frame::XFrame2 >& rFrame,
3146 Window* pParent, WinBits ) :
3148 SplitWindow( pParent, WB_3DLOOK | WB_NOSPLITDRAW ),
3150 xFrame ( rFrame ),
3151 pIndexWin ( NULL ),
3152 pTextWin ( NULL ),
3153 pHelpInterceptor ( new HelpInterceptor_Impl() ),
3154 pHelpListener ( new HelpListener_Impl( pHelpInterceptor ) ),
3155 nExpandWidth ( 0 ),
3156 nCollapseWidth ( 0 ),
3157 nHeight ( 0 ),
3158 nIndexSize ( 40 ),
3159 nTextSize ( 60 ),
3160 bIndex ( sal_True ),
3161 bGrabFocusToToolBox ( sal_False ),
3162 aWinPos ( 0, 0 ),
3163 sTitle ( pParent->GetText() )
3165 SetHelpId( HID_HELP_WINDOW );
3166 SetStyle( GetStyle() | WB_DIALOGCONTROL );
3168 pHelpInterceptor->InitWaiter( this );
3169 pIndexWin = new SfxHelpIndexWindow_Impl( this );
3170 pIndexWin->SetDoubleClickHdl( LINK( this, SfxHelpWindow_Impl, OpenHdl ) );
3171 pIndexWin->SetSelectFactoryHdl( LINK( this, SfxHelpWindow_Impl, SelectFactoryHdl ) );
3172 pIndexWin->Show();
3173 pTextWin = new SfxHelpTextWindow_Impl( this );
3174 Reference < XFrames > xFrames = rFrame->getFrames();
3175 xFrames->append( Reference<XFrame>(pTextWin->getFrame(), UNO_QUERY_THROW) );
3176 pTextWin->SetSelectHdl( LINK( this, SfxHelpWindow_Impl, SelectHdl ) );
3177 pTextWin->Show();
3178 pHelpInterceptor->setInterception( Reference<XFrame>(pTextWin->getFrame(), UNO_QUERY_THROW) );
3179 pHelpListener->SetChangeHdl( LINK( this, SfxHelpWindow_Impl, ChangeHdl ) );
3180 LoadConfig();
3183 // -----------------------------------------------------------------------
3185 SfxHelpWindow_Impl::~SfxHelpWindow_Impl()
3187 SaveConfig();
3188 Window* pDel = pIndexWin;
3189 pIndexWin = NULL;
3190 delete pDel;
3192 pTextWin->CloseFrame();
3193 delete pTextWin;
3196 // -----------------------------------------------------------------------
3198 long SfxHelpWindow_Impl::PreNotify( NotifyEvent& rNEvt )
3200 sal_Bool bHandled = sal_False;
3201 if ( rNEvt.GetType() == EVENT_KEYINPUT )
3203 // Backward == <ALT><LEFT> or <BACKSPACE> Forward == <ALT><RIGHT>
3204 const KeyCode& rKeyCode = rNEvt.GetKeyEvent()->GetKeyCode();
3205 sal_uInt16 nKey = rKeyCode.GetCode();
3206 if ( ( rKeyCode.IsMod2() && ( KEY_LEFT == nKey || KEY_RIGHT == nKey ) ) ||
3207 ( !rKeyCode.GetModifier() && KEY_BACKSPACE == nKey && !pIndexWin->HasFocusOnEdit() ) )
3209 DoAction( rKeyCode.GetCode() == KEY_RIGHT ? TBI_FORWARD : TBI_BACKWARD );
3210 bHandled = sal_True;
3212 else if ( rKeyCode.IsMod1() && ( KEY_F4 == nKey || KEY_W == nKey ) )
3214 // <CTRL><F4> or <CTRL><W> -> close top frame
3215 CloseWindow();
3216 bHandled = sal_True;
3219 return bHandled ? 1 : Window::PreNotify( rNEvt );
3222 // -----------------------------------------------------------------------
3224 void SfxHelpWindow_Impl::setContainerWindow( Reference < ::com::sun::star::awt::XWindow > xWin )
3226 xWindow = xWin;
3227 MakeLayout();
3230 // -----------------------------------------------------------------------
3232 void SfxHelpWindow_Impl::SetFactory( const String& rFactory )
3234 pIndexWin->SetFactory( rFactory, sal_True );
3237 // -----------------------------------------------------------------------
3239 void SfxHelpWindow_Impl::SetHelpURL( const String& rURL )
3241 INetURLObject aObj( rURL );
3242 if ( aObj.GetProtocol() == INET_PROT_VND_SUN_STAR_HELP )
3243 SetFactory( aObj.GetHost() );
3246 // -----------------------------------------------------------------------
3248 void SfxHelpWindow_Impl::DoAction( sal_uInt16 nActionId )
3250 switch ( nActionId )
3252 case TBI_INDEX :
3254 bIndex = !bIndex;
3255 MakeLayout();
3256 pTextWin->ToggleIndex( bIndex );
3257 break;
3260 case TBI_START :
3262 ShowStartPage();
3263 break;
3266 case TBI_BACKWARD :
3267 case TBI_FORWARD :
3269 URL aURL;
3270 aURL.Complete = ".uno:Backward";
3271 if ( TBI_FORWARD == nActionId )
3272 aURL.Complete = ".uno:Forward";
3273 PARSE_URL( aURL );
3274 pHelpInterceptor->dispatch( aURL, Sequence < PropertyValue >() );
3275 break;
3278 case TBI_SEARCHDIALOG :
3280 pTextWin->DoSearch();
3281 break;
3284 case TBI_PRINT :
3285 case TBI_SOURCEVIEW :
3286 case TBI_COPY :
3287 case TBI_SELECTIONMODE:
3289 Reference < XDispatchProvider > xProv( pTextWin->getFrame(), UNO_QUERY );
3290 if ( xProv.is() )
3292 URL aURL;
3293 if ( TBI_PRINT == nActionId )
3294 aURL.Complete = ".uno:Print";
3295 else if ( TBI_SOURCEVIEW == nActionId )
3296 aURL.Complete = ".uno:SourceView";
3297 else if ( TBI_COPY == nActionId )
3298 aURL.Complete = ".uno:Copy";
3299 else if ( TBI_SELECTIONMODE == nActionId )
3300 aURL.Complete = ".uno:SelectTextMode";
3301 else
3302 aURL.Complete = ".uno:SearchDialog";
3303 PARSE_URL( aURL );
3304 Reference < XDispatch > xDisp = xProv->queryDispatch( aURL, String(), 0 );
3305 if ( xDisp.is() )
3306 xDisp->dispatch( aURL, Sequence < PropertyValue >() );
3308 break;
3311 case TBI_BOOKMARKS :
3313 String aURL = pHelpInterceptor->GetCurrentURL();
3314 if ( aURL.Len() > 0 )
3318 Content aCnt( aURL, Reference< ::com::sun::star::ucb::XCommandEnvironment >(), comphelper::getProcessComponentContext() );
3319 ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > xInfo = aCnt.getProperties();
3320 if ( xInfo->hasPropertyByName( PROPERTY_TITLE ) )
3322 ::com::sun::star::uno::Any aAny = aCnt.getPropertyValue( PROPERTY_TITLE );
3323 OUString aValue;
3324 if ( aAny >>= aValue )
3326 String aTitle( aValue );
3327 SfxAddHelpBookmarkDialog_Impl aDlg( this, sal_False );
3328 aDlg.SetTitle( aTitle );
3329 if ( aDlg.Execute() == RET_OK )
3331 aTitle = aDlg.GetTitle();
3332 pIndexWin->AddBookmarks( aTitle, aURL );
3337 catch( Exception& )
3339 OSL_FAIL( "SfxHelpWindow_Impl::DoAction(): unexpected exception" );
3342 break;
3347 // -----------------------------------------------------------------------
3349 void SfxHelpWindow_Impl::CloseWindow()
3353 // search for top frame
3354 Reference< XFramesSupplier > xCreator = getTextFrame()->getCreator();
3355 while ( xCreator.is() && !xCreator->isTop() )
3357 xCreator = xCreator->getCreator();
3360 // when found, close it
3361 if ( xCreator.is() && xCreator->isTop() )
3363 Reference < XCloseable > xCloser( xCreator, UNO_QUERY );
3364 if ( xCloser.is() )
3365 xCloser->close( sal_False );
3368 catch( Exception& )
3370 SAL_WARN( "sfx2.appl", "SfxHelpWindow_Impl::CloseWindow(): caught an exception" );
3374 // -----------------------------------------------------------------------
3376 void SfxHelpWindow_Impl::UpdateToolbox()
3378 pTextWin->GetToolBox().EnableItem( TBI_BACKWARD, pHelpInterceptor->HasHistoryPred() );
3379 pTextWin->GetToolBox().EnableItem( TBI_FORWARD, pHelpInterceptor->HasHistorySucc() );
3382 // -----------------------------------------------------------------------
3384 sal_Bool SfxHelpWindow_Impl::HasHistoryPredecessor() const
3386 return pHelpInterceptor->HasHistoryPred();
3389 // -----------------------------------------------------------------------
3391 sal_Bool SfxHelpWindow_Impl::HasHistorySuccessor() const
3393 return pHelpInterceptor->HasHistorySucc();
3396 // class SfxAddHelpBookmarkDialog_Impl -----------------------------------
3398 SfxAddHelpBookmarkDialog_Impl::SfxAddHelpBookmarkDialog_Impl( Window* pParent, sal_Bool bRename ) :
3400 ModalDialog( pParent, SfxResId( DLG_HELP_ADDBOOKMARK ) ),
3402 aTitleFT ( this, SfxResId( FT_BOOKMARK_TITLE ) ),
3403 aTitleED ( this, SfxResId( ED_BOOKMARK_TITLE ) ),
3404 aOKBtn ( this, SfxResId( PB_BOOKMARK_OK ) ),
3405 aEscBtn ( this, SfxResId( PB_BOOKMARK_CANCEL ) ),
3406 aHelpBtn ( this, SfxResId( PB_BOOKMARK_HELP ) )
3409 if ( bRename )
3410 SetText( SfxResId(STR_BOOKMARK_RENAME).toString() );
3412 FreeResource();
3415 // -----------------------------------------------------------------------
3417 SfxAddHelpBookmarkDialog_Impl::~SfxAddHelpBookmarkDialog_Impl()
3421 // -----------------------------------------------------------------------
3423 void SfxAddHelpBookmarkDialog_Impl::SetTitle( const String& rTitle )
3425 aTitleED.SetText( rTitle );
3426 aTitleED.SetSelection( Selection( 0, rTitle.Len() ) );
3429 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */