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_sw.hxx" 30 31 32 #include <hintids.hxx> 33 #include <com/sun/star/lang/XMultiServiceFactory.hpp> 34 #include <comphelper/processfactory.hxx> 35 #include <editeng/unolingu.hxx> 36 #include <unotools/localedatawrapper.hxx> 37 #include <i18npool/lang.h> 38 #ifndef _ZFORMAT_HXX //autogen 39 #define _ZFORLIST_DECLARE_TABLE 40 #include <svl/zformat.hxx> 41 #endif 42 #include <svl/eitem.hxx> 43 #include <svx/svxids.hrc> 44 #include <svx/numinf.hxx> 45 #include <vcl/msgbox.hxx> 46 #include <svx/flagsdef.hxx> 47 #include <svl/itemset.hxx> 48 #include <docsh.hxx> 49 #include <swtypes.hxx> 50 #include <swmodule.hxx> 51 #include <view.hxx> 52 #include <wrtsh.hxx> 53 #include <numfmtlb.hxx> 54 #include <utlui.hrc> 55 #include "swabstdlg.hxx" 56 #include "dialog.hrc" 57 #include <unomid.h> 58 #include <sfx2/viewfrm.hxx> 59 60 using namespace ::com::sun::star::uno; 61 using namespace ::com::sun::star::lang; 62 63 64 // STATIC DATA ----------------------------------------------------------- 65 66 /*-------------------------------------------------------------------- 67 Beschreibung: 68 nFormatType: Formate dieses Typs anzeigen 69 nDefFmt: Dieses Format selektieren und ggf vorher 70 einfuegen 71 --------------------------------------------------------------------*/ 72 73 NumFormatListBox::NumFormatListBox( Window* pWin, const ResId& rResId, 74 short nFormatType, sal_uLong nDefFmt, 75 sal_Bool bUsrFmts ) : 76 ListBox ( pWin, rResId ), 77 nCurrFormatType (-1), 78 nStdEntry (0), 79 bOneArea (sal_False), 80 nDefFormat (nDefFmt), 81 pVw (0), 82 pOwnFormatter (0), 83 bShowLanguageControl(sal_False), 84 bUseAutomaticLanguage(sal_True) 85 { 86 Init(nFormatType, bUsrFmts); 87 } 88 89 /*-------------------------------------------------------------------- 90 Beschreibung: 91 --------------------------------------------------------------------*/ 92 93 NumFormatListBox::NumFormatListBox( Window* pWin, SwView* pView, 94 const ResId& rResId, short nFormatType, 95 sal_uLong nDefFmt, sal_Bool bUsrFmts ) : 96 ListBox ( pWin, rResId ), 97 nCurrFormatType (-1), 98 nStdEntry (0), 99 bOneArea (sal_False), 100 nDefFormat (nDefFmt), 101 pVw (pView), 102 pOwnFormatter (0), 103 bShowLanguageControl(sal_False), 104 bUseAutomaticLanguage(sal_True) 105 { 106 Init(nFormatType, bUsrFmts); 107 } 108 109 /* -----------------15.06.98 11:29------------------- 110 * 111 * --------------------------------------------------*/ 112 113 void NumFormatListBox::Init(short nFormatType, sal_Bool bUsrFmts) 114 { 115 SwView *pView = GetView(); 116 117 if (pView) 118 eCurLanguage = pView->GetWrtShell().GetCurLang(); 119 else 120 eCurLanguage = SvxLocaleToLanguage( SvtSysLocale().GetLocaleData().getLocale() ); 121 122 if (bUsrFmts == sal_False) 123 { 124 Reference< XMultiServiceFactory > xMSF = ::comphelper::getProcessServiceFactory(); 125 pOwnFormatter = new SvNumberFormatter(xMSF, eCurLanguage); 126 } 127 128 SetFormatType(nFormatType); 129 SetDefFormat(nDefFormat); 130 131 SetSelectHdl(LINK(this, NumFormatListBox, SelectHdl)); 132 } 133 134 /*-------------------------------------------------------------------- 135 Beschreibung: 136 --------------------------------------------------------------------*/ 137 138 NumFormatListBox::~NumFormatListBox() 139 { 140 if (pOwnFormatter) 141 delete pOwnFormatter; 142 } 143 /*-------------------------------------------------------------------- 144 Beschreibung: 145 --------------------------------------------------------------------*/ 146 147 SwView* NumFormatListBox::GetView() 148 { 149 if( pVw ) 150 return pVw; 151 return ::GetActiveView(); 152 } 153 154 /*-------------------------------------------------------------------- 155 Beschreibung: 156 --------------------------------------------------------------------*/ 157 158 void NumFormatListBox::SetFormatType(const short nFormatType) 159 { 160 if (nCurrFormatType == -1 || 161 (nCurrFormatType & nFormatType) == 0) // Es gibt Mischformate, wie z.B. DateTime 162 { 163 SvNumberFormatter* pFormatter; 164 165 if( pOwnFormatter ) 166 pFormatter = pOwnFormatter; 167 else 168 { 169 SwView *pView = GetView(); 170 DBG_ASSERT(pView, "no view found"); 171 if(!pView) 172 return; 173 SwWrtShell &rSh = pView->GetWrtShell(); 174 pFormatter = rSh.GetNumberFormatter(); 175 } 176 177 Clear(); // Alle Eintraege in der Listbox entfernen 178 179 NfIndexTableOffset eOffsetStart = NF_NUMBER_START; 180 NfIndexTableOffset eOffsetEnd = NF_NUMBER_START; 181 182 switch( nFormatType ) 183 { 184 case NUMBERFORMAT_NUMBER: 185 eOffsetStart=NF_NUMBER_START; 186 eOffsetEnd=NF_NUMBER_END; 187 break; 188 189 case NUMBERFORMAT_PERCENT: 190 eOffsetStart=NF_PERCENT_START; 191 eOffsetEnd=NF_PERCENT_END; 192 break; 193 194 case NUMBERFORMAT_CURRENCY: 195 eOffsetStart=NF_CURRENCY_START; 196 eOffsetEnd=NF_CURRENCY_END; 197 break; 198 199 case NUMBERFORMAT_DATETIME: 200 eOffsetStart=NF_DATE_START; 201 eOffsetEnd=NF_TIME_END; 202 break; 203 204 case NUMBERFORMAT_DATE: 205 eOffsetStart=NF_DATE_START; 206 eOffsetEnd=NF_DATE_END; 207 break; 208 209 case NUMBERFORMAT_TIME: 210 eOffsetStart=NF_TIME_START; 211 eOffsetEnd=NF_TIME_END; 212 break; 213 214 case NUMBERFORMAT_SCIENTIFIC: 215 eOffsetStart=NF_SCIENTIFIC_START; 216 eOffsetEnd=NF_SCIENTIFIC_END; 217 break; 218 219 case NUMBERFORMAT_FRACTION: 220 eOffsetStart=NF_FRACTION_START; 221 eOffsetEnd=NF_FRACTION_END; 222 break; 223 224 case NUMBERFORMAT_LOGICAL: 225 eOffsetStart=NF_BOOLEAN; 226 eOffsetEnd=NF_BOOLEAN; 227 break; 228 229 case NUMBERFORMAT_TEXT: 230 eOffsetStart=NF_TEXT; 231 eOffsetEnd=NF_TEXT; 232 break; 233 234 case NUMBERFORMAT_ALL: 235 eOffsetStart=NF_NUMERIC_START; 236 eOffsetEnd = NfIndexTableOffset( NF_INDEX_TABLE_ENTRIES - 1 ); 237 break; 238 239 default: 240 DBG_ERROR("what a format?"); 241 break; 242 } 243 244 const SvNumberformat* pFmt; 245 sal_uInt16 nPos, i = 0; 246 sal_uLong nFormat; 247 Color* pCol; 248 double fVal = GetDefValue( nFormatType ); 249 String sValue; 250 251 sal_uLong nSysNumFmt = pFormatter->GetFormatIndex( 252 NF_NUMBER_SYSTEM, eCurLanguage ); 253 sal_uLong nSysShortDateFmt = pFormatter->GetFormatIndex( 254 NF_DATE_SYSTEM_SHORT, eCurLanguage ); 255 sal_uLong nSysLongDateFmt = pFormatter->GetFormatIndex( 256 NF_DATE_SYSTEM_LONG, eCurLanguage ); 257 258 for( long nIndex = eOffsetStart; nIndex <= eOffsetEnd; ++nIndex ) 259 { 260 nFormat = pFormatter->GetFormatIndex( 261 (NfIndexTableOffset)nIndex, eCurLanguage ); 262 pFmt = pFormatter->GetEntry( nFormat ); 263 264 if( nFormat == pFormatter->GetFormatIndex( NF_NUMBER_STANDARD, 265 eCurLanguage ) 266 || ((SvNumberformat*)pFmt)->GetOutputString( fVal, sValue, &pCol ) 267 || nFormatType == NUMBERFORMAT_UNDEFINED ) 268 sValue = pFmt->GetFormatstring(); 269 else if( nFormatType == NUMBERFORMAT_TEXT ) 270 { 271 String sTxt(C2S("\"ABC\"")); 272 pFormatter->GetOutputString( sTxt, nFormat, sValue, &pCol); 273 } 274 275 if (nFormat != nSysNumFmt && 276 nFormat != nSysShortDateFmt && 277 nFormat != nSysLongDateFmt) 278 { 279 nPos = InsertEntry( sValue ); 280 SetEntryData( nPos, (void*)nFormat ); 281 282 if( nFormat == pFormatter->GetStandardFormat( 283 nFormatType, eCurLanguage ) ) 284 nStdEntry = i; 285 ++i; 286 } 287 } 288 289 if (!pOwnFormatter) 290 { 291 nPos = InsertEntry(SW_RESSTR( STR_DEFINE_NUMBERFORMAT )); 292 SetEntryData( nPos, NULL ); 293 } 294 295 SelectEntryPos( nStdEntry ); 296 297 nCurrFormatType = nFormatType; 298 } 299 } 300 301 /*-------------------------------------------------------------------- 302 Beschreibung: 303 --------------------------------------------------------------------*/ 304 305 void NumFormatListBox::SetDefFormat(const sal_uLong nDefFmt) 306 { 307 if (nDefFmt == ULONG_MAX) 308 { 309 nDefFormat = nDefFmt; 310 return; 311 } 312 313 SvNumberFormatter* pFormatter; 314 if (pOwnFormatter) 315 pFormatter = pOwnFormatter; 316 else 317 { 318 SwView *pView = GetView(); 319 DBG_ASSERT(pView, "no view found"); 320 if(!pView) 321 return; 322 SwWrtShell &rSh = pView->GetWrtShell(); 323 pFormatter = rSh.GetNumberFormatter(); 324 } 325 326 short nType = pFormatter->GetType(nDefFmt); 327 328 SetFormatType(nType); 329 330 sal_uLong nFormat = pFormatter->GetFormatForLanguageIfBuiltIn(nDefFmt, eCurLanguage); 331 332 for (sal_uInt16 i = 0; i < GetEntryCount(); i++) 333 { 334 if (nFormat == (sal_uLong)GetEntryData(i)) 335 { 336 SelectEntryPos(i); 337 nStdEntry = i; 338 nDefFormat = GetFormat(); 339 return; 340 } 341 } 342 343 // Kein Eintrag gefunden: 344 double fValue = GetDefValue(nType); 345 String sValue; 346 Color* pCol = 0; 347 348 if (nType == NUMBERFORMAT_TEXT) 349 { 350 String sTxt(C2S("\"ABC\"")); 351 pFormatter->GetOutputString(sTxt, nDefFmt, sValue, &pCol); 352 } 353 else 354 pFormatter->GetOutputString(fValue, nDefFmt, sValue, &pCol); 355 356 sal_uInt16 nPos = 0; 357 while ((sal_uLong)GetEntryData(nPos) == ULONG_MAX) 358 nPos++; 359 360 // 361 sal_uLong nSysNumFmt = pFormatter->GetFormatIndex( NF_NUMBER_SYSTEM, eCurLanguage); 362 sal_uLong nSysShortDateFmt = pFormatter->GetFormatIndex( NF_DATE_SYSTEM_SHORT, eCurLanguage); 363 sal_uLong nSysLongDateFmt = pFormatter->GetFormatIndex( NF_DATE_SYSTEM_LONG, eCurLanguage); 364 sal_Bool bSysLang = sal_False; 365 if( eCurLanguage == GetAppLanguage() ) 366 bSysLang = sal_True; 367 sal_uLong nNumFormatForLanguage = pFormatter->GetFormatForLanguageIfBuiltIn(nSysNumFmt, LANGUAGE_SYSTEM ); 368 sal_uLong nShortDateFormatForLanguage = pFormatter->GetFormatForLanguageIfBuiltIn(nSysShortDateFmt, LANGUAGE_SYSTEM ); 369 sal_uLong nLongDateFormatForLanguage = pFormatter->GetFormatForLanguageIfBuiltIn(nSysLongDateFmt, LANGUAGE_SYSTEM ); 370 371 if ( 372 nDefFmt == nSysNumFmt || 373 nDefFmt == nSysShortDateFmt || 374 nDefFmt == nSysLongDateFmt || 375 ( 376 bSysLang && 377 ( 378 nDefFmt == nNumFormatForLanguage || 379 nDefFmt == nShortDateFormatForLanguage || 380 nDefFmt == nLongDateFormatForLanguage 381 ) 382 ) 383 ) 384 { 385 sValue += String(SW_RES(RID_STR_SYSTEM)); 386 } 387 388 nPos = InsertEntry(sValue, nPos); // Als ersten numerischen Eintrag einfuegen 389 SetEntryData(nPos, (void*)nDefFmt); 390 SelectEntryPos(nPos); 391 nDefFormat = GetFormat(); 392 } 393 394 /*-------------------------------------------------------------------- 395 Beschreibung: 396 --------------------------------------------------------------------*/ 397 398 sal_uLong NumFormatListBox::GetFormat() const 399 { 400 sal_uInt16 nPos = GetSelectEntryPos(); 401 402 return (sal_uLong)GetEntryData(nPos); 403 } 404 405 /*-------------------------------------------------------------------- 406 Beschreibung: 407 --------------------------------------------------------------------*/ 408 409 IMPL_LINK( NumFormatListBox, SelectHdl, ListBox *, pBox ) 410 { 411 sal_uInt16 nPos = pBox->GetSelectEntryPos(); 412 String sDefine(SW_RES( STR_DEFINE_NUMBERFORMAT )); 413 SwView *pView = GetView(); 414 415 if( pView && nPos == pBox->GetEntryCount() - 1 && 416 pBox->GetEntry( nPos ) == sDefine ) 417 { 418 SwWrtShell &rSh = pView->GetWrtShell(); 419 SvNumberFormatter* pFormatter = rSh.GetNumberFormatter(); 420 421 SfxItemSet aCoreSet( rSh.GetAttrPool(), 422 SID_ATTR_NUMBERFORMAT_VALUE, SID_ATTR_NUMBERFORMAT_VALUE, 423 SID_ATTR_NUMBERFORMAT_INFO, SID_ATTR_NUMBERFORMAT_INFO, 424 SID_ATTR_NUMBERFORMAT_ONE_AREA, SID_ATTR_NUMBERFORMAT_ONE_AREA, 425 SID_ATTR_NUMBERFORMAT_NOLANGUAGE, SID_ATTR_NUMBERFORMAT_NOLANGUAGE, 426 SID_ATTR_NUMBERFORMAT_ADD_AUTO, SID_ATTR_NUMBERFORMAT_ADD_AUTO, 427 0 ); 428 429 double fValue = GetDefValue( nCurrFormatType); 430 431 sal_uLong nFormat = pFormatter->GetStandardFormat( nCurrFormatType, eCurLanguage); 432 aCoreSet.Put( SfxUInt32Item( SID_ATTR_NUMBERFORMAT_VALUE, nFormat )); 433 434 aCoreSet.Put( SvxNumberInfoItem( pFormatter, fValue, 435 SID_ATTR_NUMBERFORMAT_INFO ) ); 436 437 if( (NUMBERFORMAT_DATE | NUMBERFORMAT_TIME) & nCurrFormatType ) 438 aCoreSet.Put(SfxBoolItem(SID_ATTR_NUMBERFORMAT_ONE_AREA, bOneArea)); 439 440 aCoreSet.Put(SfxBoolItem(SID_ATTR_NUMBERFORMAT_NOLANGUAGE, !bShowLanguageControl)); 441 aCoreSet.Put(SfxBoolItem(SID_ATTR_NUMBERFORMAT_ADD_AUTO, bUseAutomaticLanguage)); 442 443 SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create(); 444 DBG_ASSERT(pFact, "SwAbstractDialogFactory fail!"); 445 446 SfxAbstractDialog* pDlg = pFact->CreateSfxDialog( this, aCoreSet, 447 GetView()->GetViewFrame()->GetFrame().GetFrameInterface(), 448 RC_DLG_SWNUMFMTDLG ); 449 DBG_ASSERT(pDlg, "Dialogdiet fail!"); 450 451 if (RET_OK == pDlg->Execute()) 452 { 453 const SfxPoolItem* pItem = pView->GetDocShell()-> 454 GetItem( SID_ATTR_NUMBERFORMAT_INFO ); 455 456 if( pItem && 0 != ((SvxNumberInfoItem*)pItem)->GetDelCount() ) 457 { 458 const sal_uInt32* pDelArr = ((SvxNumberInfoItem*)pItem)->GetDelArray(); 459 460 for ( sal_uInt16 i = 0; i < ((SvxNumberInfoItem*)pItem)->GetDelCount(); i++ ) 461 pFormatter->DeleteEntry( pDelArr[i] ); 462 } 463 464 const SfxItemSet* pOutSet = pDlg->GetOutputItemSet(); 465 if( SFX_ITEM_SET == pOutSet->GetItemState( 466 SID_ATTR_NUMBERFORMAT_VALUE, sal_False, &pItem )) 467 { 468 sal_uInt32 nNumberFormat = ((SfxUInt32Item*)pItem)->GetValue(); 469 // oj #105473# change order of calls 470 const SvNumberformat* pFmt = pFormatter->GetEntry(nNumberFormat); 471 if( pFmt ) 472 eCurLanguage = pFmt->GetLanguage(); 473 // SetDefFormat uses eCurLanguage to look for if this format already in the list 474 SetDefFormat(nNumberFormat); 475 } 476 if( bShowLanguageControl && SFX_ITEM_SET == pOutSet->GetItemState( 477 SID_ATTR_NUMBERFORMAT_ADD_AUTO, sal_False, &pItem )) 478 { 479 bUseAutomaticLanguage = ((const SfxBoolItem*)pItem)->GetValue(); 480 } 481 } 482 else 483 SetDefFormat(nFormat); 484 485 delete pDlg; 486 } 487 return 0; 488 } 489 490 /*-------------------------------------------------------------------- 491 Beschreibung: 492 --------------------------------------------------------------------*/ 493 494 double NumFormatListBox::GetDefValue(const short nFormatType) const 495 { 496 double fDefValue = 0.0; 497 498 switch (nFormatType) 499 { 500 case NUMBERFORMAT_DATE: 501 case NUMBERFORMAT_DATE|NUMBERFORMAT_TIME: 502 fDefValue = SVX_NUMVAL_DATE; 503 break; 504 505 case NUMBERFORMAT_TIME: 506 fDefValue = SVX_NUMVAL_TIME; 507 break; 508 /* { 509 String sValue("31.8.1997 16:57:34"); 510 sal_uLong nFormat = pFormatter->GetStandardFormat(nFormatType, LANGUAGE_GERMAN); 511 pFormatter->IsNumberFormat( sValue, nFormat, fDefValue ); 512 } 513 break;*/ 514 515 case NUMBERFORMAT_TEXT: 516 case NUMBERFORMAT_UNDEFINED: 517 fDefValue = 0; 518 break; 519 520 case NUMBERFORMAT_CURRENCY: 521 fDefValue = SVX_NUMVAL_CURRENCY; 522 break; 523 524 case NUMBERFORMAT_PERCENT: 525 fDefValue = SVX_NUMVAL_PERCENT; 526 break; 527 528 case NUMBERFORMAT_LOGICAL: 529 fDefValue = SVX_NUMVAL_BOOLEAN; 530 break; 531 532 default: 533 fDefValue = SVX_NUMVAL_STANDARD; 534 break; 535 } 536 537 return fDefValue; 538 } 539 540 /*-------------------------------------------------------------------- 541 Beschreibung: 542 --------------------------------------------------------------------*/ 543 544 void NumFormatListBox::Clear() 545 { 546 ListBox::Clear(); 547 nCurrFormatType = -1; 548 } 549 550