fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / sc / source / ui / view / cellsh.cxx
blobaba13687fb3f14e6cf4d7046de36212ead625132
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "scitems.hxx"
22 #include <svl/slstitm.hxx>
23 #include <svl/stritem.hxx>
24 #include <svl/whiter.hxx>
25 #include <unotools/moduleoptions.hxx>
26 #include <svtools/cliplistener.hxx>
27 #include <svtools/insdlg.hxx>
28 #include <sot/formats.hxx>
29 #include <svx/hlnkitem.hxx>
30 #include <sfx2/app.hxx>
31 #include <sfx2/bindings.hxx>
32 #include <sfx2/childwin.hxx>
33 #include <sfx2/objface.hxx>
34 #include <sfx2/request.hxx>
35 #include <sfx2/viewfrm.hxx>
36 #include <sfx2/sidebar/EnumContext.hxx>
37 #include <svx/clipfmtitem.hxx>
38 #include <svx/sidebar/ContextChangeEventMultiplexer.hxx>
39 #include <editeng/langitem.hxx>
41 #include "cellsh.hxx"
42 #include "sc.hrc"
43 #include "docsh.hxx"
44 #include "attrib.hxx"
45 #include "scresid.hxx"
46 #include "tabvwsh.hxx"
47 #include "impex.hxx"
48 #include "formulacell.hxx"
49 #include "scmod.hxx"
50 #include "globstr.hrc"
51 #include "transobj.hxx"
52 #include "drwtrans.hxx"
53 #include "scabstdlg.hxx"
54 #include "dociter.hxx"
55 #include "postit.hxx"
56 #include "cliputil.hxx"
57 #include "clipparam.hxx"
58 #include "markdata.hxx"
59 #include <gridwin.hxx>
61 #define ScCellShell
62 #define CellMovement
63 #include "scslots.hxx"
65 TYPEINIT1( ScCellShell, ScFormatShell );
67 SFX_IMPL_INTERFACE(ScCellShell, ScFormatShell)
69 void ScCellShell::InitInterface_Impl()
71 GetStaticInterface()->RegisterObjectBar(SFX_OBJECTBAR_OBJECT | SFX_VISIBILITY_STANDARD | SFX_VISIBILITY_SERVER,
72 RID_OBJECTBAR_FORMAT);
74 GetStaticInterface()->RegisterPopupMenu(ScResId(RID_POPUP_CELLS));
77 ScCellShell::ScCellShell(ScViewData* pData) :
78 ScFormatShell(pData),
79 pImpl( new CellShell_Impl() ),
80 bPastePossible(false)
82 SetHelpId(HID_SCSHELL_CELLSH);
83 SetName(OUString("Cell"));
84 SfxShell::SetContextName(sfx2::sidebar::EnumContext::GetContextName(sfx2::sidebar::EnumContext::Context_Cell));
87 ScCellShell::~ScCellShell()
89 if ( pImpl->m_pClipEvtLstnr )
91 pImpl->m_pClipEvtLstnr->AddRemoveListener( GetViewData()->GetActiveWin(), false );
93 // The listener may just now be waiting for the SolarMutex and call the link
94 // afterwards, in spite of RemoveListener. So the link has to be reset, too.
95 pImpl->m_pClipEvtLstnr->ClearCallbackLink();
97 pImpl->m_pClipEvtLstnr->release();
100 delete pImpl->m_pLinkedDlg;
101 delete pImpl->m_pRequest;
102 delete pImpl;
105 void ScCellShell::GetBlockState( SfxItemSet& rSet )
107 ScTabViewShell* pTabViewShell = GetViewData()->GetViewShell();
108 ScRange aMarkRange;
109 ScMarkType eMarkType = GetViewData()->GetSimpleArea( aMarkRange );
110 bool bSimpleArea = (eMarkType == SC_MARK_SIMPLE);
111 bool bOnlyNotBecauseOfMatrix;
112 bool bEditable = pTabViewShell->SelectionEditable( &bOnlyNotBecauseOfMatrix );
113 ScDocument* pDoc = GetViewData()->GetDocument();
114 ScDocShell* pDocShell = GetViewData()->GetDocShell();
115 ScMarkData& rMark = GetViewData()->GetMarkData();
116 SCCOL nCol1, nCol2;
117 SCROW nRow1, nRow2;
118 nCol1 = aMarkRange.aStart.Col();
119 nRow1 = aMarkRange.aStart.Row();
120 nCol2 = aMarkRange.aEnd.Col();
121 nRow2 = aMarkRange.aEnd.Row();
123 SfxWhichIter aIter(rSet);
124 sal_uInt16 nWhich = aIter.FirstWhich();
125 while ( nWhich )
127 bool bDisable = false;
128 bool bNeedEdit = true; // need selection be editable?
129 switch ( nWhich )
131 case FID_FILL_TO_BOTTOM: // fill to top / bottom
133 bDisable = !bSimpleArea || (nRow1 == 0 && nRow2 == 0);
134 if ( !bDisable && bEditable )
135 { // do not damage matrix
136 bDisable = pDoc->HasSelectedBlockMatrixFragment(
137 nCol1, nRow1, nCol2, nRow1, rMark ); // first row
140 break;
141 case FID_FILL_TO_TOP:
143 bDisable = (!bSimpleArea) || (nRow1 == MAXROW && nRow2 == MAXROW);
144 if ( !bDisable && bEditable )
145 { // do not damage matrix
146 bDisable = pDoc->HasSelectedBlockMatrixFragment(
147 nCol1, nRow2, nCol2, nRow2, rMark ); // last row
150 break;
151 case FID_FILL_TO_RIGHT: // fill to left / right
153 bDisable = !bSimpleArea || (nCol1 == 0 && nCol2 == 0);
154 if ( !bDisable && bEditable )
155 { // do not damage matrix
156 bDisable = pDoc->HasSelectedBlockMatrixFragment(
157 nCol1, nRow1, nCol1, nRow2, rMark ); // first column
160 break;
161 case FID_FILL_TO_LEFT:
163 bDisable = (!bSimpleArea) || (nCol1 == MAXCOL && nCol2 == MAXCOL);
164 if ( !bDisable && bEditable )
165 { // do not damage matrix
166 bDisable = pDoc->HasSelectedBlockMatrixFragment(
167 nCol2, nRow1, nCol2, nRow2, rMark ); // last column
170 break;
172 case SID_RANDOM_NUMBER_GENERATOR_DIALOG:
173 case SID_SAMPLING_DIALOG:
174 case SID_DESCRIPTIVE_STATISTICS_DIALOG:
175 case SID_ANALYSIS_OF_VARIANCE_DIALOG:
176 case SID_CORRELATION_DIALOG:
177 case SID_COVARIANCE_DIALOG:
179 bDisable = !bSimpleArea;
181 break;
183 case FID_FILL_SERIES: // fill block
184 case SID_OPENDLG_TABOP: // multiple-cell operations, are at least 2 cells marked?
185 if (pDoc->GetChangeTrack()!=NULL &&nWhich ==SID_OPENDLG_TABOP)
186 bDisable = true;
187 else
188 bDisable = (!bSimpleArea) || (nCol1 == nCol2 && nRow1 == nRow2);
190 if ( !bDisable && bEditable && nWhich == FID_FILL_SERIES )
191 { // do not damage matrix
192 bDisable = pDoc->HasSelectedBlockMatrixFragment(
193 nCol1, nRow1, nCol2, nRow1, rMark ) // first row
194 || pDoc->HasSelectedBlockMatrixFragment(
195 nCol1, nRow2, nCol2, nRow2, rMark ) // last row
196 || pDoc->HasSelectedBlockMatrixFragment(
197 nCol1, nRow1, nCol1, nRow2, rMark ) // first column
198 || pDoc->HasSelectedBlockMatrixFragment(
199 nCol2, nRow1, nCol2, nRow2, rMark ); // last column
201 break;
202 case FID_FILL_SINGLE_EDIT:
203 bDisable = false;
204 break;
205 case SID_CUT: // cut
206 case FID_INS_CELL: // insert cells, just simple selection
207 bDisable = (!bSimpleArea);
208 break;
210 case FID_INS_ROW: // insert rows
211 case FID_INS_CELLSDOWN:
212 bDisable = (!bSimpleArea) || GetViewData()->SimpleColMarked();
213 break;
215 case FID_INS_COLUMN: // insert columns
216 case FID_INS_CELLSRIGHT:
217 bDisable = (!bSimpleArea) || GetViewData()->SimpleRowMarked();
218 break;
220 case SID_COPY: // copy
221 // not editable because of matrix only? Do not damage matrix
222 //! is not called, when protected AND matrix, we will have
223 //! to live with this... is caught in Copy-Routine, otherwise
224 //! work is to be done once more
225 if ( !(!bEditable && bOnlyNotBecauseOfMatrix) )
226 bNeedEdit = false; // allowed when protected/ReadOnly
227 break;
229 case SID_AUTOFORMAT: // Autoformat, at least 3x3 selected
230 bDisable = (!bSimpleArea)
231 || ((nCol2 - nCol1) < 2) || ((nRow2 - nRow1) < 2);
232 break;
234 case SID_CELL_FORMAT_RESET :
235 case FID_CELL_FORMAT :
236 case SID_ENABLE_HYPHENATION :
237 // not editable because of matrix only? Attribute ok nonetheless
238 if ( !bEditable && bOnlyNotBecauseOfMatrix )
239 bNeedEdit = false;
240 break;
242 case FID_VALIDATION:
244 if ( pDocShell && pDocShell->IsDocShared() )
246 bDisable = true;
249 break;
251 case SID_TRANSLITERATE_HALFWIDTH:
252 case SID_TRANSLITERATE_FULLWIDTH:
253 case SID_TRANSLITERATE_HIRAGANA:
254 case SID_TRANSLITERATE_KATAGANA:
255 ScViewUtil::HideDisabledSlot( rSet, GetViewData()->GetBindings(), nWhich );
256 break;
257 case SID_CONVERT_FORMULA_TO_VALUE:
259 // Check and see if the marked range has at least one formula cell.
260 bDisable = !pDoc->HasFormulaCell(aMarkRange);
262 break;
264 if (!bDisable && bNeedEdit && !bEditable)
265 bDisable = true;
267 if (bDisable)
268 rSet.DisableItem(nWhich);
269 else if (nWhich == SID_ENABLE_HYPHENATION)
271 // toggle slots need a bool item
272 rSet.Put( SfxBoolItem( nWhich, false ) );
274 nWhich = aIter.NextWhich();
278 // functionen, disabled depending on cursor position
279 // Default:
280 // SID_INSERT_POSTIT, SID_CHARMAP, SID_OPENDLG_FUNCTION
282 void ScCellShell::GetCellState( SfxItemSet& rSet )
284 ScDocShell* pDocShell = GetViewData()->GetDocShell();
285 ScDocument& rDoc = GetViewData()->GetDocShell()->GetDocument();
286 ScAddress aCursor( GetViewData()->GetCurX(), GetViewData()->GetCurY(),
287 GetViewData()->GetTabNo() );
289 SfxWhichIter aIter(rSet);
290 sal_uInt16 nWhich = aIter.FirstWhich();
291 while ( nWhich )
293 bool bDisable = false;
294 bool bNeedEdit = true; // need cursor position be editable?
295 switch ( nWhich )
297 case SID_THESAURUS:
299 CellType eType = rDoc.GetCellType( aCursor );
300 bDisable = ( eType != CELLTYPE_STRING && eType != CELLTYPE_EDIT);
301 if (!bDisable)
303 // test for available languages
304 sal_uInt16 nLang = ScViewUtil::GetEffLanguage( &rDoc, aCursor );
305 bDisable = !ScModule::HasThesaurusLanguage( nLang );
308 break;
309 case SID_OPENDLG_FUNCTION:
311 ScMarkData aMarkData = GetViewData()->GetMarkData();
312 aMarkData.MarkToSimple();
313 ScRange aRange;
314 aMarkData.GetMarkArea(aRange);
315 if(aMarkData.IsMarked())
317 if (!rDoc.IsBlockEditable( aCursor.Tab(), aRange.aStart.Col(),aRange.aStart.Row(),
318 aRange.aEnd.Col(),aRange.aEnd.Row() ))
320 bDisable = true;
322 bNeedEdit=false;
326 break;
327 case SID_INSERT_POSTIT:
329 ScAddress aPos( GetViewData()->GetCurX(), GetViewData()->GetCurY(), GetViewData()->GetTabNo() );
330 if( rDoc.GetNote(aPos) )
332 bDisable = true;
334 else
336 bDisable = false;
337 if ( pDocShell && pDocShell->IsDocShared() )
339 bDisable = true;
343 break;
344 case SID_EDIT_POSTIT:
346 ScAddress aPos( GetViewData()->GetCurX(), GetViewData()->GetCurY(), GetViewData()->GetTabNo() );
347 if( rDoc.GetNote(aPos) )
349 bDisable = false;
351 else
353 bDisable = true;
356 break;
358 if (!bDisable && bNeedEdit)
359 if (!rDoc.IsBlockEditable( aCursor.Tab(), aCursor.Col(),aCursor.Row(),
360 aCursor.Col(),aCursor.Row() ))
361 bDisable = true;
362 if (bDisable)
363 rSet.DisableItem(nWhich);
364 nWhich = aIter.NextWhich();
368 static bool lcl_TestFormat( SvxClipboardFormatItem& rFormats, const TransferableDataHelper& rDataHelper,
369 SotClipboardFormatId nFormatId )
371 if ( rDataHelper.HasFormat( nFormatId ) )
373 // translated format name strings are no longer inserted here,
374 // handled by "paste special" dialog / toolbox controller instead.
375 // Only the object type name has to be set here:
376 OUString aStrVal;
377 if ( nFormatId == SotClipboardFormatId::EMBED_SOURCE )
379 TransferableObjectDescriptor aDesc;
380 if ( ((TransferableDataHelper&)rDataHelper).GetTransferableObjectDescriptor(
381 SotClipboardFormatId::OBJECTDESCRIPTOR, aDesc ) )
382 aStrVal = aDesc.maTypeName;
384 else if ( nFormatId == SotClipboardFormatId::EMBED_SOURCE_OLE
385 || nFormatId == SotClipboardFormatId::EMBEDDED_OBJ_OLE )
387 OUString aSource;
388 SvPasteObjectHelper::GetEmbeddedName( rDataHelper, aStrVal, aSource, nFormatId );
391 if ( !aStrVal.isEmpty() )
392 rFormats.AddClipbrdFormat( nFormatId, aStrVal );
393 else
394 rFormats.AddClipbrdFormat( nFormatId );
396 return true;
399 return false;
402 void ScCellShell::GetPossibleClipboardFormats( SvxClipboardFormatItem& rFormats )
404 vcl::Window* pWin = GetViewData()->GetActiveWin();
405 bool bDraw = ( ScDrawTransferObj::GetOwnClipboard( pWin ) != NULL );
407 TransferableDataHelper aDataHelper( TransferableDataHelper::CreateFromSystemClipboard( pWin ) );
409 lcl_TestFormat( rFormats, aDataHelper, SotClipboardFormatId::DRAWING );
410 lcl_TestFormat( rFormats, aDataHelper, SotClipboardFormatId::SVXB );
411 lcl_TestFormat( rFormats, aDataHelper, SotClipboardFormatId::GDIMETAFILE );
412 lcl_TestFormat( rFormats, aDataHelper, SotClipboardFormatId::PNG );
413 lcl_TestFormat( rFormats, aDataHelper, SotClipboardFormatId::BITMAP );
414 lcl_TestFormat( rFormats, aDataHelper, SotClipboardFormatId::EMBED_SOURCE );
416 if ( !bDraw )
418 lcl_TestFormat( rFormats, aDataHelper, SotClipboardFormatId::LINK );
419 lcl_TestFormat( rFormats, aDataHelper, SotClipboardFormatId::STRING );
420 lcl_TestFormat( rFormats, aDataHelper, SotClipboardFormatId::DIF );
421 lcl_TestFormat( rFormats, aDataHelper, SotClipboardFormatId::RTF );
422 lcl_TestFormat( rFormats, aDataHelper, SotClipboardFormatId::HTML );
423 lcl_TestFormat( rFormats, aDataHelper, SotClipboardFormatId::HTML_SIMPLE );
424 lcl_TestFormat( rFormats, aDataHelper, SotClipboardFormatId::BIFF_8 );
425 lcl_TestFormat( rFormats, aDataHelper, SotClipboardFormatId::BIFF_5 );
428 if ( !lcl_TestFormat( rFormats, aDataHelper, SotClipboardFormatId::EMBED_SOURCE_OLE ) )
429 lcl_TestFormat( rFormats, aDataHelper, SotClipboardFormatId::EMBEDDED_OBJ_OLE );
432 // insert, insert contents
434 static bool lcl_IsCellPastePossible( const TransferableDataHelper& rData )
436 bool bPossible = false;
437 if ( ScTransferObj::GetOwnClipboard( NULL ) || ScDrawTransferObj::GetOwnClipboard( NULL ) )
438 bPossible = true;
439 else
441 if ( rData.HasFormat( SotClipboardFormatId::PNG ) ||
442 rData.HasFormat( SotClipboardFormatId::BITMAP ) ||
443 rData.HasFormat( SotClipboardFormatId::GDIMETAFILE ) ||
444 rData.HasFormat( SotClipboardFormatId::SVXB ) ||
445 rData.HasFormat( SotClipboardFormatId::PRIVATE ) ||
446 rData.HasFormat( SotClipboardFormatId::RTF ) ||
447 rData.HasFormat( SotClipboardFormatId::EMBED_SOURCE ) ||
448 rData.HasFormat( SotClipboardFormatId::LINK_SOURCE ) ||
449 rData.HasFormat( SotClipboardFormatId::EMBED_SOURCE_OLE ) ||
450 rData.HasFormat( SotClipboardFormatId::LINK_SOURCE_OLE ) ||
451 rData.HasFormat( SotClipboardFormatId::EMBEDDED_OBJ_OLE ) ||
452 rData.HasFormat( SotClipboardFormatId::STRING ) ||
453 rData.HasFormat( SotClipboardFormatId::SYLK ) ||
454 rData.HasFormat( SotClipboardFormatId::LINK ) ||
455 rData.HasFormat( SotClipboardFormatId::HTML ) ||
456 rData.HasFormat( SotClipboardFormatId::HTML_SIMPLE ) ||
457 rData.HasFormat( SotClipboardFormatId::DIF ) )
459 bPossible = true;
462 return bPossible;
465 IMPL_LINK( ScCellShell, ClipboardChanged, TransferableDataHelper*, pDataHelper )
467 if ( pDataHelper )
469 bPastePossible = lcl_IsCellPastePossible( *pDataHelper );
471 SfxBindings& rBindings = GetViewData()->GetBindings();
472 rBindings.Invalidate( SID_PASTE );
473 rBindings.Invalidate( SID_PASTE_SPECIAL );
474 rBindings.Invalidate( SID_PASTE_ONLY_VALUE );
475 rBindings.Invalidate( SID_PASTE_ONLY_TEXT );
476 rBindings.Invalidate( SID_PASTE_ONLY_FORMULA );
477 rBindings.Invalidate( SID_CLIPBOARD_FORMAT_ITEMS );
479 return 0;
482 namespace {
484 bool checkDestRanges(ScViewData& rViewData)
486 ScRange aDummy;
487 ScMarkType eMarkType = rViewData.GetSimpleArea( aDummy);
488 if (eMarkType != SC_MARK_MULTI)
490 // Single destination range.
491 if (eMarkType != SC_MARK_SIMPLE && eMarkType != SC_MARK_SIMPLE_FILTERED)
492 return false;
495 // Multiple destination ranges.
497 ScDocument* pDoc = rViewData.GetDocument();
498 vcl::Window* pWin = rViewData.GetActiveWin();
499 if (!pWin)
500 return false;
502 ScTransferObj* pOwnClip = ScTransferObj::GetOwnClipboard(pWin);
503 if (!pOwnClip)
504 // If it's not a Calc document, we won't be picky.
505 return true;
507 ScDocument* pClipDoc = pOwnClip->GetDocument();
508 if (!pClipDoc)
509 return false;
511 ScRange aSrcRange = pClipDoc->GetClipParam().getWholeRange();
512 SCROW nRowSize = aSrcRange.aEnd.Row() - aSrcRange.aStart.Row() + 1;
513 SCCOL nColSize = aSrcRange.aEnd.Col() - aSrcRange.aStart.Col() + 1;
515 ScMarkData aMark = rViewData.GetMarkData();
516 ScRangeList aRanges;
517 aMark.MarkToSimple();
518 aMark.FillRangeListWithMarks(&aRanges, false);
520 return ScClipUtil::CheckDestRanges(pDoc, nColSize, nRowSize, aMark, aRanges);
525 void ScCellShell::GetClipState( SfxItemSet& rSet )
527 // SID_PASTE
528 // SID_PASTE_SPECIAL
529 // SID_CLIPBOARD_FORMAT_ITEMS
531 if ( !pImpl->m_pClipEvtLstnr )
533 // create listener
534 pImpl->m_pClipEvtLstnr = new TransferableClipboardListener( LINK( this, ScCellShell, ClipboardChanged ) );
535 pImpl->m_pClipEvtLstnr->acquire();
536 vcl::Window* pWin = GetViewData()->GetActiveWin();
537 pImpl->m_pClipEvtLstnr->AddRemoveListener( pWin, true );
539 // get initial state
540 TransferableDataHelper aDataHelper( TransferableDataHelper::CreateFromSystemClipboard( pWin ) );
541 bPastePossible = lcl_IsCellPastePossible( aDataHelper );
544 bool bDisable = !bPastePossible;
546 // cell protection / multiple selection
548 if (!bDisable)
550 SCCOL nCol = GetViewData()->GetCurX();
551 SCROW nRow = GetViewData()->GetCurY();
552 SCTAB nTab = GetViewData()->GetTabNo();
553 ScDocument& rDoc = GetViewData()->GetDocShell()->GetDocument();
554 if (!rDoc.IsBlockEditable( nTab, nCol,nRow, nCol,nRow ))
555 bDisable = true;
557 if (!checkDestRanges(*GetViewData()))
558 bDisable = true;
561 if (bDisable)
563 rSet.DisableItem( SID_PASTE );
564 rSet.DisableItem( SID_PASTE_SPECIAL );
565 rSet.DisableItem( SID_PASTE_ONLY_VALUE );
566 rSet.DisableItem( SID_PASTE_ONLY_TEXT );
567 rSet.DisableItem( SID_PASTE_ONLY_FORMULA );
568 rSet.DisableItem( SID_CLIPBOARD_FORMAT_ITEMS );
570 else if ( rSet.GetItemState( SID_CLIPBOARD_FORMAT_ITEMS ) != SfxItemState::UNKNOWN )
572 SvxClipboardFormatItem aFormats( SID_CLIPBOARD_FORMAT_ITEMS );
573 GetPossibleClipboardFormats( aFormats );
574 rSet.Put( aFormats );
578 // only SID_HYPERLINK_GETLINK:
580 void ScCellShell::GetHLinkState( SfxItemSet& rSet )
582 // always return an item (or inserting will be disabled)
583 // if the cell at the cursor contains only a link, return that link
585 SvxHyperlinkItem aHLinkItem;
586 if ( !GetViewData()->GetView()->HasBookmarkAtCursor( &aHLinkItem ) )
588 //! put selected text into item?
591 rSet.Put(aHLinkItem);
594 void ScCellShell::GetState(SfxItemSet &rSet)
596 ScTabViewShell* pTabViewShell = GetViewData()->GetViewShell();
597 ScDocShell* pDocSh = GetViewData()->GetDocShell();
598 ScViewData* pData = GetViewData();
599 ScDocument* pDoc = pData->GetDocument();
600 ScMarkData& rMark = pData->GetMarkData();
601 SCCOL nPosX = pData->GetCurX();
602 SCROW nPosY = pData->GetCurY();
603 SCTAB nTab = pData->GetTabNo();
605 SCTAB nTabCount = pDoc->GetTableCount();
606 SCTAB nTabSelCount = rMark.GetSelectCount();
608 SfxWhichIter aIter(rSet);
609 sal_uInt16 nWhich = aIter.FirstWhich();
610 while ( nWhich )
612 switch ( nWhich )
614 case SID_DETECTIVE_REFRESH:
615 if (!pDoc->HasDetectiveOperations())
616 rSet.DisableItem( nWhich );
617 break;
619 case SID_RANGE_ADDRESS:
621 ScRange aRange;
622 if ( pData->GetSimpleArea( aRange ) == SC_MARK_SIMPLE )
624 sal_uInt16 nFlags = SCA_VALID | SCA_TAB_3D;
625 OUString aStr(aRange.Format(nFlags,pDoc));
626 rSet.Put( SfxStringItem( nWhich, aStr ) );
629 break;
631 case SID_RANGE_NOTETEXT:
633 // always take cursor position, do not use top-left cell of selection
634 OUString aNoteText;
635 if ( const ScPostIt* pNote = pDoc->GetNote(nPosX, nPosY, nTab) )
636 aNoteText = pNote->GetText();
637 rSet.Put( SfxStringItem( nWhich, aNoteText ) );
639 break;
641 case SID_RANGE_ROW:
642 rSet.Put( SfxInt32Item( nWhich, nPosY+1 ) );
643 break;
645 case SID_RANGE_COL:
646 rSet.Put( SfxInt16Item( nWhich, nPosX+1 ) );
647 break;
649 case SID_RANGE_TABLE:
650 rSet.Put( SfxInt16Item( nWhich, nTab+1 ) );
651 break;
653 case SID_RANGE_VALUE:
655 double nValue;
656 pDoc->GetValue( nPosX, nPosY, nTab, nValue );
657 rSet.Put( ScDoubleItem( nWhich, nValue ) );
659 break;
661 case SID_RANGE_FORMULA:
663 OUString aString;
664 pDoc->GetFormula( nPosX, nPosY, nTab, aString );
665 if( aString.isEmpty() )
667 pDoc->GetInputString( nPosX, nPosY, nTab, aString );
669 rSet.Put( SfxStringItem( nWhich, aString ) );
671 break;
673 case SID_RANGE_TEXTVALUE:
675 OUString aString = pDoc->GetString(nPosX, nPosY, nTab);
676 rSet.Put( SfxStringItem( nWhich, aString ) );
678 break;
680 case SID_STATUS_SELMODE:
682 /* 0: STD Click cancels Sel
683 * 1: ER Click extends selection
684 * 2: ERG Click defines further selection
686 sal_uInt16 nMode = pTabViewShell->GetLockedModifiers();
688 switch ( nMode )
690 case KEY_SHIFT: nMode = 1; break;
691 case KEY_MOD1: nMode = 2; break; // Control-key
692 case 0:
693 default:
694 nMode = 0;
697 rSet.Put( SfxUInt16Item( nWhich, nMode ) );
699 break;
701 case SID_STATUS_DOCPOS:
703 OUString aStr = ScGlobal::GetRscString( STR_TABLE_COUNT );
705 aStr = aStr.replaceFirst("%1", OUString::number( nTab + 1 ) );
706 aStr = aStr.replaceFirst("%2", OUString::number( nTabCount ) );
708 rSet.Put( SfxStringItem( nWhich, aStr ) ); }
709 break;
711 case SID_ROWCOL_SELCOUNT:
713 ScRange aMarkRange;
714 GetViewData()->GetSimpleArea( aMarkRange );
715 SCCOL nCol1, nCol2;
716 SCROW nRow1, nRow2;
717 nCol1 = aMarkRange.aStart.Col();
718 nRow1 = aMarkRange.aStart.Row();
719 nCol2 = aMarkRange.aEnd.Col();
720 nRow2 = aMarkRange.aEnd.Row();
721 if( nCol2 != nCol1 || nRow1 != nRow2 )
723 OUString aStr = ScGlobal::GetRscString( STR_ROWCOL_SELCOUNT );
724 aStr = aStr.replaceAll( "$1", OUString::number( nRow2 - nRow1 + 1 ));
725 aStr = aStr.replaceAll( "$2", OUString::number( nCol2 - nCol1 + 1 ));
726 rSet.Put( SfxStringItem( nWhich, aStr ) );
729 break;
731 // calculations etc. with date/time/Fail/position&size together
733 // #i34458# The SfxStringItem belongs only into SID_TABLE_CELL. It no longer has to be
734 // duplicated in SID_ATTR_POSITION or SID_ATTR_SIZE for SvxPosSizeStatusBarControl.
735 case SID_TABLE_CELL:
737 // Test, if error under cursor
738 // (not pDoc->GetErrCode, to avoid erasing circular references)
740 // In interpreter may happen via rescheduled Basic
741 if ( pDoc->IsInInterpreter() )
742 rSet.Put( SfxStringItem( nWhich, OUString("...") ) );
743 else
745 sal_uInt16 nErrCode = 0;
746 ScFormulaCell* pCell = pDoc->GetFormulaCell(ScAddress(nPosX, nPosY, nTab));
747 if (pCell)
749 if (!pCell->IsRunning())
750 nErrCode = pCell->GetErrCode();
753 OUString aFuncStr;
754 if ( pTabViewShell->GetFunction( aFuncStr, nErrCode ) )
755 rSet.Put( SfxStringItem( nWhich, aFuncStr ) );
758 break;
760 case SID_DATA_SELECT:
761 // HasSelectionData includes column content and validity,
762 // page fields have to be checked separately.
763 if ( !pDoc->HasSelectionData( nPosX, nPosY, nTab ) &&
764 !pTabViewShell->HasPageFieldDataAtCursor() )
765 rSet.DisableItem( nWhich );
766 break;
768 case SID_STATUS_SUM:
770 OUString aFuncStr;
771 if ( pTabViewShell->GetFunction( aFuncStr ) )
772 rSet.Put( SfxStringItem( nWhich, aFuncStr ) );
774 break;
776 case FID_MERGE_ON:
777 if ( pDoc->GetChangeTrack() || !pTabViewShell->TestMergeCells() )
778 rSet.DisableItem( nWhich );
779 break;
781 case FID_MERGE_OFF:
782 if ( pDoc->GetChangeTrack() || !pTabViewShell->TestRemoveMerge() )
783 rSet.DisableItem( nWhich );
784 break;
786 case FID_MERGE_TOGGLE:
787 if ( pDoc->GetChangeTrack() )
788 rSet.DisableItem( nWhich );
789 else
791 bool bCanMerge = pTabViewShell->TestMergeCells();
792 bool bCanSplit = pTabViewShell->TestRemoveMerge();
793 if( !bCanMerge && !bCanSplit )
794 rSet.DisableItem( nWhich );
795 else
796 rSet.Put( SfxBoolItem( nWhich, bCanSplit ) );
798 break;
800 case FID_INS_ROWBRK:
801 if ( nPosY==0 || (pDoc->HasRowBreak(nPosY, nTab) & BREAK_MANUAL) )
802 rSet.DisableItem( nWhich );
803 break;
805 case FID_INS_COLBRK:
806 if ( nPosX==0 || (pDoc->HasColBreak(nPosX, nTab) & BREAK_MANUAL) )
807 rSet.DisableItem( nWhich );
808 break;
810 case FID_DEL_ROWBRK:
811 if ( nPosY==0 || (pDoc->HasRowBreak(nPosY, nTab) & BREAK_MANUAL) == 0 )
812 rSet.DisableItem( nWhich );
813 break;
815 case FID_DEL_COLBRK:
816 if ( nPosX==0 || (pDoc->HasColBreak(nPosX, nTab) & BREAK_MANUAL) == 0 )
817 rSet.DisableItem( nWhich );
818 break;
820 case FID_FILL_TAB:
821 if ( nTabSelCount < 2 )
822 rSet.DisableItem( nWhich );
823 break;
825 case SID_SELECT_SCENARIO:
827 std::vector<OUString> aList;
828 Color aDummyCol;
830 if ( !pDoc->IsScenario(nTab) )
832 OUString aStr;
833 sal_uInt16 nFlags;
834 SCTAB nScTab = nTab + 1;
835 bool bSheetProtected = pDoc->IsTabProtected(nTab);
837 while ( pDoc->IsScenario(nScTab) )
839 pDoc->GetName( nScTab, aStr );
840 aList.push_back(aStr);
841 pDoc->GetScenarioData( nScTab, aStr, aDummyCol, nFlags );
842 aList.push_back(aStr);
843 // Protection is sal_True if both Sheet and Scenario are protected
844 aList.push_back((bSheetProtected && (nFlags & SC_SCENARIO_PROTECT)) ? OUString("1") : OUString("0"));
845 ++nScTab;
848 else
850 OUString aComment;
851 sal_uInt16 nDummyFlags;
852 pDoc->GetScenarioData( nTab, aComment, aDummyCol, nDummyFlags );
853 OSL_ENSURE( aList.empty(), "List not empty!" );
854 aList.push_back(aComment);
857 rSet.Put( SfxStringListItem( nWhich, &aList ) );
859 break;
861 case FID_ROW_HIDE:
862 case FID_ROW_SHOW:
863 case FID_COL_HIDE:
864 case FID_COL_SHOW:
865 case FID_COL_OPT_WIDTH:
866 case FID_ROW_OPT_HEIGHT:
867 case FID_DELETE_CELL:
868 if ( pDoc->IsTabProtected(nTab) || pDocSh->IsReadOnly())
869 rSet.DisableItem( nWhich );
870 break;
872 case SID_OUTLINE_MAKE:
874 if ( GetViewData()->GetDocument()->GetDPAtCursor( GetViewData()->GetCurX(),
875 GetViewData()->GetCurY(), GetViewData()->GetTabNo() ) )
877 //! test for data pilot operation
879 else if (pDoc->GetChangeTrack()!=NULL || GetViewData()->IsMultiMarked())
881 rSet.DisableItem( nWhich );
884 break;
885 case SID_OUTLINE_SHOW:
886 if ( GetViewData()->GetDocument()->GetDPAtCursor( GetViewData()->GetCurX(),
887 GetViewData()->GetCurY(), GetViewData()->GetTabNo() ) )
889 //! test for data pilot operation
891 else if (!pTabViewShell->OutlinePossible(false))
892 rSet.DisableItem( nWhich );
893 break;
895 case SID_OUTLINE_HIDE:
896 if ( GetViewData()->GetDocument()->GetDPAtCursor( GetViewData()->GetCurX(),
897 GetViewData()->GetCurY(), GetViewData()->GetTabNo() ) )
899 //! test for data pilot operation
901 else if (!pTabViewShell->OutlinePossible(true))
902 rSet.DisableItem( nWhich );
903 break;
905 case SID_OUTLINE_REMOVE:
907 if ( GetViewData()->GetDocument()->GetDPAtCursor( GetViewData()->GetCurX(),
908 GetViewData()->GetCurY(), GetViewData()->GetTabNo() ) )
910 //! test for data pilot operation
912 else
914 bool bCol, bRow;
915 pTabViewShell->TestRemoveOutline( bCol, bRow );
916 if ( !bCol && !bRow )
917 rSet.DisableItem( nWhich );
920 break;
922 case FID_COL_WIDTH:
924 //GetViewData()->GetCurX();
925 SfxUInt16Item aWidthItem( FID_COL_WIDTH, pDoc->GetColWidth( nPosX , nTab) );
926 rSet.Put( aWidthItem );
927 if ( pDocSh->IsReadOnly())
928 rSet.DisableItem( nWhich );
930 //XXX disable if not conclusive
932 break;
934 case FID_ROW_HEIGHT:
936 //GetViewData()->GetCurY();
937 SfxUInt16Item aHeightItem( FID_ROW_HEIGHT, pDoc->GetRowHeight( nPosY , nTab) );
938 rSet.Put( aHeightItem );
939 //XXX disable if not conclusive
940 if ( pDocSh->IsReadOnly())
941 rSet.DisableItem( nWhich );
943 break;
945 case SID_DETECTIVE_FILLMODE:
946 rSet.Put(SfxBoolItem( nWhich, pTabViewShell->IsAuditShell() ));
947 break;
949 case FID_INPUTLINE_STATUS:
950 OSL_FAIL( "Old update method. Use ScTabViewShell::UpdateInputHandler()." );
951 break;
953 case SID_SCENARIOS: // scenarios:
954 if (!(rMark.IsMarked() || rMark.IsMultiMarked())) // only, if something selected
955 rSet.DisableItem( nWhich );
956 break;
958 case FID_NOTE_VISIBLE:
960 const ScPostIt* pNote = pDoc->GetNote(nPosX, nPosY, nTab);
961 if ( pNote && pDoc->IsBlockEditable( nTab, nPosX,nPosY, nPosX,nPosY ) )
962 rSet.Put( SfxBoolItem( nWhich, pNote->IsCaptionShown() ) );
963 else
964 rSet.DisableItem( nWhich );
966 break;
968 case FID_HIDE_NOTE:
969 case FID_SHOW_NOTE:
971 bool bEnable = false;
972 bool bSearchForHidden = nWhich == FID_SHOW_NOTE;
973 if (!rMark.IsMarked() && !rMark.IsMultiMarked())
975 // Check current cell
976 const ScPostIt* pNote = pDoc->GetNote(nPosX, nPosY, nTab);
977 if ( pNote && pDoc->IsBlockEditable( nTab, nPosX,nPosY, nPosX,nPosY ) )
978 if ( pNote->IsCaptionShown() != bSearchForHidden)
979 bEnable = true;
981 else
983 // Check selection range
984 ScRangeListRef aRangesRef;
985 pData->GetMultiArea(aRangesRef);
986 ScRangeList aRanges = *aRangesRef;
987 std::vector<sc::NoteEntry> aNotes;
988 pDoc->GetNotesInRange(aRanges, aNotes);
989 for(std::vector<sc::NoteEntry>::const_iterator itr = aNotes.begin(),
990 itrEnd = aNotes.end(); itr != itrEnd; ++itr)
992 const ScAddress& rAdr = itr->maPos;
993 if( pDoc->IsBlockEditable( rAdr.Tab(), rAdr.Col(), rAdr.Row(), rAdr.Col(), rAdr.Row() ))
995 if (itr->mpNote->IsCaptionShown() != bSearchForHidden)
997 bEnable = true;
998 break;
1004 if ( !bEnable )
1005 rSet.DisableItem( nWhich );
1007 break;
1009 case SID_DELETE_NOTE:
1011 bool bEnable = false;
1012 if ( rMark.IsMarked() || rMark.IsMultiMarked() )
1014 if ( pDoc->IsSelectionEditable( rMark ) )
1016 // look for at least one note in selection
1017 ScRangeList aRanges;
1018 rMark.FillRangeListWithMarks( &aRanges, false );
1019 bEnable = pDoc->ContainsNotesInRange( aRanges );
1022 else
1024 bEnable = pDoc->IsBlockEditable( nTab, nPosX,nPosY, nPosX,nPosY ) &&
1025 pDoc->GetNote(nPosX, nPosY, nTab);
1027 if ( !bEnable )
1028 rSet.DisableItem( nWhich );
1030 break;
1032 case SID_OPENDLG_CONSOLIDATE:
1033 case SCITEM_CONSOLIDATEDATA:
1035 if(pDoc->GetChangeTrack()!=NULL)
1036 rSet.DisableItem( nWhich);
1038 break;
1040 case SID_CHINESE_CONVERSION:
1041 case SID_HANGUL_HANJA_CONVERSION:
1042 ScViewUtil::HideDisabledSlot( rSet, pData->GetBindings(), nWhich );
1043 break;
1045 case FID_USE_NAME:
1047 if ( pDocSh && pDocSh->IsDocShared() )
1048 rSet.DisableItem( nWhich );
1049 else
1051 ScRange aRange;
1052 if ( pData->GetSimpleArea( aRange ) != SC_MARK_SIMPLE )
1053 rSet.DisableItem( nWhich );
1056 break;
1058 case FID_DEFINE_NAME:
1059 case FID_INSERT_NAME:
1060 case FID_ADD_NAME:
1061 case SID_DEFINE_COLROWNAMERANGES:
1063 if ( pDocSh && pDocSh->IsDocShared() )
1065 rSet.DisableItem( nWhich );
1068 break;
1070 case SID_SPELL_DIALOG:
1072 if ( pDoc && pData && pDoc->IsTabProtected( pData->GetTabNo() ) )
1074 bool bVisible = false;
1075 SfxViewFrame* pViewFrame = ( pTabViewShell ? pTabViewShell->GetViewFrame() : NULL );
1076 if ( pViewFrame && pViewFrame->HasChildWindow( nWhich ) )
1078 SfxChildWindow* pChild = pViewFrame->GetChildWindow( nWhich );
1079 vcl::Window* pWin = ( pChild ? pChild->GetWindow() : NULL );
1080 if ( pWin && pWin->IsVisible() )
1082 bVisible = true;
1085 if ( !bVisible )
1087 rSet.DisableItem( nWhich );
1091 break;
1093 } // switch ( nWitch )
1094 nWhich = aIter.NextWhich();
1095 } // while ( nWitch )
1098 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */