[PATCH 2/2] Smarter auto-complete capitalization (#i22961#) and i18n handling
Brad Sowden
code at sowden.org
Mon Jun 4 03:02:34 PDT 2012
If a word is in sentence case then the auto-completed word should
be in the same case i.e. if the auto-complete list contains the
word "LIBRE" then "Lib" should auto-complete to "Libre" rather
than "LibRE". See OpenOffice bug 22961.
Also implement better i18n handling for calander month and day
names. Previously, if a month or day name was not ASCII then it
would only auto-complete if it exactly matched the names retrieved
from the internal calander i.e. had be a case sensitive match.
Change-Id: I0c4543bd9e912072bce1ceaf4adecd41b55b576b
---
sw/source/ui/docvw/edtwin.cxx | 114 +++++++++++++++++++++++++----------------
1 files changed, 70 insertions(+), 44 deletions(-)
diff --git a/sw/source/ui/docvw/edtwin.cxx b/sw/source/ui/docvw/edtwin.cxx
index dca8219..831ab46 100644
--- a/sw/source/ui/docvw/edtwin.cxx
+++ b/sw/source/ui/docvw/edtwin.cxx
@@ -5565,67 +5565,93 @@ void QuickHelpData::Stop( SwWrtShell& rSh )
void QuickHelpData::FillStrArr( SwWrtShell& rSh, const String& rWord )
{
+ enum Capitalization { CASE_LOWER, CASE_UPPER, CASE_SENTENCE, CASE_OTHER };
+
+ // Determine word capitalization
+ const CharClass& rCC = GetAppCharClass();
+ const String sWordLower = rCC.lowercase( rWord );
+ Capitalization aWordCase = CASE_OTHER;
+ if ( rWord.Len() > 0 )
+ {
+ if ( rWord.GetChar(0) == sWordLower.GetChar(0) )
+ {
+ if ( rWord == sWordLower )
+ aWordCase = CASE_LOWER;
+ }
+ else
+ {
+ // First character is not lower case i.e. assume upper or title case
+ String sWordSentence = sWordLower;
+ sWordSentence.SetChar( 0, rWord.GetChar(0) );
+ if ( rWord == sWordSentence )
+ aWordCase = CASE_SENTENCE;
+ else
+ {
+ if ( rWord == static_cast<String>( rCC.uppercase( rWord ) ) )
+ aWordCase = CASE_UPPER;
+ }
+ }
+ }
+
salhelper::SingletonRef<SwCalendarWrapper>* pCalendar = s_getCalendarWrapper();
(*pCalendar)->LoadDefaultCalendar( rSh.GetCurLang() );
+ // Add matching calendar month and day names
+ uno::Sequence< i18n::CalendarItem2 > aNames( (*pCalendar)->getMonths() );
+ for ( sal_uInt16 i = 0; i < 2; ++i )
{
- uno::Sequence< i18n::CalendarItem2 > aNames(
- (*pCalendar)->getMonths() );
- for( int n = 0; n < 2; ++n )
+ for ( long n = 0; n < aNames.getLength(); ++n )
{
- for( long nPos = 0, nEnd = aNames.getLength(); nPos < nEnd; ++nPos )
+ const String& rStr( aNames[n].FullName );
+ // Check string longer than word and case insensitive match
+ if( rStr.Len() > rWord.Len() &&
+ static_cast<String>( rCC.lowercase( rStr, 0, rWord.Len() ) )
+ == sWordLower )
{
- String sStr( aNames[ nPos ].FullName );
- if( rWord.Len() + 1 < sStr.Len() &&
-
-//!!! UNICODE: missing interface
- COMPARE_EQUAL == rWord.CompareIgnoreCaseToAscii(
- sStr, rWord.Len() ))
+ if ( aWordCase == CASE_LOWER )
+ pHelpStrings->push_back( rCC.lowercase( rStr ) );
+ else if ( aWordCase == CASE_SENTENCE )
{
- pHelpStrings->push_back( sStr );
+ String sTmp = rCC.lowercase( rStr );
+ sTmp.SetChar( 0, rStr.GetChar(0) );
+ pHelpStrings->push_back( sTmp );
}
+ else if ( aWordCase == CASE_UPPER )
+ pHelpStrings->push_back( rCC.uppercase( rStr ) );
+ else // CASE_OTHER - use retrieved capitalization
+ pHelpStrings->push_back( rStr );
}
- if( !n ) // get data for the second loop
- aNames = (*pCalendar)->getDays();
}
+ // Data for second loop iteration
+ if ( i == 0 )
+ aNames = (*pCalendar)->getDays();
}
- // and than add all words from the AutoCompleteWord-List
- const SwAutoCompleteWord& rACLst = rSh.GetAutoCompleteWords();
- sal_uInt16 nStt, nEnd;
- if( rACLst.GetRange( rWord, nStt, nEnd ) )
+ // Add matching words from AutoCompleteWord list
+ const SwAutoCompleteWord& rACList = rSh.GetAutoCompleteWords();
+ sal_uInt16 nPos, nEnd;
+ // TODO - GetRange only performs a case insensitive match for ASCII
+ if ( rACList.GetRange( rWord, nPos, nEnd ) )
{
- while( nStt < nEnd )
+ for ( ; nPos < nEnd; ++nPos )
{
- const String& rS = rACLst[ nStt ];
- // only if the count of chars
- // from the suggest greater as the
- // actual word
- if( rS.Len() > rWord.Len() )
+ const String& rStr = rACList[nPos];
+ // Check string longer than word
+ if ( rStr.Len() > rWord.Len() )
{
- CharClass &rCC = GetAppCharClass();
- String aMatch;
- int upper = 0, lower = 0, letters = 0;
- for( xub_StrLen i = 0; i < rWord.Len(); i++ ) {
- sal_Int32 nCharType = rCC.getCharacterType( rWord, i );
- if( !CharClass::isLetterType( nCharType ) )
- continue;
- letters++;
- if( i18n::KCharacterType::LOWER & nCharType )
- lower++;
- if( i18n::KCharacterType::UPPER & nCharType )
- upper++;
+ if ( aWordCase == CASE_LOWER )
+ pHelpStrings->push_back( rCC.lowercase( rStr ) );
+ else if ( aWordCase == CASE_SENTENCE )
+ {
+ String sTmp = rCC.lowercase( rStr );
+ sTmp.SetChar( 0, rStr.GetChar(0) );
+ pHelpStrings->push_back( sTmp );
}
- if (lower == letters)
- aMatch = rCC.lowercase( rS );
- else if (upper == letters)
- aMatch = rCC.uppercase( rS );
- else // mixed case - use what we have
- aMatch = rS;
-
- pHelpStrings->push_back( aMatch );
+ else if ( aWordCase == CASE_UPPER )
+ pHelpStrings->push_back( rCC.uppercase( rStr ) );
+ else // CASE_OTHER - use retrieved capitalization
+ pHelpStrings->push_back( rStr );
}
- ++nStt;
}
}
}
--
1.7.7.6
--------------060300000803050900070304--
More information about the LibreOffice
mailing list