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