/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /************************************************************************* * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * Copyright 2000, 2010 Oracle and/or its affiliates. * * OpenOffice.org - a multi-platform office productivity suite * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 3 * only, as published by the Free Software Foundation. * * OpenOffice.org is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License version 3 for more details * (a copy is included in the LICENSE file that accompanied this code). * * You should have received a copy of the GNU Lesser General Public License * version 3 along with OpenOffice.org. If not, see * * for a copy of the LGPLv3 License. * ************************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_sfx2.hxx" #include "newhelp.hxx" #include #include "sfxresid.hxx" #include "helpinterceptor.hxx" #include "helper.hxx" #include #include #include "sfxtypes.hxx" #include "panelist.hxx" #include "imgmgr.hxx" #include "srchdlg.hxx" #include "sfxhelp.hxx" #include "app.hrc" #include "newhelp.hrc" #include "helpid.hrc" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace ::ucbhelper; using namespace ::com::sun::star::ucb; using namespace ::com::sun::star; using namespace ::com::sun::star::beans; using namespace ::com::sun::star::container; using namespace ::com::sun::star::frame; using namespace ::com::sun::star::i18n; using namespace ::com::sun::star::lang; using namespace ::com::sun::star::style; using namespace ::com::sun::star::text; using namespace ::com::sun::star::uno; using namespace ::com::sun::star::util; using namespace ::com::sun::star::view; using namespace ::com::sun::star::ui; using namespace ::comphelper; // defines --------------------------------------------------------------- #define SPLITSET_ID 0 #define COLSET_ID 1 #define INDEXWIN_ID 2 #define TEXTWIN_ID 3 #define TOOLBOX_OFFSET 3 #define TBI_INDEX 1001 #define TBI_BACKWARD 1002 #define TBI_FORWARD 1003 #define TBI_START 1004 #define TBI_PRINT 1005 #define TBI_COPY 1006 #define TBI_BOOKMARKS 1007 #define TBI_SEARCHDIALOG 1008 #define TBI_SOURCEVIEW 1009 #define TBI_SELECTIONMODE 1010 #define TBI_ONSTARTUP 1011 #define CONFIGNAME_HELPWIN DEFINE_CONST_UNICODE("OfficeHelp") #define CONFIGNAME_INDEXWIN DEFINE_CONST_UNICODE("OfficeHelpIndex") #define CONFIGNAME_SEARCHPAGE DEFINE_CONST_UNICODE("OfficeHelpSearch") #define IMAGE_URL DEFINE_CONST_UNICODE("private:factory/") #define PROPERTY_KEYWORDLIST DEFINE_CONST_OUSTRING("KeywordList") #define PROPERTY_KEYWORDREF DEFINE_CONST_OUSTRING("KeywordRef") #define PROPERTY_ANCHORREF DEFINE_CONST_OUSTRING("KeywordAnchorForRef") #define PROPERTY_TITLEREF DEFINE_CONST_OUSTRING("KeywordTitleForRef") #define PROPERTY_TITLE DEFINE_CONST_OUSTRING("Title") #define HELP_URL DEFINE_CONST_OUSTRING("vnd.sun.star.help://") #define HELP_SEARCH_TAG DEFINE_CONST_OUSTRING("/?Query=") #define USERITEM_NAME DEFINE_CONST_OUSTRING("UserItem") #define PACKAGE_SETUP DEFINE_CONST_OUSTRING("/org.openoffice.Setup") #define PATH_OFFICE_FACTORIES DEFINE_CONST_OUSTRING("Office/Factories/") #define KEY_HELP_ON_OPEN DEFINE_CONST_OUSTRING("ooSetupFactoryHelpOnOpen") #define KEY_UI_NAME DEFINE_CONST_OUSTRING("ooSetupFactoryUIName") #define PARSE_URL( aURL ) \ Reference < XURLTransformer > xTrans( ::comphelper::getProcessServiceFactory()->createInstance( \ DEFINE_CONST_UNICODE("com.sun.star.util.URLTransformer" )), UNO_QUERY ); \ xTrans->parseStrict( aURL ) //......................................................................... namespace sfx2 { //......................................................................... void HandleTaskPaneList( Window* pWindow, BOOL bAddToList ) { Window* pParent = pWindow->GetParent(); DBG_ASSERT( pParent, "HandleTaskPaneList(): every window here should have a parent" ); SystemWindow* pSysWin = pParent->GetSystemWindow(); if( pSysWin ) { TaskPaneList* pTaskPaneList = pSysWin->GetTaskPaneList(); if( pTaskPaneList ) { if( bAddToList ) pTaskPaneList->AddWindow( pWindow ); else pTaskPaneList->RemoveWindow( pWindow ); } } } /** Prepare a search string for searching or selecting. For searching every search word needs the postfix '*' and the delimiter ' ' if necessary. For selecting the delimiter '|' is required to search with regular expressions. Samples: search string | output for searching | output for selecting ----------------------------------------------------------- "text" | "text*" | "text" "text*" | "text*" | "text" "text menu" | "text* menu*" | "text|menu" */ String PrepareSearchString( const String& rSearchString, Reference< XBreakIterator > xBreak, bool bForSearch ) { String sSearchStr; sal_Int32 nStartPos = 0; const Locale aLocale = Application::GetSettings().GetUILocale(); Boundary aBoundary = xBreak->getWordBoundary( rSearchString, nStartPos, aLocale, WordType::ANYWORD_IGNOREWHITESPACES, sal_True ); while ( aBoundary.startPos != aBoundary.endPos ) { nStartPos = aBoundary.endPos; String sSearchToken( rSearchString.Copy( (USHORT)aBoundary.startPos, (USHORT)aBoundary.endPos - (USHORT)aBoundary.startPos ) ); if ( sSearchToken.Len() > 0 && ( sSearchToken.Len() > 1 || sSearchToken.GetChar(0) != '.' ) ) { if ( bForSearch && sSearchToken.GetChar( sSearchToken.Len() - 1 ) != '*' ) sSearchToken += '*'; if ( sSearchToken.Len() > 1 || ( sSearchToken.Len() > 0 && sSearchToken.GetChar( 0 ) != '*' ) ) { if ( sSearchStr.Len() > 0 ) { if ( bForSearch ) sSearchStr += ' '; else sSearchStr += '|'; } sSearchStr += sSearchToken; } } aBoundary = xBreak->nextWord( rSearchString, nStartPos, aLocale, WordType::ANYWORD_IGNOREWHITESPACES ); } return sSearchStr; } //......................................................................... // namespace sfx2 } //......................................................................... // struct IndexEntry_Impl ------------------------------------------------ struct IndexEntry_Impl { sal_Bool m_bSubEntry; String m_aURL; IndexEntry_Impl( const String& rURL, sal_Bool bSubEntry ) : m_bSubEntry( bSubEntry ), m_aURL( rURL ) {} }; #define NEW_ENTRY( url, bool ) \ (void*)(ULONG)( new IndexEntry_Impl( url, bool ) ) // struct ContentEntry_Impl ---------------------------------------------- struct ContentEntry_Impl { String aURL; sal_Bool bIsFolder; ContentEntry_Impl( const String& rURL, sal_Bool bFolder ) : aURL( rURL ), bIsFolder( bFolder ) {} }; // ContentListBox_Impl --------------------------------------------------- ContentListBox_Impl::ContentListBox_Impl( Window* pParent, const ResId& rResId ) : SvTreeListBox( pParent, rResId ), aOpenBookImage ( SfxResId( IMG_HELP_CONTENT_BOOK_OPEN ) ), aClosedBookImage ( SfxResId( IMG_HELP_CONTENT_BOOK_CLOSED ) ), aDocumentImage ( SfxResId( IMG_HELP_CONTENT_DOC ) ) { SetWindowBits( WB_HIDESELECTION | WB_HSCROLL ); SetEntryHeight( 16 ); SetSelectionMode( SINGLE_SELECTION ); SetSpaceBetweenEntries( 2 ); SetNodeBitmaps( aClosedBookImage, aOpenBookImage ); SetSublistOpenWithReturn(); SetSublistOpenWithLeftRight(); InitRoot(); } // ----------------------------------------------------------------------- ContentListBox_Impl::~ContentListBox_Impl() { USHORT nPos = 0; SvLBoxEntry* pEntry = GetEntry( nPos++ ); while ( pEntry ) { ::rtl::OUString aTemp( GetEntryText( pEntry ) ); ClearChildren( pEntry ); delete (ContentEntry_Impl*)pEntry->GetUserData(); pEntry = GetEntry( nPos++ ); } } // ----------------------------------------------------------------------- void ContentListBox_Impl::InitRoot() { String aHelpTreeviewURL( DEFINE_CONST_UNICODE("vnd.sun.star.hier://com.sun.star.help.TreeView/") ); ::com::sun::star::uno::Sequence< ::rtl::OUString > aList = SfxContentHelper::GetHelpTreeViewContents( aHelpTreeviewURL ); const ::rtl::OUString* pEntries = aList.getConstArray(); UINT32 i, nCount = aList.getLength(); for ( i = 0; i < nCount; ++i ) { String aRow( pEntries[i] ); String aTitle, aURL; xub_StrLen nIdx = 0; aTitle = aRow.GetToken( 0, '\t', nIdx ); aURL = aRow.GetToken( 0, '\t', nIdx ); sal_Unicode cFolder = aRow.GetToken( 0, '\t', nIdx ).GetChar(0); sal_Bool bIsFolder = ( '1' == cFolder ); SvLBoxEntry* pEntry = InsertEntry( aTitle, aOpenBookImage, aClosedBookImage, NULL, TRUE ); if ( bIsFolder ) pEntry->SetUserData( new ContentEntry_Impl( aURL, sal_True ) ); } } // ----------------------------------------------------------------------- void ContentListBox_Impl::ClearChildren( SvLBoxEntry* pParent ) { SvLBoxEntry* pEntry = FirstChild( pParent ); while ( pEntry ) { ::rtl::OUString aTemp( GetEntryText( pEntry ) ); ClearChildren( pEntry ); delete (ContentEntry_Impl*)pEntry->GetUserData(); pEntry = NextSibling( pEntry ); } } // ----------------------------------------------------------------------- void ContentListBox_Impl::RequestingChilds( SvLBoxEntry* pParent ) { try { if ( !pParent->HasChilds() ) { if ( pParent->GetUserData() ) { String aTmpURL( ( (ContentEntry_Impl*)pParent->GetUserData() )->aURL ); ::com::sun::star::uno::Sequence< ::rtl::OUString > aList = SfxContentHelper::GetHelpTreeViewContents( aTmpURL ); const ::rtl::OUString* pEntries = aList.getConstArray(); UINT32 i, nCount = aList.getLength(); for ( i = 0; i < nCount; ++i ) { String aRow( pEntries[i] ); String aTitle, aURL; xub_StrLen nIdx = 0; aTitle = aRow.GetToken( 0, '\t', nIdx ); aURL = aRow.GetToken( 0, '\t', nIdx ); sal_Unicode cFolder = aRow.GetToken( 0, '\t', nIdx ).GetChar(0); sal_Bool bIsFolder = ( '1' == cFolder ); SvLBoxEntry* pEntry = NULL; if ( bIsFolder ) { pEntry = InsertEntry( aTitle, aOpenBookImage, aClosedBookImage, pParent, TRUE ); pEntry->SetUserData( new ContentEntry_Impl( aURL, sal_True ) ); } else { pEntry = InsertEntry( aTitle, aDocumentImage, aDocumentImage, pParent ); Any aAny( ::utl::UCBContentHelper::GetProperty( aURL, String(RTL_CONSTASCII_USTRINGPARAM("TargetURL" ) ) ) ); rtl::OUString aTargetURL; if ( aAny >>= aTargetURL ) pEntry->SetUserData( new ContentEntry_Impl( aTargetURL, sal_False ) ); } } } } } catch( Exception& ) { OSL_FAIL( "ContentListBox_Impl::RequestingChilds(): unexpected exception" ); } } // ----------------------------------------------------------------------- long ContentListBox_Impl::Notify( NotifyEvent& rNEvt ) { sal_Bool bHandled = sal_False; if ( rNEvt.GetType() == EVENT_KEYINPUT && KEY_RETURN == rNEvt.GetKeyEvent()->GetKeyCode().GetCode() ) { GetDoubleClickHdl().Call( NULL ); bHandled = sal_True; } return bHandled ? 1 : SvTreeListBox::Notify( rNEvt ); } // ----------------------------------------------------------------------- String ContentListBox_Impl::GetSelectEntry() const { String aRet; SvLBoxEntry* pEntry = FirstSelected(); if ( pEntry && !( (ContentEntry_Impl*)pEntry->GetUserData() )->bIsFolder ) aRet = ( (ContentEntry_Impl*)pEntry->GetUserData() )->aURL; return aRet; } // class HelpTabPage_Impl ------------------------------------------------ HelpTabPage_Impl::HelpTabPage_Impl( Window* pParent, SfxHelpIndexWindow_Impl* _pIdxWin, const ResId& rResId ) : TabPage( pParent, rResId ), m_pIdxWin( _pIdxWin ) { } // class ContentTabPage_Impl --------------------------------------------- ContentTabPage_Impl::ContentTabPage_Impl( Window* pParent, SfxHelpIndexWindow_Impl* _pIdxWin ) : HelpTabPage_Impl( pParent, _pIdxWin, SfxResId( TP_HELP_CONTENT ) ), aContentBox( this, SfxResId( LB_CONTENTS ) ) { FreeResource(); aContentBox.Show(); } // ----------------------------------------------------------------------- void ContentTabPage_Impl::Resize() { Size aSize = GetOutputSizePixel(); aSize.Width() -= 8; aSize.Height() -= 8; aContentBox.SetPosSizePixel( Point( 4, 4 ), aSize ); } // ----------------------------------------------------------------------- void ContentTabPage_Impl::ActivatePage() { if ( !m_pIdxWin->WasCursorLeftOrRight() ) SetFocusOnBox(); } // ----------------------------------------------------------------------- Control* ContentTabPage_Impl::GetLastFocusControl() { return &aContentBox; } // class IndexBox_Impl --------------------------------------------------- IndexBox_Impl::IndexBox_Impl( Window* pParent, const ResId& rResId ) : ComboBox( pParent, rResId ) { EnableAutocomplete( TRUE ); EnableUserDraw( TRUE ); } // ----------------------------------------------------------------------- void IndexBox_Impl::UserDraw( const UserDrawEvent& rUDEvt ) { IndexEntry_Impl* pEntry = (IndexEntry_Impl*)(ULONG)GetEntryData( rUDEvt.GetItemId() ); if ( pEntry && pEntry->m_bSubEntry ) { // indent sub entries Point aPos( rUDEvt.GetRect().TopLeft() ); aPos.X() += 8; aPos.Y() += ( rUDEvt.GetRect().GetHeight() - rUDEvt.GetDevice()->GetTextHeight() ) / 2; String aEntry( GetEntry( rUDEvt.GetItemId() ) ); USHORT nPos = aEntry.Search( ';' ); rUDEvt.GetDevice()->DrawText( aPos, ( nPos != STRING_NOTFOUND ) ? aEntry.Copy( nPos + 1 ) : aEntry ); } else DrawEntry( rUDEvt, FALSE, TRUE, TRUE ); } // ----------------------------------------------------------------------- long IndexBox_Impl::Notify( NotifyEvent& rNEvt ) { sal_Bool bHandled = sal_False; if ( rNEvt.GetType() == EVENT_KEYINPUT && KEY_RETURN == rNEvt.GetKeyEvent()->GetKeyCode().GetCode() ) { GetDoubleClickHdl().Call( NULL ); bHandled = sal_True; } return bHandled ? 1 : ComboBox::Notify( rNEvt ); } // ----------------------------------------------------------------------- void IndexBox_Impl::SelectExecutableEntry() { USHORT nPos = GetEntryPos( GetText() ); if ( nPos != COMBOBOX_ENTRY_NOTFOUND ) { USHORT nOldPos = nPos; String aEntryText; IndexEntry_Impl* pEntry = (IndexEntry_Impl*)(ULONG)GetEntryData( nPos ); USHORT nCount = GetEntryCount(); while ( nPos < nCount && ( !pEntry || pEntry->m_aURL.Len() == 0 ) ) { pEntry = (IndexEntry_Impl*)(ULONG)GetEntryData( ++nPos ); aEntryText = GetEntry( nPos ); } if ( nOldPos != nPos ) SetText( aEntryText ); } } // class IndexTabPage_Impl ----------------------------------------------- IndexTabPage_Impl::IndexTabPage_Impl( Window* pParent, SfxHelpIndexWindow_Impl* _pIdxWin ) : HelpTabPage_Impl( pParent, _pIdxWin, SfxResId( TP_HELP_INDEX ) ), aExpressionFT ( this, SfxResId( FT_EXPRESSION ) ), aIndexCB ( this, SfxResId( CB_INDEX ) ), aOpenBtn ( this, SfxResId( PB_OPEN_INDEX ) ), bIsActivated ( sal_False ) { FreeResource(); aOpenBtn.SetClickHdl( LINK( this, IndexTabPage_Impl, OpenHdl ) ); Link aTimeoutLink = LINK( this, IndexTabPage_Impl, TimeoutHdl ); aFactoryTimer.SetTimeoutHdl( aTimeoutLink ); aFactoryTimer.SetTimeout( 300 ); aKeywordTimer.SetTimeoutHdl( aTimeoutLink ); aFactoryTimer.SetTimeout( 300 ); nMinWidth = aOpenBtn.GetSizePixel().Width(); } // ----------------------------------------------------------------------- IndexTabPage_Impl::~IndexTabPage_Impl() { ClearIndex(); } // ----------------------------------------------------------------------- namespace sfx2 { struct equalOUString { bool operator()( const ::rtl::OUString& rKey1, const ::rtl::OUString& rKey2 ) const { return !!( rKey1 == rKey2 ); } }; struct hashOUString { size_t operator()( const ::rtl::OUString& rName ) const { return rName.hashCode(); } }; typedef ::boost::unordered_map< ::rtl::OUString, int, hashOUString, equalOUString > KeywordInfo; } #define UNIFY_AND_INSERT_TOKEN( aToken ) \ it = \ aInfo.insert( sfx2::KeywordInfo::value_type( aToken, 0 ) ).first; \ if ( ( tmp = it->second++ ) != 0 ) \ nPos = aIndexCB.InsertEntry( aToken + rtl::OUString( append, tmp ) ); \ else \ nPos = aIndexCB.InsertEntry( aToken ) #define INSERT_DATA( j ) \ if ( aAnchorList[j].getLength() > 0 ) \ { \ aData.append( aRefList[j] ).append( sal_Unicode('#') ).append( aAnchorList[j] ); \ aIndexCB.SetEntryData( nPos, NEW_ENTRY( aData.makeStringAndClear(), insert ) ); \ } \ else \ aIndexCB.SetEntryData( nPos, NEW_ENTRY( aRefList[j], insert ) ); // ----------------------------------------------------------------------- void IndexTabPage_Impl::InitializeIndex() { WaitObject( this ); // By now more than 256 equal entries are not allowed sal_Unicode append[256]; for( int k = 0; k < 256; ++k ) append[k] = sal_Unicode( ' ' ); sfx2::KeywordInfo aInfo; aIndexCB.SetUpdateMode( FALSE ); try { ::rtl::OUString aURL = HELP_URL; aURL += ::rtl::OUString( sFactory ); String aTemp = aURL; AppendConfigToken( aTemp, sal_True ); aURL = aTemp; Content aCnt( aURL, Reference< ::com::sun::star::ucb::XCommandEnvironment > () ); ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > xInfo = aCnt.getProperties(); if ( xInfo->hasPropertyByName( PROPERTY_ANCHORREF ) ) { ::com::sun::star::uno::Sequence< ::rtl::OUString > aPropSeq( 4 ); aPropSeq[0] = PROPERTY_KEYWORDLIST; aPropSeq[1] = PROPERTY_KEYWORDREF; aPropSeq[2] = PROPERTY_ANCHORREF; aPropSeq[3] = PROPERTY_TITLEREF; // abi: use one possibly remote call only ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any > aAnySeq = aCnt.getPropertyValues( aPropSeq ); ::com::sun::star::uno::Sequence< ::rtl::OUString > aKeywordList; ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< ::rtl::OUString > > aKeywordRefList; ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< ::rtl::OUString > > aAnchorRefList; ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< ::rtl::OUString > > aTitleRefList; if ( ( aAnySeq[0] >>= aKeywordList ) && ( aAnySeq[1] >>= aKeywordRefList ) && ( aAnySeq[2] >>= aAnchorRefList ) && ( aAnySeq[3] >>= aTitleRefList ) ) { sal_Bool insert; USHORT nPos; int ndx,tmp; ::rtl::OUString aIndex, aTempString; ::rtl::OUStringBuffer aData( 128 ); // Capacity of up to 128 characters sfx2::KeywordInfo::iterator it; for ( int i = 0; i < aKeywordList.getLength(); ++i ) { // abi: Do not copy, but use references const ::rtl::OUString& aKeywordPair = aKeywordList[i]; DBG_ASSERT( aKeywordPair.getLength() > 0, "invalid help index" ); const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aRefList = aKeywordRefList[i]; const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aAnchorList = aAnchorRefList[i]; const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aTitleList = aTitleRefList[i]; DBG_ASSERT( aRefList.getLength() == aAnchorList.getLength(),"reference list and title list of different length" ); insert = ( ( ndx = aKeywordPair.indexOf( sal_Unicode( ';' ) ) ) == -1 ? sal_False : sal_True ); if ( insert ) { aTempString = aKeywordPair.copy( 0, ndx ); if ( aIndex != aTempString ) { aIndex = aTempString; UNIFY_AND_INSERT_TOKEN( aTempString ); } } else aIndex = ::rtl::OUString(); // Assume the token is trimed UNIFY_AND_INSERT_TOKEN( aKeywordPair ); sal_uInt32 nRefListLen = aRefList.getLength(); DBG_ASSERT( aAnchorList.getLength(), "*IndexTabPage_Impl::InitializeIndex(): AnchorList is empty!" ); \ DBG_ASSERT( nRefListLen, "*IndexTabPage_Impl::InitializeIndex(): RefList is empty!" ); \ if ( aAnchorList.getLength() && nRefListLen ) { INSERT_DATA( 0 ); } for ( sal_uInt32 j = 1; j < nRefListLen ; ++j ) { aData .append( aKeywordPair ) .append( sal_Unicode(' ') ) .append( sal_Unicode('-') ) .append( sal_Unicode(' ') ) .append( aTitleList[j] ); aTempString = aData.makeStringAndClear(); UNIFY_AND_INSERT_TOKEN( aTempString ); INSERT_DATA( j ); } } } } } catch( Exception& ) { OSL_FAIL( "IndexTabPage_Impl::InitializeIndex(): unexpected exception" ); } aIndexCB.SetUpdateMode( TRUE ); if ( sKeyword.Len() > 0 ) aKeywordLink.Call( this ); } #undef INSERT_DATA #undef UNIFY_AND_INSERT_TOKEN // ----------------------------------------------------------------------- void IndexTabPage_Impl::ClearIndex() { USHORT nCount = aIndexCB.GetEntryCount(); for ( USHORT i = 0; i < nCount; ++i ) delete (IndexEntry_Impl*)(ULONG)aIndexCB.GetEntryData(i); aIndexCB.Clear(); } // ----------------------------------------------------------------------- IMPL_LINK( IndexTabPage_Impl, OpenHdl, PushButton*, EMPTYARG ) { aIndexCB.GetDoubleClickHdl().Call( &aIndexCB ); return 0; } // ----------------------------------------------------------------------- IMPL_LINK( IndexTabPage_Impl, TimeoutHdl, Timer*, pTimer ) { if ( &aFactoryTimer == pTimer ) InitializeIndex(); else if ( &aKeywordTimer == pTimer && sKeyword.Len() > 0 ) aKeywordLink.Call( this ); return 0; } // ----------------------------------------------------------------------- void IndexTabPage_Impl::Resize() { Size aSize = GetSizePixel(); if ( aSize.Width() < nMinWidth ) aSize.Width() = nMinWidth; Point aPnt = aExpressionFT.GetPosPixel(); Size aNewSize = aExpressionFT.GetSizePixel(); aNewSize.Width() = aSize.Width() - ( aPnt.X() * 2 ); aExpressionFT.SetSizePixel( aNewSize ); Size a6Size = LogicToPixel( Size( 6, 6 ), MAP_APPFONT ); Size aBtnSize = aOpenBtn.GetSizePixel(); aPnt = aIndexCB.GetPosPixel(); aNewSize = aIndexCB.GetSizePixel(); aNewSize.Width() = aSize.Width() - ( aPnt.X() * 2 ); aNewSize.Height() = aSize.Height() - aPnt.Y(); aNewSize.Height() -= ( aBtnSize.Height() + ( a6Size.Height() * 3 / 2 ) ); aIndexCB.SetSizePixel( aNewSize ); aPnt.X() += ( aNewSize.Width() - aBtnSize.Width() ); aPnt.Y() += aNewSize.Height() + ( a6Size.Height() / 2 ); long nMinX = aIndexCB.GetPosPixel().X(); if ( aPnt.X() < nMinX ) aPnt.X() = nMinX; aOpenBtn.SetPosPixel( aPnt ); } // ----------------------------------------------------------------------- void IndexTabPage_Impl::ActivatePage() { if ( !bIsActivated ) { bIsActivated = sal_True; aFactoryTimer.Start(); } if ( !m_pIdxWin->WasCursorLeftOrRight() ) SetFocusOnBox(); } // ----------------------------------------------------------------------- Control* IndexTabPage_Impl::GetLastFocusControl() { return &aOpenBtn; } // ----------------------------------------------------------------------- void IndexTabPage_Impl::SetDoubleClickHdl( const Link& rLink ) { aIndexCB.SetDoubleClickHdl( rLink ); } // ----------------------------------------------------------------------- void IndexTabPage_Impl::SetFactory( const String& rFactory ) { String sNewFactory( rFactory ); DBG_ASSERT( sNewFactory.Len() > 0, "empty factory" ); bool bValid = m_pIdxWin->IsValidFactory( rFactory ); if ( sFactory.Len() == 0 && !bValid ) { sNewFactory = SfxHelp::GetDefaultHelpModule(); bValid = true; } if ( sNewFactory != sFactory && bValid ) { sFactory = sNewFactory; ClearIndex(); if ( bIsActivated ) aFactoryTimer.Start(); } } // ----------------------------------------------------------------------- String IndexTabPage_Impl::GetSelectEntry() const { String aRet; IndexEntry_Impl* pEntry = (IndexEntry_Impl*)(ULONG)aIndexCB.GetEntryData( aIndexCB.GetEntryPos( aIndexCB.GetText() ) ); if ( pEntry ) aRet = pEntry->m_aURL; return aRet; } // ----------------------------------------------------------------------- void IndexTabPage_Impl::SetKeyword( const String& rKeyword ) { sKeyword = rKeyword; if ( aIndexCB.GetEntryCount() > 0 ) aKeywordTimer.Start(); else if ( !bIsActivated ) aFactoryTimer.Start(); } // ----------------------------------------------------------------------- sal_Bool IndexTabPage_Impl::HasKeyword() const { sal_Bool bRet = sal_False; if ( sKeyword.Len() > 0 ) { USHORT nPos = aIndexCB.GetEntryPos( sKeyword ); bRet = ( nPos != LISTBOX_ENTRY_NOTFOUND ); } return bRet; } // ----------------------------------------------------------------------- sal_Bool IndexTabPage_Impl::HasKeywordIgnoreCase() { sal_Bool bRet = sal_False; if ( sKeyword.Len() > 0 ) { USHORT nEntries = aIndexCB.GetEntryCount(); String sIndexItem; const vcl::I18nHelper& rI18nHelper = GetSettings().GetLocaleI18nHelper(); for ( USHORT n = 0; n < nEntries; n++) { sIndexItem = aIndexCB.GetEntry( n ); if (rI18nHelper.MatchString( sIndexItem, sKeyword )) { sKeyword = sIndexItem; bRet = sal_True; } } } return bRet; } // ----------------------------------------------------------------------- void IndexTabPage_Impl::OpenKeyword() { if ( sKeyword.Len() > 0 ) { aIndexCB.SetText( sKeyword ); aIndexCB.GetDoubleClickHdl().Call( NULL ); sKeyword.Erase(); } } // class SearchBox_Impl -------------------------------------------------- long SearchBox_Impl::PreNotify( NotifyEvent& rNEvt ) { sal_Bool bHandled = sal_False; if ( !IsInDropDown() && rNEvt.GetWindow() == GetSubEdit() && rNEvt.GetType() == EVENT_KEYINPUT && KEY_RETURN == rNEvt.GetKeyEvent()->GetKeyCode().GetCode() ) { aSearchLink.Call( NULL ); bHandled = sal_True; } return bHandled ? 1 : ComboBox::PreNotify( rNEvt ); } // ----------------------------------------------------------------------- void SearchBox_Impl::Select() { if ( !IsTravelSelect() ) aSearchLink.Call( NULL ); } // class SearchResultsBox_Impl ------------------------------------------- long SearchResultsBox_Impl::Notify( NotifyEvent& rNEvt ) { sal_Bool bHandled = sal_False; if ( rNEvt.GetType() == EVENT_KEYINPUT && KEY_RETURN == rNEvt.GetKeyEvent()->GetKeyCode().GetCode() ) { GetDoubleClickHdl().Call( NULL ); bHandled = sal_True; } return bHandled ? 1 : ListBox::Notify( rNEvt ); } // class SearchTabPage_Impl ---------------------------------------------- SearchTabPage_Impl::SearchTabPage_Impl( Window* pParent, SfxHelpIndexWindow_Impl* _pIdxWin ) : HelpTabPage_Impl( pParent, _pIdxWin, SfxResId( TP_HELP_SEARCH ) ), aSearchFT ( this, SfxResId( FT_SEARCH ) ), aSearchED ( this, SfxResId( ED_SEARCH ) ), aSearchBtn ( this, SfxResId( PB_SEARCH ) ), aFullWordsCB ( this, SfxResId( CB_FULLWORDS ) ), aScopeCB ( this, SfxResId( CB_SCOPE ) ), aResultsLB ( this, SfxResId( LB_RESULT ) ), aOpenBtn ( this, SfxResId( PB_OPEN_SEARCH ) ), xBreakIterator ( vcl::unohelper::CreateBreakIterator() ) { FreeResource(); Link aLink = LINK( this, SearchTabPage_Impl, SearchHdl ); aSearchED.SetSearchLink( aLink ); aSearchBtn.SetClickHdl( aLink ); aSearchED.SetModifyHdl( LINK( this, SearchTabPage_Impl, ModifyHdl ) ); aOpenBtn.SetClickHdl( LINK( this, SearchTabPage_Impl, OpenHdl ) ); aMinSize = GetSizePixel(); SvtViewOptions aViewOpt( E_TABPAGE, CONFIGNAME_SEARCHPAGE ); if ( aViewOpt.Exists() ) { String aUserData; Any aUserItem = aViewOpt.GetUserItem( USERITEM_NAME ); ::rtl::OUString aTemp; if ( aUserItem >>= aTemp ) { aUserData = String( aTemp ); BOOL bChecked = ( 1 == aUserData.GetToken(0).ToInt32() ) ? TRUE : FALSE; aFullWordsCB.Check( bChecked ); bChecked = ( 1 == aUserData.GetToken(1).ToInt32() ) ? TRUE : FALSE; aScopeCB.Check( bChecked ); for ( USHORT i = 2; i < aUserData.GetTokenCount(); ++i ) { String aToken = aUserData.GetToken(i); aSearchED.InsertEntry( INetURLObject::decode( aToken, '%', INetURLObject::DECODE_WITH_CHARSET ) ); } } } ModifyHdl( &aSearchED ); } // ----------------------------------------------------------------------- SearchTabPage_Impl::~SearchTabPage_Impl() { SvtViewOptions aViewOpt( E_TABPAGE, CONFIGNAME_SEARCHPAGE ); sal_Int32 nChecked = aFullWordsCB.IsChecked() ? 1 : 0; String aUserData = String::CreateFromInt32( nChecked ); aUserData += ';'; nChecked = aScopeCB.IsChecked() ? 1 : 0; aUserData += String::CreateFromInt32( nChecked ); aUserData += ';'; USHORT nCount = Min( aSearchED.GetEntryCount(), (USHORT)10 ); // save only 10 entries for ( USHORT i = 0; i < nCount; ++i ) { rtl::OUString aText = aSearchED.GetEntry(i); aUserData += String(INetURLObject::encode( aText, INetURLObject::PART_UNO_PARAM_VALUE, '%', INetURLObject::ENCODE_ALL )); aUserData += ';'; } aUserData.EraseTrailingChars(';'); Any aUserItem = makeAny( ::rtl::OUString( aUserData ) ); aViewOpt.SetUserItem( USERITEM_NAME, aUserItem ); } // ----------------------------------------------------------------------- void SearchTabPage_Impl::ClearSearchResults() { USHORT nCount = aResultsLB.GetEntryCount(); for ( USHORT i = 0; i < nCount; ++i ) delete (String*)(ULONG)aResultsLB.GetEntryData(i); aResultsLB.Clear(); aResultsLB.Update(); } // ----------------------------------------------------------------------- void SearchTabPage_Impl::RememberSearchText( const String& rSearchText ) { for ( USHORT i = 0; i < aSearchED.GetEntryCount(); ++i ) { if ( rSearchText == aSearchED.GetEntry(i) ) { aSearchED.RemoveEntry(i); break; } } aSearchED.InsertEntry( rSearchText, 0 ); } // ----------------------------------------------------------------------- IMPL_LINK( SearchTabPage_Impl, SearchHdl, PushButton*, EMPTYARG ) { String aSearchText = TRIM( aSearchED.GetText() ); if ( aSearchText.Len() > 0 ) { EnterWait(); ClearSearchResults(); RememberSearchText( aSearchText ); String aSearchURL = HELP_URL; aSearchURL += aFactory; aSearchURL += String( HELP_SEARCH_TAG ); if ( !aFullWordsCB.IsChecked() ) aSearchText = sfx2::PrepareSearchString( aSearchText, xBreakIterator, true ); aSearchURL += aSearchText; AppendConfigToken( aSearchURL, sal_False ); if ( aScopeCB.IsChecked() ) aSearchURL += DEFINE_CONST_UNICODE("&Scope=Heading"); Sequence< ::rtl::OUString > aFactories = SfxContentHelper::GetResultSet( aSearchURL ); const ::rtl::OUString* pFacs = aFactories.getConstArray(); UINT32 i, nCount = aFactories.getLength(); for ( i = 0; i < nCount; ++i ) { String aRow( pFacs[i] ); String aTitle, aType; xub_StrLen nIdx = 0; aTitle = aRow.GetToken( 0, '\t', nIdx ); aType = aRow.GetToken( 0, '\t', nIdx ); String* pURL = new String( aRow.GetToken( 0, '\t', nIdx ) ); USHORT nPos = aResultsLB.InsertEntry( aTitle ); aResultsLB.SetEntryData( nPos, (void*)(ULONG)pURL ); } LeaveWait(); if ( !nCount ) { InfoBox aBox( this, SfxResId( RID_INFO_NOSEARCHRESULTS ) ); aBox.SetText( String( SfxResId( STR_HELP_WINDOW_TITLE ) ) ); aBox.Execute(); } } return 0; } // ----------------------------------------------------------------------- IMPL_LINK( SearchTabPage_Impl, OpenHdl, PushButton*, EMPTYARG ) { aResultsLB.GetDoubleClickHdl().Call( &aResultsLB ); return 0; } // ----------------------------------------------------------------------- IMPL_LINK( SearchTabPage_Impl, ModifyHdl, Edit*, EMPTYARG ) { String aSearchText = TRIM( aSearchED.GetText() ); aSearchBtn.Enable( aSearchText.Len() > 0 ); return 0; } // ----------------------------------------------------------------------- void SearchTabPage_Impl::Resize() { Size a6Size = LogicToPixel( Size( 6, 6 ), MAP_APPFONT ); Size aSize = GetSizePixel(); if ( aSize.Width() < aMinSize.Width() ) aSize.Width() = aMinSize.Width(); Point aPnt = aSearchFT.GetPosPixel(); Size aNewSize = aSearchFT.GetSizePixel(); aNewSize.Width() = aSize.Width() - ( aPnt.X() * 2 ); aSearchFT.SetSizePixel( aNewSize ); aNewSize.Height() = aResultsLB.GetSizePixel().Height(); aResultsLB.SetSizePixel( aNewSize ); aNewSize.Height() = aFullWordsCB.GetSizePixel().Height(); aFullWordsCB.SetSizePixel( aNewSize ); aScopeCB.SetSizePixel( aNewSize ); aNewSize = aSearchED.GetSizePixel(); aNewSize.Width() = aSize.Width() - ( aPnt.X() * 2 ) - ( aSearchBtn.GetSizePixel().Width() + ( aPnt.X() / 2 ) ); aSearchED.SetSizePixel( aNewSize ); Point aNewPnt = aSearchBtn.GetPosPixel(); aNewPnt.X() = aPnt.X() + aNewSize.Width() + ( aPnt.X() / 2 ); aSearchBtn.SetPosPixel( aNewPnt ); if ( aSize.Height() > aMinSize.Height() ) { long n3Height = a6Size.Height() / 2; Size aBtnSize = aOpenBtn.GetSizePixel(); long nExtraHeight = aBtnSize.Height() + n3Height; aPnt = aResultsLB.GetPosPixel(); aNewSize = aResultsLB.GetSizePixel(); aNewSize.Height() = aSize.Height() - aPnt.Y(); aNewSize.Height() -= ( nExtraHeight + ( a6Size.Height() * 3 / 2 ) ); aResultsLB.SetSizePixel( aNewSize ); aPnt.X() += ( aNewSize.Width() - aBtnSize.Width() ); aPnt.Y() += aNewSize.Height() + a6Size.Height(); aOpenBtn.SetPosPixel( aPnt ); } } // ----------------------------------------------------------------------- void SearchTabPage_Impl::ActivatePage() { if ( !m_pIdxWin->WasCursorLeftOrRight() ) aSearchED.GrabFocus(); } // ----------------------------------------------------------------------- Control* SearchTabPage_Impl::GetLastFocusControl() { return &aOpenBtn; } // ----------------------------------------------------------------------- void SearchTabPage_Impl::SetDoubleClickHdl( const Link& rLink ) { aResultsLB.SetDoubleClickHdl( rLink ); } // ----------------------------------------------------------------------- String SearchTabPage_Impl::GetSelectEntry() const { String aRet; String* pData = (String*)(ULONG)aResultsLB.GetEntryData( aResultsLB.GetSelectEntryPos() ); if ( pData ) aRet = String( *pData ); return aRet; } // ----------------------------------------------------------------------- void SearchTabPage_Impl::ClearPage() { ClearSearchResults(); aSearchED.SetText( String() ); } // ----------------------------------------------------------------------- sal_Bool SearchTabPage_Impl::OpenKeyword( const String& rKeyword ) { sal_Bool bRet = sal_False; aSearchED.SetText( rKeyword ); SearchHdl( NULL ); if ( aResultsLB.GetEntryCount() > 0 ) { // found keyword -> open it aResultsLB.SelectEntryPos(0); OpenHdl( NULL ); bRet = sal_True; } return bRet; } // class BookmarksTabPage_Impl ------------------------------------------- void GetBookmarkEntry_Impl ( Sequence< PropertyValue >& aBookmarkEntry, ::rtl::OUString& rTitle, ::rtl::OUString& rURL ) { for ( int i = 0; i < aBookmarkEntry.getLength(); i++ ) { PropertyValue aValue = aBookmarkEntry[i]; if ( aValue.Name == HISTORY_PROPERTYNAME_URL ) aValue.Value >>= rURL; else if ( aValue.Name == HISTORY_PROPERTYNAME_TITLE ) aValue.Value >>= rTitle; } } // ----------------------------------------------------------------------- BookmarksBox_Impl::BookmarksBox_Impl( Window* pParent, const ResId& rResId ) : ListBox( pParent, rResId ) { } // ----------------------------------------------------------------------- BookmarksBox_Impl::~BookmarksBox_Impl() { // save bookmarks to configuration SvtHistoryOptions aHistOpt; aHistOpt.Clear( eHELPBOOKMARKS ); rtl::OUString sEmpty; USHORT nCount = GetEntryCount(); for ( USHORT i = 0; i < nCount; ++i ) { String aTitle = GetEntry(i); String* pURL = (String*)(ULONG)GetEntryData(i); aHistOpt.AppendItem( eHELPBOOKMARKS, rtl::OUString( *pURL ), sEmpty, rtl::OUString( aTitle ), sEmpty ); delete pURL; } } // ----------------------------------------------------------------------- void BookmarksBox_Impl::DoAction( USHORT nAction ) { switch ( nAction ) { case MID_OPEN : GetDoubleClickHdl().Call( NULL ); break; case MID_RENAME : { USHORT nPos = GetSelectEntryPos(); if ( nPos != LISTBOX_ENTRY_NOTFOUND ) { SfxAddHelpBookmarkDialog_Impl aDlg( this, sal_True ); aDlg.SetTitle( GetEntry( nPos ) ); if ( aDlg.Execute() == RET_OK ) { String* pURL = (String*)(ULONG)GetEntryData( nPos ); RemoveEntry( nPos ); rtl::OUString aImageURL = IMAGE_URL; aImageURL += INetURLObject( *pURL ).GetHost(); nPos = InsertEntry( aDlg.GetTitle(), SvFileInformationManager::GetImage( aImageURL, false ) ); SetEntryData( nPos, (void*)(ULONG)( new String( *pURL ) ) ); SelectEntryPos( nPos ); delete pURL; } } break; } case MID_DELETE : { USHORT nPos = GetSelectEntryPos(); if ( nPos != LISTBOX_ENTRY_NOTFOUND ) { RemoveEntry( nPos ); USHORT nCount = GetEntryCount(); if ( nCount ) { if ( nPos >= nCount ) nPos = nCount - 1; SelectEntryPos( nPos ); } } break; } } } // ----------------------------------------------------------------------- long BookmarksBox_Impl::Notify( NotifyEvent& rNEvt ) { long nRet = 0; USHORT nType = rNEvt.GetType(); if ( EVENT_KEYINPUT == nType ) { USHORT nCode = rNEvt.GetKeyEvent()->GetKeyCode().GetCode(); if ( KEY_DELETE == nCode && GetEntryCount() > 0 ) { DoAction( MID_DELETE ); nRet = 1; } else if ( KEY_RETURN == nCode ) { GetDoubleClickHdl().Call( NULL ); nRet = 1; } } else if ( EVENT_COMMAND == nType ) { const CommandEvent* pCEvt = rNEvt.GetCommandEvent(); if ( pCEvt->GetCommand() == COMMAND_CONTEXTMENU ) { PopupMenu aMenu( SfxResId( MENU_HELP_BOOKMARKS ) ); sal_uInt16 nId = aMenu.Execute( this, pCEvt->GetMousePosPixel() ); if ( nId != MENU_ITEM_NOTFOUND ) DoAction( nId ); nRet = 1; } } return nRet ? nRet : ListBox::Notify( rNEvt ); } // class BookmarksTabPage_Impl ------------------------------------------- BookmarksTabPage_Impl::BookmarksTabPage_Impl( Window* pParent, SfxHelpIndexWindow_Impl* _pIdxWin ) : HelpTabPage_Impl( pParent, _pIdxWin, SfxResId( TP_HELP_BOOKMARKS ) ), aBookmarksFT ( this, SfxResId( FT_BOOKMARKS ) ), aBookmarksBox ( this, SfxResId( LB_BOOKMARKS ) ), aBookmarksPB ( this, SfxResId( PB_BOOKMARKS ) ) { FreeResource(); nMinWidth = aBookmarksPB.GetSizePixel().Width(); aBookmarksPB.SetClickHdl( LINK( this, BookmarksTabPage_Impl, OpenHdl ) ); // load bookmarks from configuration Sequence< Sequence< PropertyValue > > aBookmarkSeq; aBookmarkSeq = SvtHistoryOptions().GetList( eHELPBOOKMARKS ); ::rtl::OUString aTitle; ::rtl::OUString aURL; UINT32 i, nCount = aBookmarkSeq.getLength(); for ( i = 0; i < nCount; ++i ) { GetBookmarkEntry_Impl( aBookmarkSeq[i], aTitle, aURL ); AddBookmarks( aTitle, aURL ); } } // ----------------------------------------------------------------------- IMPL_LINK( BookmarksTabPage_Impl, OpenHdl, PushButton*, EMPTYARG ) { aBookmarksBox.GetDoubleClickHdl().Call( &aBookmarksBox ); return 0; } // ----------------------------------------------------------------------- void BookmarksTabPage_Impl::Resize() { Size aSize = GetSizePixel(); if ( aSize.Width() < nMinWidth ) aSize.Width() = nMinWidth; Point aPnt = aBookmarksFT.GetPosPixel(); Size aNewSize = aBookmarksFT.GetSizePixel(); aNewSize.Width() = aSize.Width() - ( aPnt.X() * 2 ); aBookmarksFT.SetSizePixel( aNewSize ); Size a6Size = LogicToPixel( Size( 6, 6 ), MAP_APPFONT ); Size aBtnSize = aBookmarksPB.GetSizePixel(); aPnt = aBookmarksBox.GetPosPixel(); aNewSize = aBookmarksBox.GetSizePixel(); aNewSize.Width() = aSize.Width() - ( aPnt.X() * 2 ); aNewSize.Height() = aSize.Height() - aPnt.Y(); aNewSize.Height() -= ( aBtnSize.Height() + ( a6Size.Height() * 3 / 2 ) ); aBookmarksBox.SetSizePixel( aNewSize ); aPnt.X() += ( aNewSize.Width() - aBtnSize.Width() ); aPnt.Y() += aNewSize.Height() + ( a6Size.Height() / 2 ); long nMinX = aBookmarksBox.GetPosPixel().X(); if ( aPnt.X() < nMinX ) aPnt.X() = nMinX; aBookmarksPB.SetPosPixel( aPnt ); } // ----------------------------------------------------------------------- void BookmarksTabPage_Impl::ActivatePage() { if ( !m_pIdxWin->WasCursorLeftOrRight() ) SetFocusOnBox(); } // ----------------------------------------------------------------------- Control* BookmarksTabPage_Impl::GetLastFocusControl() { return &aBookmarksPB; } // ----------------------------------------------------------------------- void BookmarksTabPage_Impl::SetDoubleClickHdl( const Link& rLink ) { aBookmarksBox.SetDoubleClickHdl( rLink ); } // ----------------------------------------------------------------------- String BookmarksTabPage_Impl::GetSelectEntry() const { String aRet; String* pData = (String*)(ULONG)aBookmarksBox.GetEntryData( aBookmarksBox.GetSelectEntryPos() ); if ( pData ) aRet = String( *pData ); return aRet; } // ----------------------------------------------------------------------- void BookmarksTabPage_Impl::AddBookmarks( const String& rTitle, const String& rURL ) { rtl::OUString aImageURL = IMAGE_URL; aImageURL += INetURLObject( rURL ).GetHost(); USHORT nPos = aBookmarksBox.InsertEntry( rTitle, SvFileInformationManager::GetImage( aImageURL, false ) ); aBookmarksBox.SetEntryData( nPos, (void*)(ULONG)( new String( rURL ) ) ); } // class SfxHelpIndexWindow_Impl ----------------------------------------- sal_Bool SfxHelpWindow_Impl::splitHelpURL(const ::rtl::OUString& sHelpURL, ::rtl::OUString& sFactory, ::rtl::OUString& sContent, ::rtl::OUString& sAnchor ) { Reference < XURLTransformer > xParser( ::comphelper::getProcessServiceFactory()->createInstance( DEFINE_CONST_UNICODE("com.sun.star.util.URLTransformer" )), UNO_QUERY_THROW ); URL aURL; aURL.Complete = sHelpURL; sal_Bool bResult = xParser->parseStrict(aURL); sFactory = aURL.Server; sContent = aURL.Path.copy(1); // strip "/"! sAnchor = aURL.Mark; return bResult; } ::rtl::OUString SfxHelpWindow_Impl::buildHelpURL(const ::rtl::OUString& sFactory , const ::rtl::OUString& sContent , const ::rtl::OUString& sAnchor , sal_Bool bUseQuestionMark) { ::rtl::OUStringBuffer sHelpURL(256); sHelpURL.append(HELP_URL); sHelpURL.append(sFactory); sHelpURL.append(sContent); String sURL = String(sHelpURL.makeStringAndClear()); AppendConfigToken(sURL, bUseQuestionMark); if (sAnchor.getLength()) sURL += String(sAnchor); return ::rtl::OUString(sURL); } void SfxHelpWindow_Impl::loadHelpContent(const ::rtl::OUString& sHelpURL, sal_Bool bAddToHistory) { Reference< XComponentLoader > xLoader(getTextFrame(), UNO_QUERY); if (!xLoader.is()) return; // If a print job runs do not open a new page Reference< XFrame > xTextFrame = pTextWin->getFrame(); Reference< XController > xTextController ; if (xTextFrame.is()) xTextController = xTextFrame->getController (); if ( xTextController.is() && !xTextController->suspend( sal_True ) ) { xTextController->suspend( sal_False ); return; } // save url to history if (bAddToHistory) pHelpInterceptor->addURL(sHelpURL); if ( !IsWait() ) EnterWait(); sal_Bool bSuccess = sal_False; // TODO implement locale fallback ... see below while(sal_True) { try { Reference< XComponent > xContent = xLoader->loadComponentFromURL(sHelpURL, DEFINE_CONST_UNICODE("_self"), 0, Sequence< PropertyValue >()); if (xContent.is()) { bSuccess = sal_True; // break; } } catch(const RuntimeException&) { throw; } catch(const Exception&) { /*break;*/ } /* TODO try next locale ... no further locale available? => break loop and show error page */ } openDone(sHelpURL, bSuccess); if ( IsWait() ) LeaveWait(); } SfxHelpIndexWindow_Impl::SfxHelpIndexWindow_Impl( SfxHelpWindow_Impl* _pParent ) : Window( _pParent, SfxResId( WIN_HELPINDEX ) ), aActiveLB ( this, SfxResId( LB_ACTIVE ) ), aActiveLine ( this, SfxResId( FL_ACTIVE ) ), aTabCtrl ( this, SfxResId( TC_INDEX ) ), aIndexKeywordLink ( LINK( this, SfxHelpIndexWindow_Impl, KeywordHdl ) ), pParentWin ( _pParent ), pCPage ( NULL ), pIPage ( NULL ), pSPage ( NULL ), pBPage ( NULL ), bWasCursorLeftOrRight( false ), bIsInitDone ( false ) { FreeResource(); sfx2::AddToTaskPaneList( this ); aTabCtrl.SetActivatePageHdl( LINK( this, SfxHelpIndexWindow_Impl, ActivatePageHdl ) ); aTabCtrl.Show(); sal_Int32 nPageId = HELP_INDEX_PAGE_INDEX; SvtViewOptions aViewOpt( E_TABDIALOG, CONFIGNAME_INDEXWIN ); if ( aViewOpt.Exists() ) nPageId = aViewOpt.GetPageID(); aTabCtrl.SetCurPageId( (USHORT)nPageId ); ActivatePageHdl( &aTabCtrl ); aActiveLB.SetSelectHdl( LINK( this, SfxHelpIndexWindow_Impl, SelectHdl ) ); nMinWidth = ( aActiveLB.GetSizePixel().Width() / 2 ); aTimer.SetTimeoutHdl( LINK( this, SfxHelpIndexWindow_Impl, InitHdl ) ); aTimer.SetTimeout( 200 ); aTimer.Start(); } // ----------------------------------------------------------------------- SfxHelpIndexWindow_Impl::~SfxHelpIndexWindow_Impl() { sfx2::RemoveFromTaskPaneList( this ); DELETEZ( pCPage ); DELETEZ( pIPage ); DELETEZ( pSPage ); DELETEZ( pBPage ); for ( USHORT i = 0; i < aActiveLB.GetEntryCount(); ++i ) delete (String*)(ULONG)aActiveLB.GetEntryData(i); SvtViewOptions aViewOpt( E_TABDIALOG, CONFIGNAME_INDEXWIN ); aViewOpt.SetPageID( (sal_Int32)aTabCtrl.GetCurPageId() ); } // ----------------------------------------------------------------------- void SfxHelpIndexWindow_Impl::Initialize() { String aHelpURL = HELP_URL; AppendConfigToken( aHelpURL, sal_True ); Sequence< ::rtl::OUString > aFactories = SfxContentHelper::GetResultSet( aHelpURL ); const ::rtl::OUString* pFacs = aFactories.getConstArray(); UINT32 i, nCount = aFactories.getLength(); for ( i = 0; i < nCount; ++i ) { String aRow( pFacs[i] ); String aTitle, aType, aURL; xub_StrLen nIdx = 0; aTitle = aRow.GetToken( 0, '\t', nIdx ); aType = aRow.GetToken( 0, '\t', nIdx ); aURL = aRow.GetToken( 0, '\t', nIdx ); String* pFactory = new String( INetURLObject( aURL ).GetHost() ); USHORT nPos = aActiveLB.InsertEntry( aTitle ); aActiveLB.SetEntryData( nPos, (void*)(ULONG)pFactory ); } aActiveLB.SetDropDownLineCount( (USHORT)nCount ); if ( aActiveLB.GetSelectEntryPos() == LISTBOX_ENTRY_NOTFOUND ) SetActiveFactory(); } // ----------------------------------------------------------------------- void SfxHelpIndexWindow_Impl::SetActiveFactory() { DBG_ASSERT( pIPage, "index page not initialized" ); if ( !bIsInitDone && !aActiveLB.GetEntryCount() ) { aTimer.Stop(); InitHdl( NULL ); } for ( USHORT i = 0; i < aActiveLB.GetEntryCount(); ++i ) { String* pFactory = (String*)(ULONG)aActiveLB.GetEntryData(i); pFactory->ToLowerAscii(); if ( *pFactory == pIPage->GetFactory() ) { if ( aActiveLB.GetSelectEntryPos() != i ) { aActiveLB.SelectEntryPos(i); aSelectFactoryLink.Call( NULL ); } break; } } } // ----------------------------------------------------------------------- HelpTabPage_Impl* SfxHelpIndexWindow_Impl::GetCurrentPage( USHORT& rCurId ) { rCurId = aTabCtrl.GetCurPageId(); HelpTabPage_Impl* pPage = NULL; switch ( rCurId ) { case HELP_INDEX_PAGE_CONTENTS: { pPage = GetContentPage(); break; } case HELP_INDEX_PAGE_INDEX: { pPage = GetIndexPage(); break; } case HELP_INDEX_PAGE_SEARCH: { pPage = GetSearchPage(); break; } case HELP_INDEX_PAGE_BOOKMARKS: { pPage = GetBookmarksPage(); break; } } DBG_ASSERT( pPage, "SfxHelpIndexWindow_Impl::GetCurrentPage(): no current page" ); return pPage; } // ----------------------------------------------------------------------- IMPL_LINK( SfxHelpIndexWindow_Impl, ActivatePageHdl, TabControl *, pTabCtrl ) { USHORT nId = 0; TabPage* pPage = GetCurrentPage( nId ); pTabCtrl->SetTabPage( nId, pPage ); return 0; } // ----------------------------------------------------------------------- IMPL_LINK( SfxHelpIndexWindow_Impl, SelectHdl, ListBox *, EMPTYARG ) { aTimer.Start(); return 0; } // ----------------------------------------------------------------------- IMPL_LINK( SfxHelpIndexWindow_Impl, InitHdl, Timer *, EMPTYARG ) { bIsInitDone = true; Initialize(); // now use the timer for selection aTimer.SetTimeoutHdl( LINK( this, SfxHelpIndexWindow_Impl, SelectFactoryHdl ) ); aTimer.SetTimeout( 1000 ); return 0; } // ----------------------------------------------------------------------- IMPL_LINK( SfxHelpIndexWindow_Impl, SelectFactoryHdl, Timer *, EMPTYARG ) { String* pFactory = (String*)(ULONG)aActiveLB.GetEntryData( aActiveLB.GetSelectEntryPos() ); if ( pFactory ) { String aFactory( *pFactory ); aFactory.ToLowerAscii(); SetFactory( aFactory, sal_False ); aSelectFactoryLink.Call( this ); } return 0; } // ----------------------------------------------------------------------- IMPL_LINK( SfxHelpIndexWindow_Impl, KeywordHdl, IndexTabPage_Impl *, EMPTYARG ) { // keyword found on index? sal_Bool bIndex = pIPage->HasKeyword(); if( !bIndex) bIndex = pIPage->HasKeywordIgnoreCase(); // then set index or search page as current. USHORT nPageId = ( bIndex ) ? HELP_INDEX_PAGE_INDEX : HELP_INDEX_PAGE_SEARCH; if ( nPageId != aTabCtrl.GetCurPageId() ) { aTabCtrl.SetCurPageId( nPageId ); ActivatePageHdl( &aTabCtrl ); } // at last we open the keyword if ( bIndex ) pIPage->OpenKeyword(); else if ( !pSPage->OpenKeyword( sKeyword ) ) pParentWin->ShowStartPage(); return 0; } // ----------------------------------------------------------------------- void SfxHelpIndexWindow_Impl::Resize() { Size aSize = GetOutputSizePixel(); if ( aSize.Width() < nMinWidth ) aSize.Width() = nMinWidth; Point aPnt = aActiveLB.GetPosPixel(); Size aNewSize = aActiveLB.GetSizePixel(); aNewSize.Width() = aSize.Width() - ( aPnt.X() * 2 ); aActiveLB.SetSizePixel( aNewSize ); aPnt = aActiveLine.GetPosPixel(); aNewSize = aActiveLine.GetSizePixel(); aNewSize.Width() = aSize.Width() - ( aPnt.X() * 2 ); aActiveLine.SetSizePixel( aNewSize ); aPnt = aTabCtrl.GetPosPixel(); aNewSize = aSize; aSize.Width() -= aPnt.X(); aSize.Height() -= aPnt.Y(); aTabCtrl.SetSizePixel( aSize ); } // ----------------------------------------------------------------------- long SfxHelpIndexWindow_Impl::PreNotify( NotifyEvent& rNEvt ) { long nDone = 0; USHORT nType = rNEvt.GetType(); if ( EVENT_KEYINPUT == nType && rNEvt.GetKeyEvent() ) { const KeyCode& rKeyCode = rNEvt.GetKeyEvent()->GetKeyCode(); USHORT nCode = rKeyCode.GetCode(); if ( KEY_TAB == nCode ) { // don't exit index pane with USHORT nPageId = 0; HelpTabPage_Impl* pCurPage = GetCurrentPage( nPageId ); Control* pControl = pCurPage->GetLastFocusControl(); BOOL bShift = rKeyCode.IsShift(); BOOL bCtrl = rKeyCode.IsMod1(); if ( !bCtrl && bShift && aActiveLB.HasChildPathFocus() ) { pControl->GrabFocus(); nDone = 1; } else if ( !bCtrl && !bShift && pControl->HasChildPathFocus() ) { aActiveLB.GrabFocus(); nDone = 1; } else if ( bCtrl ) { // moves through the pages if ( nPageId < HELP_INDEX_PAGE_LAST ) nPageId++; else nPageId = HELP_INDEX_PAGE_FIRST; aTabCtrl.SetCurPageId( (USHORT)nPageId ); ActivatePageHdl( &aTabCtrl ); nDone = 1; } } else if ( aTabCtrl.HasFocus() && ( KEY_LEFT == nCode || KEY_RIGHT == nCode ) ) { bWasCursorLeftOrRight = true; } } return nDone ? nDone : Window::PreNotify( rNEvt ); } // ----------------------------------------------------------------------- void SfxHelpIndexWindow_Impl::DataChanged( const DataChangedEvent& rDCEvt ) { Window::DataChanged( rDCEvt ); if ( ( ( rDCEvt.GetType() == DATACHANGED_SETTINGS ) || ( rDCEvt.GetType() == DATACHANGED_DISPLAY ) ) && ( rDCEvt.GetFlags() & SETTINGS_STYLE ) ) { SetBackground( Wallpaper( GetSettings().GetStyleSettings().GetFaceColor() ) ); } } // ----------------------------------------------------------------------- void SfxHelpIndexWindow_Impl::SetDoubleClickHdl( const Link& rLink ) { aPageDoubleClickLink = rLink; if ( pCPage ) pCPage->SetOpenHdl( aPageDoubleClickLink ); if ( pIPage ) pIPage->SetDoubleClickHdl( aPageDoubleClickLink ); if ( pSPage ) pSPage->SetDoubleClickHdl( aPageDoubleClickLink ); if ( pBPage ) pBPage->SetDoubleClickHdl( aPageDoubleClickLink ); } // ----------------------------------------------------------------------- void SfxHelpIndexWindow_Impl::SetFactory( const String& rFactory, sal_Bool bActive ) { if ( rFactory.Len() > 0 ) { GetIndexPage()->SetFactory( rFactory ); // the index page did a check if rFactory is valid, // so the index page always returns a valid factory GetSearchPage()->SetFactory( GetIndexPage()->GetFactory() ); if ( bActive ) SetActiveFactory(); } } // ----------------------------------------------------------------------- String SfxHelpIndexWindow_Impl::GetSelectEntry() const { String sRet; switch ( aTabCtrl.GetCurPageId() ) { case HELP_INDEX_PAGE_CONTENTS: sRet = pCPage->GetSelectEntry(); break; case HELP_INDEX_PAGE_INDEX: sRet = pIPage->GetSelectEntry(); break; case HELP_INDEX_PAGE_SEARCH: sRet = pSPage->GetSelectEntry(); break; case HELP_INDEX_PAGE_BOOKMARKS: sRet = pBPage->GetSelectEntry(); break; } return sRet; } // ----------------------------------------------------------------------- void SfxHelpIndexWindow_Impl::AddBookmarks( const String& rTitle, const String& rURL ) { GetBookmarksPage()->AddBookmarks( rTitle, rURL ); } // ----------------------------------------------------------------------- bool SfxHelpIndexWindow_Impl::IsValidFactory( const String& _rFactory ) { bool bValid = false; for ( USHORT i = 0; i < aActiveLB.GetEntryCount(); ++i ) { String* pFactory = (String*)(ULONG)aActiveLB.GetEntryData(i); if ( *pFactory == _rFactory ) { bValid = true; break; } } return bValid; } // ----------------------------------------------------------------------- void SfxHelpIndexWindow_Impl::ClearSearchPage() { if ( pSPage ) pSPage->ClearPage(); } // ----------------------------------------------------------------------- void SfxHelpIndexWindow_Impl::GrabFocusBack() { if ( aTabCtrl.GetCurPageId() == HELP_INDEX_PAGE_CONTENTS && pCPage ) pCPage->SetFocusOnBox(); else if ( aTabCtrl.GetCurPageId() == HELP_INDEX_PAGE_INDEX && pIPage ) pIPage->SetFocusOnBox(); else if ( aTabCtrl.GetCurPageId() == HELP_INDEX_PAGE_SEARCH && pSPage ) pSPage->SetFocusOnBox(); else if ( aTabCtrl.GetCurPageId() == HELP_INDEX_PAGE_BOOKMARKS && pBPage ) pBPage->SetFocusOnBox(); } // ----------------------------------------------------------------------- sal_Bool SfxHelpIndexWindow_Impl::HasFocusOnEdit() const { sal_Bool bRet = sal_False; if ( aTabCtrl.GetCurPageId() == HELP_INDEX_PAGE_INDEX && pIPage ) bRet = pIPage->HasFocusOnEdit(); else if ( aTabCtrl.GetCurPageId() == HELP_INDEX_PAGE_SEARCH && pSPage ) bRet = pSPage->HasFocusOnEdit(); return bRet; } // ----------------------------------------------------------------------- String SfxHelpIndexWindow_Impl::GetSearchText() const { String sRet; if ( aTabCtrl.GetCurPageId() == HELP_INDEX_PAGE_SEARCH && pSPage ) sRet = pSPage->GetSearchText(); return sRet; } // ----------------------------------------------------------------------- sal_Bool SfxHelpIndexWindow_Impl::IsFullWordSearch() const { sal_Bool bRet = sal_False; if ( aTabCtrl.GetCurPageId() == HELP_INDEX_PAGE_SEARCH && pSPage ) bRet = pSPage->IsFullWordSearch(); return bRet; } // ----------------------------------------------------------------------- void SfxHelpIndexWindow_Impl::OpenKeyword( const String& rKeyword ) { sKeyword = rKeyword; DBG_ASSERT( pIPage, "invalid index page" ); pIPage->SetKeyword( sKeyword ); } // ----------------------------------------------------------------------- void SfxHelpIndexWindow_Impl::SelectExecutableEntry() { if ( aTabCtrl.GetCurPageId() == HELP_INDEX_PAGE_INDEX && pIPage ) pIPage->SelectExecutableEntry(); } // class TextWin_Impl ---------------------------------------------------- TextWin_Impl::TextWin_Impl( Window* p ) : DockingWindow( p, 0 ) { } TextWin_Impl::~TextWin_Impl() { } long TextWin_Impl::Notify( NotifyEvent& rNEvt ) { if( ( rNEvt.GetType() == EVENT_KEYINPUT ) && rNEvt.GetKeyEvent()->GetKeyCode().GetCode() == KEY_TAB ) return GetParent()->Notify( rNEvt ); else return DockingWindow::Notify( rNEvt ); } // ----------------------------------------------------------------------- // remove docking area acceptor from layoutmanager, so it will not layout anything further .-) void lcl_disableLayoutOfFrame(const Reference< XFrame >& xFrame) { static const ::rtl::OUString PROP_LAYOUT_MANAGER(DEFINE_CONST_UNICODE("LayoutManager")); Reference< XPropertySet > xPropSet(xFrame, UNO_QUERY_THROW); xPropSet->setPropertyValue(PROP_LAYOUT_MANAGER, makeAny(Reference< XLayoutManager >())); } // class SfxHelpTextWindow_Impl ------------------------------------------ SfxHelpTextWindow_Impl::SfxHelpTextWindow_Impl( SfxHelpWindow_Impl* pParent ) : Window( pParent, WB_CLIPCHILDREN | WB_TABSTOP | WB_DIALOGCONTROL ), aToolBox ( this, 0 ), aOnStartupCB ( this, SfxResId( RID_HELP_ONSTARTUP_BOX ) ), aIndexOnImage ( SfxResId( IMG_HELP_TOOLBOX_INDEX_ON ) ), aIndexOffImage ( SfxResId( IMG_HELP_TOOLBOX_INDEX_OFF ) ), aIndexOnText ( SfxResId( STR_HELP_BUTTON_INDEX_ON ) ), aIndexOffText ( SfxResId( STR_HELP_BUTTON_INDEX_OFF ) ), aOnStartupText ( SfxResId( RID_HELP_ONSTARTUP_TEXT ) ), pHelpWin ( pParent ), pTextWin ( new TextWin_Impl( this ) ), pSrchDlg ( NULL ), nMinPos ( 0 ), bIsDebug ( sal_False ), bIsIndexOn ( sal_False ), bIsInClose ( sal_False ), bIsFullWordSearch ( sal_False ) { sfx2::AddToTaskPaneList( &aToolBox ); xFrame = Reference < XFrame > ( ::comphelper::getProcessServiceFactory()->createInstance( DEFINE_CONST_UNICODE("com.sun.star.frame.Frame") ), UNO_QUERY ); xFrame->initialize( VCLUnoHelper::GetInterface ( pTextWin ) ); xFrame->setName( DEFINE_CONST_UNICODE("OFFICE_HELP") ); lcl_disableLayoutOfFrame(xFrame); aToolBox.SetHelpId( HID_HELP_TOOLBOX ); aToolBox.InsertItem( TBI_INDEX, aIndexOffText ); aToolBox.SetHelpId( TBI_INDEX, HID_HELP_TOOLBOXITEM_INDEX ); aToolBox.InsertSeparator(); aToolBox.InsertItem( TBI_BACKWARD, String( SfxResId( STR_HELP_BUTTON_PREV ) ) ); aToolBox.SetHelpId( TBI_BACKWARD, HID_HELP_TOOLBOXITEM_BACKWARD ); aToolBox.InsertItem( TBI_FORWARD, String( SfxResId( STR_HELP_BUTTON_NEXT ) ) ); aToolBox.SetHelpId( TBI_FORWARD, HID_HELP_TOOLBOXITEM_FORWARD ); aToolBox.InsertItem( TBI_START, String( SfxResId( STR_HELP_BUTTON_START ) ) ); aToolBox.SetHelpId( TBI_START, HID_HELP_TOOLBOXITEM_START ); aToolBox.InsertSeparator(); aToolBox.InsertItem( TBI_PRINT, String( SfxResId( STR_HELP_BUTTON_PRINT ) ) ); aToolBox.SetHelpId( TBI_PRINT, HID_HELP_TOOLBOXITEM_PRINT ); aToolBox.InsertItem( TBI_BOOKMARKS, String( SfxResId( STR_HELP_BUTTON_ADDBOOKMARK ) ) ); aToolBox.SetHelpId( TBI_BOOKMARKS, HID_HELP_TOOLBOXITEM_BOOKMARKS ); aToolBox.InsertItem( TBI_SEARCHDIALOG, String( SfxResId( STR_HELP_BUTTON_SEARCHDIALOG ) ) ); aToolBox.SetHelpId( TBI_SEARCHDIALOG, HID_HELP_TOOLBOXITEM_SEARCHDIALOG ); InitToolBoxImages(); aToolBox.Show(); InitOnStartupBox( false ); aOnStartupCB.SetClickHdl( LINK( this, SfxHelpTextWindow_Impl, CheckHdl ) ); aSelectTimer.SetTimeoutHdl( LINK( this, SfxHelpTextWindow_Impl, SelectHdl ) ); aSelectTimer.SetTimeout( 1000 ); char* pEnv = getenv( "help_debug" ); if ( pEnv ) bIsDebug = sal_True; SvtMiscOptions().AddListenerLink( LINK( this, SfxHelpTextWindow_Impl, NotifyHdl ) ); if ( aOnStartupCB.GetHelpId() == 0 ) aOnStartupCB.SetHelpId( HID_HELP_ONSTARTUP_BOX ); } // ----------------------------------------------------------------------- SfxHelpTextWindow_Impl::~SfxHelpTextWindow_Impl() { sfx2::RemoveFromTaskPaneList( &aToolBox ); bIsInClose = sal_True; SvtMiscOptions().RemoveListenerLink( LINK( this, SfxHelpTextWindow_Impl, NotifyHdl ) ); delete pSrchDlg; } // ----------------------------------------------------------------------- sal_Bool SfxHelpTextWindow_Impl::HasSelection() const { // is there any selection in the text and not only a cursor? sal_Bool bRet = sal_False; Reference < XTextRange > xRange = getCursor(); if ( xRange.is() ) { Reference < XText > xText = xRange->getText(); Reference < XTextCursor > xCursor = xText->createTextCursorByRange( xRange ); bRet = !xCursor->isCollapsed(); } return bRet; } // ----------------------------------------------------------------------- void SfxHelpTextWindow_Impl::InitToolBoxImages() { sal_Bool bLarge = SvtMiscOptions().AreCurrentSymbolsLarge(); aIndexOnImage = Image( SfxResId( bLarge ? IMG_HELP_TOOLBOX_L_INDEX_ON : IMG_HELP_TOOLBOX_INDEX_ON ) ); aIndexOffImage = Image( SfxResId( bLarge ? IMG_HELP_TOOLBOX_L_INDEX_OFF : IMG_HELP_TOOLBOX_INDEX_OFF ) ); aToolBox.SetItemImage( TBI_INDEX, bIsIndexOn ? aIndexOffImage : aIndexOnImage ); aToolBox.SetItemImage( TBI_BACKWARD, Image( SfxResId( bLarge ? IMG_HELP_TOOLBOX_L_PREV : IMG_HELP_TOOLBOX_PREV ) ) ); aToolBox.SetItemImage( TBI_FORWARD, Image( SfxResId( bLarge ? IMG_HELP_TOOLBOX_L_NEXT : IMG_HELP_TOOLBOX_NEXT ) ) ); aToolBox.SetItemImage( TBI_START, Image( SfxResId( bLarge ? IMG_HELP_TOOLBOX_L_START : IMG_HELP_TOOLBOX_START ) ) ); aToolBox.SetItemImage( TBI_PRINT, Image( SfxResId( bLarge ? IMG_HELP_TOOLBOX_L_PRINT : IMG_HELP_TOOLBOX_PRINT ) ) ); aToolBox.SetItemImage( TBI_BOOKMARKS, Image( SfxResId( bLarge ? IMG_HELP_TOOLBOX_L_BOOKMARKS : IMG_HELP_TOOLBOX_BOOKMARKS ) ) ); aToolBox.SetItemImage( TBI_SEARCHDIALOG, Image( SfxResId( bLarge ? IMG_HELP_TOOLBOX_L_SEARCHDIALOG : IMG_HELP_TOOLBOX_SEARCHDIALOG ) ) ); Size aSize = aToolBox.CalcWindowSizePixel(); aSize.Height() += TOOLBOX_OFFSET; aToolBox.SetPosSizePixel( Point( 0, TOOLBOX_OFFSET ), aSize ); SvtMiscOptions aMiscOptions; if ( aMiscOptions.GetToolboxStyle() != aToolBox.GetOutStyle() ) aToolBox.SetOutStyle( aMiscOptions.GetToolboxStyle() ); } // ----------------------------------------------------------------------- void SfxHelpTextWindow_Impl::InitOnStartupBox( bool bOnlyText ) { sCurrentFactory = SfxHelp::GetCurrentModuleIdentifier(); Reference< XMultiServiceFactory > xMultiServiceFac = ::comphelper::getProcessServiceFactory(); Reference< XInterface > xConfig; ::rtl::OUString sPath( PATH_OFFICE_FACTORIES ); sPath += sCurrentFactory; ::rtl::OUString sKey( KEY_HELP_ON_OPEN ); // Attention: This check boy knows two states: // 1) Reading of the config key fails with an exception or by getting an empty Any (!) => check box must be hidden // 2) We read TRUE/FALSE => check box must be shown and enabled/disabled bool bHideBox = true; sal_Bool bHelpAtStartup = sal_False; try { xConfiguration = ConfigurationHelper::openConfig( xMultiServiceFac, PACKAGE_SETUP, ConfigurationHelper::E_STANDARD ); if ( xConfiguration.is() ) { Any aAny = ConfigurationHelper::readRelativeKey( xConfiguration, sPath, sKey ); if (aAny >>= bHelpAtStartup) bHideBox = false; } } catch( Exception& ) { bHideBox = true; } if ( bHideBox ) aOnStartupCB.Hide(); else { // detect module name String sModuleName; if ( xConfiguration.is() ) { ::rtl::OUString sTemp; sKey = KEY_UI_NAME; try { Any aAny = ConfigurationHelper::readRelativeKey( xConfiguration, sPath, sKey ); aAny >>= sTemp; } catch( Exception& ) { DBG_ERRORFILE( "SfxHelpTextWindow_Impl::InitOnStartupBox(): unexpected exception" ); } sModuleName = String( sTemp ); } if ( sModuleName.Len() > 0 ) { // set module name in checkbox text String sText( aOnStartupText ); sText.SearchAndReplace( String::CreateFromAscii( "%MODULENAME" ), sModuleName ); aOnStartupCB.SetText( sText ); // and show it aOnStartupCB.Show(); // set check state aOnStartupCB.Check( bHelpAtStartup ); aOnStartupCB.SaveValue(); // calculate and set optimal width of the onstartup checkbox String sCBText( DEFINE_CONST_UNICODE( "XXX" ) ); sCBText += aOnStartupCB.GetText(); long nTextWidth = aOnStartupCB.GetTextWidth( sCBText ); Size aSize = aOnStartupCB.GetSizePixel(); aSize.Width() = nTextWidth; aOnStartupCB.SetSizePixel( aSize ); SetOnStartupBoxPosition(); } if ( !bOnlyText ) { // set position of the checkbox Size a3Size = LogicToPixel( Size( 3, 3 ), MAP_APPFONT ); Size aTBSize = aToolBox.GetSizePixel(); Size aCBSize = aOnStartupCB.GetSizePixel(); Point aPnt = aToolBox.GetPosPixel(); aPnt.X() += aTBSize.Width() + a3Size.Width(); aPnt.Y() += ( ( aTBSize.Height() - aCBSize.Height() ) / 2 ); aOnStartupCB.SetPosPixel( aPnt ); nMinPos = aPnt.X(); } } } // ----------------------------------------------------------------------- void SfxHelpTextWindow_Impl::SetOnStartupBoxPosition() { long nX = Max( GetOutputSizePixel().Width() - aOnStartupCB.GetSizePixel().Width(), nMinPos ); Point aPos = aOnStartupCB.GetPosPixel(); aPos.X() = nX; aOnStartupCB.SetPosPixel( aPos ); } // ----------------------------------------------------------------------- Reference< XBreakIterator > SfxHelpTextWindow_Impl::GetBreakIterator() { if ( !xBreakIterator.is() ) xBreakIterator = vcl::unohelper::CreateBreakIterator(); DBG_ASSERT( xBreakIterator.is(), "Could not create BreakIterator" ); return xBreakIterator; } // ----------------------------------------------------------------------- Reference< XTextRange > SfxHelpTextWindow_Impl::getCursor() const { // return the current cursor Reference< XTextRange > xCursor; try { Reference < XSelectionSupplier > xSelSup( xFrame->getController(), UNO_QUERY ); if ( xSelSup.is() ) { Any aAny = xSelSup->getSelection(); Reference < XIndexAccess > xSelection; if ( aAny >>= xSelection ) { if ( xSelection->getCount() == 1 ) { aAny = xSelection->getByIndex(0); aAny >>= xCursor; } } } } catch( Exception& ) { OSL_FAIL( "SfxHelpTextWindow_Impl::getCursor(): unexpected exception" ); } return xCursor; } // ----------------------------------------------------------------------- bool SfxHelpTextWindow_Impl::isHandledKey( const KeyCode& _rKeyCode ) { bool bRet = false; USHORT nCode = _rKeyCode.GetCode(); // the keys (select all), (copy), // (find),

(print) and (close window) // were handled in help if ( _rKeyCode.IsMod1() && ( KEY_A == nCode || KEY_C == nCode || KEY_F == nCode || KEY_P == nCode || KEY_W == nCode ) ) { if ( KEY_F == nCode ) DoSearch(); else bRet = true; } return bRet; } // ----------------------------------------------------------------------- IMPL_LINK( SfxHelpTextWindow_Impl, SelectHdl, Timer*, EMPTYARG ) { try { // select the words, which are equal to the search text of the search page Reference < XController > xController = xFrame->getController(); if ( xController.is() ) { // get document Reference < XSearchable > xSearchable( xController->getModel(), UNO_QUERY ); if ( xSearchable.is() ) { // create descriptor, set string and find all words Reference < XSearchDescriptor > xSrchDesc = xSearchable->createSearchDescriptor(); Reference < XPropertySet > xPropSet( xSrchDesc, UNO_QUERY ); xPropSet->setPropertyValue( DEFINE_CONST_OUSTRING("SearchRegularExpression"), makeAny( sal_Bool( sal_True ) ) ); if ( bIsFullWordSearch ) xPropSet->setPropertyValue( DEFINE_CONST_OUSTRING("SearchWords"), makeAny( sal_Bool( sal_True ) ) ); String sSearchString = sfx2::PrepareSearchString( aSearchText, GetBreakIterator(), false ); xSrchDesc->setSearchString( sSearchString ); Reference< XIndexAccess > xSelection = xSearchable->findAll( xSrchDesc ); // then select all found words Reference < XSelectionSupplier > xSelectionSup( xController, UNO_QUERY ); if ( xSelectionSup.is() ) { Any aAny; aAny <<= xSelection; xSelectionSup->select( aAny ); } } } } catch( Exception& ) { OSL_FAIL( "SfxHelpTextWindow_Impl::SelectHdl(): unexpected exception" ); } return 1; } // ----------------------------------------------------------------------- IMPL_LINK( SfxHelpTextWindow_Impl, NotifyHdl, SvtMiscOptions*, pOptions ) { (void)pOptions; // unused variable InitToolBoxImages(); Resize(); aToolBox.Invalidate(); return 0; } // ----------------------------------------------------------------------- IMPL_LINK( SfxHelpTextWindow_Impl, FindHdl, sfx2::SearchDialog*, pDlg ) { bool bWrapAround = ( NULL == pDlg ); if ( bWrapAround ) pDlg = pSrchDlg; DBG_ASSERT( pDlg, "invalid search dialog" ); String sSearchText = pDlg->GetSearchText(); try { // select the words, which are equal to the search text of the search page Reference < XController > xController = xFrame->getController(); if ( xController.is() ) { // get document Reference < XSearchable > xSearchable( xController->getModel(), UNO_QUERY ); if ( xSearchable.is() ) { // create descriptor, set string and find all words Reference < XSearchDescriptor > xSrchDesc = xSearchable->createSearchDescriptor(); Reference < XPropertySet > xPropSet( xSrchDesc, UNO_QUERY ); xPropSet->setPropertyValue( DEFINE_CONST_OUSTRING("SearchWords"), makeAny( sal_Bool( pDlg->IsOnlyWholeWords() != false ) ) ); xPropSet->setPropertyValue( DEFINE_CONST_OUSTRING("SearchCaseSensitive"), makeAny( sal_Bool( pDlg->IsMarchCase() != false ) ) ); xPropSet->setPropertyValue( DEFINE_CONST_OUSTRING("SearchBackwards"), makeAny( sal_Bool( pDlg->IsSearchBackwards() != false ) ) ); xSrchDesc->setSearchString( sSearchText ); Reference< XInterface > xSelection; Reference< XTextRange > xCursor = getCursor(); if ( xCursor.is() ) { if ( pDlg->IsSearchBackwards() ) xCursor = xCursor->getStart(); xSelection = xSearchable->findNext( xCursor, xSrchDesc ); } else xSelection = xSearchable->findFirst( xSrchDesc ); // then select the found word if ( xSelection.is() ) { Reference < XSelectionSupplier > xSelectionSup( xController, UNO_QUERY ); if ( xSelectionSup.is() ) { Any aAny; aAny <<= xSelection; xSelectionSup->select( aAny ); } } else if ( pDlg->IsWrapAround() && !bWrapAround ) { Reference < text::XTextViewCursorSupplier > xCrsrSupp( xController, uno::UNO_QUERY ); Reference < text::XTextViewCursor > xTVCrsr( xCrsrSupp->getViewCursor(), uno::UNO_QUERY ); if ( xTVCrsr.is() ) { Reference < text::XTextDocument > xDoc( xController->getModel(), uno::UNO_QUERY ); Reference < text::XText > xText = xDoc->getText(); if ( xText.is() ) { if ( pDlg->IsSearchBackwards() ) xTVCrsr->gotoRange( xText->getEnd(), sal_False ); else xTVCrsr->gotoRange( xText->getStart(), sal_False ); FindHdl( NULL ); } } } else { DBG_ASSERT( pSrchDlg, "no search dialog" ); InfoBox aBox( pSrchDlg, SfxResId( RID_INFO_NOSEARCHTEXTFOUND ) ); aBox.Execute(); pSrchDlg->SetFocusOnEdit(); } } } } catch( Exception& ) { OSL_FAIL( "SfxHelpTextWindow_Impl::SelectHdl(): unexpected exception" ); } return 0; } // ----------------------------------------------------------------------- IMPL_LINK( SfxHelpTextWindow_Impl, CloseHdl, sfx2::SearchDialog*, pDlg ) { if ( pDlg ) delete pSrchDlg; pSrchDlg = NULL; return 0; } // ----------------------------------------------------------------------- IMPL_LINK( SfxHelpTextWindow_Impl, CheckHdl, CheckBox*, pBox ) { if ( xConfiguration.is() ) { sal_Bool bChecked = pBox->IsChecked(); ::rtl::OUString sPath( PATH_OFFICE_FACTORIES ); sPath += sCurrentFactory; try { ConfigurationHelper::writeRelativeKey( xConfiguration, sPath, KEY_HELP_ON_OPEN, makeAny( bChecked ) ); ConfigurationHelper::flush( xConfiguration ); } catch( Exception& ) { DBG_ERRORFILE( "SfxHelpTextWindow_Impl::CheckHdl(): unexpected exception" ); } } return 0; } // ----------------------------------------------------------------------- void SfxHelpTextWindow_Impl::Resize() { Size aSize = GetOutputSizePixel(); long nToolBoxHeight = aToolBox.GetSizePixel().Height() + TOOLBOX_OFFSET; aSize.Height() -= nToolBoxHeight; pTextWin->SetPosSizePixel( Point( 0, nToolBoxHeight ), aSize ); SetOnStartupBoxPosition(); } // ----------------------------------------------------------------------- long SfxHelpTextWindow_Impl::PreNotify( NotifyEvent& rNEvt ) { long nDone = 0; USHORT nType = rNEvt.GetType(); if ( EVENT_COMMAND == nType && rNEvt.GetCommandEvent() ) { const CommandEvent* pCmdEvt = rNEvt.GetCommandEvent(); Window* pCmdWin = rNEvt.GetWindow(); if ( pCmdEvt->GetCommand() == COMMAND_CONTEXTMENU && pCmdWin != this && pCmdWin != &aToolBox ) { Point aPos; if ( pCmdEvt->IsMouseEvent() ) aPos = pCmdEvt->GetMousePosPixel(); else aPos = Point( pTextWin->GetPosPixel().X() + 20, 20 ); aPos.Y() += pTextWin->GetPosPixel().Y(); PopupMenu aMenu; if ( bIsIndexOn ) aMenu.InsertItem( TBI_INDEX, aIndexOffText, Image( SfxResId( IMG_HELP_TOOLBOX_INDEX_OFF ) ) ); else aMenu.InsertItem( TBI_INDEX, aIndexOnText, Image( SfxResId( IMG_HELP_TOOLBOX_INDEX_ON ) ) ); aMenu.SetHelpId( TBI_INDEX, HID_HELP_TOOLBOXITEM_INDEX ); aMenu.InsertSeparator(); aMenu.InsertItem( TBI_BACKWARD, String( SfxResId( STR_HELP_BUTTON_PREV ) ), Image( SfxResId( IMG_HELP_TOOLBOX_PREV ) ) ); aMenu.SetHelpId( TBI_BACKWARD, HID_HELP_TOOLBOXITEM_BACKWARD ); aMenu.EnableItem( TBI_BACKWARD, pHelpWin->HasHistoryPredecessor() ); aMenu.InsertItem( TBI_FORWARD, String( SfxResId( STR_HELP_BUTTON_NEXT ) ), Image( SfxResId( IMG_HELP_TOOLBOX_NEXT ) ) ); aMenu.SetHelpId( TBI_FORWARD, HID_HELP_TOOLBOXITEM_FORWARD ); aMenu.EnableItem( TBI_FORWARD, pHelpWin->HasHistorySuccessor() ); aMenu.InsertItem( TBI_START, String( SfxResId( STR_HELP_BUTTON_START ) ), Image( SfxResId( IMG_HELP_TOOLBOX_START ) ) ); aMenu.SetHelpId( TBI_START, HID_HELP_TOOLBOXITEM_START ); aMenu.InsertSeparator(); aMenu.InsertItem( TBI_PRINT, String( SfxResId( STR_HELP_BUTTON_PRINT ) ), Image( SfxResId( IMG_HELP_TOOLBOX_PRINT ) ) ); aMenu.SetHelpId( TBI_PRINT, HID_HELP_TOOLBOXITEM_PRINT ); aMenu.InsertItem( TBI_BOOKMARKS, String( SfxResId( STR_HELP_BUTTON_ADDBOOKMARK ) ), Image( SfxResId( IMG_HELP_TOOLBOX_BOOKMARKS ) ) ); aMenu.SetHelpId( TBI_BOOKMARKS, HID_HELP_TOOLBOXITEM_BOOKMARKS ); aMenu.InsertItem( TBI_SEARCHDIALOG, String( SfxResId( STR_HELP_BUTTON_SEARCHDIALOG ) ), Image( SfxResId( IMG_HELP_TOOLBOX_SEARCHDIALOG ) ) ); aMenu.SetHelpId( TBI_SEARCHDIALOG, HID_HELP_TOOLBOXITEM_SEARCHDIALOG ); aMenu.InsertSeparator(); aMenu.InsertItem( TBI_SELECTIONMODE, String( SfxResId( STR_HELP_MENU_TEXT_SELECTION_MODE ) ) ); aMenu.SetHelpId( TBI_SELECTIONMODE, HID_HELP_TEXT_SELECTION_MODE ); Reference < XDispatchProvider > xProv( xFrame, UNO_QUERY ); URL aURL; aURL.Complete = DEFINE_CONST_UNICODE(".uno:SelectTextMode"); PARSE_URL( aURL ); Reference < XDispatch > xDisp = xProv.is() ? xProv->queryDispatch( aURL, rtl::OUString(), 0 ) : Reference < XDispatch >(); if(xDisp.is()) { HelpStatusListener_Impl* pStateListener; ReferencexStateListener = pStateListener = new HelpStatusListener_Impl(xDisp, aURL ); FeatureStateEvent rEvent = pStateListener->GetStateEvent(); sal_Bool bCheck = sal_False; rEvent.State >>= bCheck; aMenu.CheckItem(TBI_SELECTIONMODE, bCheck); } aMenu.InsertSeparator(); aMenu.InsertItem( TBI_COPY, String( SfxResId( STR_HELP_MENU_TEXT_COPY ) ), Image( SfxResId( IMG_HELP_TOOLBOX_COPY ) ) ); aMenu.SetHelpId( TBI_COPY, SID_COPY ); aMenu.EnableItem( TBI_COPY, HasSelection() ); if ( bIsDebug ) { aMenu.InsertSeparator(); aMenu.InsertItem( TBI_SOURCEVIEW, String( SfxResId( STR_HELP_BUTTON_SOURCEVIEW ) ) ); } if( SvtMenuOptions().IsEntryHidingEnabled() == sal_False ) aMenu.SetMenuFlags( aMenu.GetMenuFlags() | MENU_FLAG_HIDEDISABLEDENTRIES ); USHORT nId = aMenu.Execute( this, aPos ); pHelpWin->DoAction( nId ); nDone = 1; } } else if ( EVENT_KEYINPUT == nType && rNEvt.GetKeyEvent() ) { const KeyEvent* pKEvt = rNEvt.GetKeyEvent(); const KeyCode& rKeyCode = pKEvt->GetKeyCode(); USHORT nKeyGroup = rKeyCode.GetGroup(); USHORT nKey = rKeyCode.GetCode(); if ( KEYGROUP_ALPHA == nKeyGroup && !isHandledKey( rKeyCode ) ) { // do nothing disables the writer accelerators nDone = 1; } else if ( rKeyCode.IsMod1() && ( KEY_F4 == nKey || KEY_W == nKey ) ) { // or -> close top frame pHelpWin->CloseWindow(); nDone = 1; } else if ( KEY_TAB == nKey && aOnStartupCB.HasChildPathFocus() ) { aToolBox.GrabFocus(); nDone = 1; } } return nDone ? nDone : Window::PreNotify( rNEvt ); } // ----------------------------------------------------------------------- void SfxHelpTextWindow_Impl::GetFocus() { if ( !bIsInClose ) { try { if( xFrame.is() ) { Reference< ::com::sun::star::awt::XWindow > xWindow = xFrame->getComponentWindow(); if( xWindow.is() ) xWindow->setFocus(); } } catch( Exception& ) { DBG_ERRORFILE( "SfxHelpTextWindow_Impl::GetFocus(): unexpected exception" ); } } } // ----------------------------------------------------------------------- void SfxHelpTextWindow_Impl::DataChanged( const DataChangedEvent& rDCEvt ) { Window::DataChanged( rDCEvt ); if ( ( ( rDCEvt.GetType() == DATACHANGED_SETTINGS ) || ( rDCEvt.GetType() == DATACHANGED_DISPLAY ) ) && ( rDCEvt.GetFlags() & SETTINGS_STYLE ) ) { SetBackground( Wallpaper( GetSettings().GetStyleSettings().GetFaceColor() ) ); InitToolBoxImages(); } } // ----------------------------------------------------------------------- void SfxHelpTextWindow_Impl::ToggleIndex( sal_Bool bOn ) { bIsIndexOn = bOn; if ( bIsIndexOn ) { aToolBox.SetItemImage( TBI_INDEX, aIndexOffImage ); aToolBox.SetItemText( TBI_INDEX, aIndexOffText ); } else { aToolBox.SetItemImage( TBI_INDEX, aIndexOnImage ); aToolBox.SetItemText( TBI_INDEX, aIndexOnText ); } } // ----------------------------------------------------------------------- void SfxHelpTextWindow_Impl::SelectSearchText( const String& rSearchText, sal_Bool _bIsFullWordSearch ) { aSearchText = rSearchText; bIsFullWordSearch = _bIsFullWordSearch; aSelectTimer.Start(); } // ----------------------------------------------------------------------- void SfxHelpTextWindow_Impl::SetPageStyleHeaderOff() const { #ifdef DBG_UTIL sal_Bool bSetOff = sal_False; #endif // set off the pagestyle header to prevent print output of the help URL try { Reference < XController > xController = xFrame->getController(); Reference < XSelectionSupplier > xSelSup( xController, UNO_QUERY ); if ( xSelSup.is() ) { Reference < XIndexAccess > xSelection; if ( xSelSup->getSelection() >>= xSelection ) { Reference < XTextRange > xRange; if ( xSelection->getByIndex(0) >>= xRange ) { Reference < XText > xText = xRange->getText(); Reference < XPropertySet > xProps( xText->createTextCursorByRange( xRange ), UNO_QUERY ); ::rtl::OUString sStyleName; if ( xProps->getPropertyValue( DEFINE_CONST_OUSTRING("PageStyleName") ) >>= sStyleName ) { Reference < XStyleFamiliesSupplier > xStyles( xController->getModel(), UNO_QUERY ); Reference < XNameContainer > xContainer; if ( xStyles->getStyleFamilies()->getByName( DEFINE_CONST_OUSTRING("PageStyles") ) >>= xContainer ) { Reference < XStyle > xStyle; if ( xContainer->getByName( sStyleName ) >>= xStyle ) { Reference < XPropertySet > xPropSet( xStyle, UNO_QUERY ); xPropSet->setPropertyValue( DEFINE_CONST_OUSTRING("HeaderIsOn"), makeAny( sal_Bool( sal_False ) ) ); Reference< XModifiable > xReset(xStyles, UNO_QUERY); xReset->setModified(sal_False); #ifdef DBG_UTIL bSetOff = sal_True; #endif } } } } } } } catch( Exception& ) { DBG_ERRORFILE( "SfxHelpTextWindow_Impl::SetPageStyleHeaderOff(): unexpected exception" ); } #ifdef DBG_UTIL if ( !bSetOff ) { DBG_ERRORFILE( "SfxHelpTextWindow_Impl::SetPageStyleHeaderOff(): set off failed" ); } #endif } // ----------------------------------------------------------------------- void SfxHelpTextWindow_Impl::CloseFrame() { bIsInClose = sal_True; try { ::com::sun::star::uno::Reference< ::com::sun::star::util::XCloseable > xCloseable ( xFrame, ::com::sun::star::uno::UNO_QUERY ); if (xCloseable.is()) xCloseable->close(sal_True); } catch( ::com::sun::star::util::CloseVetoException& ) { } } // ----------------------------------------------------------------------- void SfxHelpTextWindow_Impl::DoSearch() { if ( !pSrchDlg ) { // create the search dialog pSrchDlg = new sfx2::SearchDialog( pTextWin, DEFINE_CONST_UNICODE("HelpSearchDialog") ); // set handler pSrchDlg->SetFindHdl( LINK( this, SfxHelpTextWindow_Impl, FindHdl ) ); pSrchDlg->SetCloseHdl( LINK( this, SfxHelpTextWindow_Impl, CloseHdl ) ); // get selected text of the help page to set it as the search text Reference< XTextRange > xCursor = getCursor(); if ( xCursor.is() ) { String sText = xCursor->getString(); if ( sText.Len() > 0 ) pSrchDlg->SetSearchText( sText ); } pSrchDlg->Show(); } } // class SfxHelpWindow_Impl ---------------------------------------------- void SfxHelpWindow_Impl::Resize() { SplitWindow::Resize(); InitSizes(); } // ----------------------------------------------------------------------- void SfxHelpWindow_Impl::Split() { static long nMinSplitSize = 5; static long nMaxSplitSize = 99 - nMinSplitSize; SplitWindow::Split(); nIndexSize = GetItemSize( INDEXWIN_ID ); nTextSize = GetItemSize( TEXTWIN_ID ); BOOL bMod = FALSE; if( nIndexSize < nMinSplitSize ) { nIndexSize = nMinSplitSize; nTextSize = nMaxSplitSize; bMod = TRUE; } else if( nTextSize < nMinSplitSize ) { nTextSize = nMinSplitSize; nIndexSize = nMaxSplitSize; bMod = TRUE; } else bMod = FALSE; if( bMod ) { SetItemSize( INDEXWIN_ID, nIndexSize ); SetItemSize( TEXTWIN_ID, nTextSize ); } InitSizes(); } // ----------------------------------------------------------------------- void SfxHelpWindow_Impl::GetFocus() { pTextWin->GrabFocus(); } // ----------------------------------------------------------------------- void SfxHelpWindow_Impl::MakeLayout() { if ( nHeight > 0 && xWindow.is() ) { Window* pScreenWin = VCLUnoHelper::GetWindow( xWindow ); /* #i55528# Hide() / Show() will produce starnge effects. The returned size (used later to be written back into the configuration) isnt the right after a resize during the window is hidden. If this resize is done if the window is visible evyrthing works as aspected. Some VCL-patches could not solve this problem so I've established the workaround: resize the help window if it's visible .-) */ ::com::sun::star::awt::Rectangle aRect = xWindow->getPosSize(); sal_Int32 nOldWidth = bIndex ? nCollapseWidth : nExpandWidth; sal_Int32 nWidth = bIndex ? nExpandWidth : nCollapseWidth; xWindow->setPosSize( aRect.X, aRect.Y, nWidth, nHeight, ::com::sun::star::awt::PosSize::SIZE ); if ( aRect.Width > 0 && aRect.Height > 0 ) { Rectangle aScreenRect = pScreenWin->GetClientWindowExtentsRelative( NULL ); Point aNewPos = aScreenRect.TopLeft(); sal_Int32 nDiffWidth = nOldWidth - nWidth; aNewPos.X() += nDiffWidth; pScreenWin->SetPosPixel( aNewPos ); } else if ( aWinPos.X() > 0 && aWinPos.Y() > 0 ) pScreenWin->SetPosPixel( aWinPos ); } Clear(); if ( bIndex ) { pIndexWin->Show(); InsertItem( COLSET_ID, 100, SPLITWINDOW_APPEND, SPLITSET_ID, SWIB_PERCENTSIZE | SWIB_COLSET ); InsertItem( INDEXWIN_ID, pIndexWin, nIndexSize, SPLITWINDOW_APPEND, COLSET_ID, SWIB_PERCENTSIZE ); InsertItem( TEXTWIN_ID, pTextWin, nTextSize, SPLITWINDOW_APPEND, COLSET_ID, SWIB_PERCENTSIZE ); } else { pIndexWin->Hide(); InsertItem( COLSET_ID, 100, SPLITWINDOW_APPEND, SPLITSET_ID, SWIB_PERCENTSIZE | SWIB_COLSET ); InsertItem( TEXTWIN_ID, pTextWin, 100, SPLITWINDOW_APPEND, 1, SWIB_PERCENTSIZE ); } } // ----------------------------------------------------------------------- void SfxHelpWindow_Impl::InitSizes() { if ( xWindow.is() ) { ::com::sun::star::awt::Rectangle aRect = xWindow->getPosSize(); nHeight = aRect.Height; if ( bIndex ) { nExpandWidth = aRect.Width; nCollapseWidth = nExpandWidth * nTextSize / 100; } else { nCollapseWidth = aRect.Width; nExpandWidth = nCollapseWidth * 100 / nTextSize; } } } // ----------------------------------------------------------------------- void SfxHelpWindow_Impl::LoadConfig() { SvtViewOptions aViewOpt( E_WINDOW, CONFIGNAME_HELPWIN ); if ( aViewOpt.Exists() ) { bIndex = aViewOpt.IsVisible(); String aUserData; Any aUserItem = aViewOpt.GetUserItem( USERITEM_NAME ); rtl::OUString aTemp; if ( aUserItem >>= aTemp ) { aUserData = String( aTemp ); DBG_ASSERT( aUserData.GetTokenCount() == 6, "invalid user data" ); USHORT nIdx = 0; nIndexSize = aUserData.GetToken( 0, ';', nIdx ).ToInt32(); nTextSize = aUserData.GetToken( 0, ';', nIdx ).ToInt32(); sal_Int32 nWidth = aUserData.GetToken( 0, ';', nIdx ).ToInt32(); nHeight = aUserData.GetToken( 0, ';', nIdx ).ToInt32(); aWinPos.X() = aUserData.GetToken( 0, ';', nIdx ).ToInt32(); aWinPos.Y() = aUserData.GetToken( 0, ';', nIdx ).ToInt32(); if ( bIndex ) { nExpandWidth = nWidth; nCollapseWidth = nExpandWidth * nTextSize / 100; } else { nCollapseWidth = nWidth; nExpandWidth = nCollapseWidth * 100 / nTextSize; } } pTextWin->ToggleIndex( bIndex ); } } // ----------------------------------------------------------------------- void SfxHelpWindow_Impl::SaveConfig() { SvtViewOptions aViewOpt( E_WINDOW, CONFIGNAME_HELPWIN ); sal_Int32 nW = 0, nH = 0; if ( xWindow.is() ) { ::com::sun::star::awt::Rectangle aRect = xWindow->getPosSize(); nW = aRect.Width; nH = aRect.Height; } aViewOpt.SetVisible( bIndex ); String aUserData = String::CreateFromInt32( nIndexSize ); aUserData += ';'; aUserData += String::CreateFromInt32( nTextSize ); aUserData += ';'; aUserData += String::CreateFromInt32( nW ); aUserData += ';'; aUserData += String::CreateFromInt32( nH ); Window* pScreenWin = VCLUnoHelper::GetWindow( xWindow ); aWinPos = pScreenWin->GetWindowExtentsRelative( NULL ).TopLeft(); aUserData += ';'; aUserData += String::CreateFromInt32( aWinPos.X() ); aUserData += ';'; aUserData += String::CreateFromInt32( aWinPos.Y() ); aViewOpt.SetUserItem( USERITEM_NAME, makeAny( rtl::OUString( aUserData ) ) ); } // ----------------------------------------------------------------------- void SfxHelpWindow_Impl::ShowStartPage() { ::rtl::OUString sHelpURL = SfxHelpWindow_Impl::buildHelpURL(pIndexWin->GetFactory(), DEFINE_CONST_UNICODE("/start"), ::rtl::OUString(), sal_True); loadHelpContent(sHelpURL); } // ----------------------------------------------------------------------- IMPL_LINK( SfxHelpWindow_Impl, SelectHdl, ToolBox* , pToolBox ) { if ( pToolBox ) { bGrabFocusToToolBox = pToolBox->HasChildPathFocus(); DoAction( pToolBox->GetCurItemId() ); } return 1; } //------------------------------------------------------------------------- IMPL_LINK( SfxHelpWindow_Impl, OpenHdl, SfxHelpIndexWindow_Impl* , EMPTYARG ) { pIndexWin->SelectExecutableEntry(); String aEntry = pIndexWin->GetSelectEntry(); if ( aEntry.Len() < 1 ) return 0; ::rtl::OUString sHelpURL; BOOL bComplete = rtl::OUString(aEntry).toAsciiLowerCase().match(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("vnd.sun.star.help")),0); if (bComplete) sHelpURL = ::rtl::OUString(aEntry); else { String aId; String aAnchor = String('#'); if ( aEntry.GetTokenCount( '#' ) == 2 ) { aId = aEntry.GetToken( 0, '#' ); aAnchor += aEntry.GetToken( 1, '#' ); } else aId = aEntry; aEntry = '/'; aEntry += aId; sHelpURL = SfxHelpWindow_Impl::buildHelpURL(pIndexWin->GetFactory(), aEntry, aAnchor, sal_True); } loadHelpContent(sHelpURL); return 0; } //------------------------------------------------------------------------- IMPL_LINK( SfxHelpWindow_Impl, SelectFactoryHdl, SfxHelpIndexWindow_Impl* , pWin ) { if ( sTitle.Len() == 0 ) sTitle = GetParent()->GetText(); String aNewTitle = sTitle; aNewTitle += DEFINE_CONST_UNICODE(" - "); aNewTitle += pIndexWin->GetActiveFactoryTitle(); Reference< XTitle > xTitle(xFrame, UNO_QUERY); if (xTitle.is ()) xTitle->setTitle (aNewTitle); if ( pWin ) ShowStartPage(); pIndexWin->ClearSearchPage(); return 0; } // ----------------------------------------------------------------------- IMPL_LINK( SfxHelpWindow_Impl, ChangeHdl, HelpListener_Impl*, pListener ) { SetFactory( pListener->GetFactory() ); return 0; } // ----------------------------------------------------------------------- void SfxHelpWindow_Impl::openDone(const ::rtl::OUString& sURL , sal_Bool bSuccess) { INetURLObject aObj( sURL ); if ( aObj.GetProtocol() == INET_PROT_VND_SUN_STAR_HELP ) SetFactory( aObj.GetHost() ); if ( IsWait() ) LeaveWait(); if ( bGrabFocusToToolBox ) { pTextWin->GetToolBox().GrabFocus(); bGrabFocusToToolBox = sal_False; } else pIndexWin->GrabFocusBack(); if ( bSuccess ) { // set some view settings: "prevent help tips" and "helpid == 68245" try { Reference < XController > xController = pTextWin->getFrame()->getController(); if ( xController.is() ) { Reference < XViewSettingsSupplier > xSettings( xController, UNO_QUERY ); Reference < XPropertySet > xViewProps = xSettings->getViewSettings(); Reference< XPropertySetInfo > xInfo = xViewProps->getPropertySetInfo(); Any aBoolAny = makeAny( sal_Bool( sal_True ) ); xViewProps->setPropertyValue( DEFINE_CONST_OUSTRING("PreventHelpTips"), aBoolAny ); xViewProps->setPropertyValue( DEFINE_CONST_OUSTRING("ShowGraphics"), aBoolAny ); xViewProps->setPropertyValue( DEFINE_CONST_OUSTRING("ShowTables"), aBoolAny ); xViewProps->setPropertyValue( DEFINE_CONST_OUSTRING("HelpURL"), makeAny( DEFINE_CONST_OUSTRING("HID:68245") ) ); ::rtl::OUString sProperty( DEFINE_CONST_OUSTRING("IsExecuteHyperlinks") ); if ( xInfo->hasPropertyByName( sProperty ) ) xViewProps->setPropertyValue( sProperty, aBoolAny ); xController->restoreViewData(pHelpInterceptor->GetViewData()); } } catch( Exception& ) { OSL_FAIL( "SfxHelpWindow_Impl::OpenDoneHdl(): unexpected exception" ); } // When the SearchPage opens the help doc, then select all words, which are equal to its text String sSearchText = TRIM( pIndexWin->GetSearchText() ); if ( sSearchText.Len() > 0 ) pTextWin->SelectSearchText( sSearchText, pIndexWin->IsFullWordSearch() ); // no page style header -> this prevents a print output of the URL pTextWin->SetPageStyleHeaderOff(); } } // ----------------------------------------------------------------------- SfxHelpWindow_Impl::SfxHelpWindow_Impl( const ::com::sun::star::uno::Reference < ::com::sun::star::frame::XFrame >& rFrame, Window* pParent, WinBits ) : SplitWindow( pParent, WB_3DLOOK | WB_NOSPLITDRAW ), xFrame ( rFrame ), pIndexWin ( NULL ), pTextWin ( NULL ), pHelpInterceptor ( new HelpInterceptor_Impl() ), pHelpListener ( new HelpListener_Impl( pHelpInterceptor ) ), nExpandWidth ( 0 ), nCollapseWidth ( 0 ), nHeight ( 0 ), nIndexSize ( 40 ), nTextSize ( 60 ), bIndex ( sal_True ), bGrabFocusToToolBox ( sal_False ), aWinPos ( 0, 0 ), sTitle ( pParent->GetText() ) { SetHelpId( HID_HELP_WINDOW ); SetStyle( GetStyle() | WB_DIALOGCONTROL ); pHelpInterceptor->InitWaiter( this ); pIndexWin = new SfxHelpIndexWindow_Impl( this ); pIndexWin->SetDoubleClickHdl( LINK( this, SfxHelpWindow_Impl, OpenHdl ) ); pIndexWin->SetSelectFactoryHdl( LINK( this, SfxHelpWindow_Impl, SelectFactoryHdl ) ); pIndexWin->Show(); pTextWin = new SfxHelpTextWindow_Impl( this ); Reference < XFramesSupplier > xSup( rFrame, UNO_QUERY ); Reference < XFrames > xFrames = xSup->getFrames(); xFrames->append( pTextWin->getFrame() ); pTextWin->SetSelectHdl( LINK( this, SfxHelpWindow_Impl, SelectHdl ) ); pTextWin->Show(); pHelpInterceptor->setInterception( pTextWin->getFrame() ); pHelpListener->SetChangeHdl( LINK( this, SfxHelpWindow_Impl, ChangeHdl ) ); LoadConfig(); } // ----------------------------------------------------------------------- SfxHelpWindow_Impl::~SfxHelpWindow_Impl() { SaveConfig(); Window* pDel = pIndexWin; pIndexWin = NULL; delete pDel; pTextWin->CloseFrame(); delete pTextWin; } // ----------------------------------------------------------------------- long SfxHelpWindow_Impl::PreNotify( NotifyEvent& rNEvt ) { sal_Bool bHandled = sal_False; if ( rNEvt.GetType() == EVENT_KEYINPUT ) { // Backward == or Forward == const KeyCode& rKeyCode = rNEvt.GetKeyEvent()->GetKeyCode(); USHORT nKey = rKeyCode.GetCode(); if ( ( rKeyCode.IsMod2() && ( KEY_LEFT == nKey || KEY_RIGHT == nKey ) ) || ( !rKeyCode.GetModifier() && KEY_BACKSPACE == nKey && !pIndexWin->HasFocusOnEdit() ) ) { DoAction( rKeyCode.GetCode() == KEY_RIGHT ? TBI_FORWARD : TBI_BACKWARD ); bHandled = sal_True; } else if ( rKeyCode.IsMod1() && ( KEY_F4 == nKey || KEY_W == nKey ) ) { // or -> close top frame CloseWindow(); bHandled = sal_True; } } return bHandled ? 1 : Window::PreNotify( rNEvt ); } // ----------------------------------------------------------------------- void SfxHelpWindow_Impl::setContainerWindow( Reference < ::com::sun::star::awt::XWindow > xWin ) { xWindow = xWin; MakeLayout(); } // ----------------------------------------------------------------------- void SfxHelpWindow_Impl::SetFactory( const String& rFactory ) { pIndexWin->SetFactory( rFactory, sal_True ); } // ----------------------------------------------------------------------- void SfxHelpWindow_Impl::SetHelpURL( const String& rURL ) { INetURLObject aObj( rURL ); if ( aObj.GetProtocol() == INET_PROT_VND_SUN_STAR_HELP ) SetFactory( aObj.GetHost() ); } // ----------------------------------------------------------------------- void SfxHelpWindow_Impl::DoAction( USHORT nActionId ) { switch ( nActionId ) { case TBI_INDEX : { bIndex = !bIndex; MakeLayout(); pTextWin->ToggleIndex( bIndex ); break; } case TBI_START : { ShowStartPage(); break; } case TBI_BACKWARD : case TBI_FORWARD : { URL aURL; aURL.Complete = DEFINE_CONST_UNICODE(".uno:Backward"); if ( TBI_FORWARD == nActionId ) aURL.Complete = DEFINE_CONST_UNICODE(".uno:Forward"); PARSE_URL( aURL ); pHelpInterceptor->dispatch( aURL, Sequence < PropertyValue >() ); break; } case TBI_SEARCHDIALOG : { pTextWin->DoSearch(); break; } case TBI_PRINT : case TBI_SOURCEVIEW : case TBI_COPY : case TBI_SELECTIONMODE: { Reference < XDispatchProvider > xProv( pTextWin->getFrame(), UNO_QUERY ); if ( xProv.is() ) { URL aURL; if ( TBI_PRINT == nActionId ) aURL.Complete = DEFINE_CONST_UNICODE(".uno:Print"); else if ( TBI_SOURCEVIEW == nActionId ) aURL.Complete = DEFINE_CONST_UNICODE(".uno:SourceView"); else if ( TBI_COPY == nActionId ) aURL.Complete = DEFINE_CONST_UNICODE(".uno:Copy"); else if ( TBI_SELECTIONMODE == nActionId ) aURL.Complete = DEFINE_CONST_UNICODE(".uno:SelectTextMode"); else aURL.Complete = DEFINE_CONST_UNICODE(".uno:SearchDialog"); PARSE_URL( aURL ); Reference < XDispatch > xDisp = xProv->queryDispatch( aURL, String(), 0 ); if ( xDisp.is() ) xDisp->dispatch( aURL, Sequence < PropertyValue >() ); } break; } case TBI_BOOKMARKS : { String aURL = pHelpInterceptor->GetCurrentURL(); if ( aURL.Len() > 0 ) { try { Content aCnt( aURL, Reference< ::com::sun::star::ucb::XCommandEnvironment > () ); ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > xInfo = aCnt.getProperties(); if ( xInfo->hasPropertyByName( PROPERTY_TITLE ) ) { ::com::sun::star::uno::Any aAny = aCnt.getPropertyValue( PROPERTY_TITLE ); rtl::OUString aValue; if ( aAny >>= aValue ) { String aTitle( aValue ); SfxAddHelpBookmarkDialog_Impl aDlg( this, sal_False ); aDlg.SetTitle( aTitle ); if ( aDlg.Execute() == RET_OK ) { aTitle = aDlg.GetTitle(); pIndexWin->AddBookmarks( aTitle, aURL ); } } } } catch( Exception& ) { OSL_FAIL( "SfxHelpWindow_Impl::DoAction(): unexpected exception" ); } } break; } } } // ----------------------------------------------------------------------- void SfxHelpWindow_Impl::CloseWindow() { try { // search for top frame Reference< XFramesSupplier > xCreator = getTextFrame()->getCreator(); while ( xCreator.is() && !xCreator->isTop() ) { xCreator = xCreator->getCreator(); } // when found, close it if ( xCreator.is() && xCreator->isTop() ) { Reference < XCloseable > xCloser( xCreator, UNO_QUERY ); if ( xCloser.is() ) xCloser->close( sal_False ); } } catch( Exception& ) { DBG_ERRORFILE( "SfxHelpWindow_Impl::CloseWindow(): caught an exception" ); } } // ----------------------------------------------------------------------- void SfxHelpWindow_Impl::UpdateToolbox() { pTextWin->GetToolBox().EnableItem( TBI_BACKWARD, pHelpInterceptor->HasHistoryPred() ); pTextWin->GetToolBox().EnableItem( TBI_FORWARD, pHelpInterceptor->HasHistorySucc() ); } // ----------------------------------------------------------------------- sal_Bool SfxHelpWindow_Impl::HasHistoryPredecessor() const { return pHelpInterceptor->HasHistoryPred(); } // ----------------------------------------------------------------------- sal_Bool SfxHelpWindow_Impl::HasHistorySuccessor() const { return pHelpInterceptor->HasHistorySucc(); } // class SfxAddHelpBookmarkDialog_Impl ----------------------------------- SfxAddHelpBookmarkDialog_Impl::SfxAddHelpBookmarkDialog_Impl( Window* pParent, sal_Bool bRename ) : ModalDialog( pParent, SfxResId( DLG_HELP_ADDBOOKMARK ) ), aTitleFT ( this, SfxResId( FT_BOOKMARK_TITLE ) ), aTitleED ( this, SfxResId( ED_BOOKMARK_TITLE ) ), aOKBtn ( this, SfxResId( PB_BOOKMARK_OK ) ), aEscBtn ( this, SfxResId( PB_BOOKMARK_CANCEL ) ), aHelpBtn ( this, SfxResId( PB_BOOKMARK_HELP ) ) { if ( bRename ) SetText( String( SfxResId( STR_BOOKMARK_RENAME ) ) ); FreeResource(); } // ----------------------------------------------------------------------- SfxAddHelpBookmarkDialog_Impl::~SfxAddHelpBookmarkDialog_Impl() { } // ----------------------------------------------------------------------- void SfxAddHelpBookmarkDialog_Impl::SetTitle( const String& rTitle ) { aTitleED.SetText( rTitle ); aTitleED.SetSelection( Selection( 0, rTitle.Len() ) ); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */