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]