/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include class CustomLink : public FixedHyperlink { public: CustomLink( vcl::Window* pParent, WinBits nWinStyle ) : FixedHyperlink( pParent, nWinStyle ) { vcl::Font aFont = GetControlFont( ); aFont.SetUnderline( LINESTYLE_NONE ); SetControlFont( aFont ); } protected: virtual void MouseMove( const MouseEvent& rMEvt ) override { // changes the style if the control is enabled if ( !rMEvt.IsLeaveWindow() && IsEnabled() ) { vcl::Font aFont = GetControlFont( ); aFont.SetUnderline( LINESTYLE_SINGLE ); SetControlFont( aFont ); } else { vcl::Font aFont = GetControlFont( ); aFont.SetUnderline( LINESTYLE_NONE ); SetControlFont( aFont ); } FixedHyperlink::MouseMove( rMEvt ); } }; Breadcrumb::Breadcrumb( vcl::Window* pParent ) : VclHBox( pParent ) { m_eMode = SvtBreadcrumbMode::ONLY_CURRENT_PATH; set_spacing( SPACING ); appendField(); // root } Breadcrumb::~Breadcrumb() { disposeOnce(); } void Breadcrumb::dispose() { for( std::vector>::size_type i = 0; i < m_aLinks.size(); i++ ) { m_aSeparators[i].disposeAndClear(); m_aLinks[i].disposeAndClear(); } VclHBox::dispose(); } void Breadcrumb::EnableFields( bool bEnable ) { VclHBox::Enable( bEnable ); if( bEnable ) { INetURLObject aURL( m_aCurrentURL ); int nSegments = aURL.getSegmentCount(); m_aLinks[nSegments]->Enable( false ); } } void Breadcrumb::SetClickHdl( const Link& rLink ) { m_aClickHdl = rLink; } const OUString& Breadcrumb::GetHdlURL() { return m_sClickedURL; } void Breadcrumb::SetRootName( const OUString& rURL ) { m_sRootName = rURL; // we changed root - clear all fields for( std::vector>::size_type i = 1; i < m_aLinks.size(); i++ ) { m_aLinks[i]->SetText( "" ); m_aLinks[i]->Hide(); m_aSeparators[i]->Hide(); m_aLinks[i]->Enable(); } } void Breadcrumb::SetURL( const OUString& rURL ) { m_aCurrentURL = rURL; INetURLObject aURL( rURL ); aURL.setFinalSlash(); //prepare the Host port OUString sHostPort; if( aURL.HasPort() ) { sHostPort += ":"; sHostPort += OUString::number( aURL.GetPort() ); } OUString sUser = aURL.GetUser( INetURLObject::DecodeMechanism::NONE ); OUString sPath = aURL.GetURLPath(INetURLObject::DecodeMechanism::WithCharset); OUString sRootPath = INetURLObject::GetScheme( aURL.GetProtocol() ) + sUser + ( sUser.isEmpty() ? OUString() : "@" ) + aURL.GetHost() + sHostPort; int nSegments = aURL.getSegmentCount(); unsigned int nPos = 0; bool bClear = ( m_eMode == SvtBreadcrumbMode::ONLY_CURRENT_PATH ); // root field m_aLinks[0]->SetText( m_sRootName ); m_aLinks[0]->Enable(); m_aLinks[0]->SetURL( sRootPath ); // fill the other fields for( unsigned int i = 1; i < (unsigned int)nSegments + 1; i++ ) { if( i >= m_aLinks.size() ) appendField(); unsigned int nEnd = sPath.indexOf( '/', nPos + 1 ); OUString sLabel = OUString( sPath.getStr() + nPos + 1, nEnd - nPos - 1 ); if( m_eMode == SvtBreadcrumbMode::ALL_VISITED ) { if( m_aLinks[i]->GetText() != sLabel ) bClear = true; } m_aLinks[i]->SetText( sLabel ); m_aLinks[i]->SetURL( sRootPath + OUString( sPath.getStr(), nEnd ) ); m_aLinks[i]->Hide(); m_aLinks[i]->Enable(); m_aSeparators[i]->Hide(); nPos = nEnd; } // clear unused fields for( std::vector>::size_type i = nSegments + 1; i < m_aLinks.size(); i++ ) { if( bClear ) m_aLinks[i]->SetText( "" ); m_aLinks[i]->Hide(); m_aSeparators[i]->Hide(); m_aLinks[i]->Enable(); } // show fields Resize(); unsigned int nMaxWidth = GetSizePixel().Width(); unsigned int nSeparatorWidth = m_aSeparators[0]->GetSizePixel().Width(); unsigned int nCurrentWidth = 0; unsigned int nLastVisible = nSegments; bool bRight = ( m_eMode == SvtBreadcrumbMode::ALL_VISITED ); bool bLeft = true; int i = 0; while( bLeft || bRight ) { if( nSegments - i == -1 ) bLeft = false; if( bLeft ) { unsigned int nIndex = nSegments - i; if( showField( nIndex, nMaxWidth - nCurrentWidth ) ) { nCurrentWidth += m_aLinks[nIndex]->GetSizePixel().Width() + nSeparatorWidth + 2*SPACING; } else { // label is too long if( nSegments != 0 ) { m_aLinks[0]->SetText( "..." ); m_aLinks[0]->Enable( false ); } bLeft = false; } } if( nSegments + i == (int)m_aLinks.size() ) bRight = false; if( i != 0 && bRight ) { unsigned int nIndex = nSegments + i; if( m_aLinks[nIndex]->GetText().isEmpty() ) { bRight = false; } else if( showField( nIndex, nMaxWidth - nCurrentWidth ) ) { nCurrentWidth += m_aLinks[nIndex]->GetSizePixel().Width() + nSeparatorWidth + 3*SPACING; nLastVisible = nIndex; } else { bRight = false; } } i++; } // current dir should be inactive m_aLinks[nSegments]->Enable( false ); // hide last separator m_aSeparators[nLastVisible]->Hide(); } void Breadcrumb::SetMode( SvtBreadcrumbMode eMode ) { m_eMode = eMode; } void Breadcrumb::appendField() { m_aLinks.push_back( VclPtr< CustomLink >::Create( this, WB_TABSTOP ) ); m_aLinks[m_aLinks.size() - 1]->Hide(); m_aLinks[m_aLinks.size() - 1]->SetClickHdl( LINK( this, Breadcrumb, ClickLinkHdl ) ); m_aSeparators.push_back( VclPtr< FixedText >::Create( this ) ); m_aSeparators[m_aLinks.size() - 1]->SetText( ">" ); m_aSeparators[m_aLinks.size() - 1]->Hide(); } bool Breadcrumb::showField( unsigned int nIndex, unsigned int nWidthMax ) { m_aLinks[nIndex]->Show(); m_aSeparators[nIndex]->Show(); unsigned int nSeparatorWidth = m_aSeparators[0]->GetSizePixel().Width(); unsigned int nWidth = m_aLinks[nIndex]->GetSizePixel().Width() + nSeparatorWidth + 3*SPACING; if( nWidth > nWidthMax ) { if( nIndex != 0 ) { m_aLinks[nIndex]->Hide(); m_aSeparators[nIndex]->Hide(); } return false; } return true; } IMPL_LINK( Breadcrumb, ClickLinkHdl, FixedHyperlink&, rLink, void ) { m_sClickedURL = rLink.GetURL(); m_aClickHdl.Call( this ); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ istro/mimo/mimo-6-4 LibreOffice 核心代码仓库文档基金会
summaryrefslogtreecommitdiff
AgeCommit message (Expand)Author
2020-05-31Resolves tdf#133268: Update Colibre color paletteRizal Muttaqin