Branch libreoffice-5-0-4
[LibreOffice.git] / sfx2 / source / appl / newhelp.cxx
blob33b717d691ddd545399e6b5bac1407978940c080
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 <rtl/ustrbuf.hxx>
40 #include <comphelper/configurationhelper.hxx>
41 #include <comphelper/processfactory.hxx>
42 #include <comphelper/string.hxx>
43 #include <toolkit/helper/vclunohelper.hxx>
44 #include <com/sun/star/awt/PosSize.hpp>
45 #include <com/sun/star/awt/XWindow.hpp>
46 #include <com/sun/star/beans/Property.hpp>
47 #include <com/sun/star/beans/PropertyValue.hpp>
48 #include <com/sun/star/beans/XPropertySetInfo.hpp>
49 #include <com/sun/star/container/XIndexAccess.hpp>
50 #include <com/sun/star/frame/XComponentLoader.hpp>
51 #include <com/sun/star/frame/XTitle.hpp>
52 #include <com/sun/star/frame/XLayoutManager.hpp>
53 #include <com/sun/star/frame/DispatchResultState.hpp>
54 #include <com/sun/star/frame/XController.hpp>
55 #include <com/sun/star/frame/XDispatch.hpp>
56 #include <com/sun/star/frame/XDispatchProvider.hpp>
57 #include <com/sun/star/frame/XDispatchProviderInterception.hpp>
58 #include <com/sun/star/frame/Frame.hpp>
59 #include <com/sun/star/i18n/XBreakIterator.hpp>
60 #include <com/sun/star/i18n/WordType.hpp>
61 #include <com/sun/star/lang/XComponent.hpp>
62 #include <com/sun/star/lang/DisposedException.hpp>
63 #include <com/sun/star/style/XStyle.hpp>
64 #include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
65 #include <com/sun/star/text/XText.hpp>
66 #include <com/sun/star/text/XTextCursor.hpp>
67 #include <com/sun/star/text/XTextDocument.hpp>
68 #include <com/sun/star/text/XTextRange.hpp>
69 #include <com/sun/star/text/XTextViewCursor.hpp>
70 #include <com/sun/star/text/XTextViewCursorSupplier.hpp>
71 #include <com/sun/star/ucb/CommandAbortedException.hpp>
72 #include <com/sun/star/util/URL.hpp>
73 #include <com/sun/star/util/XSearchable.hpp>
74 #include <com/sun/star/util/XSearchDescriptor.hpp>
75 #include <com/sun/star/util/URLTransformer.hpp>
76 #include <com/sun/star/util/XURLTransformer.hpp>
77 #include <com/sun/star/util/XModifiable.hpp>
78 #include <com/sun/star/util/XCloseable.hpp>
79 #include <com/sun/star/util/CloseVetoException.hpp>
80 #include <com/sun/star/ui/XDockingAreaAcceptor.hpp>
81 #include <com/sun/star/view/XSelectionSupplier.hpp>
82 #include <com/sun/star/view/XViewSettingsSupplier.hpp>
83 #include <svtools/helpopt.hxx>
84 #include <unotools/historyoptions.hxx>
85 #include <svtools/menuoptions.hxx>
86 #include <unotools/pathoptions.hxx>
87 #include <unotools/viewoptions.hxx>
88 #include <svtools/svtresid.hxx>
89 #include <tools/urlobj.hxx>
90 #include <unotools/streamhelper.hxx>
91 #include <svtools/imagemgr.hxx>
92 #include <svtools/miscopt.hxx>
93 #include <svtools/imgdef.hxx>
94 #include <vcl/builderfactory.hxx>
95 #include <vcl/layout.hxx>
96 #include <vcl/unohelp.hxx>
97 #include <vcl/i18nhelp.hxx>
98 #include <vcl/settings.hxx>
100 #include <ucbhelper/content.hxx>
101 #include <vcl/msgbox.hxx>
102 #include <vcl/waitobj.hxx>
103 #include <unotools/ucbhelper.hxx>
105 #include <sfx2/viewfrm.hxx>
106 #include <sfx2/objsh.hxx>
107 #include <sfx2/docfac.hxx>
109 #include <unordered_map>
110 #include <vector>
112 using namespace ::ucbhelper;
113 using namespace ::com::sun::star::ucb;
115 using namespace ::com::sun::star;
116 using namespace ::com::sun::star::beans;
117 using namespace ::com::sun::star::container;
118 using namespace ::com::sun::star::frame;
119 using namespace ::com::sun::star::i18n;
120 using namespace ::com::sun::star::lang;
121 using namespace ::com::sun::star::style;
122 using namespace ::com::sun::star::text;
123 using namespace ::com::sun::star::uno;
124 using namespace ::com::sun::star::util;
125 using namespace ::com::sun::star::view;
126 using namespace ::com::sun::star::ui;
128 using namespace ::comphelper;
130 // defines ---------------------------------------------------------------
132 #define SPLITSET_ID 0
133 #define COLSET_ID 1
134 #define INDEXWIN_ID 2
135 #define TEXTWIN_ID 3
137 #define TOOLBOX_OFFSET 3
139 #define TBI_INDEX 1001
140 #define TBI_BACKWARD 1002
141 #define TBI_FORWARD 1003
142 #define TBI_START 1004
143 #define TBI_PRINT 1005
144 #define TBI_COPY 1006
145 #define TBI_BOOKMARKS 1007
146 #define TBI_SEARCHDIALOG 1008
147 #define TBI_SOURCEVIEW 1009
148 #define TBI_SELECTIONMODE 1010
150 #define CONFIGNAME_HELPWIN "OfficeHelp"
151 #define CONFIGNAME_INDEXWIN "OfficeHelpIndex"
152 #define CONFIGNAME_SEARCHPAGE "OfficeHelpSearch"
153 #define IMAGE_URL "private:factory/"
155 #define PROPERTY_KEYWORDLIST "KeywordList"
156 #define PROPERTY_KEYWORDREF "KeywordRef"
157 #define PROPERTY_ANCHORREF "KeywordAnchorForRef"
158 #define PROPERTY_TITLEREF "KeywordTitleForRef"
159 #define PROPERTY_TITLE "Title"
160 #define HELP_URL "vnd.sun.star.help://"
161 #define HELP_SEARCH_TAG "/?Query="
162 #define USERITEM_NAME "UserItem"
164 #define PACKAGE_SETUP "/org.openoffice.Setup"
165 #define PATH_OFFICE_FACTORIES "Office/Factories/"
166 #define KEY_HELP_ON_OPEN "ooSetupFactoryHelpOnOpen"
167 #define KEY_UI_NAME "ooSetupFactoryUIName"
169 #define PARSE_URL( aURL ) \
170 Reference< util::XURLTransformer > xTrans( util::URLTransformer::create( ::comphelper::getProcessComponentContext() ) ); \
171 xTrans->parseStrict( aURL )
174 namespace sfx2
178 void HandleTaskPaneList( vcl::Window* pWindow, bool bAddToList )
180 vcl::Window* pParent = pWindow->GetParent();
181 DBG_ASSERT( pParent, "HandleTaskPaneList(): every window here should have a parent" );
183 SystemWindow* pSysWin = pParent->GetSystemWindow();
184 if( pSysWin )
186 TaskPaneList* pTaskPaneList = pSysWin->GetTaskPaneList();
187 if( pTaskPaneList )
189 if( bAddToList )
190 pTaskPaneList->AddWindow( pWindow );
191 else
192 pTaskPaneList->RemoveWindow( pWindow );
197 /** Prepare a search string for searching or selecting.
198 For searching every search word needs the postfix '*' and the delimiter ' ' if necessary.
199 For selecting the delimiter '|' is required to search with regular expressions.
200 Samples:
201 search string | output for searching | output for selecting
202 -----------------------------------------------------------
203 "text" | "text*" | "text"
204 "text*" | "text*" | "text"
205 "text menu" | "text* menu*" | "text|menu"
207 OUString PrepareSearchString( const OUString& rSearchString,
208 Reference< XBreakIterator > xBreak, bool bForSearch )
210 OUString sSearchStr;
211 sal_Int32 nStartPos = 0;
212 const lang::Locale aLocale = Application::GetSettings().GetUILanguageTag().getLocale();
213 Boundary aBoundary = xBreak->getWordBoundary(
214 rSearchString, nStartPos, aLocale, WordType::ANYWORD_IGNOREWHITESPACES, sal_True );
216 while ( aBoundary.startPos != aBoundary.endPos )
218 nStartPos = aBoundary.endPos;
219 OUString sSearchToken( rSearchString.copy(
220 (sal_uInt16)aBoundary.startPos, (sal_uInt16)aBoundary.endPos - (sal_uInt16)aBoundary.startPos ) );
221 if ( !sSearchToken.isEmpty() && ( sSearchToken.getLength() > 1 || sSearchToken[0] != '.' ) )
223 if ( bForSearch && sSearchToken[ sSearchToken.getLength() - 1 ] != '*' )
224 sSearchToken += "*";
226 if ( sSearchToken.getLength() > 1 ||
227 ( sSearchToken.getLength() > 0 && sSearchToken[ 0 ] != '*' ) )
229 if ( !sSearchStr.isEmpty() )
231 if ( bForSearch )
232 sSearchStr += " ";
233 else
234 sSearchStr += "|";
236 sSearchStr += sSearchToken;
239 aBoundary = xBreak->nextWord( rSearchString, nStartPos,
240 aLocale, WordType::ANYWORD_IGNOREWHITESPACES );
243 return sSearchStr;
246 // namespace sfx2
250 // struct IndexEntry_Impl ------------------------------------------------
252 struct IndexEntry_Impl
254 bool m_bSubEntry;
255 OUString m_aURL;
257 IndexEntry_Impl( const OUString& rURL, bool bSubEntry ) :
258 m_bSubEntry( bSubEntry ), m_aURL( rURL ) {}
261 // struct ContentEntry_Impl ----------------------------------------------
263 struct ContentEntry_Impl
265 OUString aURL;
266 bool bIsFolder;
268 ContentEntry_Impl( const OUString& rURL, bool bFolder ) :
269 aURL( rURL ), bIsFolder( bFolder ) {}
272 // ContentListBox_Impl ---------------------------------------------------
274 ContentListBox_Impl::ContentListBox_Impl(vcl::Window* pParent, WinBits nStyle)
275 : SvTreeListBox(pParent, nStyle)
276 , aOpenBookImage(SfxResId(IMG_HELP_CONTENT_BOOK_OPEN))
277 , aClosedBookImage(SfxResId(IMG_HELP_CONTENT_BOOK_CLOSED))
278 , aDocumentImage(SfxResId(IMG_HELP_CONTENT_DOC))
281 SetStyle( GetStyle() | WB_HIDESELECTION | WB_HSCROLL );
283 SetEntryHeight( 16 );
284 SetSelectionMode( SINGLE_SELECTION );
285 SetSpaceBetweenEntries( 2 );
286 SetNodeBitmaps( aClosedBookImage, aOpenBookImage );
288 SetSublistOpenWithReturn();
289 SetSublistOpenWithLeftRight();
291 InitRoot();
294 VCL_BUILDER_DECL_FACTORY(ContentListBox)
296 WinBits nWinStyle = WB_TABSTOP;
297 OString sBorder = VclBuilder::extractCustomProperty(rMap);
298 if (!sBorder.isEmpty())
299 nWinStyle |= WB_BORDER;
300 rRet = VclPtr<ContentListBox_Impl>::Create(pParent, nWinStyle);
303 ContentListBox_Impl::~ContentListBox_Impl()
305 disposeOnce();
308 void ContentListBox_Impl::dispose()
310 sal_uInt16 nPos = 0;
311 SvTreeListEntry* pEntry = GetEntry( nPos++ );
312 while ( pEntry )
314 ClearChildren( pEntry );
315 delete static_cast<ContentEntry_Impl*>(pEntry->GetUserData());
316 pEntry = GetEntry( nPos++ );
318 SvTreeListBox::dispose();
321 void ContentListBox_Impl::InitRoot()
323 OUString aHelpTreeviewURL( "vnd.sun.star.hier://com.sun.star.help.TreeView/" );
324 std::vector< OUString > aList =
325 SfxContentHelper::GetHelpTreeViewContents( aHelpTreeviewURL );
327 for(size_t i = 0, n = aList.size(); i < n; ++i )
329 const OUString& aRow = aList[i];
330 sal_Int32 nIdx = 0;
331 OUString aTitle = aRow.getToken( 0, '\t', nIdx );
332 OUString aURL = aRow.getToken( 0, '\t', nIdx );
333 sal_Unicode cFolder = aRow.getToken( 0, '\t', nIdx )[0];
334 bool bIsFolder = ( '1' == cFolder );
335 SvTreeListEntry* pEntry = InsertEntry( aTitle, aOpenBookImage, aClosedBookImage, NULL, true );
336 if ( bIsFolder )
337 pEntry->SetUserData( new ContentEntry_Impl( aURL, true ) );
343 void ContentListBox_Impl::ClearChildren( SvTreeListEntry* pParent )
345 SvTreeListEntry* pEntry = FirstChild( pParent );
346 while ( pEntry )
348 ClearChildren( pEntry );
349 delete static_cast<ContentEntry_Impl*>(pEntry->GetUserData());
350 pEntry = NextSibling( pEntry );
356 void ContentListBox_Impl::RequestingChildren( SvTreeListEntry* pParent )
360 if ( !pParent->HasChildren() )
362 if ( pParent->GetUserData() )
364 OUString aTmpURL( static_cast<ContentEntry_Impl*>(pParent->GetUserData())->aURL );
365 std::vector<OUString > aList =
366 SfxContentHelper::GetHelpTreeViewContents( aTmpURL );
368 for (size_t i = 0,n = aList.size(); i < n; ++i )
370 const OUString& aRow = aList[i];
371 sal_Int32 nIdx = 0;
372 OUString aTitle = aRow.getToken( 0, '\t', nIdx );
373 OUString aURL = aRow.getToken( 0, '\t', nIdx );
374 sal_Unicode cFolder = aRow.getToken( 0, '\t', nIdx )[0];
375 bool bIsFolder = ( '1' == cFolder );
376 SvTreeListEntry* pEntry = NULL;
377 if ( bIsFolder )
379 pEntry = InsertEntry( aTitle, aOpenBookImage, aClosedBookImage, pParent, true );
380 pEntry->SetUserData( new ContentEntry_Impl( aURL, true ) );
382 else
384 pEntry = InsertEntry( aTitle, aDocumentImage, aDocumentImage, pParent );
385 Any aAny( ::utl::UCBContentHelper::GetProperty( aURL, OUString("TargetURL" ) ) );
386 OUString aTargetURL;
387 if ( aAny >>= aTargetURL )
388 pEntry->SetUserData( new ContentEntry_Impl( aTargetURL, false ) );
394 catch( Exception& )
396 OSL_FAIL( "ContentListBox_Impl::RequestingChildren(): unexpected exception" );
402 bool ContentListBox_Impl::Notify( NotifyEvent& rNEvt )
404 bool bHandled = false;
405 if ( rNEvt.GetType() == MouseNotifyEvent::KEYINPUT &&
406 KEY_RETURN == rNEvt.GetKeyEvent()->GetKeyCode().GetCode() )
408 GetDoubleClickHdl().Call( NULL );
409 bHandled = true;
412 return bHandled || SvTreeListBox::Notify( rNEvt );
417 OUString ContentListBox_Impl::GetSelectEntry() const
419 OUString aRet;
420 SvTreeListEntry* pEntry = FirstSelected();
421 if ( pEntry && !static_cast<ContentEntry_Impl*>(pEntry->GetUserData())->bIsFolder )
422 aRet = static_cast<ContentEntry_Impl*>(pEntry->GetUserData())->aURL;
423 return aRet;
426 // class HelpTabPage_Impl ------------------------------------------------
427 HelpTabPage_Impl::HelpTabPage_Impl(vcl::Window* pParent, SfxHelpIndexWindow_Impl* _pIdxWin,
428 const OString& rID, const OUString& rUIXMLDescription)
429 : TabPage( pParent, rID, rUIXMLDescription)
430 , m_pIdxWin( _pIdxWin )
434 HelpTabPage_Impl::~HelpTabPage_Impl()
436 disposeOnce();
439 void HelpTabPage_Impl::dispose()
441 m_pIdxWin.clear();
442 TabPage::dispose();
445 // class ContentTabPage_Impl ---------------------------------------------
446 ContentTabPage_Impl::ContentTabPage_Impl(vcl::Window* pParent, SfxHelpIndexWindow_Impl* _pIdxWin)
447 : HelpTabPage_Impl(pParent, _pIdxWin, "HelpContentPage",
448 "sfx/ui/helpcontentpage.ui")
450 get(m_pContentBox, "content");
451 Size aSize(LogicToPixel(Size(108 , 188), MAP_APPFONT));
452 m_pContentBox->set_width_request(aSize.Width());
453 m_pContentBox->set_height_request(aSize.Height());
456 ContentTabPage_Impl::~ContentTabPage_Impl()
458 disposeOnce();
461 void ContentTabPage_Impl::dispose()
463 m_pContentBox.clear();
464 HelpTabPage_Impl::dispose();
467 void ContentTabPage_Impl::ActivatePage()
469 if ( !m_pIdxWin->WasCursorLeftOrRight() )
470 SetFocusOnBox();
473 Control* ContentTabPage_Impl::GetLastFocusControl()
475 return m_pContentBox;
478 // class IndexBox_Impl ---------------------------------------------------
480 IndexBox_Impl::IndexBox_Impl(vcl::Window* pParent, WinBits nStyle)
481 : ComboBox(pParent, nStyle)
483 EnableAutocomplete(true);
484 EnableUserDraw(true);
487 VCL_BUILDER_DECL_FACTORY(IndexBox)
489 WinBits nWinBits = WB_CLIPCHILDREN|WB_LEFT|WB_VCENTER|WB_3DLOOK;
490 OString sBorder = VclBuilder::extractCustomProperty(rMap);
491 if (!sBorder.isEmpty())
492 nWinBits |= WB_BORDER;
493 VclPtrInstance<IndexBox_Impl> pListBox(pParent, nWinBits);
494 pListBox->EnableAutoSize(true);
495 rRet = pListBox;
498 void IndexBox_Impl::UserDraw( const UserDrawEvent& rUDEvt )
500 IndexEntry_Impl* pEntry = static_cast<IndexEntry_Impl*>(GetEntryData( rUDEvt.GetItemId() ));
501 if ( pEntry && pEntry->m_bSubEntry )
503 // indent sub entries
504 Point aPos( rUDEvt.GetRect().TopLeft() );
505 aPos.X() += 8;
506 aPos.Y() += (rUDEvt.GetRect().GetHeight() - rUDEvt.GetRenderContext()->GetTextHeight()) / 2;
507 OUString aEntry( GetEntry( rUDEvt.GetItemId() ) );
508 sal_Int32 nPos = aEntry.indexOf( ';' );
509 rUDEvt.GetRenderContext()->DrawText(aPos, (nPos !=-1) ? aEntry.copy(nPos + 1) : aEntry);
511 else
512 DrawEntry( rUDEvt, false, true, true );
517 bool IndexBox_Impl::Notify( NotifyEvent& rNEvt )
519 bool bHandled = false;
520 if ( rNEvt.GetType() == MouseNotifyEvent::KEYINPUT &&
521 KEY_RETURN == rNEvt.GetKeyEvent()->GetKeyCode().GetCode() )
523 GetDoubleClickHdl().Call( NULL );
524 bHandled = true;
527 return bHandled || ComboBox::Notify( rNEvt );
532 void IndexBox_Impl::SelectExecutableEntry()
534 sal_Int32 nPos = GetEntryPos( GetText() );
535 if ( nPos != COMBOBOX_ENTRY_NOTFOUND )
537 sal_Int32 nOldPos = nPos;
538 OUString aEntryText;
539 IndexEntry_Impl* pEntry = static_cast<IndexEntry_Impl*>(GetEntryData( nPos ));
540 sal_Int32 nCount = GetEntryCount();
541 while ( nPos < nCount && ( !pEntry || pEntry->m_aURL.isEmpty() ) )
543 pEntry = static_cast<IndexEntry_Impl*>(GetEntryData( ++nPos ));
544 aEntryText = GetEntry( nPos );
547 if ( nOldPos != nPos )
548 SetText( aEntryText );
552 // class IndexTabPage_Impl -----------------------------------------------
554 IndexTabPage_Impl::IndexTabPage_Impl(vcl::Window* pParent, SfxHelpIndexWindow_Impl* _pIdxWin)
555 : HelpTabPage_Impl(pParent, _pIdxWin, "HelpIndexPage",
556 "sfx/ui/helpindexpage.ui")
557 , bIsActivated(false)
559 get(m_pIndexCB, "terms");
560 Size aSize(LogicToPixel(Size(108, 97), MAP_APPFONT));
561 m_pIndexCB->set_width_request(aSize.Width());
562 m_pIndexCB->set_height_request(aSize.Height());
563 get(m_pOpenBtn, "display");
565 m_pOpenBtn->SetClickHdl( LINK( this, IndexTabPage_Impl, OpenHdl ) );
566 Link<Timer *, void> aTimeoutLink = LINK( this, IndexTabPage_Impl, TimeoutHdl );
567 aFactoryIdle.SetIdleHdl( LINK(this, IndexTabPage_Impl, IdleHdl ));
568 aFactoryIdle.SetPriority(SchedulerPriority::LOWER);
569 aKeywordTimer.SetTimeoutHdl( aTimeoutLink );
572 IndexTabPage_Impl::~IndexTabPage_Impl()
574 disposeOnce();
577 void IndexTabPage_Impl::dispose()
579 ClearIndex();
580 m_pIndexCB.clear();
581 m_pOpenBtn.clear();
582 HelpTabPage_Impl::dispose();
587 namespace sfx2 {
589 typedef std::unordered_map< OUString, int, OUStringHash > KeywordInfo;
592 #define NEW_ENTRY( url, bool ) \
593 new IndexEntry_Impl( url, bool )
595 #define UNIFY_AND_INSERT_TOKEN( aToken ) \
596 it = aInfo.insert( sfx2::KeywordInfo::value_type( aToken, 0 ) ).first; \
597 if ( ( tmp = it->second++ ) != 0 ) \
598 nPos = m_pIndexCB->InsertEntry( aToken + OUString( append, tmp ) ); \
599 else \
600 nPos = m_pIndexCB->InsertEntry( aToken )
602 #define INSERT_DATA( j ) \
603 if ( aAnchorList[j].getLength() > 0 ) \
605 aData.append( aRefList[j] ).append( '#' ).append( aAnchorList[j] ); \
606 m_pIndexCB->SetEntryData( nPos, NEW_ENTRY( aData.makeStringAndClear(), insert ) ); \
608 else \
609 m_pIndexCB->SetEntryData( nPos, NEW_ENTRY( aRefList[j], insert ) );
613 void IndexTabPage_Impl::InitializeIndex()
615 WaitObject aWaitCursor( this );
617 // By now more than 256 equal entries are not allowed
618 sal_Unicode append[256];
619 for( int k = 0; k < 256; ++k )
620 append[k] = ' ';
622 sfx2::KeywordInfo aInfo;
623 m_pIndexCB->SetUpdateMode( false );
627 OUStringBuffer aURL = HELP_URL;
628 aURL.append(sFactory);
629 AppendConfigToken(aURL, true);
631 Content aCnt( aURL.makeStringAndClear(), Reference< ::com::sun::star::ucb::XCommandEnvironment >(), comphelper::getProcessComponentContext() );
632 ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > xInfo = aCnt.getProperties();
633 if ( xInfo->hasPropertyByName( PROPERTY_ANCHORREF ) )
635 ::com::sun::star::uno::Sequence< OUString > aPropSeq( 4 );
636 aPropSeq[0] = PROPERTY_KEYWORDLIST;
637 aPropSeq[1] = PROPERTY_KEYWORDREF;
638 aPropSeq[2] = PROPERTY_ANCHORREF;
639 aPropSeq[3] = PROPERTY_TITLEREF;
641 // abi: use one possibly remote call only
642 ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any > aAnySeq =
643 aCnt.getPropertyValues( aPropSeq );
645 ::com::sun::star::uno::Sequence< OUString > aKeywordList;
646 ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< OUString > > aKeywordRefList;
647 ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< OUString > > aAnchorRefList;
648 ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< OUString > > aTitleRefList;
650 if ( ( aAnySeq[0] >>= aKeywordList ) && ( aAnySeq[1] >>= aKeywordRefList ) &&
651 ( aAnySeq[2] >>= aAnchorRefList ) && ( aAnySeq[3] >>= aTitleRefList ) )
653 sal_uInt16 nPos;
654 int ndx,tmp;
655 OUString aIndex, aTempString;
656 OUStringBuffer aData( 128 ); // Capacity of up to 128 characters
657 sfx2::KeywordInfo::iterator it;
659 for ( int i = 0; i < aKeywordList.getLength(); ++i )
661 // abi: Do not copy, but use references
662 const OUString& aKeywordPair = aKeywordList[i];
663 DBG_ASSERT( !aKeywordPair.isEmpty(), "invalid help index" );
664 const ::com::sun::star::uno::Sequence< OUString >& aRefList = aKeywordRefList[i];
665 const ::com::sun::star::uno::Sequence< OUString >& aAnchorList = aAnchorRefList[i];
666 const ::com::sun::star::uno::Sequence< OUString >& aTitleList = aTitleRefList[i];
668 DBG_ASSERT( aRefList.getLength() == aAnchorList.getLength(),"reference list and title list of different length" );
670 const bool insert = ( ndx = aKeywordPair.indexOf( ';' ) ) != -1;
672 if ( insert )
674 aTempString = aKeywordPair.copy( 0, ndx );
675 if ( aIndex != aTempString )
677 aIndex = aTempString;
678 UNIFY_AND_INSERT_TOKEN( aTempString );
681 else
682 aIndex.clear();
684 // Assume the token is trimed
685 UNIFY_AND_INSERT_TOKEN( aKeywordPair );
687 sal_uInt32 nRefListLen = aRefList.getLength();
689 DBG_ASSERT( aAnchorList.getLength(), "*IndexTabPage_Impl::InitializeIndex(): AnchorList is empty!" ); \
690 DBG_ASSERT( nRefListLen, "*IndexTabPage_Impl::InitializeIndex(): RefList is empty!" ); \
692 if ( aAnchorList.getLength() && nRefListLen )
694 INSERT_DATA( 0 );
697 for ( sal_uInt32 j = 1; j < nRefListLen ; ++j )
699 aData
700 .append( aKeywordPair )
701 .append( ' ' )
702 .append( '-' )
703 .append( ' ' )
704 .append( aTitleList[j] );
706 aTempString = aData.makeStringAndClear();
707 UNIFY_AND_INSERT_TOKEN( aTempString );
708 INSERT_DATA( j );
714 catch( Exception& )
716 OSL_FAIL( "IndexTabPage_Impl::InitializeIndex(): unexpected exception" );
719 m_pIndexCB->SetUpdateMode( true );
721 if ( !sKeyword.isEmpty() )
722 aKeywordLink.Call( this );
725 #undef INSERT_DATA
726 #undef UNIFY_AND_INSERT_TOKEN
730 void IndexTabPage_Impl::ClearIndex()
732 sal_uInt16 nCount = m_pIndexCB->GetEntryCount();
733 for ( sal_uInt16 i = 0; i < nCount; ++i )
734 delete static_cast<IndexEntry_Impl*>(m_pIndexCB->GetEntryData(i));
735 m_pIndexCB->Clear();
738 IMPL_LINK_NOARG(IndexTabPage_Impl, OpenHdl)
740 m_pIndexCB->GetDoubleClickHdl().Call(m_pIndexCB);
741 return 0;
744 IMPL_LINK_TYPED( IndexTabPage_Impl, IdleHdl, Idle*, pIdle, void )
746 if ( &aFactoryIdle == pIdle )
747 InitializeIndex();
750 IMPL_LINK_TYPED( IndexTabPage_Impl, TimeoutHdl, Timer*, pTimer, void)
752 if(&aKeywordTimer == pTimer && !sKeyword.isEmpty())
753 aKeywordLink.Call(this);
756 void IndexTabPage_Impl::ActivatePage()
758 if ( !bIsActivated )
760 bIsActivated = true;
761 aFactoryIdle.Start();
764 if ( !m_pIdxWin->WasCursorLeftOrRight() )
765 SetFocusOnBox();
768 Control* IndexTabPage_Impl::GetLastFocusControl()
770 return m_pOpenBtn;
773 void IndexTabPage_Impl::SetDoubleClickHdl( const Link<>& rLink )
775 m_pIndexCB->SetDoubleClickHdl( rLink );
778 void IndexTabPage_Impl::SetFactory( const OUString& rFactory )
780 OUString sNewFactory( rFactory );
781 DBG_ASSERT( !sNewFactory.isEmpty(), "empty factory" );
782 bool bValid = m_pIdxWin->IsValidFactory( rFactory );
784 if ( sFactory.isEmpty() && !bValid )
786 sNewFactory = SfxHelp::GetDefaultHelpModule();
787 bValid = true;
790 if ( sNewFactory != sFactory && bValid )
792 sFactory = sNewFactory;
793 ClearIndex();
794 if ( bIsActivated )
795 aFactoryIdle.Start();
801 OUString IndexTabPage_Impl::GetSelectEntry() const
803 OUString aRet;
804 IndexEntry_Impl* pEntry = static_cast<IndexEntry_Impl*>(m_pIndexCB->GetEntryData( m_pIndexCB->GetEntryPos( m_pIndexCB->GetText() ) ));
805 if ( pEntry )
806 aRet = pEntry->m_aURL;
807 return aRet;
812 void IndexTabPage_Impl::SetKeyword( const OUString& rKeyword )
814 sKeyword = rKeyword;
816 if ( m_pIndexCB->GetEntryCount() > 0 )
817 aKeywordTimer.Start();
818 else if ( !bIsActivated )
819 aFactoryIdle.Start();
824 bool IndexTabPage_Impl::HasKeyword() const
826 bool bRet = false;
827 if ( !sKeyword.isEmpty() )
829 sal_Int32 nPos = m_pIndexCB->GetEntryPos( sKeyword );
830 bRet = ( nPos != LISTBOX_ENTRY_NOTFOUND );
833 return bRet;
838 bool IndexTabPage_Impl::HasKeywordIgnoreCase()
840 bool bRet = false;
841 if ( !sKeyword.isEmpty() )
843 sal_Int32 nEntries = m_pIndexCB->GetEntryCount();
844 OUString sIndexItem;
845 const vcl::I18nHelper& rI18nHelper = GetSettings().GetLocaleI18nHelper();
846 for ( sal_Int32 n = 0; n < nEntries; n++)
848 sIndexItem = m_pIndexCB->GetEntry( n );
849 if (rI18nHelper.MatchString( sIndexItem, sKeyword ))
851 sKeyword = sIndexItem;
852 bRet = true;
857 return bRet;
862 void IndexTabPage_Impl::OpenKeyword()
864 if ( !sKeyword.isEmpty() )
866 m_pIndexCB->SetText( sKeyword );
867 m_pIndexCB->GetDoubleClickHdl().Call( NULL );
868 sKeyword.clear();
872 // class SearchBox_Impl --------------------------------------------------
874 VCL_BUILDER_DECL_FACTORY(SearchBox)
876 (void)rMap;
877 WinBits nWinBits = WB_CLIPCHILDREN|WB_LEFT|WB_VCENTER|WB_3DLOOK|WB_SIMPLEMODE|WB_DROPDOWN;
878 VclPtrInstance<SearchBox_Impl> pComboBox(pParent, nWinBits);
879 pComboBox->EnableAutoSize(true);
880 rRet = pComboBox;
883 bool SearchBox_Impl::PreNotify( NotifyEvent& rNEvt )
885 bool bHandled = false;
886 if ( !IsInDropDown() &&
887 rNEvt.GetWindow() == GetSubEdit() &&
888 rNEvt.GetType() == MouseNotifyEvent::KEYINPUT &&
889 KEY_RETURN == rNEvt.GetKeyEvent()->GetKeyCode().GetCode() )
891 aSearchLink.Call( NULL );
892 bHandled = true;
894 return bHandled || ComboBox::PreNotify( rNEvt );
899 void SearchBox_Impl::Select()
901 if ( !IsTravelSelect() )
902 aSearchLink.Call( NULL );
905 // class SearchResultsBox_Impl -------------------------------------------
907 VCL_BUILDER_DECL_FACTORY(SearchResultsBox)
909 WinBits nWinBits = WB_CLIPCHILDREN|WB_LEFT|WB_VCENTER|WB_3DLOOK;
910 OString sBorder = VclBuilder::extractCustomProperty(rMap);
911 if (!sBorder.isEmpty())
912 nWinBits |= WB_BORDER;
913 VclPtrInstance<SearchResultsBox_Impl> pListBox(pParent, nWinBits);
914 pListBox->EnableAutoSize(true);
915 rRet = pListBox;
918 bool SearchResultsBox_Impl::Notify( NotifyEvent& rNEvt )
920 bool bHandled = false;
921 if ( rNEvt.GetType() == MouseNotifyEvent::KEYINPUT &&
922 KEY_RETURN == rNEvt.GetKeyEvent()->GetKeyCode().GetCode() )
924 GetDoubleClickHdl().Call( NULL );
925 bHandled = true;
928 return bHandled || ListBox::Notify( rNEvt );
931 // class SearchTabPage_Impl ----------------------------------------------
933 SearchTabPage_Impl::SearchTabPage_Impl(vcl::Window* pParent, SfxHelpIndexWindow_Impl* _pIdxWin)
934 : HelpTabPage_Impl(pParent, _pIdxWin, "HelpSearchPage",
935 "sfx/ui/helpsearchpage.ui")
936 , xBreakIterator(vcl::unohelper::CreateBreakIterator())
938 get(m_pSearchED, "search");
939 get(m_pSearchBtn, "find");
940 get(m_pFullWordsCB, "completewords");
941 get(m_pScopeCB, "headings");
942 get(m_pResultsLB, "results");
943 Size aSize(LogicToPixel(Size(128 , 30), MAP_APPFONT));
944 m_pResultsLB->set_width_request(aSize.Width());
945 m_pResultsLB->set_height_request(aSize.Height());
946 get(m_pOpenBtn, "display");
948 Link<> aLink = LINK( this, SearchTabPage_Impl, SearchHdl );
949 m_pSearchED->SetSearchLink( aLink );
950 m_pSearchBtn->SetClickHdl(aLink);
951 m_pSearchED->SetModifyHdl( LINK( this, SearchTabPage_Impl, ModifyHdl ) );
952 m_pOpenBtn->SetClickHdl( LINK( this, SearchTabPage_Impl, OpenHdl ) );
954 SvtViewOptions aViewOpt( E_TABPAGE, CONFIGNAME_SEARCHPAGE );
955 if ( aViewOpt.Exists() )
957 OUString aUserData;
958 Any aUserItem = aViewOpt.GetUserItem( USERITEM_NAME );
959 if ( aUserItem >>= aUserData )
961 bool bChecked = aUserData.getToken(0, ';').toInt32() == 1;
962 m_pFullWordsCB->Check( bChecked );
963 bChecked = aUserData.getToken(1, ';').toInt32() == 1;
964 m_pScopeCB->Check( bChecked );
966 for ( sal_uInt16 i = 2; i < comphelper::string::getTokenCount(aUserData, ';'); ++i )
968 OUString aToken = aUserData.getToken(i, ';');
969 m_pSearchED->InsertEntry( INetURLObject::decode(
970 aToken, INetURLObject::DECODE_WITH_CHARSET ) );
975 ModifyHdl(m_pSearchED);
978 SearchTabPage_Impl::~SearchTabPage_Impl()
980 disposeOnce();
983 void SearchTabPage_Impl::dispose()
985 SvtViewOptions aViewOpt( E_TABPAGE, CONFIGNAME_SEARCHPAGE );
986 sal_Int32 nChecked = m_pFullWordsCB->IsChecked() ? 1 : 0;
987 OUString aUserData = OUString::number( nChecked );
988 aUserData += ";";
989 nChecked = m_pScopeCB->IsChecked() ? 1 : 0;
990 aUserData += OUString::number( nChecked );
991 aUserData += ";";
992 sal_Int32 nCount = std::min( m_pSearchED->GetEntryCount(), (sal_Int32)10 ); // save only 10 entries
994 for ( sal_Int32 i = 0; i < nCount; ++i )
996 OUString aText = m_pSearchED->GetEntry(i);
997 aUserData += INetURLObject::encode(
998 aText, INetURLObject::PART_UNO_PARAM_VALUE,
999 INetURLObject::ENCODE_ALL );
1000 aUserData += ";";
1003 aUserData = comphelper::string::stripEnd(aUserData, ';');
1004 Any aUserItem = makeAny( OUString( aUserData ) );
1005 aViewOpt.SetUserItem( USERITEM_NAME, aUserItem );
1007 m_pSearchED.clear();
1008 m_pSearchBtn.clear();
1009 m_pFullWordsCB.clear();
1010 m_pScopeCB.clear();
1011 m_pResultsLB.clear();
1012 m_pOpenBtn.clear();
1013 HelpTabPage_Impl::dispose();
1018 void SearchTabPage_Impl::ClearSearchResults()
1020 sal_uInt16 nCount = m_pResultsLB->GetEntryCount();
1021 for ( sal_uInt16 i = 0; i < nCount; ++i )
1022 delete static_cast<OUString*>(m_pResultsLB->GetEntryData(i));
1023 m_pResultsLB->Clear();
1024 m_pResultsLB->Update();
1029 void SearchTabPage_Impl::RememberSearchText( const OUString& rSearchText )
1031 for ( sal_uInt16 i = 0; i < m_pSearchED->GetEntryCount(); ++i )
1033 if ( rSearchText == m_pSearchED->GetEntry(i) )
1035 m_pSearchED->RemoveEntryAt(i);
1036 break;
1040 m_pSearchED->InsertEntry( rSearchText, 0 );
1045 IMPL_LINK_NOARG(SearchTabPage_Impl, SearchHdl)
1047 OUString aSearchText = comphelper::string::strip(m_pSearchED->GetText(), ' ');
1048 if ( !aSearchText.isEmpty() )
1050 EnterWait();
1051 ClearSearchResults();
1052 RememberSearchText( aSearchText );
1053 OUStringBuffer aSearchURL(HELP_URL);
1054 aSearchURL.append(aFactory);
1055 aSearchURL.append(HELP_SEARCH_TAG);
1056 if ( !m_pFullWordsCB->IsChecked() )
1057 aSearchText = sfx2::PrepareSearchString( aSearchText, xBreakIterator, true );
1058 aSearchURL.append(aSearchText);
1059 AppendConfigToken(aSearchURL, false);
1060 if ( m_pScopeCB->IsChecked() )
1061 aSearchURL.append("&Scope=Heading");
1062 std::vector< OUString > aFactories = SfxContentHelper::GetResultSet(aSearchURL.makeStringAndClear());
1063 for (size_t i = 0, n = aFactories.size(); i < n; ++i )
1065 const OUString& rRow = aFactories[i];
1066 sal_Int32 nIdx = 0;
1067 OUString aTitle = rRow.getToken( 0, '\t', nIdx );
1068 nIdx = 0;
1069 OUString* pURL = new OUString( rRow.getToken( 2, '\t', nIdx ) );
1070 sal_uInt16 nPos = m_pResultsLB->InsertEntry( aTitle );
1071 m_pResultsLB->SetEntryData( nPos, pURL );
1073 LeaveWait();
1075 if ( aFactories.empty() )
1077 ScopedVclPtrInstance< MessageDialog > aBox(this, SfxResId( STR_INFO_NOSEARCHRESULTS ), VCL_MESSAGE_INFO);
1078 aBox->Execute();
1081 return 0;
1084 IMPL_LINK_NOARG(SearchTabPage_Impl, OpenHdl)
1086 m_pResultsLB->GetDoubleClickHdl().Call(m_pResultsLB);
1087 return 0;
1090 IMPL_LINK_NOARG(SearchTabPage_Impl, ModifyHdl)
1092 OUString aSearchText = comphelper::string::strip(m_pSearchED->GetText(), ' ');
1093 m_pSearchBtn->Enable(!aSearchText.isEmpty());
1094 return 0;
1097 void SearchTabPage_Impl::ActivatePage()
1099 if ( !m_pIdxWin->WasCursorLeftOrRight() )
1100 m_pSearchED->GrabFocus();
1103 Control* SearchTabPage_Impl::GetLastFocusControl()
1105 return m_pOpenBtn;
1108 void SearchTabPage_Impl::SetDoubleClickHdl( const Link<>& rLink )
1110 m_pResultsLB->SetDoubleClickHdl( rLink );
1115 OUString SearchTabPage_Impl::GetSelectEntry() const
1117 OUString aRet;
1118 OUString* pData = static_cast<OUString*>(m_pResultsLB->GetSelectEntryData());
1119 if ( pData )
1120 aRet = *pData;
1121 return aRet;
1126 void SearchTabPage_Impl::ClearPage()
1128 ClearSearchResults();
1129 m_pSearchED->SetText( OUString() );
1134 bool SearchTabPage_Impl::OpenKeyword( const OUString& rKeyword )
1136 bool bRet = false;
1137 m_pSearchED->SetText( rKeyword );
1138 SearchHdl( NULL );
1139 if ( m_pResultsLB->GetEntryCount() > 0 )
1141 // found keyword -> open it
1142 m_pResultsLB->SelectEntryPos(0);
1143 OpenHdl( NULL );
1144 bRet = true;
1147 return bRet;
1150 // class BookmarksTabPage_Impl -------------------------------------------
1152 void GetBookmarkEntry_Impl
1154 Sequence< PropertyValue >& aBookmarkEntry,
1155 OUString& rTitle,
1156 OUString& rURL
1159 for ( int i = 0; i < aBookmarkEntry.getLength(); i++ )
1161 PropertyValue aValue = aBookmarkEntry[i];
1162 if ( aValue.Name == HISTORY_PROPERTYNAME_URL )
1163 aValue.Value >>= rURL;
1164 else if ( aValue.Name == HISTORY_PROPERTYNAME_TITLE )
1165 aValue.Value >>= rTitle;
1169 BookmarksBox_Impl::BookmarksBox_Impl(vcl::Window* pParent, WinBits nStyle)
1170 : ListBox(pParent, nStyle)
1174 VCL_BUILDER_DECL_FACTORY(BookmarksBox)
1176 WinBits nWinBits = WB_CLIPCHILDREN|WB_LEFT|WB_VCENTER|WB_3DLOOK|WB_SIMPLEMODE;
1177 OString sBorder = VclBuilder::extractCustomProperty(rMap);
1178 if (!sBorder.isEmpty())
1179 nWinBits |= WB_BORDER;
1180 VclPtrInstance<BookmarksBox_Impl> pListBox(pParent, nWinBits);
1181 pListBox->EnableAutoSize(true);
1182 rRet = pListBox;
1185 BookmarksBox_Impl::~BookmarksBox_Impl()
1187 disposeOnce();
1190 void BookmarksBox_Impl::dispose()
1192 // save bookmarks to configuration
1193 SvtHistoryOptions aHistOpt;
1194 aHistOpt.Clear( eHELPBOOKMARKS );
1195 OUString sEmpty;
1196 sal_uInt16 nCount = GetEntryCount();
1197 for ( sal_uInt16 i = 0; i < nCount; ++i )
1199 OUString aTitle = GetEntry(i);
1200 OUString* pURL = static_cast<OUString*>(GetEntryData(i));
1201 aHistOpt.AppendItem(eHELPBOOKMARKS, *pURL, sEmpty, aTitle, sEmpty, boost::none);
1202 delete pURL;
1204 ListBox::dispose();
1209 void BookmarksBox_Impl::DoAction( sal_uInt16 nAction )
1211 switch ( nAction )
1213 case MID_OPEN :
1214 GetDoubleClickHdl().Call( NULL );
1215 break;
1217 case MID_RENAME :
1219 sal_Int32 nPos = GetSelectEntryPos();
1220 if ( nPos != LISTBOX_ENTRY_NOTFOUND )
1222 ScopedVclPtrInstance< SfxAddHelpBookmarkDialog_Impl > aDlg(this, true);
1223 aDlg->SetTitle( GetEntry( nPos ) );
1224 if ( aDlg->Execute() == RET_OK )
1226 OUString* pURL = static_cast<OUString*>(GetEntryData( nPos ));
1227 RemoveEntry( nPos );
1228 OUString aImageURL = IMAGE_URL;
1229 aImageURL += INetURLObject( *pURL ).GetHost();
1230 nPos = InsertEntry( aDlg->GetTitle(), SvFileInformationManager::GetImage( INetURLObject(aImageURL), false ) );
1231 SetEntryData( nPos, new OUString( *pURL ) );
1232 SelectEntryPos( nPos );
1233 delete pURL;
1236 break;
1239 case MID_DELETE :
1241 sal_Int32 nPos = GetSelectEntryPos();
1242 if ( nPos != LISTBOX_ENTRY_NOTFOUND )
1244 RemoveEntry( nPos );
1245 sal_uInt16 nCount = GetEntryCount();
1246 if ( nCount )
1248 if ( nPos >= nCount )
1249 nPos = nCount - 1;
1250 SelectEntryPos( nPos );
1253 break;
1260 bool BookmarksBox_Impl::Notify( NotifyEvent& rNEvt )
1262 bool nRet = false;
1263 MouseNotifyEvent nType = rNEvt.GetType();
1264 if ( MouseNotifyEvent::KEYINPUT == nType )
1266 sal_uInt16 nCode = rNEvt.GetKeyEvent()->GetKeyCode().GetCode();
1267 if ( KEY_DELETE == nCode && GetEntryCount() > 0 )
1269 DoAction( MID_DELETE );
1270 nRet = true;
1272 else if ( KEY_RETURN == nCode )
1274 GetDoubleClickHdl().Call( NULL );
1275 nRet = true;
1278 else if ( MouseNotifyEvent::COMMAND == nType )
1280 const CommandEvent* pCEvt = rNEvt.GetCommandEvent();
1281 if ( pCEvt->GetCommand() == CommandEventId::ContextMenu )
1283 PopupMenu aMenu( SfxResId( MENU_HELP_BOOKMARKS ) );
1284 sal_uInt16 nId = aMenu.Execute( this, pCEvt->GetMousePosPixel() );
1285 if ( nId != MENU_ITEM_NOTFOUND )
1286 DoAction( nId );
1287 nRet = true;
1291 return nRet || ListBox::Notify( rNEvt );
1294 // class BookmarksTabPage_Impl -------------------------------------------
1296 BookmarksTabPage_Impl::BookmarksTabPage_Impl(vcl::Window* pParent, SfxHelpIndexWindow_Impl* _pIdxWin)
1297 : HelpTabPage_Impl(pParent, _pIdxWin, "HelpBookmarkPage",
1298 "sfx/ui/helpbookmarkpage.ui")
1300 get(m_pBookmarksPB, "display");
1301 get(m_pBookmarksBox, "bookmarks");
1302 Size aSize(LogicToPixel(Size(120 , 200), MAP_APPFONT));
1303 m_pBookmarksBox->set_width_request(aSize.Width());
1304 m_pBookmarksBox->set_height_request(aSize.Height());
1306 m_pBookmarksPB->SetClickHdl( LINK( this, BookmarksTabPage_Impl, OpenHdl ) );
1308 // load bookmarks from configuration
1309 Sequence< Sequence< PropertyValue > > aBookmarkSeq;
1310 aBookmarkSeq = SvtHistoryOptions().GetList( eHELPBOOKMARKS );
1312 OUString aTitle;
1313 OUString aURL;
1315 sal_uInt32 i, nCount = aBookmarkSeq.getLength();
1316 for ( i = 0; i < nCount; ++i )
1318 GetBookmarkEntry_Impl( aBookmarkSeq[i], aTitle, aURL );
1319 AddBookmarks( aTitle, aURL );
1323 BookmarksTabPage_Impl::~BookmarksTabPage_Impl()
1325 disposeOnce();
1328 void BookmarksTabPage_Impl::dispose()
1330 m_pBookmarksBox.clear();
1331 m_pBookmarksPB.clear();
1332 HelpTabPage_Impl::dispose();
1336 IMPL_LINK_NOARG(BookmarksTabPage_Impl, OpenHdl)
1338 m_pBookmarksBox->GetDoubleClickHdl().Call(m_pBookmarksBox);
1339 return 0;
1342 void BookmarksTabPage_Impl::ActivatePage()
1344 if ( !m_pIdxWin->WasCursorLeftOrRight() )
1345 SetFocusOnBox();
1348 Control* BookmarksTabPage_Impl::GetLastFocusControl()
1350 return m_pBookmarksPB;
1353 void BookmarksTabPage_Impl::SetDoubleClickHdl( const Link<>& rLink )
1355 m_pBookmarksBox->SetDoubleClickHdl(rLink);
1358 OUString BookmarksTabPage_Impl::GetSelectEntry() const
1360 OUString aRet;
1361 OUString* pData = static_cast<OUString*>(m_pBookmarksBox->GetSelectEntryData());
1362 if ( pData )
1363 aRet = *pData;
1364 return aRet;
1369 void BookmarksTabPage_Impl::AddBookmarks( const OUString& rTitle, const OUString& rURL )
1371 OUString aImageURL = IMAGE_URL;
1372 aImageURL += INetURLObject( rURL ).GetHost();
1373 sal_uInt16 nPos = m_pBookmarksBox->InsertEntry( rTitle, SvFileInformationManager::GetImage( INetURLObject(aImageURL), false ) );
1374 m_pBookmarksBox->SetEntryData( nPos, new OUString( rURL ) );
1377 OUString SfxHelpWindow_Impl::buildHelpURL(const OUString& sFactory ,
1378 const OUString& sContent ,
1379 const OUString& sAnchor ,
1380 bool bUseQuestionMark)
1382 OUStringBuffer sHelpURL(256);
1383 sHelpURL.append(HELP_URL);
1384 sHelpURL.append(sFactory);
1385 sHelpURL.append(sContent);
1386 AppendConfigToken(sHelpURL, bUseQuestionMark);
1387 if (!sAnchor.isEmpty())
1388 sHelpURL.append(sAnchor);
1389 return sHelpURL.makeStringAndClear();
1392 void SfxHelpWindow_Impl::loadHelpContent(const OUString& sHelpURL, bool bAddToHistory)
1394 Reference< XComponentLoader > xLoader(getTextFrame(), UNO_QUERY);
1395 if (!xLoader.is())
1396 return;
1398 // If a print job runs do not open a new page
1399 Reference< XFrame2 > xTextFrame = pTextWin->getFrame();
1400 Reference< XController > xTextController ;
1401 if (xTextFrame.is())
1402 xTextController = xTextFrame->getController ();
1403 if ( xTextController.is() && !xTextController->suspend( sal_True ) )
1405 xTextController->suspend( sal_False );
1406 return;
1409 // save url to history
1410 if (bAddToHistory)
1411 pHelpInterceptor->addURL(sHelpURL);
1413 if ( !IsWait() )
1414 EnterWait();
1415 bool bSuccess = false;
1416 // TODO implement locale fallback ... see below while(true)
1420 Reference< XComponent > xContent = xLoader->loadComponentFromURL(sHelpURL, "_self", 0, Sequence< PropertyValue >());
1421 if (xContent.is())
1423 bSuccess = true;
1426 catch(const RuntimeException&)
1427 { throw; }
1428 catch(const Exception&)
1429 { /*break;*/ }
1431 /* TODO try next locale ...
1432 no further locale available? => break loop and show error page
1435 openDone(sHelpURL, bSuccess);
1436 if ( IsWait() )
1437 LeaveWait();
1440 SfxHelpIndexWindow_Impl::SfxHelpIndexWindow_Impl(SfxHelpWindow_Impl* _pParent)
1441 : Window(_pParent, 0)
1442 , aIndexKeywordLink(LINK(this, SfxHelpIndexWindow_Impl, KeywordHdl))
1443 , pParentWin(_pParent)
1444 , pCPage(NULL)
1445 , pIPage(NULL)
1446 , pSPage(NULL)
1447 , pBPage(NULL)
1448 , bWasCursorLeftOrRight(false)
1449 , bIsInitDone(false)
1451 m_pUIBuilder = new VclBuilder(this, getUIRootDir(), "sfx/ui/helpcontrol.ui", "HelpControl");
1452 get(m_pActiveLB, "active");
1453 get(m_pTabCtrl, "tabcontrol");
1455 sfx2::AddToTaskPaneList( this );
1457 m_pTabCtrl->SetActivatePageHdl( LINK( this, SfxHelpIndexWindow_Impl, ActivatePageHdl ) );
1459 sal_Int32 nPageId = m_pTabCtrl->GetPageId("index");
1460 SvtViewOptions aViewOpt( E_TABDIALOG, CONFIGNAME_INDEXWIN );
1461 if ( aViewOpt.Exists() )
1462 nPageId = aViewOpt.GetPageID();
1463 m_pTabCtrl->SetCurPageId( (sal_uInt16)nPageId );
1464 ActivatePageHdl( m_pTabCtrl );
1465 m_pActiveLB->SetSelectHdl( LINK( this, SfxHelpIndexWindow_Impl, SelectHdl ) );
1466 nMinWidth = ( m_pActiveLB->GetSizePixel().Width() / 2 );
1468 aIdle.SetIdleHdl( LINK( this, SfxHelpIndexWindow_Impl, InitHdl ) );
1469 aIdle.SetPriority( SchedulerPriority::LOWER );
1470 aIdle.Start();
1472 Show();
1477 SfxHelpIndexWindow_Impl::~SfxHelpIndexWindow_Impl()
1479 disposeOnce();
1482 void SfxHelpIndexWindow_Impl::dispose()
1484 sfx2::RemoveFromTaskPaneList( this );
1486 pCPage.disposeAndClear();
1487 pIPage.disposeAndClear();
1488 pSPage.disposeAndClear();
1489 pBPage.disposeAndClear();
1491 for ( sal_uInt16 i = 0; i < m_pActiveLB->GetEntryCount(); ++i )
1492 delete static_cast<OUString*>(m_pActiveLB->GetEntryData(i));
1494 SvtViewOptions aViewOpt( E_TABDIALOG, CONFIGNAME_INDEXWIN );
1495 aViewOpt.SetPageID( (sal_Int32)m_pTabCtrl->GetCurPageId() );
1497 disposeBuilder();
1498 m_pActiveLB.clear();
1499 m_pTabCtrl.clear();
1500 pParentWin.clear();
1501 vcl::Window::dispose();
1506 void SfxHelpIndexWindow_Impl::Initialize()
1508 OUStringBuffer aHelpURL(HELP_URL);
1509 AppendConfigToken(aHelpURL, true);
1510 std::vector<OUString> aFactories = SfxContentHelper::GetResultSet(aHelpURL.makeStringAndClear());
1511 for (size_t i = 0, n = aFactories.size(); i < n; ++i )
1513 const OUString& rRow = aFactories[i];
1514 sal_Int32 nIdx = 0;
1515 OUString aTitle = rRow.getToken( 0, '\t', nIdx );
1516 nIdx = 0;
1517 OUString aURL = rRow.getToken( 2, '\t', nIdx );
1518 OUString* pFactory = new OUString( INetURLObject( aURL ).GetHost() );
1519 sal_uInt16 nPos = m_pActiveLB->InsertEntry( aTitle );
1520 m_pActiveLB->SetEntryData( nPos, pFactory );
1523 m_pActiveLB->SetDropDownLineCount( (sal_uInt16)aFactories.size() );
1524 if ( m_pActiveLB->GetSelectEntryPos() == LISTBOX_ENTRY_NOTFOUND )
1525 SetActiveFactory();
1530 void SfxHelpIndexWindow_Impl::SetActiveFactory()
1532 DBG_ASSERT( pIPage, "index page not initialized" );
1533 if ( !bIsInitDone && !m_pActiveLB->GetEntryCount() )
1535 aIdle.Stop();
1536 InitHdl( NULL );
1539 for ( sal_uInt16 i = 0; i < m_pActiveLB->GetEntryCount(); ++i )
1541 OUString* pFactory = static_cast<OUString*>(m_pActiveLB->GetEntryData(i));
1542 *pFactory = pFactory->toAsciiLowerCase();
1543 if ( *pFactory == pIPage->GetFactory() )
1545 if ( m_pActiveLB->GetSelectEntryPos() != i )
1547 m_pActiveLB->SelectEntryPos(i);
1548 aSelectFactoryLink.Call( NULL );
1550 break;
1557 HelpTabPage_Impl* SfxHelpIndexWindow_Impl::GetCurrentPage( sal_uInt16& rCurId )
1559 rCurId = m_pTabCtrl->GetCurPageId();
1560 HelpTabPage_Impl* pPage = NULL;
1562 OString sName(m_pTabCtrl->GetPageName(rCurId));
1564 if (sName == "contents")
1566 pPage = GetContentPage();
1568 else if (sName == "index")
1570 pPage = GetIndexPage();
1572 else if (sName == "find")
1574 pPage = GetSearchPage();
1576 else if (sName == "bookmarks")
1578 pPage = GetBookmarksPage();
1581 DBG_ASSERT( pPage, "SfxHelpIndexWindow_Impl::GetCurrentPage(): no current page" );
1582 return pPage;
1585 IMPL_LINK( SfxHelpIndexWindow_Impl, ActivatePageHdl, TabControl *, pTabCtrl )
1587 sal_uInt16 nId = 0;
1588 TabPage* pPage = GetCurrentPage( nId );
1589 pTabCtrl->SetTabPage( nId, pPage );
1590 return 0;
1593 IMPL_LINK_NOARG(SfxHelpIndexWindow_Impl, SelectHdl)
1595 aIdle.Start();
1597 return 0;
1600 IMPL_LINK_NOARG_TYPED(SfxHelpIndexWindow_Impl, InitHdl, Idle *, void)
1602 bIsInitDone = true;
1603 Initialize();
1605 // now use the timer for selection
1606 aIdle.SetIdleHdl( LINK( this, SfxHelpIndexWindow_Impl, SelectFactoryHdl ) );
1607 aIdle.SetPriority( SchedulerPriority::LOWEST );
1610 IMPL_LINK_NOARG_TYPED(SfxHelpIndexWindow_Impl, SelectFactoryHdl, Idle *, void)
1612 OUString* pFactory = static_cast<OUString*>(m_pActiveLB->GetSelectEntryData());
1613 if ( pFactory )
1615 SetFactory( OUString( *pFactory ).toAsciiLowerCase(), false );
1616 aSelectFactoryLink.Call( this );
1620 IMPL_LINK_NOARG(SfxHelpIndexWindow_Impl, KeywordHdl)
1622 // keyword found on index?
1623 bool bIndex = pIPage->HasKeyword();
1625 if( !bIndex)
1626 bIndex = pIPage->HasKeywordIgnoreCase();
1627 // then set index or search page as current.
1628 sal_uInt16 nPageId = ( bIndex ) ? m_pTabCtrl->GetPageId("index") : m_pTabCtrl->GetPageId("find");
1629 if ( nPageId != m_pTabCtrl->GetCurPageId() )
1631 m_pTabCtrl->SetCurPageId( nPageId );
1632 ActivatePageHdl( m_pTabCtrl );
1635 // at last we open the keyword
1636 if ( bIndex )
1637 pIPage->OpenKeyword();
1638 else if ( !pSPage->OpenKeyword( sKeyword ) )
1639 pParentWin->ShowStartPage();
1641 return 0;
1644 void SfxHelpIndexWindow_Impl::Resize()
1646 vcl::Window *pChild = GetWindow(GetWindowType::FirstChild);
1647 if (!pChild)
1648 return;
1649 VclContainer::setLayoutAllocation(*pChild, Point(0,0), GetSizePixel());
1652 Size SfxHelpIndexWindow_Impl::GetOptimalSize() const
1654 const vcl::Window *pChild = GetWindow(GetWindowType::FirstChild);
1655 if (!pChild)
1656 return Window::GetOptimalSize();
1657 return VclContainer::getLayoutRequisition(*pChild);
1660 bool SfxHelpIndexWindow_Impl::PreNotify(NotifyEvent& rNEvt)
1662 bool nDone = false;
1663 MouseNotifyEvent nType = rNEvt.GetType();
1664 if ( MouseNotifyEvent::KEYINPUT == nType && rNEvt.GetKeyEvent() )
1666 const vcl::KeyCode& rKeyCode = rNEvt.GetKeyEvent()->GetKeyCode();
1667 sal_uInt16 nCode = rKeyCode.GetCode();
1669 if ( KEY_TAB == nCode )
1671 // don't exit index pane with <TAB>
1672 sal_uInt16 nPageId = 0;
1673 HelpTabPage_Impl* pCurPage = GetCurrentPage( nPageId );
1674 Control* pControl = pCurPage->GetLastFocusControl();
1675 bool bShift = rKeyCode.IsShift();
1676 bool bCtrl = rKeyCode.IsMod1();
1677 if ( !bCtrl && bShift && m_pActiveLB->HasChildPathFocus() )
1679 pControl->GrabFocus();
1680 nDone = true;
1682 else if ( !bCtrl && !bShift && pControl->HasChildPathFocus() )
1684 m_pActiveLB->GrabFocus();
1685 nDone = true;
1687 else if ( bCtrl )
1689 sal_uInt16 nPagePos = m_pTabCtrl->GetPagePos(nPageId);
1690 sal_uInt16 nPageCount = m_pTabCtrl->GetPageCount();
1692 ++nPageId;
1693 // <CTRL><TAB> moves through the pages
1694 if (nPagePos >= nPageCount)
1695 nPagePos = 0;
1697 m_pTabCtrl->SetCurPageId(m_pTabCtrl->GetPageId(nPagePos));
1698 ActivatePageHdl( m_pTabCtrl );
1699 nDone = true;
1702 else if ( m_pTabCtrl->HasFocus() && ( KEY_LEFT == nCode || KEY_RIGHT == nCode ) )
1704 bWasCursorLeftOrRight = true;
1708 return nDone || Window::PreNotify( rNEvt );
1713 void SfxHelpIndexWindow_Impl::DataChanged( const DataChangedEvent& rDCEvt )
1715 Window::DataChanged( rDCEvt );
1717 if ( ( ( rDCEvt.GetType() == DataChangedEventType::SETTINGS ) ||
1718 ( rDCEvt.GetType() == DataChangedEventType::DISPLAY ) ) &&
1719 ( rDCEvt.GetFlags() & AllSettingsFlags::STYLE ) )
1721 SetBackground( Wallpaper( GetSettings().GetStyleSettings().GetFaceColor() ) );
1727 void SfxHelpIndexWindow_Impl::SetDoubleClickHdl( const Link<>& rLink )
1729 aPageDoubleClickLink = rLink;
1730 if ( pCPage )
1731 pCPage->SetOpenHdl( aPageDoubleClickLink );
1732 if ( pIPage )
1733 pIPage->SetDoubleClickHdl( aPageDoubleClickLink );
1734 if ( pSPage )
1735 pSPage->SetDoubleClickHdl( aPageDoubleClickLink );
1736 if ( pBPage )
1737 pBPage->SetDoubleClickHdl( aPageDoubleClickLink );
1742 void SfxHelpIndexWindow_Impl::SetFactory( const OUString& rFactory, bool bActive )
1744 if ( !rFactory.isEmpty() )
1746 GetIndexPage()->SetFactory( rFactory );
1747 // the index page did a check if rFactory is valid,
1748 // so the index page always returns a valid factory
1749 GetSearchPage()->SetFactory( GetIndexPage()->GetFactory() );
1750 if ( bActive )
1751 SetActiveFactory();
1755 OUString SfxHelpIndexWindow_Impl::GetSelectEntry() const
1757 OUString sRet;
1759 OString sName(m_pTabCtrl->GetPageName(m_pTabCtrl->GetCurPageId()));
1761 if (sName == "contents")
1763 sRet = pCPage->GetSelectEntry();
1765 else if (sName == "index")
1767 sRet = pIPage->GetSelectEntry();
1769 else if (sName == "find")
1771 sRet = pSPage->GetSelectEntry();
1773 else if (sName == "bookmarks")
1775 sRet = pBPage->GetSelectEntry();
1778 return sRet;
1781 void SfxHelpIndexWindow_Impl::AddBookmarks( const OUString& rTitle, const OUString& rURL )
1783 GetBookmarksPage()->AddBookmarks( rTitle, rURL );
1788 bool SfxHelpIndexWindow_Impl::IsValidFactory( const OUString& _rFactory )
1790 bool bValid = false;
1791 for ( sal_uInt16 i = 0; i < m_pActiveLB->GetEntryCount(); ++i )
1793 OUString* pFactory = static_cast<OUString*>(m_pActiveLB->GetEntryData(i));
1794 if ( *pFactory == _rFactory )
1796 bValid = true;
1797 break;
1800 return bValid;
1805 void SfxHelpIndexWindow_Impl::ClearSearchPage()
1807 if ( pSPage )
1808 pSPage->ClearPage();
1811 void SfxHelpIndexWindow_Impl::GrabFocusBack()
1813 OString sName(m_pTabCtrl->GetPageName(m_pTabCtrl->GetCurPageId()));
1815 if (sName == "contents" && pCPage)
1816 pCPage->SetFocusOnBox();
1817 else if (sName == "index" && pIPage)
1818 pIPage->SetFocusOnBox();
1819 else if (sName == "find" && pSPage)
1820 pSPage->SetFocusOnBox();
1821 else if (sName == "bookmarks" && pBPage)
1822 pBPage->SetFocusOnBox();
1825 bool SfxHelpIndexWindow_Impl::HasFocusOnEdit() const
1827 bool bRet = false;
1828 OString sName(m_pTabCtrl->GetPageName(m_pTabCtrl->GetCurPageId()));
1829 if (sName == "index" && pIPage)
1830 bRet = pIPage->HasFocusOnEdit();
1831 else if (sName == "find" && pSPage)
1832 bRet = pSPage->HasFocusOnEdit();
1833 return bRet;
1837 OUString SfxHelpIndexWindow_Impl::GetSearchText() const
1839 OUString sRet;
1840 OString sName(m_pTabCtrl->GetPageName(m_pTabCtrl->GetCurPageId()));
1841 if (sName == "find" && pSPage)
1842 sRet = pSPage->GetSearchText();
1843 return sRet;
1846 bool SfxHelpIndexWindow_Impl::IsFullWordSearch() const
1848 bool bRet = false;
1849 OString sName(m_pTabCtrl->GetPageName(m_pTabCtrl->GetCurPageId()));
1850 if (sName == "find" && pSPage)
1851 bRet = pSPage->IsFullWordSearch();
1852 return bRet;
1855 void SfxHelpIndexWindow_Impl::OpenKeyword( const OUString& rKeyword )
1857 sKeyword = rKeyword;
1858 DBG_ASSERT( pIPage, "invalid index page" );
1859 pIPage->SetKeyword( sKeyword );
1862 void SfxHelpIndexWindow_Impl::SelectExecutableEntry()
1864 OString sName(m_pTabCtrl->GetPageName(m_pTabCtrl->GetCurPageId()));
1865 if (sName == "index" && pIPage )
1866 pIPage->SelectExecutableEntry();
1869 // class TextWin_Impl ----------------------------------------------------
1871 TextWin_Impl::TextWin_Impl( vcl::Window* p ) : DockingWindow( p, 0 )
1875 bool TextWin_Impl::Notify( NotifyEvent& rNEvt )
1877 if( ( rNEvt.GetType() == MouseNotifyEvent::KEYINPUT ) && rNEvt.GetKeyEvent()->GetKeyCode().GetCode() == KEY_TAB )
1878 return GetParent()->Notify( rNEvt );
1879 else
1880 return DockingWindow::Notify( rNEvt );
1884 // remove docking area acceptor from layoutmanager, so it will not layout anything further .-)
1885 static void lcl_disableLayoutOfFrame(const Reference< XFrame2 >& xFrame)
1887 xFrame->setLayoutManager( Reference< XLayoutManager >() );
1890 // class SfxHelpTextWindow_Impl ------------------------------------------
1892 SfxHelpTextWindow_Impl::SfxHelpTextWindow_Impl( SfxHelpWindow_Impl* pParent ) :
1894 Window( pParent, WB_CLIPCHILDREN | WB_TABSTOP | WB_DIALOGCONTROL ),
1896 aToolBox ( VclPtr<ToolBox>::Create(this, 0) ),
1897 aOnStartupCB ( VclPtr<CheckBox>::Create(this, SfxResId( RID_HELP_ONSTARTUP_BOX )) ),
1898 aIndexOnImage ( SfxResId( IMG_HELP_TOOLBOX_INDEX_ON ) ),
1899 aIndexOffImage ( SfxResId( IMG_HELP_TOOLBOX_INDEX_OFF ) ),
1900 aIndexOnText ( SfxResId( STR_HELP_BUTTON_INDEX_ON ).toString() ),
1901 aIndexOffText ( SfxResId( STR_HELP_BUTTON_INDEX_OFF ).toString() ),
1902 aOnStartupText ( SfxResId( RID_HELP_ONSTARTUP_TEXT ).toString() ),
1903 pHelpWin ( pParent ),
1904 pTextWin ( VclPtr<TextWin_Impl>::Create( this ) ),
1905 pSrchDlg ( NULL ),
1906 nMinPos ( 0 ),
1907 bIsDebug ( false ),
1908 bIsIndexOn ( false ),
1909 bIsInClose ( false ),
1910 bIsFullWordSearch ( false )
1913 sfx2::AddToTaskPaneList( aToolBox.get() );
1915 xFrame = Frame::create( ::comphelper::getProcessComponentContext() );
1916 xFrame->initialize( VCLUnoHelper::GetInterface ( pTextWin ) );
1917 xFrame->setName( "OFFICE_HELP" );
1918 lcl_disableLayoutOfFrame(xFrame);
1920 aToolBox->SetHelpId( HID_HELP_TOOLBOX );
1922 aToolBox->InsertItem( TBI_INDEX, aIndexOffText );
1923 aToolBox->SetHelpId( TBI_INDEX, HID_HELP_TOOLBOXITEM_INDEX );
1924 aToolBox->InsertSeparator();
1925 aToolBox->InsertItem( TBI_BACKWARD, SfxResId( STR_HELP_BUTTON_PREV ).toString() );
1926 aToolBox->SetHelpId( TBI_BACKWARD, HID_HELP_TOOLBOXITEM_BACKWARD );
1927 aToolBox->InsertItem( TBI_FORWARD, SfxResId( STR_HELP_BUTTON_NEXT ).toString() );
1928 aToolBox->SetHelpId( TBI_FORWARD, HID_HELP_TOOLBOXITEM_FORWARD );
1929 aToolBox->InsertItem( TBI_START, SfxResId( STR_HELP_BUTTON_START ).toString() );
1930 aToolBox->SetHelpId( TBI_START, HID_HELP_TOOLBOXITEM_START );
1931 aToolBox->InsertSeparator();
1932 aToolBox->InsertItem( TBI_PRINT, SfxResId( STR_HELP_BUTTON_PRINT ).toString() );
1933 aToolBox->SetHelpId( TBI_PRINT, HID_HELP_TOOLBOXITEM_PRINT );
1934 aToolBox->InsertItem( TBI_BOOKMARKS, SfxResId( STR_HELP_BUTTON_ADDBOOKMARK ).toString() );
1935 aToolBox->SetHelpId( TBI_BOOKMARKS, HID_HELP_TOOLBOXITEM_BOOKMARKS );
1936 aToolBox->InsertItem( TBI_SEARCHDIALOG, SfxResId( STR_HELP_BUTTON_SEARCHDIALOG ).toString() );
1937 aToolBox->SetHelpId( TBI_SEARCHDIALOG, HID_HELP_TOOLBOXITEM_SEARCHDIALOG );
1939 InitToolBoxImages();
1940 aToolBox->Show();
1941 InitOnStartupBox( false );
1942 aOnStartupCB->SetClickHdl( LINK( this, SfxHelpTextWindow_Impl, CheckHdl ) );
1944 aSelectIdle.SetIdleHdl( LINK( this, SfxHelpTextWindow_Impl, SelectHdl ) );
1945 aSelectIdle.SetPriority( SchedulerPriority::LOWEST );
1947 char* pEnv = getenv( "help_debug" );
1948 if ( pEnv )
1949 bIsDebug = true;
1951 SvtMiscOptions().AddListenerLink( LINK( this, SfxHelpTextWindow_Impl, NotifyHdl ) );
1953 if ( !aOnStartupCB->GetHelpId().getLength() )
1954 aOnStartupCB->SetHelpId( HID_HELP_ONSTARTUP_BOX );
1959 SfxHelpTextWindow_Impl::~SfxHelpTextWindow_Impl()
1961 disposeOnce();
1964 void SfxHelpTextWindow_Impl::dispose()
1966 sfx2::RemoveFromTaskPaneList( aToolBox.get() );
1968 bIsInClose = true;
1969 SvtMiscOptions().RemoveListenerLink( LINK( this, SfxHelpTextWindow_Impl, NotifyHdl ) );
1970 pSrchDlg.disposeAndClear();
1971 aToolBox.disposeAndClear();
1972 aOnStartupCB.disposeAndClear();
1973 pHelpWin.clear();
1974 pTextWin.disposeAndClear();
1975 vcl::Window::dispose();
1980 bool SfxHelpTextWindow_Impl::HasSelection() const
1982 // is there any selection in the text and not only a cursor?
1983 bool bRet = false;
1984 Reference < XTextRange > xRange = getCursor();
1985 if ( xRange.is() )
1987 Reference < XText > xText = xRange->getText();
1988 Reference < XTextCursor > xCursor = xText->createTextCursorByRange( xRange );
1989 bRet = !xCursor->isCollapsed();
1992 return bRet;
1997 void SfxHelpTextWindow_Impl::InitToolBoxImages()
1999 bool bLarge = SvtMiscOptions().AreCurrentSymbolsLarge();
2001 aIndexOnImage = Image( SfxResId( bLarge ? IMG_HELP_TOOLBOX_L_INDEX_ON : IMG_HELP_TOOLBOX_INDEX_ON ) );
2002 aIndexOffImage = Image( SfxResId( bLarge ? IMG_HELP_TOOLBOX_L_INDEX_OFF : IMG_HELP_TOOLBOX_INDEX_OFF ) );
2004 aToolBox->SetItemImage( TBI_INDEX, bIsIndexOn ? aIndexOffImage : aIndexOnImage );
2006 aToolBox->SetItemImage( TBI_BACKWARD,
2007 Image( SfxResId( bLarge ? IMG_HELP_TOOLBOX_L_PREV : IMG_HELP_TOOLBOX_PREV ) )
2010 aToolBox->SetItemImage( TBI_FORWARD,
2011 Image( SfxResId( bLarge ? IMG_HELP_TOOLBOX_L_NEXT : IMG_HELP_TOOLBOX_NEXT ) )
2014 aToolBox->SetItemImage( TBI_START,
2015 Image( SfxResId( bLarge ? IMG_HELP_TOOLBOX_L_START : IMG_HELP_TOOLBOX_START ) )
2018 aToolBox->SetItemImage( TBI_PRINT,
2019 Image( SfxResId( bLarge ? IMG_HELP_TOOLBOX_L_PRINT : IMG_HELP_TOOLBOX_PRINT ) )
2022 aToolBox->SetItemImage( TBI_BOOKMARKS,
2023 Image( SfxResId( bLarge ? IMG_HELP_TOOLBOX_L_BOOKMARKS : IMG_HELP_TOOLBOX_BOOKMARKS ) )
2026 aToolBox->SetItemImage( TBI_SEARCHDIALOG,
2027 Image( SfxResId( bLarge ? IMG_HELP_TOOLBOX_L_SEARCHDIALOG : IMG_HELP_TOOLBOX_SEARCHDIALOG ) )
2030 Size aSize = aToolBox->CalcWindowSizePixel();
2031 aSize.Height() += TOOLBOX_OFFSET;
2032 aToolBox->SetPosSizePixel( Point( 0, TOOLBOX_OFFSET ), aSize );
2034 SvtMiscOptions aMiscOptions;
2035 if ( aMiscOptions.GetToolboxStyle() != aToolBox->GetOutStyle() )
2036 aToolBox->SetOutStyle( aMiscOptions.GetToolboxStyle() );
2041 void SfxHelpTextWindow_Impl::InitOnStartupBox( bool bOnlyText )
2043 sCurrentFactory = SfxHelp::GetCurrentModuleIdentifier();
2045 Reference< XComponentContext > xContext = ::comphelper::getProcessComponentContext();
2046 Reference< XInterface > xConfig;
2047 OUString sPath( PATH_OFFICE_FACTORIES );
2048 sPath += sCurrentFactory;
2049 OUString sKey( KEY_HELP_ON_OPEN );
2051 // Attention: This check boy knows two states:
2052 // 1) Reading of the config key fails with an exception or by getting an empty Any (!) => check box must be hidden
2053 // 2) We read sal_True/sal_False => check box must be shown and enabled/disabled
2055 bool bHideBox = true;
2056 bool bHelpAtStartup = false;
2059 xConfiguration = ConfigurationHelper::openConfig(
2060 xContext, PACKAGE_SETUP, ConfigurationHelper::E_STANDARD );
2061 if ( xConfiguration.is() )
2063 Any aAny = ConfigurationHelper::readRelativeKey( xConfiguration, sPath, sKey );
2064 if (aAny >>= bHelpAtStartup)
2065 bHideBox = false;
2068 catch( Exception& )
2070 bHideBox = true;
2073 if ( bHideBox )
2074 aOnStartupCB->Hide();
2075 else
2077 // detect module name
2078 OUString sModuleName;
2080 if ( xConfiguration.is() )
2082 OUString sTemp;
2083 sKey = KEY_UI_NAME;
2086 Any aAny = ConfigurationHelper::readRelativeKey( xConfiguration, sPath, sKey );
2087 aAny >>= sTemp;
2089 catch( Exception& )
2091 SAL_WARN( "sfx.appl", "SfxHelpTextWindow_Impl::InitOnStartupBox(): unexpected exception" );
2093 sModuleName = sTemp;
2096 if ( !sModuleName.isEmpty() )
2098 // set module name in checkbox text
2099 OUString sText( aOnStartupText );
2100 sText = sText.replaceFirst( "%MODULENAME", sModuleName );
2101 aOnStartupCB->SetText( sText );
2102 // and show it
2103 aOnStartupCB->Show();
2104 // set check state
2105 aOnStartupCB->Check( bHelpAtStartup );
2106 aOnStartupCB->SaveValue();
2108 // calculate and set optimal width of the onstartup checkbox
2109 OUString sCBText( "XXX" );
2110 sCBText += aOnStartupCB->GetText();
2111 long nTextWidth = aOnStartupCB->GetTextWidth( sCBText );
2112 Size aSize = aOnStartupCB->GetSizePixel();
2113 aSize.Width() = nTextWidth;
2114 aOnStartupCB->SetSizePixel( aSize );
2115 SetOnStartupBoxPosition();
2118 if ( !bOnlyText )
2120 // set position of the checkbox
2121 Size a3Size = LogicToPixel( Size( 3, 3 ), MAP_APPFONT );
2122 Size aTBSize = aToolBox->GetSizePixel();
2123 Size aCBSize = aOnStartupCB->GetSizePixel();
2124 Point aPnt = aToolBox->GetPosPixel();
2125 aPnt.X() += aTBSize.Width() + a3Size.Width();
2126 aPnt.Y() += ( ( aTBSize.Height() - aCBSize.Height() ) / 2 );
2127 aOnStartupCB->SetPosPixel( aPnt );
2128 nMinPos = aPnt.X();
2135 void SfxHelpTextWindow_Impl::SetOnStartupBoxPosition()
2137 long nX = std::max( GetOutputSizePixel().Width() - aOnStartupCB->GetSizePixel().Width(), nMinPos );
2138 Point aPos = aOnStartupCB->GetPosPixel();
2139 aPos.X() = nX;
2140 aOnStartupCB->SetPosPixel( aPos );
2145 Reference< XBreakIterator > SfxHelpTextWindow_Impl::GetBreakIterator()
2147 if ( !xBreakIterator.is() )
2148 xBreakIterator = vcl::unohelper::CreateBreakIterator();
2149 DBG_ASSERT( xBreakIterator.is(), "Could not create BreakIterator" );
2150 return xBreakIterator;
2155 Reference< XTextRange > SfxHelpTextWindow_Impl::getCursor() const
2157 // return the current cursor
2158 Reference< XTextRange > xCursor;
2162 Reference < XSelectionSupplier > xSelSup( xFrame->getController(), UNO_QUERY );
2163 if ( xSelSup.is() )
2165 Any aAny = xSelSup->getSelection();
2166 Reference < XIndexAccess > xSelection;
2167 if ( aAny >>= xSelection )
2169 if ( xSelection->getCount() == 1 )
2171 aAny = xSelection->getByIndex(0);
2172 aAny >>= xCursor;
2177 catch( Exception& )
2179 OSL_FAIL( "SfxHelpTextWindow_Impl::getCursor(): unexpected exception" );
2182 return xCursor;
2187 bool SfxHelpTextWindow_Impl::isHandledKey( const vcl::KeyCode& _rKeyCode )
2189 bool bRet = false;
2190 sal_uInt16 nCode = _rKeyCode.GetCode();
2192 // the keys <CTRL><A> (select all), <CTRL><C> (copy),
2193 // <CTRL><F> (find), <CTRL><P> (print) and <CTRL><W> (close window)
2194 // were handled in help
2195 if ( _rKeyCode.IsMod1() &&
2196 ( KEY_A == nCode || KEY_C == nCode || KEY_F == nCode || KEY_P == nCode || KEY_W == nCode ) )
2198 if ( KEY_F == nCode )
2199 DoSearch();
2200 else
2201 bRet = true;
2204 return bRet;
2209 IMPL_LINK_NOARG_TYPED(SfxHelpTextWindow_Impl, SelectHdl, Idle *, void)
2213 // select the words, which are equal to the search text of the search page
2214 Reference < XController > xController = xFrame->getController();
2215 if ( xController.is() )
2217 // get document
2218 Reference < XSearchable > xSearchable( xController->getModel(), UNO_QUERY );
2219 if ( xSearchable.is() )
2221 // create descriptor, set string and find all words
2222 Reference < XSearchDescriptor > xSrchDesc = xSearchable->createSearchDescriptor();
2223 xSrchDesc->setPropertyValue( "SearchRegularExpression", makeAny( true ) );
2224 if ( bIsFullWordSearch )
2225 xSrchDesc->setPropertyValue( "SearchWords", makeAny( true ) );
2227 OUString sSearchString = sfx2::PrepareSearchString( aSearchText, GetBreakIterator(), false );
2228 xSrchDesc->setSearchString( sSearchString );
2229 Reference< XIndexAccess > xSelection = xSearchable->findAll( xSrchDesc );
2231 // then select all found words
2232 Reference < XSelectionSupplier > xSelectionSup( xController, UNO_QUERY );
2233 if ( xSelectionSup.is() )
2235 Any aAny;
2236 aAny <<= xSelection;
2237 xSelectionSup->select( aAny );
2242 catch( Exception& )
2244 OSL_FAIL( "SfxHelpTextWindow_Impl::SelectHdl(): unexpected exception" );
2250 IMPL_LINK( SfxHelpTextWindow_Impl, NotifyHdl, SvtMiscOptions*, pOptions )
2252 (void)pOptions; // unused variable
2253 InitToolBoxImages();
2254 Resize();
2255 aToolBox->Invalidate();
2256 return 0;
2261 IMPL_LINK( SfxHelpTextWindow_Impl, FindHdl, sfx2::SearchDialog*, pDlg )
2263 bool bWrapAround = ( NULL == pDlg );
2264 if ( bWrapAround )
2265 pDlg = pSrchDlg;
2266 DBG_ASSERT( pDlg, "invalid search dialog" );
2267 OUString sSearchText = pDlg->GetSearchText();
2270 // select the words, which are equal to the search text of the search page
2271 Reference < XController > xController = xFrame->getController();
2272 if ( xController.is() )
2274 // get document
2275 Reference < XSearchable > xSearchable( xController->getModel(), UNO_QUERY );
2276 if ( xSearchable.is() )
2278 // create descriptor, set string and find all words
2279 Reference < XSearchDescriptor > xSrchDesc = xSearchable->createSearchDescriptor();
2280 xSrchDesc->setPropertyValue( "SearchWords", makeAny(pDlg->IsOnlyWholeWords()) );
2281 xSrchDesc->setPropertyValue( "SearchCaseSensitive", makeAny(pDlg->IsMarchCase()) );
2282 xSrchDesc->setPropertyValue( "SearchBackwards", makeAny(pDlg->IsSearchBackwards()) );
2283 xSrchDesc->setSearchString( sSearchText );
2284 Reference< XInterface > xSelection;
2285 Reference< XTextRange > xCursor = getCursor();
2287 if ( xCursor.is() )
2289 if ( pDlg->IsSearchBackwards() )
2290 xCursor = xCursor->getStart();
2291 xSelection = xSearchable->findNext( xCursor, xSrchDesc );
2293 else
2294 xSelection = xSearchable->findFirst( xSrchDesc );
2296 // then select the found word
2297 if ( xSelection.is() )
2299 Reference < XSelectionSupplier > xSelectionSup( xController, UNO_QUERY );
2300 if ( xSelectionSup.is() )
2302 Any aAny;
2303 aAny <<= xSelection;
2304 xSelectionSup->select( aAny );
2307 else if ( pDlg->IsWrapAround() && !bWrapAround )
2309 Reference < text::XTextViewCursorSupplier > xCrsrSupp( xController, uno::UNO_QUERY );
2310 Reference < text::XTextViewCursor > xTVCrsr( xCrsrSupp->getViewCursor(), uno::UNO_QUERY );
2311 if ( xTVCrsr.is() )
2313 Reference < text::XTextDocument > xDoc( xController->getModel(), uno::UNO_QUERY );
2314 Reference < text::XText > xText = xDoc->getText();
2315 if ( xText.is() )
2317 if ( pDlg->IsSearchBackwards() )
2318 xTVCrsr->gotoRange( xText->getEnd(), sal_False );
2319 else
2320 xTVCrsr->gotoRange( xText->getStart(), sal_False );
2321 FindHdl( NULL );
2325 else
2327 DBG_ASSERT( pSrchDlg, "no search dialog" );
2328 ScopedVclPtrInstance< MessageDialog > aBox(pSrchDlg, SfxResId( STR_INFO_NOSEARCHTEXTFOUND ), VCL_MESSAGE_INFO);
2329 aBox->Execute();
2330 pSrchDlg->SetFocusOnEdit();
2335 catch( Exception& )
2337 OSL_FAIL( "SfxHelpTextWindow_Impl::SelectHdl(): unexpected exception" );
2340 return 0;
2345 IMPL_LINK( SfxHelpTextWindow_Impl, CloseHdl, sfx2::SearchDialog*, /*pDlg*/ )
2347 pSrchDlg.clear();
2348 return 0;
2353 IMPL_LINK( SfxHelpTextWindow_Impl, CheckHdl, CheckBox*, pBox )
2355 if ( xConfiguration.is() )
2357 bool bChecked = pBox->IsChecked();
2358 OUString sPath( PATH_OFFICE_FACTORIES );
2359 sPath += sCurrentFactory;
2362 ConfigurationHelper::writeRelativeKey(
2363 xConfiguration, sPath, KEY_HELP_ON_OPEN, makeAny( bChecked ) );
2364 ConfigurationHelper::flush( xConfiguration );
2366 catch( Exception& )
2368 SAL_WARN( "sfx.appl", "SfxHelpTextWindow_Impl::CheckHdl(): unexpected exception" );
2372 return 0;
2377 void SfxHelpTextWindow_Impl::Resize()
2379 Size aSize = GetOutputSizePixel();
2380 long nToolBoxHeight = aToolBox->GetSizePixel().Height() + TOOLBOX_OFFSET;
2381 aSize.Height() -= nToolBoxHeight;
2382 pTextWin->SetPosSizePixel( Point( 0, nToolBoxHeight ), aSize );
2383 SetOnStartupBoxPosition();
2388 bool SfxHelpTextWindow_Impl::PreNotify( NotifyEvent& rNEvt )
2390 bool nDone = false;
2391 MouseNotifyEvent nType = rNEvt.GetType();
2392 if ( MouseNotifyEvent::COMMAND == nType && rNEvt.GetCommandEvent() )
2394 const CommandEvent* pCmdEvt = rNEvt.GetCommandEvent();
2395 vcl::Window* pCmdWin = rNEvt.GetWindow();
2397 if ( pCmdEvt->GetCommand() == CommandEventId::ContextMenu && pCmdWin != this && pCmdWin != aToolBox.get() )
2399 Point aPos;
2400 if ( pCmdEvt->IsMouseEvent() )
2401 aPos = pCmdEvt->GetMousePosPixel();
2402 else
2403 aPos = Point( pTextWin->GetPosPixel().X() + 20, 20 );
2404 aPos.Y() += pTextWin->GetPosPixel().Y();
2405 PopupMenu aMenu;
2406 if ( bIsIndexOn )
2407 aMenu.InsertItem( TBI_INDEX, aIndexOffText, Image( SfxResId( IMG_HELP_TOOLBOX_INDEX_OFF ) ) );
2408 else
2409 aMenu.InsertItem( TBI_INDEX, aIndexOnText, Image( SfxResId( IMG_HELP_TOOLBOX_INDEX_ON ) ) );
2411 aMenu.SetHelpId( TBI_INDEX, HID_HELP_TOOLBOXITEM_INDEX );
2412 aMenu.InsertSeparator();
2413 aMenu.InsertItem( TBI_BACKWARD,
2414 SfxResId( STR_HELP_BUTTON_PREV ).toString(),
2415 Image( SfxResId( IMG_HELP_TOOLBOX_PREV ) )
2417 aMenu.SetHelpId( TBI_BACKWARD, HID_HELP_TOOLBOXITEM_BACKWARD );
2418 aMenu.EnableItem( TBI_BACKWARD, pHelpWin->HasHistoryPredecessor() );
2419 aMenu.InsertItem( TBI_FORWARD,
2420 SfxResId( STR_HELP_BUTTON_NEXT ).toString(),
2421 Image( SfxResId( IMG_HELP_TOOLBOX_NEXT ) )
2423 aMenu.SetHelpId( TBI_FORWARD, HID_HELP_TOOLBOXITEM_FORWARD );
2424 aMenu.EnableItem( TBI_FORWARD, pHelpWin->HasHistorySuccessor() );
2425 aMenu.InsertItem( TBI_START,
2426 SfxResId( STR_HELP_BUTTON_START ).toString(),
2427 Image( SfxResId( IMG_HELP_TOOLBOX_START ) )
2429 aMenu.SetHelpId( TBI_START, HID_HELP_TOOLBOXITEM_START );
2430 aMenu.InsertSeparator();
2431 aMenu.InsertItem( TBI_PRINT,
2432 SfxResId( STR_HELP_BUTTON_PRINT ).toString(),
2433 Image( SfxResId( IMG_HELP_TOOLBOX_PRINT ) )
2435 aMenu.SetHelpId( TBI_PRINT, HID_HELP_TOOLBOXITEM_PRINT );
2436 aMenu.InsertItem( TBI_BOOKMARKS,
2437 SfxResId( STR_HELP_BUTTON_ADDBOOKMARK ).toString(),
2438 Image( SfxResId( IMG_HELP_TOOLBOX_BOOKMARKS ) )
2440 aMenu.SetHelpId( TBI_BOOKMARKS, HID_HELP_TOOLBOXITEM_BOOKMARKS );
2441 aMenu.InsertItem( TBI_SEARCHDIALOG,
2442 SfxResId( STR_HELP_BUTTON_SEARCHDIALOG ).toString(),
2443 Image( SfxResId( IMG_HELP_TOOLBOX_SEARCHDIALOG ) )
2445 aMenu.SetHelpId( TBI_SEARCHDIALOG, HID_HELP_TOOLBOXITEM_SEARCHDIALOG );
2446 aMenu.InsertSeparator();
2447 aMenu.InsertItem( TBI_SELECTIONMODE, SfxResId( STR_HELP_MENU_TEXT_SELECTION_MODE ).toString() );
2448 aMenu.SetHelpId( TBI_SELECTIONMODE, HID_HELP_TEXT_SELECTION_MODE );
2449 URL aURL;
2450 aURL.Complete = ".uno:SelectTextMode";
2451 PARSE_URL( aURL );
2452 Reference < XDispatch > xDisp = xFrame->queryDispatch( aURL, OUString(), 0 );
2453 if(xDisp.is())
2455 HelpStatusListener_Impl* pStateListener;
2456 Reference<XStatusListener>xStateListener = pStateListener =
2457 new HelpStatusListener_Impl(xDisp, aURL );
2458 FeatureStateEvent rEvent = pStateListener->GetStateEvent();
2459 bool bCheck = false;
2460 rEvent.State >>= bCheck;
2461 aMenu.CheckItem(TBI_SELECTIONMODE, bCheck);
2463 aMenu.InsertSeparator();
2464 aMenu.InsertItem( TBI_COPY,
2465 SfxResId(STR_HELP_MENU_TEXT_COPY).toString(),
2466 Image( SfxResId( IMG_HELP_TOOLBOX_COPY ) )
2468 aMenu.SetHelpId( TBI_COPY, ".uno:Copy" );
2469 aMenu.EnableItem( TBI_COPY, HasSelection() );
2471 if ( bIsDebug )
2473 aMenu.InsertSeparator();
2474 aMenu.InsertItem( TBI_SOURCEVIEW, SfxResId(STR_HELP_BUTTON_SOURCEVIEW).toString() );
2477 if( ! SvtMenuOptions().IsEntryHidingEnabled() )
2478 aMenu.SetMenuFlags( aMenu.GetMenuFlags() | MenuFlags::HideDisabledEntries );
2480 sal_uInt16 nId = aMenu.Execute( this, aPos );
2481 pHelpWin->DoAction( nId );
2482 nDone = true;
2485 else if ( MouseNotifyEvent::KEYINPUT == nType && rNEvt.GetKeyEvent() )
2487 const KeyEvent* pKEvt = rNEvt.GetKeyEvent();
2488 const vcl::KeyCode& rKeyCode = pKEvt->GetKeyCode();
2489 sal_uInt16 nKeyGroup = rKeyCode.GetGroup();
2490 sal_uInt16 nKey = rKeyCode.GetCode();
2491 if ( KEYGROUP_ALPHA == nKeyGroup && !isHandledKey( rKeyCode ) )
2493 // do nothing disables the writer accelerators
2494 nDone = true;
2496 else if ( rKeyCode.IsMod1() && ( KEY_F4 == nKey || KEY_W == nKey ) )
2498 // <CTRL><F4> or <CTRL><W> -> close top frame
2499 pHelpWin->CloseWindow();
2500 nDone = true;
2502 else if ( KEY_TAB == nKey && aOnStartupCB->HasChildPathFocus() )
2504 aToolBox->GrabFocus();
2505 nDone = true;
2509 return nDone || Window::PreNotify( rNEvt );
2514 void SfxHelpTextWindow_Impl::GetFocus()
2516 if ( !bIsInClose )
2520 if( xFrame.is() )
2522 Reference< ::com::sun::star::awt::XWindow > xWindow = xFrame->getComponentWindow();
2523 if( xWindow.is() )
2524 xWindow->setFocus();
2527 catch( Exception& )
2529 SAL_WARN( "sfx.appl", "SfxHelpTextWindow_Impl::GetFocus(): unexpected exception" );
2536 void SfxHelpTextWindow_Impl::DataChanged( const DataChangedEvent& rDCEvt )
2538 Window::DataChanged( rDCEvt );
2540 if ( ( ( rDCEvt.GetType() == DataChangedEventType::SETTINGS ) ||
2541 ( rDCEvt.GetType() == DataChangedEventType::DISPLAY ) ) &&
2542 ( rDCEvt.GetFlags() & AllSettingsFlags::STYLE ) )
2544 SetBackground( Wallpaper( GetSettings().GetStyleSettings().GetFaceColor() ) );
2545 InitToolBoxImages();
2551 void SfxHelpTextWindow_Impl::ToggleIndex( bool bOn )
2553 bIsIndexOn = bOn;
2554 if ( bIsIndexOn )
2556 aToolBox->SetItemImage( TBI_INDEX, aIndexOffImage );
2557 aToolBox->SetItemText( TBI_INDEX, aIndexOffText );
2559 else
2561 aToolBox->SetItemImage( TBI_INDEX, aIndexOnImage );
2562 aToolBox->SetItemText( TBI_INDEX, aIndexOnText );
2568 void SfxHelpTextWindow_Impl::SelectSearchText( const OUString& rSearchText, bool _bIsFullWordSearch )
2570 aSearchText = rSearchText;
2571 bIsFullWordSearch = _bIsFullWordSearch;
2572 aSelectIdle.Start();
2577 void SfxHelpTextWindow_Impl::SetPageStyleHeaderOff() const
2579 #ifdef DBG_UTIL
2580 bool bSetOff = false;
2581 #endif
2582 // set off the pagestyle header to prevent print output of the help URL
2585 Reference < XController > xController = xFrame->getController();
2586 Reference < XSelectionSupplier > xSelSup( xController, UNO_QUERY );
2587 if ( xSelSup.is() )
2589 Reference < XIndexAccess > xSelection;
2590 if ( xSelSup->getSelection() >>= xSelection )
2592 Reference < XTextRange > xRange;
2593 if ( xSelection->getByIndex(0) >>= xRange )
2595 Reference < XText > xText = xRange->getText();
2596 Reference < XPropertySet > xProps( xText->createTextCursorByRange( xRange ), UNO_QUERY );
2597 OUString sStyleName;
2598 if ( xProps->getPropertyValue( "PageStyleName" ) >>= sStyleName )
2600 Reference < XStyleFamiliesSupplier > xStyles( xController->getModel(), UNO_QUERY );
2601 Reference < XNameContainer > xContainer;
2602 if ( xStyles->getStyleFamilies()->getByName( "PageStyles" )
2603 >>= xContainer )
2605 Reference < XStyle > xStyle;
2606 if ( xContainer->getByName( sStyleName ) >>= xStyle )
2608 Reference < XPropertySet > xPropSet( xStyle, UNO_QUERY );
2609 xPropSet->setPropertyValue( "HeaderIsOn", makeAny( false ) );
2611 Reference< XModifiable > xReset(xStyles, UNO_QUERY);
2612 xReset->setModified(sal_False);
2613 #ifdef DBG_UTIL
2614 bSetOff = true;
2615 #endif
2623 catch( Exception& )
2625 SAL_WARN( "sfx.appl", "SfxHelpTextWindow_Impl::SetPageStyleHeaderOff(): unexpected exception" );
2628 #ifdef DBG_UTIL
2629 if ( !bSetOff )
2631 SAL_WARN( "sfx.appl", "SfxHelpTextWindow_Impl::SetPageStyleHeaderOff(): set off failed" );
2633 #endif
2638 void SfxHelpTextWindow_Impl::CloseFrame()
2640 bIsInClose = true;
2643 ::com::sun::star::uno::Reference< ::com::sun::star::util::XCloseable > xCloseable ( xFrame, ::com::sun::star::uno::UNO_QUERY );
2644 if (xCloseable.is())
2645 xCloseable->close(sal_True);
2647 catch( ::com::sun::star::util::CloseVetoException& )
2654 void SfxHelpTextWindow_Impl::DoSearch()
2656 if ( !pSrchDlg )
2658 // create the search dialog
2659 pSrchDlg = VclPtr<sfx2::SearchDialog>::Create( pTextWin, "HelpSearchDialog" );
2660 // set handler
2661 pSrchDlg->SetFindHdl( LINK( this, SfxHelpTextWindow_Impl, FindHdl ) );
2662 pSrchDlg->SetCloseHdl( LINK( this, SfxHelpTextWindow_Impl, CloseHdl ) );
2663 // get selected text of the help page to set it as the search text
2664 Reference< XTextRange > xCursor = getCursor();
2665 if ( xCursor.is() )
2667 OUString sText = xCursor->getString();
2668 if ( !sText.isEmpty() )
2669 pSrchDlg->SetSearchText( sText );
2671 pSrchDlg->Show();
2675 // class SfxHelpWindow_Impl ----------------------------------------------
2677 void SfxHelpWindow_Impl::Resize()
2679 SplitWindow::Resize();
2680 InitSizes();
2685 void SfxHelpWindow_Impl::Split()
2687 static long nMinSplitSize = 5;
2688 static long nMaxSplitSize = 99 - nMinSplitSize;
2690 SplitWindow::Split();
2692 nIndexSize = GetItemSize( INDEXWIN_ID );
2693 nTextSize = GetItemSize( TEXTWIN_ID );
2695 bool bMod = false;
2696 if( nIndexSize < nMinSplitSize )
2698 nIndexSize = nMinSplitSize;
2699 nTextSize = nMaxSplitSize;
2701 bMod = true;
2703 else if( nTextSize < nMinSplitSize )
2705 nTextSize = nMinSplitSize;
2706 nIndexSize = nMaxSplitSize;
2708 bMod = true;
2710 else
2711 bMod = false;
2713 if( bMod )
2715 SetItemSize( INDEXWIN_ID, nIndexSize );
2716 SetItemSize( TEXTWIN_ID, nTextSize );
2719 InitSizes();
2722 void SfxHelpWindow_Impl::GetFocus()
2724 if( pTextWin )
2725 pTextWin->GrabFocus();
2726 else
2727 vcl::Window::GetFocus();
2730 void SfxHelpWindow_Impl::MakeLayout()
2732 if ( nHeight > 0 && xWindow.is() )
2734 vcl::Window* pScreenWin = VCLUnoHelper::GetWindow(xWindow);
2736 /* #i55528#
2737 Hide() / Show() will produce strange effects.
2738 The returned size (used later to be written back into the configuration)
2739 is not the right after a resize during the window is hidden.
2740 If this resize is done if the window is visible evyrthing works as aspected.
2741 Some VCL-patches could not solve this problem so I've established the
2742 workaround: resize the help window if it's visible .-)
2744 ::com::sun::star::awt::Rectangle aRect = xWindow->getPosSize();
2745 sal_Int32 nOldWidth = bIndex ? nCollapseWidth : nExpandWidth;
2746 sal_Int32 nWidth = bIndex ? nExpandWidth : nCollapseWidth;
2747 xWindow->setPosSize( aRect.X, aRect.Y, nWidth, nHeight, ::com::sun::star::awt::PosSize::SIZE );
2749 if ( aRect.Width > 0 && aRect.Height > 0 )
2751 Rectangle aScreenRect = pScreenWin->GetClientWindowExtentsRelative( NULL );
2752 Point aNewPos = aScreenRect.TopLeft();
2753 sal_Int32 nDiffWidth = nOldWidth - nWidth;
2754 aNewPos.X() += nDiffWidth;
2755 pScreenWin->SetPosPixel( aNewPos );
2757 else if ( aWinPos.X() > 0 && aWinPos.Y() > 0 )
2758 pScreenWin->SetPosPixel( aWinPos );
2761 Clear();
2763 if ( bIndex )
2765 pIndexWin->Show();
2766 InsertItem( COLSET_ID, 100, SPLITWINDOW_APPEND, SPLITSET_ID, SWIB_PERCENTSIZE | SWIB_COLSET );
2767 InsertItem( INDEXWIN_ID, pIndexWin, nIndexSize, SPLITWINDOW_APPEND, COLSET_ID, SWIB_PERCENTSIZE );
2768 InsertItem( TEXTWIN_ID, pTextWin, nTextSize, SPLITWINDOW_APPEND, COLSET_ID, SWIB_PERCENTSIZE );
2770 else
2772 pIndexWin->Hide();
2773 InsertItem( COLSET_ID, 100, SPLITWINDOW_APPEND, SPLITSET_ID, SWIB_PERCENTSIZE | SWIB_COLSET );
2774 InsertItem( TEXTWIN_ID, pTextWin, 100, SPLITWINDOW_APPEND, 1, SWIB_PERCENTSIZE );
2780 void SfxHelpWindow_Impl::InitSizes()
2782 if ( xWindow.is() )
2784 ::com::sun::star::awt::Rectangle aRect = xWindow->getPosSize();
2785 nHeight = aRect.Height;
2787 if ( bIndex )
2789 nExpandWidth = aRect.Width;
2790 nCollapseWidth = nExpandWidth * nTextSize / 100;
2792 else
2794 nCollapseWidth = aRect.Width;
2795 nExpandWidth = nTextSize ? nCollapseWidth * 100 / nTextSize : 0;
2802 void SfxHelpWindow_Impl::LoadConfig()
2804 SvtViewOptions aViewOpt( E_WINDOW, CONFIGNAME_HELPWIN );
2805 if ( aViewOpt.Exists() )
2807 bIndex = aViewOpt.IsVisible();
2808 OUString aUserData;
2809 Any aUserItem = aViewOpt.GetUserItem( USERITEM_NAME );
2810 OUString aTemp;
2811 if ( aUserItem >>= aTemp )
2813 aUserData = aTemp;
2814 DBG_ASSERT( comphelper::string::getTokenCount(aUserData, ';') == 6, "invalid user data" );
2815 sal_Int32 nIdx = 0;
2816 nIndexSize = aUserData.getToken( 0, ';', nIdx ).toInt32();
2817 nTextSize = aUserData.getToken( 0, ';', nIdx ).toInt32();
2818 sal_Int32 nWidth = aUserData.getToken( 0, ';', nIdx ).toInt32();
2819 nHeight = aUserData.getToken( 0, ';', nIdx ).toInt32();
2820 aWinPos.X() = aUserData.getToken( 0, ';', nIdx ).toInt32();
2821 aWinPos.Y() = aUserData.getToken( 0, ';', nIdx ).toInt32();
2822 if ( bIndex )
2824 nExpandWidth = nWidth;
2825 nCollapseWidth = nExpandWidth * nTextSize / 100;
2827 else if (nTextSize != 0)
2829 nCollapseWidth = nWidth;
2830 nExpandWidth = nCollapseWidth * 100 / nTextSize;
2834 pTextWin->ToggleIndex( bIndex );
2840 void SfxHelpWindow_Impl::SaveConfig()
2842 SvtViewOptions aViewOpt( E_WINDOW, CONFIGNAME_HELPWIN );
2843 sal_Int32 nW = 0, nH = 0;
2845 if ( xWindow.is() )
2847 ::com::sun::star::awt::Rectangle aRect = xWindow->getPosSize();
2848 nW = aRect.Width;
2849 nH = aRect.Height;
2852 aViewOpt.SetVisible( bIndex );
2853 OUString aUserData = OUString::number( nIndexSize );
2854 aUserData += ";";
2855 aUserData += OUString::number( nTextSize );
2856 aUserData += ";";
2857 aUserData += OUString::number( nW );
2858 aUserData += ";";
2859 aUserData += OUString::number( nH );
2861 vcl::Window* pScreenWin = VCLUnoHelper::GetWindow( xWindow );
2862 aWinPos = pScreenWin->GetWindowExtentsRelative( NULL ).TopLeft();
2863 aUserData += ";";
2864 aUserData += OUString::number( aWinPos.X() );
2865 aUserData += ";";
2866 aUserData += OUString::number( aWinPos.Y() );
2868 aViewOpt.SetUserItem( USERITEM_NAME, makeAny( OUString( aUserData ) ) );
2873 void SfxHelpWindow_Impl::ShowStartPage()
2875 OUString sHelpURL = SfxHelpWindow_Impl::buildHelpURL(pIndexWin->GetFactory(),
2876 "/start",
2877 OUString(),
2878 true);
2879 loadHelpContent(sHelpURL);
2884 IMPL_LINK_TYPED( SfxHelpWindow_Impl, SelectHdl, ToolBox* , pToolBox, void )
2886 if ( pToolBox )
2888 bGrabFocusToToolBox = pToolBox->HasChildPathFocus();
2889 DoAction( pToolBox->GetCurItemId() );
2895 IMPL_LINK_NOARG(SfxHelpWindow_Impl, OpenHdl)
2897 pIndexWin->SelectExecutableEntry();
2898 OUString aEntry = pIndexWin->GetSelectEntry();
2900 if ( aEntry.isEmpty() )
2901 return 0;
2903 OUString sHelpURL;
2905 bool bComplete = OUString(aEntry).toAsciiLowerCase().match("vnd.sun.star.help");
2907 if (bComplete)
2908 sHelpURL = OUString(aEntry);
2909 else
2911 OUString aId;
2912 OUString aAnchor = OUString('#');
2913 if ( comphelper::string::getTokenCount(aEntry, '#') == 2 )
2915 aId = aEntry.getToken( 0, '#' );
2916 aAnchor += aEntry.getToken( 1, '#' );
2918 else
2919 aId = aEntry;
2921 aEntry = "/";
2922 aEntry += aId;
2924 sHelpURL = SfxHelpWindow_Impl::buildHelpURL(pIndexWin->GetFactory(),
2925 aEntry,
2926 aAnchor,
2927 true);
2930 loadHelpContent(sHelpURL);
2932 return 0;
2937 IMPL_LINK( SfxHelpWindow_Impl, SelectFactoryHdl, SfxHelpIndexWindow_Impl* , pWin )
2939 if ( sTitle.isEmpty() )
2940 sTitle = GetParent()->GetText();
2942 OUString aNewTitle = sTitle + " - " + pIndexWin->GetActiveFactoryTitle();
2944 Reference< XTitle > xTitle(xFrame, UNO_QUERY);
2945 if (xTitle.is ())
2946 xTitle->setTitle (aNewTitle);
2948 if ( pWin )
2949 ShowStartPage();
2950 pIndexWin->ClearSearchPage();
2952 return 0;
2957 IMPL_LINK( SfxHelpWindow_Impl, ChangeHdl, HelpListener_Impl*, pListener )
2959 SetFactory( pListener->GetFactory() );
2960 return 0;
2965 void SfxHelpWindow_Impl::openDone(const OUString& sURL ,
2966 bool bSuccess)
2968 INetURLObject aObj( sURL );
2969 if ( aObj.GetProtocol() == INetProtocol::VndSunStarHelp )
2970 SetFactory( aObj.GetHost() );
2971 if ( IsWait() )
2972 LeaveWait();
2973 if ( bGrabFocusToToolBox )
2975 pTextWin->GetToolBox().GrabFocus();
2976 bGrabFocusToToolBox = false;
2978 else
2979 pIndexWin->GrabFocusBack();
2980 if ( bSuccess )
2982 // set some view settings: "prevent help tips" and "helpid == 68245"
2985 Reference < XController > xController = pTextWin->getFrame()->getController();
2986 if ( xController.is() )
2988 Reference < XViewSettingsSupplier > xSettings( xController, UNO_QUERY );
2989 Reference < XPropertySet > xViewProps = xSettings->getViewSettings();
2990 Reference< XPropertySetInfo > xInfo = xViewProps->getPropertySetInfo();
2991 xViewProps->setPropertyValue( "ShowContentTips", makeAny( false ) );
2992 xViewProps->setPropertyValue( "ShowGraphics", makeAny( true ) );
2993 xViewProps->setPropertyValue( "ShowTables", makeAny( true ) );
2994 xViewProps->setPropertyValue( "HelpURL", makeAny( OUString("HID:SFX2_HID_HELP_ONHELP") ) );
2995 OUString sProperty( "IsExecuteHyperlinks" );
2996 if ( xInfo->hasPropertyByName( sProperty ) )
2997 xViewProps->setPropertyValue( sProperty, makeAny( true ) );
2998 xController->restoreViewData(pHelpInterceptor->GetViewData());
3001 catch( Exception& )
3003 OSL_FAIL( "SfxHelpWindow_Impl::OpenDoneHdl(): unexpected exception" );
3006 // When the SearchPage opens the help doc, then select all words, which are equal to its text
3007 OUString sSearchText = comphelper::string::strip(pIndexWin->GetSearchText(), ' ');
3008 if ( !sSearchText.isEmpty() )
3009 pTextWin->SelectSearchText( sSearchText, pIndexWin->IsFullWordSearch() );
3011 // no page style header -> this prevents a print output of the URL
3012 pTextWin->SetPageStyleHeaderOff();
3018 SfxHelpWindow_Impl::SfxHelpWindow_Impl(
3019 const ::com::sun::star::uno::Reference < ::com::sun::star::frame::XFrame2 >& rFrame,
3020 vcl::Window* pParent, WinBits ) :
3022 SplitWindow( pParent, WB_3DLOOK | WB_NOSPLITDRAW ),
3024 xFrame ( rFrame ),
3025 pIndexWin ( NULL ),
3026 pTextWin ( NULL ),
3027 pHelpInterceptor ( new HelpInterceptor_Impl() ),
3028 pHelpListener ( new HelpListener_Impl( pHelpInterceptor ) ),
3029 nExpandWidth ( 0 ),
3030 nCollapseWidth ( 0 ),
3031 nHeight ( 0 ),
3032 nIndexSize ( 40 ),
3033 nTextSize ( 60 ),
3034 bIndex ( true ),
3035 bGrabFocusToToolBox ( false ),
3036 aWinPos ( 0, 0 ),
3037 sTitle ( pParent->GetText() )
3039 SetHelpId( HID_HELP_WINDOW );
3040 SetStyle( GetStyle() | WB_DIALOGCONTROL );
3042 pHelpInterceptor->InitWaiter( this );
3043 pIndexWin = VclPtr<SfxHelpIndexWindow_Impl>::Create( this );
3044 pIndexWin->SetDoubleClickHdl( LINK( this, SfxHelpWindow_Impl, OpenHdl ) );
3045 pIndexWin->SetSelectFactoryHdl( LINK( this, SfxHelpWindow_Impl, SelectFactoryHdl ) );
3046 pIndexWin->SetSizePixel(LogicToPixel(Size(120, 200), MAP_APPFONT));
3047 pIndexWin->Show();
3048 pTextWin = VclPtr<SfxHelpTextWindow_Impl>::Create( this );
3049 Reference < XFrames > xFrames = rFrame->getFrames();
3050 xFrames->append( Reference<XFrame>(pTextWin->getFrame(), UNO_QUERY_THROW) );
3051 pTextWin->SetSelectHdl( LINK( this, SfxHelpWindow_Impl, SelectHdl ) );
3052 pTextWin->Show();
3053 pHelpInterceptor->setInterception( Reference<XFrame>(pTextWin->getFrame(), UNO_QUERY_THROW) );
3054 pHelpListener->SetChangeHdl( LINK( this, SfxHelpWindow_Impl, ChangeHdl ) );
3055 LoadConfig();
3060 SfxHelpWindow_Impl::~SfxHelpWindow_Impl()
3062 disposeOnce();
3065 void SfxHelpWindow_Impl::dispose()
3067 SaveConfig();
3068 pIndexWin.disposeAndClear();
3069 pTextWin->CloseFrame();
3070 pTextWin.disposeAndClear();
3071 SplitWindow::dispose();
3074 bool SfxHelpWindow_Impl::PreNotify( NotifyEvent& rNEvt )
3076 bool bHandled = false;
3077 if ( rNEvt.GetType() == MouseNotifyEvent::KEYINPUT )
3079 // Backward == <ALT><LEFT> or <BACKSPACE> Forward == <ALT><RIGHT>
3080 const vcl::KeyCode& rKeyCode = rNEvt.GetKeyEvent()->GetKeyCode();
3081 sal_uInt16 nKey = rKeyCode.GetCode();
3082 if ( ( rKeyCode.IsMod2() && ( KEY_LEFT == nKey || KEY_RIGHT == nKey ) ) ||
3083 ( !rKeyCode.GetModifier() && KEY_BACKSPACE == nKey && !pIndexWin->HasFocusOnEdit() ) )
3085 DoAction( rKeyCode.GetCode() == KEY_RIGHT ? TBI_FORWARD : TBI_BACKWARD );
3086 bHandled = true;
3088 else if ( rKeyCode.IsMod1() && ( KEY_F4 == nKey || KEY_W == nKey ) )
3090 // <CTRL><F4> or <CTRL><W> -> close top frame
3091 CloseWindow();
3092 bHandled = true;
3095 return bHandled || Window::PreNotify( rNEvt );
3098 void SfxHelpWindow_Impl::setContainerWindow( Reference < ::com::sun::star::awt::XWindow > xWin )
3100 xWindow = xWin;
3101 MakeLayout();
3104 void SfxHelpWindow_Impl::SetFactory( const OUString& rFactory )
3106 pIndexWin->SetFactory( rFactory, true );
3111 void SfxHelpWindow_Impl::SetHelpURL( const OUString& rURL )
3113 INetURLObject aObj( rURL );
3114 if ( aObj.GetProtocol() == INetProtocol::VndSunStarHelp )
3115 SetFactory( aObj.GetHost() );
3120 void SfxHelpWindow_Impl::DoAction( sal_uInt16 nActionId )
3122 switch ( nActionId )
3124 case TBI_INDEX :
3126 bIndex = !bIndex;
3127 MakeLayout();
3128 pTextWin->ToggleIndex( bIndex );
3129 break;
3132 case TBI_START :
3134 ShowStartPage();
3135 break;
3138 case TBI_BACKWARD :
3139 case TBI_FORWARD :
3141 URL aURL;
3142 aURL.Complete = ".uno:Backward";
3143 if ( TBI_FORWARD == nActionId )
3144 aURL.Complete = ".uno:Forward";
3145 PARSE_URL( aURL );
3146 pHelpInterceptor->dispatch( aURL, Sequence < PropertyValue >() );
3147 break;
3150 case TBI_SEARCHDIALOG :
3152 pTextWin->DoSearch();
3153 break;
3156 case TBI_PRINT :
3157 case TBI_SOURCEVIEW :
3158 case TBI_COPY :
3159 case TBI_SELECTIONMODE:
3161 Reference < XDispatchProvider > xProv( pTextWin->getFrame(), UNO_QUERY );
3162 if ( xProv.is() )
3164 URL aURL;
3165 if ( TBI_PRINT == nActionId )
3166 aURL.Complete = ".uno:Print";
3167 else if ( TBI_SOURCEVIEW == nActionId )
3168 aURL.Complete = ".uno:SourceView";
3169 else if ( TBI_COPY == nActionId )
3170 aURL.Complete = ".uno:Copy";
3171 else if ( TBI_SELECTIONMODE == nActionId )
3172 aURL.Complete = ".uno:SelectTextMode";
3173 else
3174 aURL.Complete = ".uno:SearchDialog";
3175 PARSE_URL( aURL );
3176 Reference < XDispatch > xDisp = xProv->queryDispatch( aURL, OUString(), 0 );
3177 if ( xDisp.is() )
3178 xDisp->dispatch( aURL, Sequence < PropertyValue >() );
3180 break;
3183 case TBI_BOOKMARKS :
3185 OUString aURL = pHelpInterceptor->GetCurrentURL();
3186 if ( !aURL.isEmpty() )
3190 Content aCnt( aURL, Reference< ::com::sun::star::ucb::XCommandEnvironment >(), comphelper::getProcessComponentContext() );
3191 ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > xInfo = aCnt.getProperties();
3192 if ( xInfo->hasPropertyByName( PROPERTY_TITLE ) )
3194 ::com::sun::star::uno::Any aAny = aCnt.getPropertyValue( PROPERTY_TITLE );
3195 OUString aValue;
3196 if ( aAny >>= aValue )
3198 OUString aTitle( aValue );
3199 ScopedVclPtrInstance< SfxAddHelpBookmarkDialog_Impl > aDlg(this, false);
3200 aDlg->SetTitle( aTitle );
3201 if ( aDlg->Execute() == RET_OK )
3203 aTitle = aDlg->GetTitle();
3204 pIndexWin->AddBookmarks( aTitle, aURL );
3209 catch( Exception& )
3211 OSL_FAIL( "SfxHelpWindow_Impl::DoAction(): unexpected exception" );
3214 break;
3221 void SfxHelpWindow_Impl::CloseWindow()
3225 // search for top frame
3226 Reference< XFramesSupplier > xCreator = getTextFrame()->getCreator();
3227 while ( xCreator.is() && !xCreator->isTop() )
3229 xCreator = xCreator->getCreator();
3232 // when found, close it
3233 if ( xCreator.is() && xCreator->isTop() )
3235 Reference < XCloseable > xCloser( xCreator, UNO_QUERY );
3236 if ( xCloser.is() )
3237 xCloser->close( sal_False );
3240 catch( Exception& )
3242 SAL_WARN( "sfx.appl", "SfxHelpWindow_Impl::CloseWindow(): caught an exception" );
3248 void SfxHelpWindow_Impl::UpdateToolbox()
3250 pTextWin->GetToolBox().EnableItem( TBI_BACKWARD, pHelpInterceptor->HasHistoryPred() );
3251 pTextWin->GetToolBox().EnableItem( TBI_FORWARD, pHelpInterceptor->HasHistorySucc() );
3256 bool SfxHelpWindow_Impl::HasHistoryPredecessor() const
3258 return pHelpInterceptor->HasHistoryPred();
3263 bool SfxHelpWindow_Impl::HasHistorySuccessor() const
3265 return pHelpInterceptor->HasHistorySucc();
3268 // class SfxAddHelpBookmarkDialog_Impl -----------------------------------
3270 SfxAddHelpBookmarkDialog_Impl::SfxAddHelpBookmarkDialog_Impl(vcl::Window* pParent, bool bRename)
3271 : ModalDialog( pParent, "BookmarkDialog", "sfx/ui/bookmarkdialog.ui")
3273 get(m_pTitleED, "entry");
3274 if (bRename)
3275 SetText(get<FixedText>("alttitle")->GetText());
3278 SfxAddHelpBookmarkDialog_Impl::~SfxAddHelpBookmarkDialog_Impl()
3280 disposeOnce();
3283 void SfxAddHelpBookmarkDialog_Impl::dispose()
3285 m_pTitleED.clear();
3286 ModalDialog::dispose();
3289 void SfxAddHelpBookmarkDialog_Impl::SetTitle( const OUString& rTitle )
3291 m_pTitleED->SetText( rTitle );
3292 m_pTitleED->SetSelection( Selection( 0, rTitle.getLength() ) );
3295 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */