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