Carsten Driesner 写道: > shizhoubo[OOoFrm] schrieb: > >> Hi Carsten, >> after I have investigated the FontMenuController::fillPopupMenu() >> source, I think the pFontNameArray[] array was sorted, so before every >> new FontName insert into the m_xPopuMenu, the new FontName is compared >> with every FontName inserted of the xPopupMenu. so that inserting >> MenuItem efficiency is very low. >> So I think before the new FontName is inserted, the pFontNameArray[] >> array should be sorted, than insert it into Menu. >> Other, I have investigated C's qsort() and STL's sort() via reading some >> document and found the STL's sort() is very quick then C's qsort(). So I >> used the STL's sort(). >> >> As stated above is what I understand. If you have good suggestions, >> please tell me. >> >> The attachment is source changing, Please, review it. I have tested the >> changing source and the changing work right, but it trigger other >> question which is the Chinese FontName was placed in the last place. but >> before the source was not changed, the Chinese FontName was plased in >> the first place. why ? Could you give me some advices ? >> >> > Hi Shizhoubo, > > I checked your changes and I have to backup Fridrich that we need a > functor for sort() to have better sorting. The built-in operator< > provided by ustring.hxx/::rtl::OUString is not I18N aware and doesn't > work correctly for many languages. That's why you see the differences > between your implementation and the old one. Please have a look into the > stl documentation for sort (http://www.sgi.com/tech/stl/sort.html) and > you can find this declaration. > > template <class RandomAccessIterator, class StrictWeakOrdering> > void sort(RandomAccessIterator first, RandomAccessIterator last, > StrictWeakOrdering comp); > > StrictWeakOrdering can be used to provide a functor (function object) > for the comparison. We need to make sure that we use the I18nHelper > class to make the comparison. See this following snippet from the old code: > > const vcl::I18nHelper& rI18nHelper = > Application::GetSettings().GetUILocaleI18nHelper(); > ... > if ( rI18nHelper.CompareString( rName, aString ) > 0 ) > break; > ... > > If you need further help don't hesitate to contact me. > > Regards, > Carsten > > Hi Carsten,
I have changed that source which is attachment. Please, review it. This, I used the STL's sort(RandomAccessIterator first, RandomAccessIterator last, StrictWeakOrdering comp) and added the function "bool lcl_I18nCompareString(rtl::OUString rStr1, rtl::OUString rStr2)" in the fontmenucontroller.cxx. Thank you for your help. Kind Regards. Shizhoubo.
--- fontmenucontroller_old.cxx 2006-12-13 23:07:08.000000000 +0800 +++ fontmenucontroller_new.cxx 2008-03-12 10:00:52.000000000 +0800 @@ -100,16 +100,22 @@ #include <vcl/mnemonic.hxx> #endif +//added for issue86787 by shizhoubo +#include <vector> +#include <algorithm> +//end for issue86787 //_________________________________________________________________________________________________________________ // Defines //_________________________________________________________________________________________________________________ -// +// using namespace com::sun::star::uno; using namespace com::sun::star::lang; using namespace com::sun::star::frame; using namespace com::sun::star::beans; using namespace com::sun::star::util; +//added for issue86787 by shizhoubo +using namespace std; namespace framework { @@ -130,53 +136,50 @@ FontMenuController::~FontMenuController() { } - +//added for issue86787 by shizhoubo +bool lcl_I18nCompareString(rtl::OUString rStr1, rtl::OUString rStr2) +{ + const vcl::I18nHelper& rI18nHelper = Application::GetSettings().GetUILocaleI18nHelper(); + return rI18nHelper.CompareString( rStr1, rStr2 ) < 0 ? 1:0; +} +//end for issue86787 // private function void FontMenuController::fillPopupMenu( const Sequence< ::rtl::OUString >& rFontNameSeq, Reference< css::awt::XPopupMenu >& rPopupMenu ) { const rtl::OUString* pFontNameArray = rFontNameSeq.getConstArray(); VCLXPopupMenu* pPopupMenu = (VCLXPopupMenu *)VCLXMenu::GetImplementation( rPopupMenu ); PopupMenu* pVCLPopupMenu = 0; - + vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() ); - + resetPopupMenu( rPopupMenu ); if ( pPopupMenu ) pVCLPopupMenu = (PopupMenu *)pPopupMenu->GetMenu(); - - if ( pVCLPopupMenu ) - { - rtl::OUString aEmpty; - const vcl::I18nHelper& rI18nHelper = Application::GetSettings().GetUILocaleI18nHelper(); - const rtl::OUString aFontNameCommandPrefix( RTL_CONSTASCII_USTRINGPARAM( ".uno:CharFontName?CharFontName.FamilyName:string=" )); - - for ( USHORT i = 0; i < rFontNameSeq.getLength(); i++ ) - { - const rtl::OUString& rName = pFontNameArray[i]; - USHORT j = m_xPopupMenu->getItemCount(); - while ( j ) - { - rtl::OUString aText = m_xPopupMenu->getItemText( m_xPopupMenu->getItemId( j-1 ) ); - - String aString = MnemonicGenerator::EraseAllMnemonicChars( aText ); - if ( rI18nHelper.CompareString( rName, aString ) > 0 ) - break; - j--; - } + if ( pVCLPopupMenu ) + { + std::vector<rtl::OUString> aVector; + for ( USHORT i = 0; i < rFontNameSeq.getLength(); i++ ) + { + aVector.push_back(MnemonicGenerator::EraseAllMnemonicChars(pFontNameArray[i])); + } + std::sort(aVector.begin(), aVector.end(), lcl_I18nCompareString); + + const rtl::OUString aFontNameCommandPrefix( RTL_CONSTASCII_USTRINGPARAM( ".uno:CharFontName?CharFontName.FamilyName:string=" )); + for(USHORT i = 0; i < aVector.size(); i++) + { + const rtl::OUString& rName = aVector[i]; + m_xPopupMenu->insertItem( i+1, rName, css::awt::MenuItemStyle::RADIOCHECK | css::awt::MenuItemStyle::AUTOCHECK, i ); + if ( rName == m_aFontFamilyName ) + m_xPopupMenu->checkItem( i+1, sal_True ); + // use VCL popup menu pointer to set vital information that are not part of the awt implementation + rtl::OUStringBuffer aCommandBuffer( aFontNameCommandPrefix ); + aCommandBuffer.append( INetURLObject::encode( rName, INetURLObject::PART_HTTP_QUERY, '%', INetURLObject::ENCODE_ALL )); + rtl::OUString aFontNameCommand = aCommandBuffer.makeStringAndClear(); + pVCLPopupMenu->SetItemCommand( i+1, aFontNameCommand ); // Store font name into item command. + } - m_xPopupMenu->insertItem( i+1, rName, css::awt::MenuItemStyle::RADIOCHECK | css::awt::MenuItemStyle::AUTOCHECK, j ); - if ( rName == m_aFontFamilyName ) - m_xPopupMenu->checkItem( i+1, sal_True ); - - // use VCL popup menu pointer to set vital information that are not part of the awt implementation - rtl::OUStringBuffer aCommandBuffer( aFontNameCommandPrefix ); - aCommandBuffer.append( INetURLObject::encode( rName, INetURLObject::PART_HTTP_QUERY, '%', INetURLObject::ENCODE_ALL )); - - rtl::OUString aFontNameCommand = aCommandBuffer.makeStringAndClear(); - pVCLPopupMenu->SetItemCommand( i+1, aFontNameCommand ); // Store font name into item command. - } - } + } } // XEventListener @@ -238,18 +241,18 @@ { css::util::URL aTargetURL; Sequence<PropertyValue> aArgs; - Reference< XURLTransformer > xURLTransformer( xServiceManager->createInstance( - rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.util.URLTransformer" ))), + Reference< XURLTransformer > xURLTransformer( xServiceManager->createInstance( + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.util.URLTransformer" ))), UNO_QUERY ); { vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() ); - + // Command URL used to dispatch the selected font family name PopupMenu* pVCLPopupMenu = (PopupMenu *)pPopupMenu->GetMenu(); aTargetURL.Complete = pVCLPopupMenu->GetItemCommand( rEvent.MenuId ); } - + xURLTransformer->parseStrict( aTargetURL ); xDispatch->dispatch( aTargetURL, aArgs ); } @@ -259,7 +262,7 @@ void SAL_CALL FontMenuController::activate( const css::awt::MenuEvent& ) throw (RuntimeException) { ResetableGuard aLock( m_aLock ); - + if ( m_xPopupMenu.is() ) { // find new font name and set check mark! @@ -304,43 +307,43 @@ if ( m_bDisposed ) throw DisposedException(); - + if ( m_xFrame.is() && !m_xPopupMenu.is() ) { // Create popup menu on demand vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() ); - + m_xPopupMenu = xPopupMenu; m_xPopupMenu->addMenuListener( Reference< css::awt::XMenuListener >( (OWeakObject*)this, UNO_QUERY )); - Reference< XURLTransformer > xURLTransformer( m_xServiceManager->createInstance( - rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.util.URLTransformer" ))), + Reference< XURLTransformer > xURLTransformer( m_xServiceManager->createInstance( + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.util.URLTransformer" ))), UNO_QUERY ); Reference< XDispatchProvider > xDispatchProvider( m_xFrame, UNO_QUERY ); - + com::sun::star::util::URL aTargetURL; aTargetURL.Complete = m_aCommandURL; xURLTransformer->parseStrict( aTargetURL ); m_xDispatch = xDispatchProvider->queryDispatch( aTargetURL, ::rtl::OUString(), 0 ); - + // Register for font list updates to get the current font list from the controller aTargetURL.Complete = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:FontNameList" )); xURLTransformer->parseStrict( aTargetURL ); m_xFontListDispatch = xDispatchProvider->queryDispatch( aTargetURL, ::rtl::OUString(), 0 ); - + updatePopupMenu(); - } + } } - + void SAL_CALL FontMenuController::updatePopupMenu() throw ( ::com::sun::star::uno::RuntimeException ) { PopupMenuControllerBase::updatePopupMenu(); ResetableGuard aLock( m_aLock ); Reference< XDispatch > xDispatch( m_xFontListDispatch ); - Reference< XURLTransformer > xURLTransformer( m_xServiceManager->createInstance( - rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.util.URLTransformer" ))), + Reference< XURLTransformer > xURLTransformer( m_xServiceManager->createInstance( + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.util.URLTransformer" ))), UNO_QUERY ); com::sun::star::util::URL aTargetURL; aTargetURL.Complete = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:FontNameList" ));
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]