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_sc.hxx" 30 31 //------------------------------------------------------------------ 32 33 #include "scitems.hxx" 34 35 #include <svl/slstitm.hxx> 36 #include <svl/stritem.hxx> 37 #include <svl/whiter.hxx> 38 #include <unotools/moduleoptions.hxx> 39 #include <svtools/cliplistener.hxx> 40 #include <svtools/insdlg.hxx> 41 #include <sot/formats.hxx> 42 #include <svx/hlnkitem.hxx> 43 #include <sfx2/app.hxx> 44 #include <sfx2/bindings.hxx> 45 #include <sfx2/childwin.hxx> 46 #include <sfx2/objface.hxx> 47 #include <sfx2/request.hxx> 48 #include <sfx2/viewfrm.hxx> 49 #include <svx/clipfmtitem.hxx> 50 #include <editeng/langitem.hxx> 51 52 #include "cellsh.hxx" 53 #include "sc.hrc" 54 #include "docsh.hxx" 55 #include "attrib.hxx" 56 #include "scresid.hxx" 57 #include "tabvwsh.hxx" 58 #include "impex.hxx" 59 #include "cell.hxx" 60 #include "scmod.hxx" 61 #include "globstr.hrc" 62 #include "transobj.hxx" 63 #include "drwtrans.hxx" 64 #include "scabstdlg.hxx" 65 #include "dociter.hxx" 66 #include "postit.hxx" 67 68 //------------------------------------------------------------------ 69 70 #define ScCellShell 71 #define CellMovement 72 #include "scslots.hxx" 73 74 TYPEINIT1( ScCellShell, ScFormatShell ); 75 76 SFX_IMPL_INTERFACE(ScCellShell, ScFormatShell , ScResId(SCSTR_CELLSHELL) ) 77 { 78 SFX_OBJECTBAR_REGISTRATION( SFX_OBJECTBAR_OBJECT | SFX_VISIBILITY_STANDARD | 79 SFX_VISIBILITY_SERVER, 80 ScResId(RID_OBJECTBAR_FORMAT)); 81 SFX_POPUPMENU_REGISTRATION(ScResId(RID_POPUP_CELLS)); 82 } 83 84 85 ScCellShell::ScCellShell(ScViewData* pData) : 86 ScFormatShell(pData), 87 pImpl( new CellShell_Impl() ), 88 bPastePossible(sal_False) 89 { 90 SetHelpId(HID_SCSHELL_CELLSH); 91 SetName(String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("Cell"))); 92 } 93 94 ScCellShell::~ScCellShell() 95 { 96 if ( pImpl->m_pClipEvtLstnr ) 97 { 98 pImpl->m_pClipEvtLstnr->AddRemoveListener( GetViewData()->GetActiveWin(), sal_False ); 99 100 // #103849# The listener may just now be waiting for the SolarMutex and call the link 101 // afterwards, in spite of RemoveListener. So the link has to be reset, too. 102 pImpl->m_pClipEvtLstnr->ClearCallbackLink(); 103 104 pImpl->m_pClipEvtLstnr->release(); 105 } 106 107 delete pImpl->m_pLinkedDlg; 108 delete pImpl->m_pRequest; 109 delete pImpl; 110 } 111 112 //------------------------------------------------------------------ 113 114 void ScCellShell::GetBlockState( SfxItemSet& rSet ) 115 { 116 ScTabViewShell* pTabViewShell = GetViewData()->GetViewShell(); 117 ScRange aMarkRange; 118 ScMarkType eMarkType = GetViewData()->GetSimpleArea( aMarkRange ); 119 sal_Bool bSimpleArea = (eMarkType == SC_MARK_SIMPLE); 120 sal_Bool bOnlyNotBecauseOfMatrix; 121 sal_Bool bEditable = pTabViewShell->SelectionEditable( &bOnlyNotBecauseOfMatrix ); 122 ScDocument* pDoc = GetViewData()->GetDocument(); 123 ScDocShell* pDocShell = GetViewData()->GetDocShell(); 124 ScMarkData& rMark = GetViewData()->GetMarkData(); 125 SCCOL nCol1, nCol2; 126 SCROW nRow1, nRow2; 127 nCol1 = aMarkRange.aStart.Col(); 128 nRow1 = aMarkRange.aStart.Row(); 129 nCol2 = aMarkRange.aEnd.Col(); 130 nRow2 = aMarkRange.aEnd.Row(); 131 132 SfxWhichIter aIter(rSet); 133 sal_uInt16 nWhich = aIter.FirstWhich(); 134 while ( nWhich ) 135 { 136 sal_Bool bDisable = sal_False; 137 sal_Bool bNeedEdit = sal_True; // muss Selektion editierbar sein? 138 switch ( nWhich ) 139 { 140 case FID_FILL_TO_BOTTOM: // Fuellen oben/unten 141 case FID_FILL_TO_TOP: // mind. 2 Zeilen markiert? 142 bDisable = (!bSimpleArea) || (nRow1 == nRow2); 143 if ( !bDisable && bEditable ) 144 { // Matrix nicht zerreissen 145 if ( nWhich == FID_FILL_TO_BOTTOM ) 146 bDisable = pDoc->HasSelectedBlockMatrixFragment( 147 nCol1, nRow1, nCol2, nRow1, rMark ); // erste Zeile 148 else 149 bDisable = pDoc->HasSelectedBlockMatrixFragment( 150 nCol1, nRow2, nCol2, nRow2, rMark ); // letzte Zeile 151 } 152 break; 153 154 case FID_FILL_TO_RIGHT: // Fuellen links/rechts 155 case FID_FILL_TO_LEFT: // mind. 2 Spalten markiert? 156 bDisable = (!bSimpleArea) || (nCol1 == nCol2); 157 if ( !bDisable && bEditable ) 158 { // Matrix nicht zerreissen 159 if ( nWhich == FID_FILL_TO_RIGHT ) 160 bDisable = pDoc->HasSelectedBlockMatrixFragment( 161 nCol1, nRow1, nCol1, nRow2, rMark ); // erste Spalte 162 else 163 bDisable = pDoc->HasSelectedBlockMatrixFragment( 164 nCol2, nRow1, nCol2, nRow2, rMark ); // letzte Spalte 165 } 166 break; 167 168 case FID_FILL_SERIES: // Block fuellen 169 case SID_OPENDLG_TABOP: // Mehrfachoperationen, mind. 2 Zellen markiert? 170 if (pDoc->GetChangeTrack()!=NULL &&nWhich ==SID_OPENDLG_TABOP) 171 bDisable = sal_True; 172 else 173 bDisable = (!bSimpleArea) || (nCol1 == nCol2 && nRow1 == nRow2); 174 175 if ( !bDisable && bEditable && nWhich == FID_FILL_SERIES ) 176 { // Matrix nicht zerreissen 177 bDisable = pDoc->HasSelectedBlockMatrixFragment( 178 nCol1, nRow1, nCol2, nRow1, rMark ) // erste Zeile 179 || pDoc->HasSelectedBlockMatrixFragment( 180 nCol1, nRow2, nCol2, nRow2, rMark ) // letzte Zeile 181 || pDoc->HasSelectedBlockMatrixFragment( 182 nCol1, nRow1, nCol1, nRow2, rMark ) // erste Spalte 183 || pDoc->HasSelectedBlockMatrixFragment( 184 nCol2, nRow1, nCol2, nRow2, rMark ); // letzte Spalte 185 } 186 break; 187 188 case SID_CUT: // Ausschneiden, 189 case FID_INS_CELL: // Zellen einfuegen, nur einf. Selektion 190 bDisable = (!bSimpleArea); 191 break; 192 193 case FID_INS_ROW: // insert rows 194 case FID_INS_CELLSDOWN: 195 bDisable = (!bSimpleArea) || GetViewData()->SimpleColMarked(); 196 break; 197 198 case FID_INS_COLUMN: // insert columns 199 case FID_INS_CELLSRIGHT: 200 bDisable = (!bSimpleArea) || GetViewData()->SimpleRowMarked(); 201 break; 202 203 case SID_COPY: // Kopieren 204 // nur wegen Matrix nicht editierbar? Matrix nicht zerreissen 205 //! schlaegt nicht zu, wenn geschuetzt UND Matrix, aber damit 206 //! muss man leben.. wird in Copy-Routine abgefangen, sonst 207 //! muesste hier nochmal Aufwand getrieben werden 208 if ( !(!bEditable && bOnlyNotBecauseOfMatrix) ) 209 bNeedEdit = sal_False; // erlaubt, wenn geschuetzt/ReadOnly 210 break; 211 212 case SID_AUTOFORMAT: // Autoformat, mind. 3x3 selektiert 213 bDisable = (!bSimpleArea) 214 || ((nCol2 - nCol1) < 2) || ((nRow2 - nRow1) < 2); 215 break; 216 217 case SID_OPENDLG_CONDFRMT : 218 { 219 if ( !bEditable && bOnlyNotBecauseOfMatrix ) 220 { 221 bNeedEdit = sal_False; 222 } 223 if ( pDocShell && pDocShell->IsDocShared() ) 224 { 225 bDisable = sal_True; 226 } 227 } 228 break; 229 230 case FID_CONDITIONAL_FORMAT : 231 case SID_CELL_FORMAT_RESET : 232 case FID_CELL_FORMAT : 233 case SID_ENABLE_HYPHENATION : 234 // nur wegen Matrix nicht editierbar? Attribute trotzdem ok 235 if ( !bEditable && bOnlyNotBecauseOfMatrix ) 236 bNeedEdit = sal_False; 237 break; 238 239 case FID_VALIDATION: 240 { 241 if ( pDocShell && pDocShell->IsDocShared() ) 242 { 243 bDisable = sal_True; 244 } 245 } 246 break; 247 248 case SID_TRANSLITERATE_HALFWIDTH: 249 case SID_TRANSLITERATE_FULLWIDTH: 250 case SID_TRANSLITERATE_HIRAGANA: 251 case SID_TRANSLITERATE_KATAGANA: 252 ScViewUtil::HideDisabledSlot( rSet, GetViewData()->GetBindings(), nWhich ); 253 break; 254 } 255 if (!bDisable && bNeedEdit && !bEditable) 256 bDisable = sal_True; 257 258 if (bDisable) 259 rSet.DisableItem(nWhich); 260 else if (nWhich == SID_ENABLE_HYPHENATION) 261 { 262 // toggle slots need a bool item 263 rSet.Put( SfxBoolItem( nWhich, sal_False ) ); 264 } 265 nWhich = aIter.NextWhich(); 266 } 267 } 268 269 // Funktionen, die je nach Cursorposition disabled sind 270 // Default: 271 // SID_INSERT_POSTIT, SID_CHARMAP, SID_OPENDLG_FUNCTION 272 273 void ScCellShell::GetCellState( SfxItemSet& rSet ) 274 { 275 ScDocShell* pDocShell = GetViewData()->GetDocShell(); 276 ScDocument* pDoc = GetViewData()->GetDocShell()->GetDocument(); 277 ScAddress aCursor( GetViewData()->GetCurX(), GetViewData()->GetCurY(), 278 GetViewData()->GetTabNo() ); 279 280 SfxWhichIter aIter(rSet); 281 sal_uInt16 nWhich = aIter.FirstWhich(); 282 while ( nWhich ) 283 { 284 sal_Bool bDisable = sal_False; 285 sal_Bool bNeedEdit = sal_True; // muss Cursorposition editierbar sein? 286 switch ( nWhich ) 287 { 288 case SID_THESAURUS: 289 { 290 CellType eType = pDoc->GetCellType( aCursor ); 291 bDisable = ( eType != CELLTYPE_STRING && eType != CELLTYPE_EDIT); 292 if (!bDisable) 293 { 294 // test for available languages 295 sal_uInt16 nLang = ScViewUtil::GetEffLanguage( pDoc, aCursor ); 296 bDisable = !ScModule::HasThesaurusLanguage( nLang ); 297 } 298 } 299 break; 300 case SID_OPENDLG_FUNCTION: 301 { 302 ScMarkData aMarkData=GetViewData()->GetMarkData(); 303 aMarkData.MarkToSimple(); 304 ScRange aRange; 305 aMarkData.GetMarkArea(aRange); 306 if(aMarkData.IsMarked()) 307 { 308 if (!pDoc->IsBlockEditable( aCursor.Tab(), aRange.aStart.Col(),aRange.aStart.Row(), 309 aRange.aEnd.Col(),aRange.aEnd.Row() )) 310 { 311 bDisable = sal_True; 312 } 313 bNeedEdit=sal_False; 314 } 315 316 } 317 break; 318 case SID_INSERT_POSTIT: 319 { 320 if ( pDocShell && pDocShell->IsDocShared() ) 321 { 322 bDisable = sal_True; 323 } 324 } 325 break; 326 } 327 if (!bDisable && bNeedEdit) 328 if (!pDoc->IsBlockEditable( aCursor.Tab(), aCursor.Col(),aCursor.Row(), 329 aCursor.Col(),aCursor.Row() )) 330 bDisable = sal_True; 331 if (bDisable) 332 rSet.DisableItem(nWhich); 333 nWhich = aIter.NextWhich(); 334 } 335 } 336 337 sal_Bool lcl_TestFormat( SvxClipboardFmtItem& rFormats, const TransferableDataHelper& rDataHelper, 338 SotFormatStringId nFormatId ) 339 { 340 if ( rDataHelper.HasFormat( nFormatId ) ) 341 { 342 // #90675# translated format name strings are no longer inserted here, 343 // handled by "paste special" dialog / toolbox controller instead. 344 // Only the object type name has to be set here: 345 String aStrVal; 346 if ( nFormatId == SOT_FORMATSTR_ID_EMBED_SOURCE ) 347 { 348 TransferableObjectDescriptor aDesc; 349 if ( ((TransferableDataHelper&)rDataHelper).GetTransferableObjectDescriptor( 350 SOT_FORMATSTR_ID_OBJECTDESCRIPTOR, aDesc ) ) 351 aStrVal = aDesc.maTypeName; 352 } 353 else if ( nFormatId == SOT_FORMATSTR_ID_EMBED_SOURCE_OLE 354 || nFormatId == SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE ) 355 { 356 String aSource; 357 SvPasteObjectHelper::GetEmbeddedName( rDataHelper, aStrVal, aSource, nFormatId ); 358 } 359 360 if ( aStrVal.Len() ) 361 rFormats.AddClipbrdFormat( nFormatId, aStrVal ); 362 else 363 rFormats.AddClipbrdFormat( nFormatId ); 364 365 return sal_True; 366 } 367 368 return sal_False; 369 } 370 371 void ScCellShell::GetPossibleClipboardFormats( SvxClipboardFmtItem& rFormats ) 372 { 373 Window* pWin = GetViewData()->GetActiveWin(); 374 sal_Bool bDraw = ( ScDrawTransferObj::GetOwnClipboard( pWin ) != NULL ); 375 376 TransferableDataHelper aDataHelper( TransferableDataHelper::CreateFromSystemClipboard( pWin ) ); 377 378 lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_DRAWING ); 379 lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_SVXB ); 380 lcl_TestFormat( rFormats, aDataHelper, SOT_FORMAT_GDIMETAFILE ); 381 lcl_TestFormat( rFormats, aDataHelper, SOT_FORMAT_BITMAP ); 382 lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_EMBED_SOURCE ); 383 384 if ( !bDraw ) 385 { 386 lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_LINK ); 387 lcl_TestFormat( rFormats, aDataHelper, SOT_FORMAT_STRING ); 388 lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_DIF ); 389 lcl_TestFormat( rFormats, aDataHelper, SOT_FORMAT_RTF ); 390 lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_HTML ); 391 lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_HTML_SIMPLE ); 392 lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_BIFF_8 ); 393 lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_BIFF_5 ); 394 } 395 396 if ( !lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_EMBED_SOURCE_OLE ) ) 397 lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE ); 398 } 399 400 // Einfuegen, Inhalte einfuegen 401 402 sal_Bool lcl_IsCellPastePossible( const TransferableDataHelper& rData ) 403 { 404 sal_Bool bPossible = sal_False; 405 if ( ScTransferObj::GetOwnClipboard( NULL ) || ScDrawTransferObj::GetOwnClipboard( NULL ) ) 406 bPossible = sal_True; 407 else 408 { 409 if ( rData.HasFormat( SOT_FORMAT_BITMAP ) || 410 rData.HasFormat( SOT_FORMAT_GDIMETAFILE ) || 411 rData.HasFormat( SOT_FORMATSTR_ID_SVXB ) || 412 rData.HasFormat( FORMAT_PRIVATE ) || 413 rData.HasFormat( SOT_FORMAT_RTF ) || 414 rData.HasFormat( SOT_FORMATSTR_ID_EMBED_SOURCE ) || 415 rData.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE ) || 416 rData.HasFormat( SOT_FORMATSTR_ID_EMBED_SOURCE_OLE ) || 417 rData.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE_OLE ) || 418 rData.HasFormat( SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE ) || 419 rData.HasFormat( SOT_FORMAT_STRING ) || 420 rData.HasFormat( SOT_FORMATSTR_ID_SYLK ) || 421 rData.HasFormat( SOT_FORMATSTR_ID_LINK ) || 422 rData.HasFormat( SOT_FORMATSTR_ID_HTML ) || 423 rData.HasFormat( SOT_FORMATSTR_ID_HTML_SIMPLE ) || 424 rData.HasFormat( SOT_FORMATSTR_ID_DIF ) ) 425 { 426 bPossible = sal_True; 427 } 428 } 429 return bPossible; 430 } 431 432 IMPL_LINK( ScCellShell, ClipboardChanged, TransferableDataHelper*, pDataHelper ) 433 { 434 if ( pDataHelper ) 435 { 436 bPastePossible = lcl_IsCellPastePossible( *pDataHelper ); 437 438 SfxBindings& rBindings = GetViewData()->GetBindings(); 439 rBindings.Invalidate( SID_PASTE ); 440 rBindings.Invalidate( SID_PASTE_SPECIAL ); 441 rBindings.Invalidate( SID_CLIPBOARD_FORMAT_ITEMS ); 442 } 443 return 0; 444 } 445 446 447 void __EXPORT ScCellShell::GetClipState( SfxItemSet& rSet ) 448 { 449 // SID_PASTE 450 // SID_PASTE_SPECIAL 451 // SID_CLIPBOARD_FORMAT_ITEMS 452 453 if ( !pImpl->m_pClipEvtLstnr ) 454 { 455 // create listener 456 pImpl->m_pClipEvtLstnr = new TransferableClipboardListener( LINK( this, ScCellShell, ClipboardChanged ) ); 457 pImpl->m_pClipEvtLstnr->acquire(); 458 Window* pWin = GetViewData()->GetActiveWin(); 459 pImpl->m_pClipEvtLstnr->AddRemoveListener( pWin, sal_True ); 460 461 // get initial state 462 TransferableDataHelper aDataHelper( TransferableDataHelper::CreateFromSystemClipboard( pWin ) ); 463 bPastePossible = lcl_IsCellPastePossible( aDataHelper ); 464 } 465 466 sal_Bool bDisable = !bPastePossible; 467 468 // Zellschutz / Multiselektion 469 470 if (!bDisable) 471 { 472 SCCOL nCol = GetViewData()->GetCurX(); 473 SCROW nRow = GetViewData()->GetCurY(); 474 SCTAB nTab = GetViewData()->GetTabNo(); 475 ScDocument* pDoc = GetViewData()->GetDocShell()->GetDocument(); 476 if (!pDoc->IsBlockEditable( nTab, nCol,nRow, nCol,nRow )) 477 bDisable = sal_True; 478 ScRange aDummy; 479 ScMarkType eMarkType = GetViewData()->GetSimpleArea( aDummy); 480 if (eMarkType != SC_MARK_SIMPLE && eMarkType != SC_MARK_SIMPLE_FILTERED) 481 bDisable = sal_True; 482 } 483 484 if (bDisable) 485 { 486 rSet.DisableItem( SID_PASTE ); 487 rSet.DisableItem( SID_PASTE_SPECIAL ); 488 rSet.DisableItem( SID_CLIPBOARD_FORMAT_ITEMS ); 489 } 490 else if ( rSet.GetItemState( SID_CLIPBOARD_FORMAT_ITEMS ) != SFX_ITEM_UNKNOWN ) 491 { 492 SvxClipboardFmtItem aFormats( SID_CLIPBOARD_FORMAT_ITEMS ); 493 GetPossibleClipboardFormats( aFormats ); 494 rSet.Put( aFormats ); 495 } 496 } 497 498 // only SID_HYPERLINK_GETLINK: 499 500 void ScCellShell::GetHLinkState( SfxItemSet& rSet ) 501 { 502 // always return an item (or inserting will be disabled) 503 // if the cell at the cursor contains only a link, return that link 504 505 SvxHyperlinkItem aHLinkItem; 506 if ( !GetViewData()->GetView()->HasBookmarkAtCursor( &aHLinkItem ) ) 507 { 508 //! put selected text into item? 509 } 510 511 rSet.Put(aHLinkItem); 512 } 513 514 void ScCellShell::GetState(SfxItemSet &rSet) 515 { 516 // removed: SID_BORDER_OBJECT (old Basic) 517 518 ScTabViewShell* pTabViewShell = GetViewData()->GetViewShell(); 519 // sal_Bool bOle = pTabViewShell->GetViewFrame()->GetFrame().IsInPlace(); 520 // sal_Bool bTabProt = GetViewData()->GetDocument()->IsTabProtected(GetViewData()->GetTabNo()); 521 ScDocShell* pDocSh = GetViewData()->GetDocShell(); 522 ScViewData* pData = GetViewData(); 523 ScDocument* pDoc = pData->GetDocument(); 524 ScMarkData& rMark = pData->GetMarkData(); 525 SCCOL nPosX = pData->GetCurX(); 526 SCROW nPosY = pData->GetCurY(); 527 SCTAB nTab = pData->GetTabNo(); 528 529 SCTAB nTabCount = pDoc->GetTableCount(); 530 SCTAB nTabSelCount = rMark.GetSelectCount(); 531 532 533 534 SfxWhichIter aIter(rSet); 535 sal_uInt16 nWhich = aIter.FirstWhich(); 536 while ( nWhich ) 537 { 538 switch ( nWhich ) 539 { 540 case SID_DETECTIVE_REFRESH: 541 if (!pDoc->HasDetectiveOperations()) 542 rSet.DisableItem( nWhich ); 543 break; 544 545 case SID_RANGE_ADDRESS: 546 { 547 ScRange aRange; 548 if ( pData->GetSimpleArea( aRange ) == SC_MARK_SIMPLE ) 549 { 550 String aStr; 551 sal_uInt16 nFlags = SCA_VALID | SCA_TAB_3D; 552 aRange.Format(aStr,nFlags,pDoc); 553 rSet.Put( SfxStringItem( nWhich, aStr ) ); 554 } 555 } 556 break; 557 558 case SID_RANGE_NOTETEXT: 559 { 560 // #43343# always take cursor position, do not use top-left cell of selection 561 ScAddress aPos( nPosX, nPosY, nTab ); 562 String aNoteText; 563 if ( const ScPostIt* pNote = pDoc->GetNote( aPos ) ) 564 aNoteText = pNote->GetText(); 565 rSet.Put( SfxStringItem( nWhich, aNoteText ) ); 566 } 567 break; 568 569 case SID_RANGE_ROW: 570 rSet.Put( SfxInt32Item( nWhich, nPosY+1 ) ); 571 break; 572 573 case SID_RANGE_COL: 574 rSet.Put( SfxInt16Item( nWhich, nPosX+1 ) ); 575 break; 576 577 case SID_RANGE_TABLE: 578 rSet.Put( SfxInt16Item( nWhich, nTab+1 ) ); 579 break; 580 581 case SID_RANGE_VALUE: 582 { 583 double nValue; 584 pDoc->GetValue( nPosX, nPosY, nTab, nValue ); 585 rSet.Put( ScDoubleItem( nWhich, nValue ) ); 586 } 587 break; 588 589 case SID_RANGE_FORMULA: 590 { 591 String aString; 592 pDoc->GetFormula( nPosX, nPosY, nTab, aString ); 593 if( aString.Len() == 0 ) 594 { 595 pDoc->GetInputString( nPosX, nPosY, nTab, aString ); 596 } 597 rSet.Put( SfxStringItem( nWhich, aString ) ); 598 } 599 break; 600 601 case SID_RANGE_TEXTVALUE: 602 { 603 String aString; 604 pDoc->GetString( nPosX, nPosY, nTab, aString ); 605 rSet.Put( SfxStringItem( nWhich, aString ) ); 606 } 607 break; 608 609 case SID_STATUS_SELMODE: 610 { 611 /* 0: STD Click hebt Sel auf 612 * 1: ER Click erweitert Selektion 613 * 2: ERG Click definiert weitere Selektion 614 */ 615 sal_uInt16 nMode = pTabViewShell->GetLockedModifiers(); 616 617 switch ( nMode ) 618 { 619 case KEY_SHIFT: nMode = 1; break; 620 case KEY_MOD1: nMode = 2; break; // Control-Taste 621 case 0: 622 default: 623 nMode = 0; 624 } 625 626 rSet.Put( SfxUInt16Item( nWhich, nMode ) ); 627 } 628 break; 629 630 case SID_STATUS_DOCPOS: 631 { 632 String aStr( ScGlobal::GetRscString( STR_TABLE ) ); 633 634 aStr += ' '; 635 aStr += String::CreateFromInt32( nTab + 1 ); 636 aStr.AppendAscii(RTL_CONSTASCII_STRINGPARAM( " / " )); 637 aStr += String::CreateFromInt32( nTabCount ); 638 rSet.Put( SfxStringItem( nWhich, aStr ) ); 639 } 640 break; 641 642 // Summe etc. mit Datum/Zeit/Fehler/Pos&Groesse zusammengefasst 643 644 // #i34458# The SfxStringItem belongs only into SID_TABLE_CELL. It no longer has to be 645 // duplicated in SID_ATTR_POSITION or SID_ATTR_SIZE for SvxPosSizeStatusBarControl. 646 case SID_TABLE_CELL: 647 { 648 // Testen, ob Fehler unter Cursor 649 // (nicht pDoc->GetErrCode, um keine zirkulaeren Referenzen auszuloesen) 650 651 // In interpreter may happen via rescheduled Basic 652 if ( pDoc->IsInInterpreter() ) 653 rSet.Put( SfxStringItem( nWhich, 654 String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("...")) ) ); 655 else 656 { 657 sal_uInt16 nErrCode = 0; 658 ScBaseCell* pCell; 659 pDoc->GetCell( nPosX, nPosY, nTab, pCell ); 660 if ( pCell && pCell->GetCellType() == CELLTYPE_FORMULA ) 661 { 662 ScFormulaCell* pFCell = (ScFormulaCell*) pCell; 663 if (!pFCell->IsRunning()) 664 nErrCode = pFCell->GetErrCode(); 665 } 666 667 String aFuncStr; 668 if ( pTabViewShell->GetFunction( aFuncStr, nErrCode ) ) 669 rSet.Put( SfxStringItem( nWhich, aFuncStr ) ); 670 } 671 } 672 break; 673 674 case SID_DATA_SELECT: 675 // HasSelectionData includes column content and validity, 676 // page fields have to be checked separately. 677 if ( !pDoc->HasSelectionData( nPosX, nPosY, nTab ) && 678 !pTabViewShell->HasPageFieldDataAtCursor() ) 679 rSet.DisableItem( nWhich ); 680 break; 681 682 case SID_STATUS_SUM: 683 { 684 String aFuncStr; 685 if ( pTabViewShell->GetFunction( aFuncStr ) ) 686 rSet.Put( SfxStringItem( nWhich, aFuncStr ) ); 687 } 688 break; 689 690 case FID_MERGE_ON: 691 if ( pDoc->GetChangeTrack() || !pTabViewShell->TestMergeCells() ) 692 rSet.DisableItem( nWhich ); 693 break; 694 695 case FID_MERGE_OFF: 696 if ( pDoc->GetChangeTrack() || !pTabViewShell->TestRemoveMerge() ) 697 rSet.DisableItem( nWhich ); 698 break; 699 700 case FID_MERGE_TOGGLE: 701 if ( pDoc->GetChangeTrack() ) 702 rSet.DisableItem( nWhich ); 703 else 704 { 705 bool bCanMerge = pTabViewShell->TestMergeCells(); 706 bool bCanSplit = pTabViewShell->TestRemoveMerge(); 707 if( !bCanMerge && !bCanSplit ) 708 rSet.DisableItem( nWhich ); 709 else 710 rSet.Put( SfxBoolItem( nWhich, bCanSplit ) ); 711 } 712 break; 713 714 case FID_INS_ROWBRK: 715 if ( nPosY==0 || (pDoc->HasRowBreak(nPosY, nTab) & BREAK_MANUAL) ) 716 rSet.DisableItem( nWhich ); 717 break; 718 719 case FID_INS_COLBRK: 720 if ( nPosX==0 || (pDoc->HasColBreak(nPosX, nTab) & BREAK_MANUAL) ) 721 rSet.DisableItem( nWhich ); 722 break; 723 724 case FID_DEL_ROWBRK: 725 if ( nPosY==0 || (pDoc->HasRowBreak(nPosY, nTab) & BREAK_MANUAL) == 0 ) 726 rSet.DisableItem( nWhich ); 727 break; 728 729 case FID_DEL_COLBRK: 730 if ( nPosX==0 || (pDoc->HasColBreak(nPosX, nTab) & BREAK_MANUAL) == 0 ) 731 rSet.DisableItem( nWhich ); 732 break; 733 734 case FID_FILL_TAB: 735 if ( nTabSelCount < 2 ) 736 rSet.DisableItem( nWhich ); 737 break; 738 739 case SID_SELECT_SCENARIO: 740 { 741 // ScDocument* pDoc = GetViewData()->GetDocument(); 742 // SCTAB nTab = GetViewData()->GetTabNo(); 743 List aList; 744 745 Color aDummyCol; 746 747 if ( !pDoc->IsScenario(nTab) ) 748 { 749 String aStr; 750 sal_uInt16 nFlags; 751 SCTAB nScTab = nTab + 1; 752 String aProtect; 753 bool bSheetProtected = pDoc->IsTabProtected(nTab); 754 755 while ( pDoc->IsScenario(nScTab) ) 756 { 757 pDoc->GetName( nScTab, aStr ); 758 aList.Insert( new String( aStr ), LIST_APPEND ); 759 pDoc->GetScenarioData( nScTab, aStr, aDummyCol, nFlags ); 760 aList.Insert( new String( aStr ), LIST_APPEND ); 761 // Protection is sal_True if both Sheet and Scenario are protected 762 aProtect = (bSheetProtected && (nFlags & SC_SCENARIO_PROTECT)) ? '1' : '0'; 763 aList.Insert( new String( aProtect), LIST_APPEND ); 764 ++nScTab; 765 } 766 } 767 else 768 { 769 String aComment; 770 sal_uInt16 nDummyFlags; 771 pDoc->GetScenarioData( nTab, aComment, aDummyCol, nDummyFlags ); 772 DBG_ASSERT( aList.Count() == 0, "List not empty!" ); 773 aList.Insert( new String( aComment ) ); 774 } 775 776 rSet.Put( SfxStringListItem( nWhich, &aList ) ); 777 778 sal_uLong nCount = aList.Count(); 779 for ( sal_uLong i=0; i<nCount; i++ ) 780 delete (String*) aList.GetObject(i); 781 } 782 break; 783 784 case FID_ROW_HIDE: 785 case FID_ROW_SHOW: 786 case FID_COL_HIDE: 787 case FID_COL_SHOW: 788 case FID_COL_OPT_WIDTH: 789 case FID_ROW_OPT_HEIGHT: 790 case FID_DELETE_CELL: 791 if ( pDoc->IsTabProtected(nTab) || pDocSh->IsReadOnly()) 792 rSet.DisableItem( nWhich ); 793 break; 794 795 /* Zellschutz bei selektierten Zellen wird bei anderen Funktionen auch nicht abgefragt... 796 case SID_DELETE: 797 { 798 if ( pDoc->IsTabProtected(nTab) ) 799 { 800 const SfxItemSet& rAttrSet = GetSelectionPattern()->GetItemSet(); 801 const ScProtectionAttr& rProtAttr = (const ScProtectionAttr&)rAttrSet.Get( ATTR_PROTECTION, sal_True ); 802 if ( rProtAttr.GetProtection() ) 803 rSet.DisableItem( nWhich ); 804 } 805 } 806 break; 807 */ 808 case SID_OUTLINE_MAKE: 809 { 810 if ( GetViewData()->GetDocument()->GetDPAtCursor( GetViewData()->GetCurX(), 811 GetViewData()->GetCurY(), GetViewData()->GetTabNo() ) ) 812 { 813 //! test for data pilot operation 814 } 815 else if (pDoc->GetChangeTrack()!=NULL || GetViewData()->IsMultiMarked()) 816 { 817 rSet.DisableItem( nWhich ); 818 } 819 } 820 break; 821 case SID_OUTLINE_SHOW: 822 if ( GetViewData()->GetDocument()->GetDPAtCursor( GetViewData()->GetCurX(), 823 GetViewData()->GetCurY(), GetViewData()->GetTabNo() ) ) 824 { 825 //! test for data pilot operation 826 } 827 else if (!pTabViewShell->OutlinePossible(sal_False)) 828 rSet.DisableItem( nWhich ); 829 break; 830 831 case SID_OUTLINE_HIDE: 832 if ( GetViewData()->GetDocument()->GetDPAtCursor( GetViewData()->GetCurX(), 833 GetViewData()->GetCurY(), GetViewData()->GetTabNo() ) ) 834 { 835 //! test for data pilot operation 836 } 837 else if (!pTabViewShell->OutlinePossible(sal_True)) 838 rSet.DisableItem( nWhich ); 839 break; 840 841 case SID_OUTLINE_REMOVE: 842 { 843 if ( GetViewData()->GetDocument()->GetDPAtCursor( GetViewData()->GetCurX(), 844 GetViewData()->GetCurY(), GetViewData()->GetTabNo() ) ) 845 { 846 //! test for data pilot operation 847 } 848 else 849 { 850 sal_Bool bCol, bRow; 851 pTabViewShell->TestRemoveOutline( bCol, bRow ); 852 if ( !bCol && !bRow ) 853 rSet.DisableItem( nWhich ); 854 } 855 } 856 break; 857 858 case FID_COL_WIDTH: 859 { 860 //GetViewData()->GetCurX(); 861 SfxUInt16Item aWidthItem( FID_COL_WIDTH, pDoc->GetColWidth( nPosX , nTab) ); 862 rSet.Put( aWidthItem ); 863 if ( pDocSh->IsReadOnly()) 864 rSet.DisableItem( nWhich ); 865 866 //XXX Disablen wenn nicht eindeutig 867 } 868 break; 869 870 case FID_ROW_HEIGHT: 871 { 872 //GetViewData()->GetCurY(); 873 SfxUInt16Item aHeightItem( FID_ROW_HEIGHT, pDoc->GetRowHeight( nPosY , nTab) ); 874 rSet.Put( aHeightItem ); 875 //XXX Disablen wenn nicht eindeutig 876 if ( pDocSh->IsReadOnly()) 877 rSet.DisableItem( nWhich ); 878 } 879 break; 880 881 case SID_DETECTIVE_FILLMODE: 882 rSet.Put(SfxBoolItem( nWhich, pTabViewShell->IsAuditShell() )); 883 break; 884 885 case FID_INPUTLINE_STATUS: 886 DBG_ERROR( "Old update method. Use ScTabViewShell::UpdateInputHandler()." ); 887 break; 888 889 case SID_SCENARIOS: // Szenarios: 890 if (!(rMark.IsMarked() || rMark.IsMultiMarked())) // nur, wenn etwas selektiert 891 rSet.DisableItem( nWhich ); 892 break; 893 894 case FID_NOTE_VISIBLE: 895 { 896 const ScPostIt* pNote = pDoc->GetNote( ScAddress( nPosX, nPosY, nTab ) ); 897 if ( pNote && pDoc->IsBlockEditable( nTab, nPosX,nPosY, nPosX,nPosY ) ) 898 rSet.Put( SfxBoolItem( nWhich, pNote->IsCaptionShown() ) ); 899 else 900 rSet.DisableItem( nWhich ); 901 } 902 break; 903 904 case SID_DELETE_NOTE: 905 { 906 sal_Bool bEnable = sal_False; 907 if ( rMark.IsMarked() || rMark.IsMultiMarked() ) 908 { 909 if ( pDoc->IsSelectionEditable( rMark ) ) 910 { 911 // look for at least one note in selection 912 ScRangeList aRanges; 913 rMark.FillRangeListWithMarks( &aRanges, sal_False ); 914 sal_uLong nCount = aRanges.Count(); 915 for (sal_uLong nPos=0; nPos<nCount && !bEnable; nPos++) 916 { 917 ScCellIterator aCellIter( pDoc, *aRanges.GetObject(nPos) ); 918 for( ScBaseCell* pCell = aCellIter.GetFirst(); pCell && !bEnable; pCell = aCellIter.GetNext() ) 919 if ( pCell->HasNote() ) 920 bEnable = sal_True; // note found 921 } 922 } 923 } 924 else 925 { 926 bEnable = pDoc->IsBlockEditable( nTab, nPosX,nPosY, nPosX,nPosY ) && 927 pDoc->GetNote( ScAddress( nPosX, nPosY, nTab ) ); 928 } 929 if ( !bEnable ) 930 rSet.DisableItem( nWhich ); 931 } 932 break; 933 934 case SID_OPENDLG_CONSOLIDATE: 935 case SCITEM_CONSOLIDATEDATA: 936 { 937 if(pDoc->GetChangeTrack()!=NULL) 938 rSet.DisableItem( nWhich); 939 } 940 break; 941 942 case SID_CHINESE_CONVERSION: 943 case SID_HANGUL_HANJA_CONVERSION: 944 ScViewUtil::HideDisabledSlot( rSet, pData->GetBindings(), nWhich ); 945 break; 946 947 case FID_USE_NAME: 948 { 949 if ( pDocSh && pDocSh->IsDocShared() ) 950 rSet.DisableItem( nWhich ); 951 else 952 { 953 ScRange aRange; 954 if ( pData->GetSimpleArea( aRange ) != SC_MARK_SIMPLE ) 955 rSet.DisableItem( nWhich ); 956 } 957 } 958 break; 959 960 case FID_DEFINE_NAME: 961 case FID_INSERT_NAME: 962 case SID_DEFINE_COLROWNAMERANGES: 963 { 964 if ( pDocSh && pDocSh->IsDocShared() ) 965 { 966 rSet.DisableItem( nWhich ); 967 } 968 } 969 break; 970 971 case SID_SPELL_DIALOG: 972 { 973 if ( pDoc && pData && pDoc->IsTabProtected( pData->GetTabNo() ) ) 974 { 975 bool bVisible = false; 976 SfxViewFrame* pViewFrame = ( pTabViewShell ? pTabViewShell->GetViewFrame() : NULL ); 977 if ( pViewFrame && pViewFrame->HasChildWindow( nWhich ) ) 978 { 979 SfxChildWindow* pChild = pViewFrame->GetChildWindow( nWhich ); 980 Window* pWin = ( pChild ? pChild->GetWindow() : NULL ); 981 if ( pWin && pWin->IsVisible() ) 982 { 983 bVisible = true; 984 } 985 } 986 if ( !bVisible ) 987 { 988 rSet.DisableItem( nWhich ); 989 } 990 } 991 } 992 break; 993 994 } // switch ( nWitch ) 995 nWhich = aIter.NextWhich(); 996 } // while ( nWitch ) 997 } 998 999 //------------------------------------------------------------------ 1000 1001 1002 1003