1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_basctl.hxx" 30 31 #include "managelang.hxx" 32 #include "iderid.hxx" 33 #include "localizationmgr.hxx" 34 #include "iderdll.hxx" 35 #include "basidesh.hxx" 36 #include "basobj.hxx" 37 38 #include "managelang.hrc" 39 #include "dlgresid.hrc" 40 #include "helpid.hrc" 41 42 #ifndef _COM_SUN_STAR_TEXT_XBREAKITERATOR_HPP_ 43 #include <com/sun/star/i18n/XBreakIterator.hpp> 44 #endif 45 #include <com/sun/star/i18n/WordType.hpp> 46 #include <com/sun/star/lang/XMultiServiceFactory.hpp> 47 #include <com/sun/star/resource/XStringResourceManager.hpp> 48 #include <comphelper/processfactory.hxx> 49 #include <vcl/unohelp.hxx> 50 #ifndef _VCL_I18NHELP_HXX 51 //#include <vcl/i18nhelp.hxx> 52 #endif 53 #include <vcl/svapp.hxx> 54 #include <vcl/msgbox.hxx> 55 #include <unotools/localedatawrapper.hxx> 56 #include <editeng/unolingu.hxx> 57 58 #include <svtools/langtab.hxx> 59 60 #include <sfx2/bindings.hxx> 61 62 using namespace ::com::sun::star::i18n; 63 using namespace ::com::sun::star::lang; 64 using namespace ::com::sun::star::resource; 65 using namespace ::com::sun::star::uno; 66 67 bool localesAreEqual( const Locale& rLocaleLeft, const Locale& rLocaleRight ) 68 { 69 bool bRet = ( rLocaleLeft.Language.equals( rLocaleRight.Language ) && 70 rLocaleLeft.Country.equals( rLocaleRight.Country ) && 71 rLocaleLeft.Variant.equals( rLocaleRight.Variant ) ); 72 return bRet; 73 } 74 75 namespace { 76 long getLongestWordWidth( const String& rText, const Window& rWin ) 77 { 78 long nWidth = 0; 79 Reference< XBreakIterator > xBreakIter( vcl::unohelper::CreateBreakIterator() ); 80 sal_Int32 nStartPos = 0; 81 const Locale aLocale = Application::GetSettings().GetUILocale(); 82 Boundary aBoundary = xBreakIter->getWordBoundary( 83 rText, nStartPos, aLocale, WordType::ANYWORD_IGNOREWHITESPACES, sal_True ); 84 85 while ( aBoundary.startPos != aBoundary.endPos ) 86 { 87 nStartPos = aBoundary.endPos; 88 String sWord( rText.Copy( 89 (sal_uInt16)aBoundary.startPos, 90 (sal_uInt16)aBoundary.endPos - (sal_uInt16)aBoundary.startPos ) ); 91 long nTemp = rWin.GetCtrlTextWidth( sWord ); 92 if ( nTemp > nWidth ) 93 nWidth = nTemp; 94 aBoundary = xBreakIter->nextWord( 95 rText, nStartPos, aLocale, WordType::ANYWORD_IGNOREWHITESPACES ); 96 } 97 98 return nWidth; 99 } 100 } 101 102 ManageLanguageDialog::ManageLanguageDialog( Window* pParent, LocalizationMgr* _pLMgr ) : 103 104 ModalDialog( pParent, IDEResId( RID_DLG_MANAGE_LANGUAGE ) ), 105 106 m_aLanguageFT ( this, IDEResId( FT_LANGUAGE ) ), 107 m_aLanguageLB ( this, IDEResId( LB_LANGUAGE ) ), 108 m_aAddPB ( this, IDEResId( PB_ADD_LANG ) ), 109 m_aDeletePB ( this, IDEResId( PB_DEL_LANG ) ), 110 m_aMakeDefPB ( this, IDEResId( PB_MAKE_DEFAULT ) ), 111 m_aInfoFT ( this, IDEResId( FT_INFO ) ), 112 m_aBtnLine ( this, IDEResId( FL_BUTTONS ) ), 113 m_aHelpBtn ( this, IDEResId( PB_HELP ) ), 114 m_aCloseBtn ( this, IDEResId( PB_CLOSE ) ), 115 m_pLocalizationMgr ( _pLMgr ), 116 m_sDefLangStr ( IDEResId( STR_DEF_LANG ) ), 117 m_sDeleteStr ( IDEResId( STR_DELETE ) ), 118 m_sCreateLangStr ( IDEResId( STR_CREATE_LANG ) ) 119 120 { 121 FreeResource(); 122 123 Init(); 124 FillLanguageBox(); 125 SelectHdl( NULL ); 126 } 127 128 ManageLanguageDialog::~ManageLanguageDialog() 129 { 130 ClearLanguageBox(); 131 } 132 133 void ManageLanguageDialog::Init() 134 { 135 // get current IDE 136 BasicIDEShell* pIDEShell = IDE_DLL()->GetShell(); 137 String sLibName = pIDEShell->GetCurLibName(); 138 // set dialog title with library name 139 String sText = GetText(); 140 sText.SearchAndReplace( String::CreateFromAscii("$1"), sLibName ); 141 SetText( sText ); 142 // set handler 143 m_aAddPB.SetClickHdl( LINK( this, ManageLanguageDialog, AddHdl ) ); 144 m_aDeletePB.SetClickHdl( LINK( this, ManageLanguageDialog, DeleteHdl ) ); 145 m_aMakeDefPB.SetClickHdl( LINK( this, ManageLanguageDialog, MakeDefHdl ) ); 146 m_aLanguageLB.SetSelectHdl( LINK( this, ManageLanguageDialog, SelectHdl ) ); 147 148 m_aLanguageLB.EnableMultiSelection( sal_True ); 149 CalcInfoSize(); 150 } 151 152 void ManageLanguageDialog::CalcInfoSize() 153 { 154 String sInfoStr = m_aInfoFT.GetText(); 155 long nInfoWidth = m_aInfoFT.GetSizePixel().Width(); 156 long nLongWord = getLongestWordWidth( sInfoStr, m_aInfoFT ); 157 long nTxtWidth = m_aInfoFT.GetCtrlTextWidth( sInfoStr ) + nLongWord; 158 long nLines = ( nTxtWidth / nInfoWidth ) + 1; 159 if ( nLines > INFO_LINES_COUNT ) 160 { 161 Size aFTSize = m_aLanguageFT.GetSizePixel(); 162 Size aSize = m_aInfoFT.GetSizePixel(); 163 long nNewHeight = aFTSize.Height() * nLines; 164 long nDelta = nNewHeight - aSize.Height(); 165 aSize.Height() = nNewHeight; 166 m_aInfoFT.SetSizePixel( aSize ); 167 168 aSize = m_aLanguageLB.GetSizePixel(); 169 aSize.Height() -= nDelta; 170 m_aLanguageLB.SetSizePixel( aSize ); 171 172 Point aNewPos = m_aInfoFT.GetPosPixel(); 173 aNewPos.Y() -= nDelta; 174 m_aInfoFT.SetPosPixel( aNewPos ); 175 aNewPos = m_aMakeDefPB.GetPosPixel(); 176 aNewPos.Y() -= nDelta; 177 m_aMakeDefPB.SetPosPixel( aNewPos ); 178 } 179 } 180 181 void ManageLanguageDialog::FillLanguageBox() 182 { 183 DBG_ASSERT( m_pLocalizationMgr, "ManageLanguageDialog::FillLanguageBox(): no localization manager" ); 184 185 if ( m_pLocalizationMgr->isLibraryLocalized() ) 186 { 187 SvtLanguageTable aLangTable; 188 Locale aDefaultLocale = m_pLocalizationMgr->getStringResourceManager()->getDefaultLocale(); 189 Sequence< Locale > aLocaleSeq = m_pLocalizationMgr->getStringResourceManager()->getLocales(); 190 const Locale* pLocale = aLocaleSeq.getConstArray(); 191 sal_Int32 i, nCount = aLocaleSeq.getLength(); 192 for ( i = 0; i < nCount; ++i ) 193 { 194 bool bIsDefault = localesAreEqual( aDefaultLocale, pLocale[i] ); 195 LanguageType eLangType = SvxLocaleToLanguage( pLocale[i] ); 196 String sLanguage = aLangTable.GetString( eLangType ); 197 if ( bIsDefault ) 198 { 199 sLanguage += ' '; 200 sLanguage += m_sDefLangStr; 201 } 202 sal_uInt16 nPos = m_aLanguageLB.InsertEntry( sLanguage ); 203 m_aLanguageLB.SetEntryData( nPos, new LanguageEntry( sLanguage, pLocale[i], bIsDefault ) ); 204 } 205 } 206 else 207 m_aLanguageLB.InsertEntry( m_sCreateLangStr ); 208 } 209 210 void ManageLanguageDialog::ClearLanguageBox() 211 { 212 sal_uInt16 i, nCount = m_aLanguageLB.GetEntryCount(); 213 for ( i = 0; i < nCount; ++i ) 214 { 215 LanguageEntry* pEntry = (LanguageEntry*)( m_aLanguageLB.GetEntryData(i) ); 216 if ( pEntry ) 217 delete pEntry; 218 } 219 m_aLanguageLB.Clear(); 220 } 221 222 IMPL_LINK( ManageLanguageDialog, AddHdl, Button *, EMPTYARG ) 223 { 224 SetDefaultLanguageDialog aDlg( this, m_pLocalizationMgr ); 225 if ( RET_OK == aDlg.Execute() ) 226 { 227 // add new locales 228 Sequence< Locale > aLocaleSeq = aDlg.GetLocales(); 229 m_pLocalizationMgr->handleAddLocales( aLocaleSeq ); 230 // update listbox 231 ClearLanguageBox(); 232 FillLanguageBox(); 233 234 SfxBindings* pBindings = BasicIDE::GetBindingsPtr(); 235 if ( pBindings ) 236 pBindings->Invalidate( SID_BASICIDE_CURRENT_LANG ); 237 } 238 return 1; 239 } 240 241 IMPL_LINK( ManageLanguageDialog, DeleteHdl, Button *, EMPTYARG ) 242 { 243 QueryBox aQBox( this, IDEResId( RID_QRYBOX_LANGUAGE ) ); 244 aQBox.SetButtonText( RET_OK, m_sDeleteStr ); 245 if ( aQBox.Execute() == RET_OK ) 246 { 247 sal_uInt16 i, nCount = m_aLanguageLB.GetSelectEntryCount(); 248 sal_uInt16 nPos = m_aLanguageLB.GetSelectEntryPos(); 249 // remove locales 250 Sequence< Locale > aLocaleSeq( nCount ); 251 for ( i = 0; i < nCount; ++i ) 252 { 253 sal_uInt16 nSelPos = m_aLanguageLB.GetSelectEntryPos(i); 254 LanguageEntry* pEntry = (LanguageEntry*)( m_aLanguageLB.GetEntryData( nSelPos ) ); 255 if ( pEntry ) 256 aLocaleSeq[i] = pEntry->m_aLocale; 257 } 258 m_pLocalizationMgr->handleRemoveLocales( aLocaleSeq ); 259 // update listbox 260 ClearLanguageBox(); 261 FillLanguageBox(); 262 // reset selection 263 nCount = m_aLanguageLB.GetEntryCount(); 264 if ( nCount <= nPos ) 265 nPos = nCount - 1; 266 m_aLanguageLB.SelectEntryPos( nPos ); 267 SelectHdl( NULL ); 268 } 269 return 1; 270 } 271 272 IMPL_LINK( ManageLanguageDialog, MakeDefHdl, Button *, EMPTYARG ) 273 { 274 sal_uInt16 nPos = m_aLanguageLB.GetSelectEntryPos(); 275 LanguageEntry* pSelectEntry = (LanguageEntry*)( m_aLanguageLB.GetEntryData( nPos ) ); 276 if ( pSelectEntry && !pSelectEntry->m_bIsDefault ) 277 { 278 // set new default entry 279 m_pLocalizationMgr->handleSetDefaultLocale( pSelectEntry->m_aLocale ); 280 // update Listbox 281 ClearLanguageBox(); 282 FillLanguageBox(); 283 // reset selection 284 m_aLanguageLB.SelectEntryPos( nPos ); 285 SelectHdl( NULL ); 286 } 287 288 return 1; 289 } 290 291 IMPL_LINK( ManageLanguageDialog, SelectHdl, ListBox *, EMPTYARG ) 292 { 293 sal_uInt16 nCount = m_aLanguageLB.GetEntryCount(); 294 bool bEmpty = ( !nCount || 295 m_aLanguageLB.GetEntryPos( m_sCreateLangStr ) != LISTBOX_ENTRY_NOTFOUND ); 296 bool bSelect = ( m_aLanguageLB.GetSelectEntryPos() != LISTBOX_ENTRY_NOTFOUND ); 297 bool bEnable = ( !bEmpty && bSelect != false ); 298 299 m_aDeletePB.Enable( bEnable != false ); 300 m_aMakeDefPB.Enable( bEnable != false && nCount > 1 && m_aLanguageLB.GetSelectEntryCount() == 1 ); 301 302 return 1; 303 } 304 305 // class SetDefaultLanguageDialog ----------------------------------------------- 306 307 SetDefaultLanguageDialog::SetDefaultLanguageDialog( Window* pParent, LocalizationMgr* _pLMgr ) : 308 309 ModalDialog( pParent, IDEResId( RID_DLG_SETDEF_LANGUAGE ) ), 310 311 m_aLanguageFT ( this, IDEResId( FT_DEF_LANGUAGE ) ), 312 m_pLanguageLB ( new SvxLanguageBox( this, IDEResId( LB_DEF_LANGUAGE ) ) ), 313 m_pCheckLangLB ( NULL ), 314 m_aInfoFT ( this, IDEResId( FT_DEF_INFO ) ), 315 m_aBtnLine ( this, IDEResId( FL_DEF_BUTTONS ) ), 316 m_aOKBtn ( this, IDEResId( PB_DEF_OK ) ), 317 m_aCancelBtn ( this, IDEResId( PB_DEF_CANCEL ) ), 318 m_aHelpBtn ( this, IDEResId( PB_DEF_HELP ) ), 319 320 m_pLocalizationMgr( _pLMgr ) 321 322 { 323 if ( m_pLocalizationMgr->isLibraryLocalized() ) 324 { 325 // change to "Add Interface Language" mode 326 SetHelpId( HID_BASICIDE_ADDNEW_LANGUAGE ); 327 m_pCheckLangLB = new SvxCheckListBox( this, IDEResId( LB_ADD_LANGUAGE ) ); 328 SetText( String( IDEResId( STR_ADDLANG_TITLE ) ) ); 329 m_aLanguageFT.SetText( String( IDEResId( STR_ADDLANG_LABEL ) ) ); 330 m_aInfoFT.SetText( String( IDEResId( STR_ADDLANG_INFO ) ) ); 331 } 332 333 FreeResource(); 334 335 FillLanguageBox(); 336 CalcInfoSize(); 337 } 338 339 SetDefaultLanguageDialog::~SetDefaultLanguageDialog() 340 { 341 delete m_pLanguageLB; 342 delete m_pCheckLangLB; 343 } 344 345 void SetDefaultLanguageDialog::FillLanguageBox() 346 { 347 // fill list with all languages 348 m_pLanguageLB->SetLanguageList( LANG_LIST_ALL, sal_False ); 349 // remove the already localized languages 350 Sequence< Locale > aLocaleSeq = m_pLocalizationMgr->getStringResourceManager()->getLocales(); 351 const Locale* pLocale = aLocaleSeq.getConstArray(); 352 sal_Int32 i, nCount = aLocaleSeq.getLength(); 353 for ( i = 0; i < nCount; ++i ) 354 m_pLanguageLB->RemoveLanguage( SvxLocaleToLanguage( pLocale[i] ) ); 355 356 // fill checklistbox if not in default mode 357 if ( m_pLocalizationMgr->isLibraryLocalized() ) 358 { 359 sal_uInt16 j, nCount_ = m_pLanguageLB->GetEntryCount(); 360 for ( j = 0; j < nCount_; ++j ) 361 { 362 m_pCheckLangLB->InsertEntry( 363 m_pLanguageLB->GetEntry(j), LISTBOX_APPEND, m_pLanguageLB->GetEntryData(j) ); 364 } 365 delete m_pLanguageLB; 366 m_pLanguageLB = NULL; 367 } 368 else 369 // preselect current UI language 370 m_pLanguageLB->SelectLanguage( Application::GetSettings().GetUILanguage() ); 371 } 372 373 void SetDefaultLanguageDialog::CalcInfoSize() 374 { 375 String sInfoStr = m_aInfoFT.GetText(); 376 long nInfoWidth = m_aInfoFT.GetSizePixel().Width(); 377 long nLongWord = getLongestWordWidth( sInfoStr, m_aInfoFT ); 378 long nTxtWidth = m_aInfoFT.GetCtrlTextWidth( sInfoStr ) + nLongWord; 379 long nLines = ( nTxtWidth / nInfoWidth ) + 1; 380 if ( nLines > INFO_LINES_COUNT ) 381 { 382 Size aFTSize = m_aLanguageFT.GetSizePixel(); 383 Size aSize = m_aInfoFT.GetSizePixel(); 384 long nNewHeight = aFTSize.Height() * nLines; 385 long nDelta = nNewHeight - aSize.Height(); 386 aSize.Height() = nNewHeight; 387 m_aInfoFT.SetSizePixel( aSize ); 388 389 Window* pWin = ( m_pLanguageLB != NULL ) ? dynamic_cast< Window* >( m_pLanguageLB ) 390 : dynamic_cast< Window* >( m_pCheckLangLB ); 391 aSize = pWin->GetSizePixel(); 392 aSize.Height() -= nDelta; 393 pWin->SetSizePixel( aSize ); 394 395 Point aNewPos = m_aInfoFT.GetPosPixel(); 396 aNewPos.Y() -= nDelta; 397 m_aInfoFT.SetPosPixel( aNewPos ); 398 } 399 } 400 401 Sequence< Locale > SetDefaultLanguageDialog::GetLocales() const 402 { 403 bool bNotLocalized = !m_pLocalizationMgr->isLibraryLocalized(); 404 sal_Int32 nSize = bNotLocalized ? 1 : m_pCheckLangLB->GetCheckedEntryCount(); 405 Sequence< Locale > aLocaleSeq( nSize ); 406 if ( bNotLocalized ) 407 { 408 Locale aLocale; 409 SvxLanguageToLocale( aLocale, m_pLanguageLB->GetSelectLanguage() ); 410 aLocaleSeq[0] = aLocale; 411 } 412 else 413 { 414 sal_uInt16 i, nCount = static_cast< sal_uInt16 >( m_pCheckLangLB->GetEntryCount() ); 415 sal_Int32 j = 0; 416 for ( i = 0; i < nCount; ++i ) 417 { 418 if ( m_pCheckLangLB->IsChecked(i) ) 419 { 420 LanguageType eType = LanguageType( (sal_uLong)m_pCheckLangLB->GetEntryData(i) ); 421 Locale aLocale; 422 SvxLanguageToLocale( aLocale, eType ); 423 aLocaleSeq[j++] = aLocale; 424 } 425 } 426 DBG_ASSERT( nSize == j, "SetDefaultLanguageDialog::GetLocales(): invalid indexes" ); 427 } 428 return aLocaleSeq; 429 } 430 431