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_sc.hxx" 26 27 28 29 // INCLUDE --------------------------------------------------------------- 30 #include <tools/list.hxx> 31 #include "scitems.hxx" 32 #include <sfx2/bindings.hxx> 33 #include <sfx2/viewsh.hxx> 34 #include <sfx2/dispatch.hxx> 35 #include <editeng/fontitem.hxx> 36 #include <editeng/langitem.hxx> 37 #include <editeng/scripttypeitem.hxx> 38 #include <svl/itempool.hxx> 39 #include <svl/itemset.hxx> 40 #include <svl/cjkoptions.hxx> 41 #include <svl/ctloptions.hxx> 42 #include <vcl/svapp.hxx> 43 #include <vcl/msgbox.hxx> 44 #include <vcl/wrkwin.hxx> 45 #include <sfx2/request.hxx> 46 #include <sfx2/objsh.hxx> 47 #include <svl/stritem.hxx> 48 #include <svl/eitem.hxx> 49 50 #include <com/sun/star/i18n/TransliterationModules.hpp> 51 #include <com/sun/star/i18n/TransliterationModulesExtra.hpp> 52 53 54 #include "viewutil.hxx" 55 #include "global.hxx" 56 #include "chgtrack.hxx" 57 #include "chgviset.hxx" 58 #include "markdata.hxx" 59 60 #include <svx/svxdlg.hxx> //CHINA001 61 #include <svx/dialogs.hrc> //CHINA001 62 // STATIC DATA ----------------------------------------------------------- 63 64 //================================================================== 65 66 // static 67 void ScViewUtil::PutItemScript( SfxItemSet& rShellSet, const SfxItemSet& rCoreSet, 68 sal_uInt16 nWhichId, sal_uInt16 nScript ) 69 { 70 // take the effective item from rCoreSet according to nScript 71 // and put in rShellSet under the (base) nWhichId 72 73 SfxItemPool& rPool = *rShellSet.GetPool(); 74 SvxScriptSetItem aSetItem( rPool.GetSlotId(nWhichId), rPool ); 75 // use PutExtended with eDefaultAs = SFX_ITEM_SET, so defaults from rCoreSet 76 // (document pool) are read and put into rShellSet (MessagePool) 77 aSetItem.GetItemSet().PutExtended( rCoreSet, SFX_ITEM_DONTCARE, SFX_ITEM_SET ); 78 const SfxPoolItem* pI = aSetItem.GetItemOfScript( nScript ); 79 if (pI) 80 rShellSet.Put( *pI, nWhichId ); 81 else 82 rShellSet.InvalidateItem( nWhichId ); 83 } 84 85 // static 86 sal_uInt16 ScViewUtil::GetEffLanguage( ScDocument* pDoc, const ScAddress& rPos ) 87 { 88 // used for thesaurus 89 90 sal_uInt8 nScript = pDoc->GetScriptType( rPos.Col(), rPos.Row(), rPos.Tab() ); 91 sal_uInt16 nWhich = ( nScript == SCRIPTTYPE_ASIAN ) ? ATTR_CJK_FONT_LANGUAGE : 92 ( ( nScript == SCRIPTTYPE_COMPLEX ) ? ATTR_CTL_FONT_LANGUAGE : ATTR_FONT_LANGUAGE ); 93 const SfxPoolItem* pItem = pDoc->GetAttr( rPos.Col(), rPos.Row(), rPos.Tab(), nWhich); 94 SvxLanguageItem* pLangIt = PTR_CAST( SvxLanguageItem, pItem ); 95 LanguageType eLnge; 96 if (pLangIt) 97 { 98 eLnge = (LanguageType) pLangIt->GetValue(); 99 if (eLnge == LANGUAGE_DONTKNOW) //! can this happen? 100 { 101 LanguageType eLatin, eCjk, eCtl; 102 pDoc->GetLanguage( eLatin, eCjk, eCtl ); 103 eLnge = ( nScript == SCRIPTTYPE_ASIAN ) ? eCjk : 104 ( ( nScript == SCRIPTTYPE_COMPLEX ) ? eCtl : eLatin ); 105 } 106 } 107 else 108 eLnge = LANGUAGE_ENGLISH_US; 109 if ( eLnge == LANGUAGE_SYSTEM ) 110 eLnge = Application::GetSettings().GetLanguage(); // never use SYSTEM for spelling 111 112 return eLnge; 113 } 114 115 // static 116 sal_Int32 ScViewUtil::GetTransliterationType( sal_uInt16 nSlotID ) 117 { 118 sal_Int32 nType = 0; 119 switch ( nSlotID ) 120 { 121 case SID_TRANSLITERATE_SENTENCE_CASE: 122 nType = com::sun::star::i18n::TransliterationModulesExtra::SENTENCE_CASE; 123 break; 124 case SID_TRANSLITERATE_TITLE_CASE: 125 nType = com::sun::star::i18n::TransliterationModulesExtra::TITLE_CASE; 126 break; 127 case SID_TRANSLITERATE_TOGGLE_CASE: 128 nType = com::sun::star::i18n::TransliterationModulesExtra::TOGGLE_CASE; 129 break; 130 case SID_TRANSLITERATE_UPPER: 131 nType = com::sun::star::i18n::TransliterationModules_LOWERCASE_UPPERCASE; 132 break; 133 case SID_TRANSLITERATE_LOWER: 134 nType = com::sun::star::i18n::TransliterationModules_UPPERCASE_LOWERCASE; 135 break; 136 case SID_TRANSLITERATE_HALFWIDTH: 137 nType = com::sun::star::i18n::TransliterationModules_FULLWIDTH_HALFWIDTH; 138 break; 139 case SID_TRANSLITERATE_FULLWIDTH: 140 nType = com::sun::star::i18n::TransliterationModules_HALFWIDTH_FULLWIDTH; 141 break; 142 case SID_TRANSLITERATE_HIRAGANA: 143 nType = com::sun::star::i18n::TransliterationModules_KATAKANA_HIRAGANA; 144 break; 145 case SID_TRANSLITERATE_KATAGANA: 146 nType = com::sun::star::i18n::TransliterationModules_HIRAGANA_KATAKANA; 147 break; 148 } 149 return nType; 150 } 151 152 // static 153 sal_Bool ScViewUtil::IsActionShown( const ScChangeAction& rAction, 154 const ScChangeViewSettings& rSettings, 155 ScDocument& rDocument ) 156 { 157 // abgelehnte werden durch eine invertierende akzeptierte Action dargestellt, 158 // die Reihenfolge von ShowRejected/ShowAccepted ist deswegen wichtig 159 160 if ( !rSettings.IsShowRejected() && rAction.IsRejecting() ) 161 return sal_False; 162 163 if ( !rSettings.IsShowAccepted() && rAction.IsAccepted() && !rAction.IsRejecting() ) 164 return sal_False; 165 166 if ( rSettings.HasAuthor() ) 167 { 168 if ( rSettings.IsEveryoneButMe() ) 169 { 170 // GetUser() am ChangeTrack ist der aktuelle Benutzer 171 ScChangeTrack* pTrack = rDocument.GetChangeTrack(); 172 if ( !pTrack || rAction.GetUser() == pTrack->GetUser() ) 173 return sal_False; 174 } 175 else if ( rAction.GetUser() != rSettings.GetTheAuthorToShow() ) 176 return sal_False; 177 } 178 179 if ( rSettings.HasComment() ) 180 { 181 String aComStr=rAction.GetComment(); 182 aComStr.AppendAscii(RTL_CONSTASCII_STRINGPARAM( " (" )); 183 rAction.GetDescription( aComStr, &rDocument ); 184 aComStr+=')'; 185 186 if(!rSettings.IsValidComment(&aComStr)) 187 return sal_False; 188 } 189 190 if ( rSettings.HasRange() ) 191 if ( !rSettings.GetTheRangeList().Intersects( rAction.GetBigRange().MakeRange() ) ) 192 return sal_False; 193 194 if ( rSettings.HasDate() && rSettings.GetTheDateMode() != SCDM_NO_DATEMODE ) 195 { 196 DateTime aDateTime = rAction.GetDateTime(); 197 const DateTime& rFirst = rSettings.GetTheFirstDateTime(); 198 const DateTime& rLast = rSettings.GetTheLastDateTime(); 199 switch ( rSettings.GetTheDateMode() ) 200 { // korrespondiert mit ScHighlightChgDlg::OKBtnHdl 201 case SCDM_DATE_BEFORE: 202 if ( aDateTime > rFirst ) 203 return sal_False; 204 break; 205 206 case SCDM_DATE_SINCE: 207 if ( aDateTime < rFirst ) 208 return sal_False; 209 break; 210 211 case SCDM_DATE_EQUAL: 212 case SCDM_DATE_BETWEEN: 213 if ( aDateTime < rFirst || aDateTime > rLast ) 214 return sal_False; 215 break; 216 217 case SCDM_DATE_NOTEQUAL: 218 if ( aDateTime >= rFirst && aDateTime <= rLast ) 219 return sal_False; 220 break; 221 222 case SCDM_DATE_SAVE: 223 { 224 ScChangeTrack* pTrack = rDocument.GetChangeTrack(); 225 if ( !pTrack || pTrack->GetLastSavedActionNumber() >= 226 rAction.GetActionNumber() ) 227 return sal_False; 228 } 229 break; 230 231 default: 232 { 233 // added to avoid warnings 234 } 235 } 236 } 237 238 if ( rSettings.HasActionRange() ) 239 { 240 sal_uLong nAction = rAction.GetActionNumber(); 241 sal_uLong nFirstAction; 242 sal_uLong nLastAction; 243 rSettings.GetTheActionRange( nFirstAction, nLastAction ); 244 if ( nAction < nFirstAction || nAction > nLastAction ) 245 { 246 return sal_False; 247 } 248 } 249 250 return sal_True; 251 } 252 253 // static 254 void ScViewUtil::UnmarkFiltered( ScMarkData& rMark, ScDocument* pDoc ) 255 { 256 rMark.MarkToMulti(); 257 258 ScRange aMultiArea; 259 rMark.GetMultiMarkArea( aMultiArea ); 260 SCCOL nStartCol = aMultiArea.aStart.Col(); 261 SCROW nStartRow = aMultiArea.aStart.Row(); 262 SCCOL nEndCol = aMultiArea.aEnd.Col(); 263 SCROW nEndRow = aMultiArea.aEnd.Row(); 264 265 bool bChanged = false; 266 SCTAB nTabCount = pDoc->GetTableCount(); 267 for (SCTAB nTab=0; nTab<nTabCount; nTab++) 268 if ( rMark.GetTableSelect(nTab ) ) 269 { 270 for (SCROW nRow = nStartRow; nRow <= nEndRow; ++nRow) 271 { 272 SCROW nLastRow = nRow; 273 if (pDoc->RowFiltered(nRow, nTab, NULL, &nLastRow)) 274 { 275 // use nStartCol/nEndCol, so the multi mark area isn't extended to all columns 276 // (visible in repaint for indentation) 277 rMark.SetMultiMarkArea( 278 ScRange(nStartCol, nRow, nTab, nEndCol, nLastRow, nTab), false); 279 bChanged = true; 280 nRow = nLastRow; 281 } 282 } 283 } 284 285 if ( bChanged && !rMark.HasAnyMultiMarks() ) 286 rMark.ResetMark(); 287 288 rMark.MarkToSimple(); 289 } 290 291 292 // static 293 bool ScViewUtil::FitToUnfilteredRows( ScRange & rRange, ScDocument * pDoc, size_t nRows ) 294 { 295 SCTAB nTab = rRange.aStart.Tab(); 296 bool bOneTabOnly = (nTab == rRange.aEnd.Tab()); 297 // Always fit the range on its first sheet. 298 DBG_ASSERT( bOneTabOnly, "ScViewUtil::ExtendToUnfilteredRows: works only on one sheet"); 299 SCROW nStartRow = rRange.aStart.Row(); 300 SCROW nLastRow = pDoc->LastNonFilteredRow(nStartRow, MAXROW, nTab); 301 if (ValidRow(nLastRow)) 302 rRange.aEnd.SetRow(nLastRow); 303 SCROW nCount = pDoc->CountNonFilteredRows(nStartRow, MAXROW, nTab); 304 return static_cast<size_t>(nCount) == nRows && bOneTabOnly; 305 } 306 307 308 // static 309 bool ScViewUtil::HasFiltered( const ScRange& rRange, ScDocument* pDoc ) 310 { 311 SCROW nStartRow = rRange.aStart.Row(); 312 SCROW nEndRow = rRange.aEnd.Row(); 313 for (SCTAB nTab=rRange.aStart.Tab(); nTab<=rRange.aEnd.Tab(); nTab++) 314 { 315 if (pDoc->HasFilteredRows(nStartRow, nEndRow, nTab)) 316 return true; 317 } 318 319 return false; 320 } 321 322 // static 323 void ScViewUtil::HideDisabledSlot( SfxItemSet& rSet, SfxBindings& rBindings, sal_uInt16 nSlotId ) 324 { 325 SvtCJKOptions aCJKOptions; 326 SvtCTLOptions aCTLOptions; 327 bool bEnabled = true; 328 329 switch( nSlotId ) 330 { 331 case SID_CHINESE_CONVERSION: 332 case SID_HANGUL_HANJA_CONVERSION: 333 bEnabled = aCJKOptions.IsAnyEnabled(); 334 break; 335 336 case SID_TRANSLITERATE_HALFWIDTH: 337 case SID_TRANSLITERATE_FULLWIDTH: 338 case SID_TRANSLITERATE_HIRAGANA: 339 case SID_TRANSLITERATE_KATAGANA: 340 bEnabled = aCJKOptions.IsChangeCaseMapEnabled(); 341 break; 342 343 case SID_INSERT_RLM: 344 case SID_INSERT_LRM: 345 case SID_INSERT_ZWNBSP: 346 case SID_INSERT_ZWSP: 347 bEnabled = aCTLOptions.IsCTLFontEnabled(); 348 break; 349 350 default: 351 DBG_ERRORFILE( "ScViewUtil::HideDisabledSlot - unknown slot ID" ); 352 return; 353 } 354 355 rBindings.SetVisibleState( nSlotId, bEnabled ); 356 if( !bEnabled ) 357 rSet.DisableItem( nSlotId ); 358 } 359 360 //================================================================== 361 362 sal_Bool ScViewUtil::ExecuteCharMap( const SvxFontItem& rOldFont, 363 SfxViewFrame& rFrame, 364 SvxFontItem& rNewFont, 365 String& rString ) 366 { 367 sal_Bool bRet = sal_False; 368 SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create(); 369 if(pFact) 370 { 371 SfxAllItemSet aSet( rFrame.GetObjectShell()->GetPool() ); 372 aSet.Put( SfxBoolItem( FN_PARAM_1, sal_False ) ); 373 aSet.Put( SvxFontItem( rOldFont.GetFamily(), rOldFont.GetFamilyName(), rOldFont.GetStyleName(), rOldFont.GetPitch(), rOldFont.GetCharSet(), aSet.GetPool()->GetWhich( SID_ATTR_CHAR_FONT ) ) ); 374 SfxAbstractDialog* pDlg = pFact->CreateSfxDialog( &rFrame.GetWindow(), aSet, rFrame.GetFrame().GetFrameInterface(), RID_SVXDLG_CHARMAP ); 375 if ( pDlg->Execute() == RET_OK ) 376 { 377 SFX_ITEMSET_ARG( pDlg->GetOutputItemSet(), pItem, SfxStringItem, SID_CHARMAP, sal_False ); 378 SFX_ITEMSET_ARG( pDlg->GetOutputItemSet(), pFontItem, SvxFontItem, SID_ATTR_CHAR_FONT, sal_False ); 379 if ( pItem ) 380 rString = pItem->GetValue(); 381 if ( pFontItem ) 382 rNewFont = SvxFontItem( pFontItem->GetFamily(), pFontItem->GetFamilyName(), pFontItem->GetStyleName(), pFontItem->GetPitch(), pFontItem->GetCharSet(), rNewFont.Which() ); 383 bRet = sal_True; 384 } 385 delete pDlg; 386 } 387 return bRet; 388 } 389 390 bool ScViewUtil::IsFullScreen( SfxViewShell& rViewShell ) 391 { 392 SfxBindings& rBindings = rViewShell.GetViewFrame()->GetBindings(); 393 SfxPoolItem* pItem = 0; 394 bool bIsFullScreen = false; 395 396 if (rBindings.QueryState( SID_WIN_FULLSCREEN, pItem ) >= SFX_ITEM_DEFAULT) 397 bIsFullScreen = static_cast< SfxBoolItem* >( pItem )->GetValue(); 398 return bIsFullScreen; 399 } 400 401 void ScViewUtil::SetFullScreen( SfxViewShell& rViewShell, bool bSet ) 402 { 403 if( IsFullScreen( rViewShell ) != bSet ) 404 { 405 SfxBoolItem aItem( SID_WIN_FULLSCREEN, bSet ); 406 rViewShell.GetDispatcher()->Execute( SID_WIN_FULLSCREEN, SFX_CALLMODE_RECORD, &aItem, 0L ); 407 } 408 } 409 410 //------------------------------------------------------------------ 411 412 ScUpdateRect::ScUpdateRect( SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2 ) 413 { 414 PutInOrder( nX1, nX2 ); 415 PutInOrder( nY1, nY2 ); 416 417 nOldStartX = nX1; 418 nOldStartY = nY1; 419 nOldEndX = nX2; 420 nOldEndY = nY2; 421 } 422 423 void ScUpdateRect::SetNew( SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2 ) 424 { 425 PutInOrder( nX1, nX2 ); 426 PutInOrder( nY1, nY2 ); 427 428 nNewStartX = nX1; 429 nNewStartY = nY1; 430 nNewEndX = nX2; 431 nNewEndY = nY2; 432 } 433 434 sal_Bool ScUpdateRect::GetDiff( SCCOL& rX1, SCROW& rY1, SCCOL& rX2, SCROW& rY2 ) 435 { 436 if ( nNewStartX == nOldStartX && nNewEndX == nOldEndX && 437 nNewStartY == nOldStartY && nNewEndY == nOldEndY ) 438 { 439 rX1 = nNewStartX; 440 rY1 = nNewStartY; 441 rX2 = nNewStartX; 442 rY2 = nNewStartY; 443 return sal_False; 444 } 445 446 rX1 = Min(nNewStartX,nOldStartX); 447 rY1 = Min(nNewStartY,nOldStartY); 448 rX2 = Max(nNewEndX,nOldEndX); 449 rY2 = Max(nNewEndY,nOldEndY); 450 451 if ( nNewStartX == nOldStartX && nNewEndX == nOldEndX ) 452 { 453 if ( nNewStartY == nOldStartY ) 454 { 455 rY1 = Min( nNewEndY, nOldEndY ); 456 rY2 = Max( nNewEndY, nOldEndY ); 457 } 458 else if ( nNewEndY == nOldEndY ) 459 { 460 rY1 = Min( nNewStartY, nOldStartY ); 461 rY2 = Max( nNewStartY, nOldStartY ); 462 } 463 } 464 else if ( nNewStartY == nOldStartY && nNewEndY == nOldEndY ) 465 { 466 if ( nNewStartX == nOldStartX ) 467 { 468 rX1 = Min( nNewEndX, nOldEndX ); 469 rX2 = Max( nNewEndX, nOldEndX ); 470 } 471 else if ( nNewEndX == nOldEndX ) 472 { 473 rX1 = Min( nNewStartX, nOldStartX ); 474 rX2 = Max( nNewStartX, nOldStartX ); 475 } 476 } 477 478 return sal_True; 479 } 480 481 #ifdef OLD_SELECTION_PAINT 482 sal_Bool ScUpdateRect::GetXorDiff( SCCOL& rX1, SCROW& rY1, SCCOL& rX2, SCROW& rY2, sal_Bool& rCont ) 483 { 484 rCont = sal_False; 485 486 if (nNewStartX == nOldStartX && nNewEndX == nOldEndX && 487 nNewStartY == nOldStartY && nNewEndY == nOldEndY) 488 { 489 rX1 = nNewStartX; 490 rY1 = nNewStartY; 491 rX2 = nNewStartX; 492 rY2 = nNewStartY; 493 return sal_False; 494 } 495 496 rX1 = Min(nNewStartX,nOldStartX); 497 rY1 = Min(nNewStartY,nOldStartY); 498 rX2 = Max(nNewEndX,nOldEndX); 499 rY2 = Max(nNewEndY,nOldEndY); 500 501 if (nNewStartX == nOldStartX && nNewEndX == nOldEndX) // nur vertikal 502 { 503 if (nNewStartY == nOldStartY) 504 { 505 rY1 = Min( nNewEndY, nOldEndY ) + 1; 506 rY2 = Max( nNewEndY, nOldEndY ); 507 } 508 else if (nNewEndY == nOldEndY) 509 { 510 rY1 = Min( nNewStartY, nOldStartY ); 511 rY2 = Max( nNewStartY, nOldStartY ) - 1; 512 } 513 else 514 { 515 rY1 = Min( nNewStartY, nOldStartY ); 516 rY2 = Max( nNewStartY, nOldStartY ) - 1; 517 rCont = sal_True; 518 nContY1 = Min( nNewEndY, nOldEndY ) + 1; 519 nContY2 = Max( nNewEndY, nOldEndY ); 520 nContX1 = rX1; 521 nContX2 = rX2; 522 } 523 } 524 else if (nNewStartY == nOldStartY && nNewEndY == nOldEndY) // nur horizontal 525 { 526 if (nNewStartX == nOldStartX) 527 { 528 rX1 = Min( nNewEndX, nOldEndX ) + 1; 529 rX2 = Max( nNewEndX, nOldEndX ); 530 } 531 else if (nNewEndX == nOldEndX) 532 { 533 rX1 = Min( nNewStartX, nOldStartX ); 534 rX2 = Max( nNewStartX, nOldStartX ) - 1; 535 } 536 else 537 { 538 rX1 = Min( nNewStartX, nOldStartX ); 539 rX2 = Max( nNewStartX, nOldStartX ) - 1; 540 rCont = sal_True; 541 nContX1 = Min( nNewEndX, nOldEndX ) + 1; 542 nContX2 = Max( nNewEndX, nOldEndX ); 543 nContY1 = rY1; 544 nContY2 = rY2; 545 } 546 } 547 else if (nNewEndX == nOldEndX && nNewEndY == nOldEndY) // links oben 548 { 549 if ((nNewStartX<nOldStartX) == (nNewStartY<nOldStartY)) 550 rX1 = Min( nNewStartX, nOldStartX ); 551 else 552 rX1 = Max( nNewStartX, nOldStartX ); // Ecke weglassen 553 rX2 = nOldEndX; 554 rY1 = Min( nNewStartY, nOldStartY ); // oben 555 rY2 = Max( nNewStartY, nOldStartY ) - 1; 556 rCont = sal_True; 557 nContY1 = rY2+1; 558 nContY2 = nOldEndY; 559 nContX1 = Min( nNewStartX, nOldStartX ); // links 560 nContX2 = Max( nNewStartX, nOldStartX ) - 1; 561 } 562 else if (nNewStartX == nOldStartX && nNewEndY == nOldEndY) // rechts oben 563 { 564 if ((nNewEndX<nOldEndX) != (nNewStartY<nOldStartY)) 565 rX2 = Max( nNewEndX, nOldEndX ); 566 else 567 rX2 = Min( nNewEndX, nOldEndX ); // Ecke weglassen 568 rX1 = nOldStartX; 569 rY1 = Min( nNewStartY, nOldStartY ); // oben 570 rY2 = Max( nNewStartY, nOldStartY ) - 1; 571 rCont = sal_True; 572 nContY1 = rY2+1; 573 nContY2 = nOldEndY; 574 nContX1 = Min( nNewEndX, nOldEndX ) + 1; // rechts 575 nContX2 = Max( nNewEndX, nOldEndX ); 576 } 577 else if (nNewEndX == nOldEndX && nNewStartY == nOldStartY) // links unten 578 { 579 if ((nNewStartX<nOldStartX) != (nNewEndY<nOldEndY)) 580 rX1 = Min( nNewStartX, nOldStartX ); 581 else 582 rX1 = Max( nNewStartX, nOldStartX ); // Ecke weglassen 583 rX2 = nOldEndX; 584 rY1 = Min( nNewEndY, nOldEndY ) + 1; // unten 585 rY2 = Max( nNewEndY, nOldEndY ); 586 rCont = sal_True; 587 nContY1 = nOldStartY; 588 nContY2 = rY1-1; 589 nContX1 = Min( nNewStartX, nOldStartX ); // links 590 nContX2 = Max( nNewStartX, nOldStartX ) - 1; 591 } 592 else if (nNewStartX == nOldStartX && nNewStartY == nOldStartY) // rechts unten 593 { 594 if ((nNewEndX<nOldEndX) == (nNewEndY<nOldEndY)) 595 rX2 = Max( nNewEndX, nOldEndX ); 596 else 597 rX2 = Min( nNewEndX, nOldEndX ); // Ecke weglassen 598 rX1 = nOldStartX; 599 rY1 = Min( nNewEndY, nOldEndY ) + 1; // unten 600 rY2 = Max( nNewEndY, nOldEndY ); 601 rCont = sal_True; 602 nContY1 = nOldStartY; 603 nContY2 = rY1-1; 604 nContX1 = Min( nNewEndX, nOldEndX ) + 1; // rechts 605 nContX2 = Max( nNewEndX, nOldEndX ); 606 } 607 else // Ueberschlag 608 { 609 rX1 = nOldStartX; 610 rY1 = nOldStartY; 611 rX2 = nOldEndX; 612 rY2 = nOldEndY; 613 rCont = sal_True; 614 nContX1 = nNewStartX; 615 nContY1 = nNewStartY; 616 nContX2 = nNewEndX; 617 nContY2 = nNewEndY; 618 } 619 620 return sal_True; 621 } 622 623 void ScUpdateRect::GetContDiff( SCCOL& rX1, SCROW& rY1, SCCOL& rX2, SCROW& rY2 ) 624 { 625 rX1 = nContX1; 626 rY1 = nContY1; 627 rX2 = nContX2; 628 rY2 = nContY2; 629 } 630 #endif 631 632 633 634 635 636 637