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