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_FORMAT_BITMAP ); 381 lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_EMBED_SOURCE ); 382 383 if ( !bDraw ) 384 { 385 lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_LINK ); 386 lcl_TestFormat( rFormats, aDataHelper, SOT_FORMAT_STRING ); 387 lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_DIF ); 388 lcl_TestFormat( rFormats, aDataHelper, SOT_FORMAT_RTF ); 389 lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_HTML ); 390 lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_HTML_SIMPLE ); 391 lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_BIFF_8 ); 392 lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_BIFF_5 ); 393 } 394 395 if ( !lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_EMBED_SOURCE_OLE ) ) 396 lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE ); 397 } 398 399 // Einfuegen, Inhalte einfuegen 400 401 sal_Bool lcl_IsCellPastePossible( const TransferableDataHelper& rData ) 402 { 403 sal_Bool bPossible = sal_False; 404 if ( ScTransferObj::GetOwnClipboard( NULL ) || ScDrawTransferObj::GetOwnClipboard( NULL ) ) 405 bPossible = sal_True; 406 else 407 { 408 if ( rData.HasFormat( SOT_FORMAT_BITMAP ) || 409 rData.HasFormat( SOT_FORMAT_GDIMETAFILE ) || 410 rData.HasFormat( SOT_FORMATSTR_ID_SVXB ) || 411 rData.HasFormat( FORMAT_PRIVATE ) || 412 rData.HasFormat( SOT_FORMAT_RTF ) || 413 rData.HasFormat( SOT_FORMATSTR_ID_EMBED_SOURCE ) || 414 rData.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE ) || 415 rData.HasFormat( SOT_FORMATSTR_ID_EMBED_SOURCE_OLE ) || 416 rData.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE_OLE ) || 417 rData.HasFormat( SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE ) || 418 rData.HasFormat( SOT_FORMAT_STRING ) || 419 rData.HasFormat( SOT_FORMATSTR_ID_SYLK ) || 420 rData.HasFormat( SOT_FORMATSTR_ID_LINK ) || 421 rData.HasFormat( SOT_FORMATSTR_ID_HTML ) || 422 rData.HasFormat( SOT_FORMATSTR_ID_HTML_SIMPLE ) || 423 rData.HasFormat( SOT_FORMATSTR_ID_DIF ) ) 424 { 425 bPossible = sal_True; 426 } 427 } 428 return bPossible; 429 } 430 431 IMPL_LINK( ScCellShell, ClipboardChanged, TransferableDataHelper*, pDataHelper ) 432 { 433 if ( pDataHelper ) 434 { 435 bPastePossible = lcl_IsCellPastePossible( *pDataHelper ); 436 437 SfxBindings& rBindings = GetViewData()->GetBindings(); 438 rBindings.Invalidate( SID_PASTE ); 439 rBindings.Invalidate( SID_PASTE_SPECIAL ); 440 rBindings.Invalidate( SID_CLIPBOARD_FORMAT_ITEMS ); 441 } 442 return 0; 443 } 444 445 446 void __EXPORT ScCellShell::GetClipState( SfxItemSet& rSet ) 447 { 448 // SID_PASTE 449 // SID_PASTE_SPECIAL 450 // SID_CLIPBOARD_FORMAT_ITEMS 451 452 if ( !pImpl->m_pClipEvtLstnr ) 453 { 454 // create listener 455 pImpl->m_pClipEvtLstnr = new TransferableClipboardListener( LINK( this, ScCellShell, ClipboardChanged ) ); 456 pImpl->m_pClipEvtLstnr->acquire(); 457 Window* pWin = GetViewData()->GetActiveWin(); 458 pImpl->m_pClipEvtLstnr->AddRemoveListener( pWin, sal_True ); 459 460 // get initial state 461 TransferableDataHelper aDataHelper( TransferableDataHelper::CreateFromSystemClipboard( pWin ) ); 462 bPastePossible = lcl_IsCellPastePossible( aDataHelper ); 463 } 464 465 sal_Bool bDisable = !bPastePossible; 466 467 // Zellschutz / Multiselektion 468 469 if (!bDisable) 470 { 471 SCCOL nCol = GetViewData()->GetCurX(); 472 SCROW nRow = GetViewData()->GetCurY(); 473 SCTAB nTab = GetViewData()->GetTabNo(); 474 ScDocument* pDoc = GetViewData()->GetDocShell()->GetDocument(); 475 if (!pDoc->IsBlockEditable( nTab, nCol,nRow, nCol,nRow )) 476 bDisable = sal_True; 477 ScRange aDummy; 478 ScMarkType eMarkType = GetViewData()->GetSimpleArea( aDummy); 479 if (eMarkType != SC_MARK_SIMPLE && eMarkType != SC_MARK_SIMPLE_FILTERED) 480 bDisable = sal_True; 481 } 482 483 if (bDisable) 484 { 485 rSet.DisableItem( SID_PASTE ); 486 rSet.DisableItem( SID_PASTE_SPECIAL ); 487 rSet.DisableItem( SID_CLIPBOARD_FORMAT_ITEMS ); 488 } 489 else if ( rSet.GetItemState( SID_CLIPBOARD_FORMAT_ITEMS ) != SFX_ITEM_UNKNOWN ) 490 { 491 SvxClipboardFmtItem aFormats( SID_CLIPBOARD_FORMAT_ITEMS ); 492 GetPossibleClipboardFormats( aFormats ); 493 rSet.Put( aFormats ); 494 } 495 } 496 497 // only SID_HYPERLINK_GETLINK: 498 499 void ScCellShell::GetHLinkState( SfxItemSet& rSet ) 500 { 501 // always return an item (or inserting will be disabled) 502 // if the cell at the cursor contains only a link, return that link 503 504 SvxHyperlinkItem aHLinkItem; 505 if ( !GetViewData()->GetView()->HasBookmarkAtCursor( &aHLinkItem ) ) 506 { 507 //! put selected text into item? 508 } 509 510 rSet.Put(aHLinkItem); 511 } 512 513 void ScCellShell::GetState(SfxItemSet &rSet) 514 { 515 // removed: SID_BORDER_OBJECT (old Basic) 516 517 ScTabViewShell* pTabViewShell = GetViewData()->GetViewShell(); 518 // sal_Bool bOle = pTabViewShell->GetViewFrame()->GetFrame().IsInPlace(); 519 // sal_Bool bTabProt = GetViewData()->GetDocument()->IsTabProtected(GetViewData()->GetTabNo()); 520 ScDocShell* pDocSh = GetViewData()->GetDocShell(); 521 ScViewData* pData = GetViewData(); 522 ScDocument* pDoc = pData->GetDocument(); 523 ScMarkData& rMark = pData->GetMarkData(); 524 SCCOL nPosX = pData->GetCurX(); 525 SCROW nPosY = pData->GetCurY(); 526 SCTAB nTab = pData->GetTabNo(); 527 528 SCTAB nTabCount = pDoc->GetTableCount(); 529 SCTAB nTabSelCount = rMark.GetSelectCount(); 530 531 532 533 SfxWhichIter aIter(rSet); 534 sal_uInt16 nWhich = aIter.FirstWhich(); 535 while ( nWhich ) 536 { 537 switch ( nWhich ) 538 { 539 case SID_DETECTIVE_REFRESH: 540 if (!pDoc->HasDetectiveOperations()) 541 rSet.DisableItem( nWhich ); 542 break; 543 544 case SID_RANGE_ADDRESS: 545 { 546 ScRange aRange; 547 if ( pData->GetSimpleArea( aRange ) == SC_MARK_SIMPLE ) 548 { 549 String aStr; 550 sal_uInt16 nFlags = SCA_VALID | SCA_TAB_3D; 551 aRange.Format(aStr,nFlags,pDoc); 552 rSet.Put( SfxStringItem( nWhich, aStr ) ); 553 } 554 } 555 break; 556 557 case SID_RANGE_NOTETEXT: 558 { 559 // #43343# always take cursor position, do not use top-left cell of selection 560 ScAddress aPos( nPosX, nPosY, nTab ); 561 String aNoteText; 562 if ( const ScPostIt* pNote = pDoc->GetNote( aPos ) ) 563 aNoteText = pNote->GetText(); 564 rSet.Put( SfxStringItem( nWhich, aNoteText ) ); 565 } 566 break; 567 568 case SID_RANGE_ROW: 569 rSet.Put( SfxInt32Item( nWhich, nPosY+1 ) ); 570 break; 571 572 case SID_RANGE_COL: 573 rSet.Put( SfxInt16Item( nWhich, nPosX+1 ) ); 574 break; 575 576 case SID_RANGE_TABLE: 577 rSet.Put( SfxInt16Item( nWhich, nTab+1 ) ); 578 break; 579 580 case SID_RANGE_VALUE: 581 { 582 double nValue; 583 pDoc->GetValue( nPosX, nPosY, nTab, nValue ); 584 rSet.Put( ScDoubleItem( nWhich, nValue ) ); 585 } 586 break; 587 588 case SID_RANGE_FORMULA: 589 { 590 String aString; 591 pDoc->GetFormula( nPosX, nPosY, nTab, aString ); 592 if( aString.Len() == 0 ) 593 { 594 pDoc->GetInputString( nPosX, nPosY, nTab, aString ); 595 } 596 rSet.Put( SfxStringItem( nWhich, aString ) ); 597 } 598 break; 599 600 case SID_RANGE_TEXTVALUE: 601 { 602 String aString; 603 pDoc->GetString( nPosX, nPosY, nTab, aString ); 604 rSet.Put( SfxStringItem( nWhich, aString ) ); 605 } 606 break; 607 608 case SID_STATUS_SELMODE: 609 { 610 /* 0: STD Click hebt Sel auf 611 * 1: ER Click erweitert Selektion 612 * 2: ERG Click definiert weitere Selektion 613 */ 614 sal_uInt16 nMode = pTabViewShell->GetLockedModifiers(); 615 616 switch ( nMode ) 617 { 618 case KEY_SHIFT: nMode = 1; break; 619 case KEY_MOD1: nMode = 2; break; // Control-Taste 620 case 0: 621 default: 622 nMode = 0; 623 } 624 625 rSet.Put( SfxUInt16Item( nWhich, nMode ) ); 626 } 627 break; 628 629 case SID_STATUS_DOCPOS: 630 { 631 String aStr( ScGlobal::GetRscString( STR_TABLE ) ); 632 633 aStr += ' '; 634 aStr += String::CreateFromInt32( nTab + 1 ); 635 aStr.AppendAscii(RTL_CONSTASCII_STRINGPARAM( " / " )); 636 aStr += String::CreateFromInt32( nTabCount ); 637 rSet.Put( SfxStringItem( nWhich, aStr ) ); 638 } 639 break; 640 641 // Summe etc. mit Datum/Zeit/Fehler/Pos&Groesse zusammengefasst 642 643 // #i34458# The SfxStringItem belongs only into SID_TABLE_CELL. It no longer has to be 644 // duplicated in SID_ATTR_POSITION or SID_ATTR_SIZE for SvxPosSizeStatusBarControl. 645 case SID_TABLE_CELL: 646 { 647 // Testen, ob Fehler unter Cursor 648 // (nicht pDoc->GetErrCode, um keine zirkulaeren Referenzen auszuloesen) 649 650 // In interpreter may happen via rescheduled Basic 651 if ( pDoc->IsInInterpreter() ) 652 rSet.Put( SfxStringItem( nWhich, 653 String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("...")) ) ); 654 else 655 { 656 sal_uInt16 nErrCode = 0; 657 ScBaseCell* pCell; 658 pDoc->GetCell( nPosX, nPosY, nTab, pCell ); 659 if ( pCell && pCell->GetCellType() == CELLTYPE_FORMULA ) 660 { 661 ScFormulaCell* pFCell = (ScFormulaCell*) pCell; 662 if (!pFCell->IsRunning()) 663 nErrCode = pFCell->GetErrCode(); 664 } 665 666 String aFuncStr; 667 if ( pTabViewShell->GetFunction( aFuncStr, nErrCode ) ) 668 rSet.Put( SfxStringItem( nWhich, aFuncStr ) ); 669 } 670 } 671 break; 672 673 case SID_DATA_SELECT: 674 // HasSelectionData includes column content and validity, 675 // page fields have to be checked separately. 676 if ( !pDoc->HasSelectionData( nPosX, nPosY, nTab ) && 677 !pTabViewShell->HasPageFieldDataAtCursor() ) 678 rSet.DisableItem( nWhich ); 679 break; 680 681 case SID_STATUS_SUM: 682 { 683 String aFuncStr; 684 if ( pTabViewShell->GetFunction( aFuncStr ) ) 685 rSet.Put( SfxStringItem( nWhich, aFuncStr ) ); 686 } 687 break; 688 689 case FID_MERGE_ON: 690 if ( pDoc->GetChangeTrack() || !pTabViewShell->TestMergeCells() ) 691 rSet.DisableItem( nWhich ); 692 break; 693 694 case FID_MERGE_OFF: 695 if ( pDoc->GetChangeTrack() || !pTabViewShell->TestRemoveMerge() ) 696 rSet.DisableItem( nWhich ); 697 break; 698 699 case FID_MERGE_TOGGLE: 700 if ( pDoc->GetChangeTrack() ) 701 rSet.DisableItem( nWhich ); 702 else 703 { 704 bool bCanMerge = pTabViewShell->TestMergeCells(); 705 bool bCanSplit = pTabViewShell->TestRemoveMerge(); 706 if( !bCanMerge && !bCanSplit ) 707 rSet.DisableItem( nWhich ); 708 else 709 rSet.Put( SfxBoolItem( nWhich, bCanSplit ) ); 710 } 711 break; 712 713 case FID_INS_ROWBRK: 714 if ( nPosY==0 || (pDoc->HasRowBreak(nPosY, nTab) & BREAK_MANUAL) ) 715 rSet.DisableItem( nWhich ); 716 break; 717 718 case FID_INS_COLBRK: 719 if ( nPosX==0 || (pDoc->HasColBreak(nPosX, nTab) & BREAK_MANUAL) ) 720 rSet.DisableItem( nWhich ); 721 break; 722 723 case FID_DEL_ROWBRK: 724 if ( nPosY==0 || (pDoc->HasRowBreak(nPosY, nTab) & BREAK_MANUAL) == 0 ) 725 rSet.DisableItem( nWhich ); 726 break; 727 728 case FID_DEL_COLBRK: 729 if ( nPosX==0 || (pDoc->HasColBreak(nPosX, nTab) & BREAK_MANUAL) == 0 ) 730 rSet.DisableItem( nWhich ); 731 break; 732 733 case FID_FILL_TAB: 734 if ( nTabSelCount < 2 ) 735 rSet.DisableItem( nWhich ); 736 break; 737 738 case SID_SELECT_SCENARIO: 739 { 740 // ScDocument* pDoc = GetViewData()->GetDocument(); 741 // SCTAB nTab = GetViewData()->GetTabNo(); 742 List aList; 743 744 Color aDummyCol; 745 746 if ( !pDoc->IsScenario(nTab) ) 747 { 748 String aStr; 749 sal_uInt16 nFlags; 750 SCTAB nScTab = nTab + 1; 751 String aProtect; 752 bool bSheetProtected = pDoc->IsTabProtected(nTab); 753 754 while ( pDoc->IsScenario(nScTab) ) 755 { 756 pDoc->GetName( nScTab, aStr ); 757 aList.Insert( new String( aStr ), LIST_APPEND ); 758 pDoc->GetScenarioData( nScTab, aStr, aDummyCol, nFlags ); 759 aList.Insert( new String( aStr ), LIST_APPEND ); 760 // Protection is sal_True if both Sheet and Scenario are protected 761 aProtect = (bSheetProtected && (nFlags & SC_SCENARIO_PROTECT)) ? '1' : '0'; 762 aList.Insert( new String( aProtect), LIST_APPEND ); 763 ++nScTab; 764 } 765 } 766 else 767 { 768 String aComment; 769 sal_uInt16 nDummyFlags; 770 pDoc->GetScenarioData( nTab, aComment, aDummyCol, nDummyFlags ); 771 DBG_ASSERT( aList.Count() == 0, "List not empty!" ); 772 aList.Insert( new String( aComment ) ); 773 } 774 775 rSet.Put( SfxStringListItem( nWhich, &aList ) ); 776 777 sal_uLong nCount = aList.Count(); 778 for ( sal_uLong i=0; i<nCount; i++ ) 779 delete (String*) aList.GetObject(i); 780 } 781 break; 782 783 case FID_ROW_HIDE: 784 case FID_ROW_SHOW: 785 case FID_COL_HIDE: 786 case FID_COL_SHOW: 787 case FID_COL_OPT_WIDTH: 788 case FID_ROW_OPT_HEIGHT: 789 case FID_DELETE_CELL: 790 if ( pDoc->IsTabProtected(nTab) || pDocSh->IsReadOnly()) 791 rSet.DisableItem( nWhich ); 792 break; 793 794 /* Zellschutz bei selektierten Zellen wird bei anderen Funktionen auch nicht abgefragt... 795 case SID_DELETE: 796 { 797 if ( pDoc->IsTabProtected(nTab) ) 798 { 799 const SfxItemSet& rAttrSet = GetSelectionPattern()->GetItemSet(); 800 const ScProtectionAttr& rProtAttr = (const ScProtectionAttr&)rAttrSet.Get( ATTR_PROTECTION, sal_True ); 801 if ( rProtAttr.GetProtection() ) 802 rSet.DisableItem( nWhich ); 803 } 804 } 805 break; 806 */ 807 case SID_OUTLINE_MAKE: 808 { 809 if ( GetViewData()->GetDocument()->GetDPAtCursor( GetViewData()->GetCurX(), 810 GetViewData()->GetCurY(), GetViewData()->GetTabNo() ) ) 811 { 812 //! test for data pilot operation 813 } 814 else if (pDoc->GetChangeTrack()!=NULL || GetViewData()->IsMultiMarked()) 815 { 816 rSet.DisableItem( nWhich ); 817 } 818 } 819 break; 820 case SID_OUTLINE_SHOW: 821 if ( GetViewData()->GetDocument()->GetDPAtCursor( GetViewData()->GetCurX(), 822 GetViewData()->GetCurY(), GetViewData()->GetTabNo() ) ) 823 { 824 //! test for data pilot operation 825 } 826 else if (!pTabViewShell->OutlinePossible(sal_False)) 827 rSet.DisableItem( nWhich ); 828 break; 829 830 case SID_OUTLINE_HIDE: 831 if ( GetViewData()->GetDocument()->GetDPAtCursor( GetViewData()->GetCurX(), 832 GetViewData()->GetCurY(), GetViewData()->GetTabNo() ) ) 833 { 834 //! test for data pilot operation 835 } 836 else if (!pTabViewShell->OutlinePossible(sal_True)) 837 rSet.DisableItem( nWhich ); 838 break; 839 840 case SID_OUTLINE_REMOVE: 841 { 842 if ( GetViewData()->GetDocument()->GetDPAtCursor( GetViewData()->GetCurX(), 843 GetViewData()->GetCurY(), GetViewData()->GetTabNo() ) ) 844 { 845 //! test for data pilot operation 846 } 847 else 848 { 849 sal_Bool bCol, bRow; 850 pTabViewShell->TestRemoveOutline( bCol, bRow ); 851 if ( !bCol && !bRow ) 852 rSet.DisableItem( nWhich ); 853 } 854 } 855 break; 856 857 case FID_COL_WIDTH: 858 { 859 //GetViewData()->GetCurX(); 860 SfxUInt16Item aWidthItem( FID_COL_WIDTH, pDoc->GetColWidth( nPosX , nTab) ); 861 rSet.Put( aWidthItem ); 862 if ( pDocSh->IsReadOnly()) 863 rSet.DisableItem( nWhich ); 864 865 //XXX Disablen wenn nicht eindeutig 866 } 867 break; 868 869 case FID_ROW_HEIGHT: 870 { 871 //GetViewData()->GetCurY(); 872 SfxUInt16Item aHeightItem( FID_ROW_HEIGHT, pDoc->GetRowHeight( nPosY , nTab) ); 873 rSet.Put( aHeightItem ); 874 //XXX Disablen wenn nicht eindeutig 875 if ( pDocSh->IsReadOnly()) 876 rSet.DisableItem( nWhich ); 877 } 878 break; 879 880 case SID_DETECTIVE_FILLMODE: 881 rSet.Put(SfxBoolItem( nWhich, pTabViewShell->IsAuditShell() )); 882 break; 883 884 case FID_INPUTLINE_STATUS: 885 DBG_ERROR( "Old update method. Use ScTabViewShell::UpdateInputHandler()." ); 886 break; 887 888 case SID_SCENARIOS: // Szenarios: 889 if (!(rMark.IsMarked() || rMark.IsMultiMarked())) // nur, wenn etwas selektiert 890 rSet.DisableItem( nWhich ); 891 break; 892 893 case FID_NOTE_VISIBLE: 894 { 895 const ScPostIt* pNote = pDoc->GetNote( ScAddress( nPosX, nPosY, nTab ) ); 896 if ( pNote && pDoc->IsBlockEditable( nTab, nPosX,nPosY, nPosX,nPosY ) ) 897 rSet.Put( SfxBoolItem( nWhich, pNote->IsCaptionShown() ) ); 898 else 899 rSet.DisableItem( nWhich ); 900 } 901 break; 902 903 case SID_DELETE_NOTE: 904 { 905 sal_Bool bEnable = sal_False; 906 if ( rMark.IsMarked() || rMark.IsMultiMarked() ) 907 { 908 if ( pDoc->IsSelectionEditable( rMark ) ) 909 { 910 // look for at least one note in selection 911 ScRangeList aRanges; 912 rMark.FillRangeListWithMarks( &aRanges, sal_False ); 913 sal_uLong nCount = aRanges.Count(); 914 for (sal_uLong nPos=0; nPos<nCount && !bEnable; nPos++) 915 { 916 ScCellIterator aCellIter( pDoc, *aRanges.GetObject(nPos) ); 917 for( ScBaseCell* pCell = aCellIter.GetFirst(); pCell && !bEnable; pCell = aCellIter.GetNext() ) 918 if ( pCell->HasNote() ) 919 bEnable = sal_True; // note found 920 } 921 } 922 } 923 else 924 { 925 bEnable = pDoc->IsBlockEditable( nTab, nPosX,nPosY, nPosX,nPosY ) && 926 pDoc->GetNote( ScAddress( nPosX, nPosY, nTab ) ); 927 } 928 if ( !bEnable ) 929 rSet.DisableItem( nWhich ); 930 } 931 break; 932 933 case SID_OPENDLG_CONSOLIDATE: 934 case SCITEM_CONSOLIDATEDATA: 935 { 936 if(pDoc->GetChangeTrack()!=NULL) 937 rSet.DisableItem( nWhich); 938 } 939 break; 940 941 case SID_CHINESE_CONVERSION: 942 case SID_HANGUL_HANJA_CONVERSION: 943 ScViewUtil::HideDisabledSlot( rSet, pData->GetBindings(), nWhich ); 944 break; 945 946 case FID_USE_NAME: 947 { 948 if ( pDocSh && pDocSh->IsDocShared() ) 949 rSet.DisableItem( nWhich ); 950 else 951 { 952 ScRange aRange; 953 if ( pData->GetSimpleArea( aRange ) != SC_MARK_SIMPLE ) 954 rSet.DisableItem( nWhich ); 955 } 956 } 957 break; 958 959 case FID_DEFINE_NAME: 960 case FID_INSERT_NAME: 961 case SID_DEFINE_COLROWNAMERANGES: 962 { 963 if ( pDocSh && pDocSh->IsDocShared() ) 964 { 965 rSet.DisableItem( nWhich ); 966 } 967 } 968 break; 969 970 case SID_SPELL_DIALOG: 971 { 972 if ( pDoc && pData && pDoc->IsTabProtected( pData->GetTabNo() ) ) 973 { 974 bool bVisible = false; 975 SfxViewFrame* pViewFrame = ( pTabViewShell ? pTabViewShell->GetViewFrame() : NULL ); 976 if ( pViewFrame && pViewFrame->HasChildWindow( nWhich ) ) 977 { 978 SfxChildWindow* pChild = pViewFrame->GetChildWindow( nWhich ); 979 Window* pWin = ( pChild ? pChild->GetWindow() : NULL ); 980 if ( pWin && pWin->IsVisible() ) 981 { 982 bVisible = true; 983 } 984 } 985 if ( !bVisible ) 986 { 987 rSet.DisableItem( nWhich ); 988 } 989 } 990 } 991 break; 992 993 } // switch ( nWitch ) 994 nWhich = aIter.NextWhich(); 995 } // while ( nWitch ) 996 } 997 998 //------------------------------------------------------------------ 999 1000 1001 1002