GPU-Calc: remove Alloc_Host_Ptr for clmem of NAN vector
[LibreOffice.git] / sc / source / ui / view / cellsh.cxx
blobcf9d13b8c3130e74de2f6da4335459884f7542ec
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"
60 //------------------------------------------------------------------
62 #define ScCellShell
63 #define CellMovement
64 #include "scslots.hxx"
66 TYPEINIT1( ScCellShell, ScFormatShell );
68 SFX_IMPL_INTERFACE(ScCellShell, ScFormatShell , ScResId(SCSTR_CELLSHELL) )
70 SFX_OBJECTBAR_REGISTRATION( SFX_OBJECTBAR_OBJECT | SFX_VISIBILITY_STANDARD |
71 SFX_VISIBILITY_SERVER,
72 ScResId(RID_OBJECTBAR_FORMAT));
73 SFX_POPUPMENU_REGISTRATION(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 //------------------------------------------------------------------
107 void ScCellShell::GetBlockState( SfxItemSet& rSet )
109 ScTabViewShell* pTabViewShell = GetViewData()->GetViewShell();
110 ScRange aMarkRange;
111 ScMarkType eMarkType = GetViewData()->GetSimpleArea( aMarkRange );
112 bool bSimpleArea = (eMarkType == SC_MARK_SIMPLE);
113 bool bOnlyNotBecauseOfMatrix;
114 bool bEditable = pTabViewShell->SelectionEditable( &bOnlyNotBecauseOfMatrix );
115 ScDocument* pDoc = GetViewData()->GetDocument();
116 ScDocShell* pDocShell = GetViewData()->GetDocShell();
117 ScMarkData& rMark = GetViewData()->GetMarkData();
118 SCCOL nCol1, nCol2;
119 SCROW nRow1, nRow2;
120 nCol1 = aMarkRange.aStart.Col();
121 nRow1 = aMarkRange.aStart.Row();
122 nCol2 = aMarkRange.aEnd.Col();
123 nRow2 = aMarkRange.aEnd.Row();
125 SfxWhichIter aIter(rSet);
126 sal_uInt16 nWhich = aIter.FirstWhich();
127 while ( nWhich )
129 bool bDisable = false;
130 bool bNeedEdit = true; // need selection be editable?
131 switch ( nWhich )
133 case FID_FILL_TO_BOTTOM: // fill to top / bottom
135 bDisable = !bSimpleArea || (nRow1 == 0 && nRow2 == 0);
136 if ( !bDisable && bEditable )
137 { // do not damage matrix
138 bDisable = pDoc->HasSelectedBlockMatrixFragment(
139 nCol1, nRow1, nCol2, nRow1, rMark ); // first row
142 break;
143 case FID_FILL_TO_TOP:
145 bDisable = (!bSimpleArea) || (nRow1 == MAXROW && nRow2 == MAXROW);
146 if ( !bDisable && bEditable )
147 { // do not damage matrix
148 bDisable = pDoc->HasSelectedBlockMatrixFragment(
149 nCol1, nRow2, nCol2, nRow2, rMark ); // last row
152 break;
153 case FID_FILL_TO_RIGHT: // fill to left / right
155 bDisable = !bSimpleArea || (nCol1 == 0 && nCol2 == 0);
156 if ( !bDisable && bEditable )
157 { // do not damage matrix
158 bDisable = pDoc->HasSelectedBlockMatrixFragment(
159 nCol1, nRow1, nCol1, nRow2, rMark ); // first column
162 break;
163 case FID_FILL_TO_LEFT:
165 bDisable = (!bSimpleArea) || (nCol1 == MAXCOL && nCol2 == MAXCOL);
166 if ( !bDisable && bEditable )
167 { // do not damage matrix
168 bDisable = pDoc->HasSelectedBlockMatrixFragment(
169 nCol2, nRow1, nCol2, nRow2, rMark ); // last column
172 break;
174 case SID_RANDOM_NUMBER_GENERATOR_DIALOG:
175 case SID_SAMPLING_DIALOG:
176 case SID_DESCRIPTIVE_STATISTICS_DIALOG:
177 case SID_ANALYSIS_OF_VARIANCE_DIALOG:
178 case SID_CORRELATION_DIALOG:
179 case SID_COVARIANCE_DIALOG:
181 bDisable = !bSimpleArea;
183 break;
185 case FID_FILL_SERIES: // fill block
186 case SID_OPENDLG_TABOP: // multiple-cell operations, are at least 2 cells marked?
187 if (pDoc->GetChangeTrack()!=NULL &&nWhich ==SID_OPENDLG_TABOP)
188 bDisable = sal_True;
189 else
190 bDisable = (!bSimpleArea) || (nCol1 == nCol2 && nRow1 == nRow2);
192 if ( !bDisable && bEditable && nWhich == FID_FILL_SERIES )
193 { // do not damage matrix
194 bDisable = pDoc->HasSelectedBlockMatrixFragment(
195 nCol1, nRow1, nCol2, nRow1, rMark ) // first row
196 || pDoc->HasSelectedBlockMatrixFragment(
197 nCol1, nRow2, nCol2, nRow2, rMark ) // last row
198 || pDoc->HasSelectedBlockMatrixFragment(
199 nCol1, nRow1, nCol1, nRow2, rMark ) // first column
200 || pDoc->HasSelectedBlockMatrixFragment(
201 nCol2, nRow1, nCol2, nRow2, rMark ); // last column
203 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 = sal_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;
258 if (!bDisable && bNeedEdit && !bEditable)
259 bDisable = sal_True;
261 if (bDisable)
262 rSet.DisableItem(nWhich);
263 else if (nWhich == SID_ENABLE_HYPHENATION)
265 // toggle slots need a bool item
266 rSet.Put( SfxBoolItem( nWhich, false ) );
268 nWhich = aIter.NextWhich();
272 // functionen, disabled depending on cursor position
273 // Default:
274 // SID_INSERT_POSTIT, SID_CHARMAP, SID_OPENDLG_FUNCTION
276 void ScCellShell::GetCellState( SfxItemSet& rSet )
278 ScDocShell* pDocShell = GetViewData()->GetDocShell();
279 ScDocument* pDoc = GetViewData()->GetDocShell()->GetDocument();
280 ScAddress aCursor( GetViewData()->GetCurX(), GetViewData()->GetCurY(),
281 GetViewData()->GetTabNo() );
283 SfxWhichIter aIter(rSet);
284 sal_uInt16 nWhich = aIter.FirstWhich();
285 while ( nWhich )
287 sal_Bool bDisable = false;
288 sal_Bool bNeedEdit = sal_True; // need cursor position be editable?
289 switch ( nWhich )
291 case SID_THESAURUS:
293 CellType eType = pDoc->GetCellType( aCursor );
294 bDisable = ( eType != CELLTYPE_STRING && eType != CELLTYPE_EDIT);
295 if (!bDisable)
297 // test for available languages
298 sal_uInt16 nLang = ScViewUtil::GetEffLanguage( pDoc, aCursor );
299 bDisable = !ScModule::HasThesaurusLanguage( nLang );
302 break;
303 case SID_OPENDLG_FUNCTION:
305 ScMarkData aMarkData=GetViewData()->GetMarkData();
306 aMarkData.MarkToSimple();
307 ScRange aRange;
308 aMarkData.GetMarkArea(aRange);
309 if(aMarkData.IsMarked())
311 if (!pDoc->IsBlockEditable( aCursor.Tab(), aRange.aStart.Col(),aRange.aStart.Row(),
312 aRange.aEnd.Col(),aRange.aEnd.Row() ))
314 bDisable = sal_True;
316 bNeedEdit=false;
320 break;
321 case SID_INSERT_POSTIT:
323 if ( pDocShell && pDocShell->IsDocShared() )
325 bDisable = sal_True;
328 break;
330 if (!bDisable && bNeedEdit)
331 if (!pDoc->IsBlockEditable( aCursor.Tab(), aCursor.Col(),aCursor.Row(),
332 aCursor.Col(),aCursor.Row() ))
333 bDisable = sal_True;
334 if (bDisable)
335 rSet.DisableItem(nWhich);
336 nWhich = aIter.NextWhich();
340 static sal_Bool lcl_TestFormat( SvxClipboardFmtItem& rFormats, const TransferableDataHelper& rDataHelper,
341 SotFormatStringId nFormatId )
343 if ( rDataHelper.HasFormat( nFormatId ) )
345 // translated format name strings are no longer inserted here,
346 // handled by "paste special" dialog / toolbox controller instead.
347 // Only the object type name has to be set here:
348 OUString aStrVal;
349 if ( nFormatId == SOT_FORMATSTR_ID_EMBED_SOURCE )
351 TransferableObjectDescriptor aDesc;
352 if ( ((TransferableDataHelper&)rDataHelper).GetTransferableObjectDescriptor(
353 SOT_FORMATSTR_ID_OBJECTDESCRIPTOR, aDesc ) )
354 aStrVal = aDesc.maTypeName;
356 else if ( nFormatId == SOT_FORMATSTR_ID_EMBED_SOURCE_OLE
357 || nFormatId == SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE )
359 OUString aSource;
360 SvPasteObjectHelper::GetEmbeddedName( rDataHelper, aStrVal, aSource, nFormatId );
363 if ( !aStrVal.isEmpty() )
364 rFormats.AddClipbrdFormat( nFormatId, aStrVal );
365 else
366 rFormats.AddClipbrdFormat( nFormatId );
368 return sal_True;
371 return false;
374 void ScCellShell::GetPossibleClipboardFormats( SvxClipboardFmtItem& rFormats )
376 Window* pWin = GetViewData()->GetActiveWin();
377 sal_Bool bDraw = ( ScDrawTransferObj::GetOwnClipboard( pWin ) != NULL );
379 TransferableDataHelper aDataHelper( TransferableDataHelper::CreateFromSystemClipboard( pWin ) );
381 lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_DRAWING );
382 lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_SVXB );
383 lcl_TestFormat( rFormats, aDataHelper, SOT_FORMAT_GDIMETAFILE );
384 lcl_TestFormat( rFormats, aDataHelper, SOT_FORMAT_BITMAP );
385 lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_EMBED_SOURCE );
387 if ( !bDraw )
389 lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_LINK );
390 lcl_TestFormat( rFormats, aDataHelper, SOT_FORMAT_STRING );
391 lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_DIF );
392 lcl_TestFormat( rFormats, aDataHelper, SOT_FORMAT_RTF );
393 lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_HTML );
394 lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_HTML_SIMPLE );
395 lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_BIFF_8 );
396 lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_BIFF_5 );
399 if ( !lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_EMBED_SOURCE_OLE ) )
400 lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE );
403 // insert, insert contents
405 static sal_Bool lcl_IsCellPastePossible( const TransferableDataHelper& rData )
407 sal_Bool bPossible = false;
408 if ( ScTransferObj::GetOwnClipboard( NULL ) || ScDrawTransferObj::GetOwnClipboard( NULL ) )
409 bPossible = sal_True;
410 else
412 if ( rData.HasFormat( SOT_FORMAT_BITMAP ) ||
413 rData.HasFormat( SOT_FORMAT_GDIMETAFILE ) ||
414 rData.HasFormat( SOT_FORMATSTR_ID_SVXB ) ||
415 rData.HasFormat( FORMAT_PRIVATE ) ||
416 rData.HasFormat( SOT_FORMAT_RTF ) ||
417 rData.HasFormat( SOT_FORMATSTR_ID_EMBED_SOURCE ) ||
418 rData.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE ) ||
419 rData.HasFormat( SOT_FORMATSTR_ID_EMBED_SOURCE_OLE ) ||
420 rData.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE_OLE ) ||
421 rData.HasFormat( SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE ) ||
422 rData.HasFormat( SOT_FORMAT_STRING ) ||
423 rData.HasFormat( SOT_FORMATSTR_ID_SYLK ) ||
424 rData.HasFormat( SOT_FORMATSTR_ID_LINK ) ||
425 rData.HasFormat( SOT_FORMATSTR_ID_HTML ) ||
426 rData.HasFormat( SOT_FORMATSTR_ID_HTML_SIMPLE ) ||
427 rData.HasFormat( SOT_FORMATSTR_ID_DIF ) )
429 bPossible = sal_True;
432 return bPossible;
435 IMPL_LINK( ScCellShell, ClipboardChanged, TransferableDataHelper*, pDataHelper )
437 if ( pDataHelper )
439 bPastePossible = lcl_IsCellPastePossible( *pDataHelper );
441 SfxBindings& rBindings = GetViewData()->GetBindings();
442 rBindings.Invalidate( SID_PASTE );
443 rBindings.Invalidate( SID_PASTE_SPECIAL );
444 rBindings.Invalidate( SID_PASTE_ONLY_VALUE );
445 rBindings.Invalidate( SID_PASTE_ONLY_TEXT );
446 rBindings.Invalidate( SID_PASTE_ONLY_FORMULA );
447 rBindings.Invalidate( SID_CLIPBOARD_FORMAT_ITEMS );
449 return 0;
452 namespace {
454 bool checkDestRanges(ScViewData& rViewData)
456 ScRange aDummy;
457 ScMarkType eMarkType = rViewData.GetSimpleArea( aDummy);
458 if (eMarkType != SC_MARK_MULTI)
460 // Single destination range.
461 if (eMarkType != SC_MARK_SIMPLE && eMarkType != SC_MARK_SIMPLE_FILTERED)
462 return false;
465 // Multiple destination ranges.
467 ScDocument* pDoc = rViewData.GetDocument();
468 Window* pWin = rViewData.GetActiveWin();
469 if (!pWin)
470 return false;
472 ScTransferObj* pOwnClip = ScTransferObj::GetOwnClipboard(pWin);
473 if (!pOwnClip)
474 // If it's not a Calc document, we won't be picky.
475 return true;
477 ScDocument* pClipDoc = pOwnClip->GetDocument();
478 if (!pClipDoc)
479 return false;
481 ScRange aSrcRange = pClipDoc->GetClipParam().getWholeRange();
482 SCROW nRowSize = aSrcRange.aEnd.Row() - aSrcRange.aStart.Row() + 1;
483 SCCOL nColSize = aSrcRange.aEnd.Col() - aSrcRange.aStart.Col() + 1;
485 ScMarkData aMark = rViewData.GetMarkData();
486 ScRangeList aRanges;
487 aMark.MarkToSimple();
488 aMark.FillRangeListWithMarks(&aRanges, false);
490 return ScClipUtil::CheckDestRanges(pDoc, nColSize, nRowSize, aMark, aRanges);
495 void ScCellShell::GetClipState( SfxItemSet& rSet )
497 // SID_PASTE
498 // SID_PASTE_SPECIAL
499 // SID_CLIPBOARD_FORMAT_ITEMS
501 if ( !pImpl->m_pClipEvtLstnr )
503 // create listener
504 pImpl->m_pClipEvtLstnr = new TransferableClipboardListener( LINK( this, ScCellShell, ClipboardChanged ) );
505 pImpl->m_pClipEvtLstnr->acquire();
506 Window* pWin = GetViewData()->GetActiveWin();
507 pImpl->m_pClipEvtLstnr->AddRemoveListener( pWin, sal_True );
509 // get initial state
510 TransferableDataHelper aDataHelper( TransferableDataHelper::CreateFromSystemClipboard( pWin ) );
511 bPastePossible = lcl_IsCellPastePossible( aDataHelper );
514 bool bDisable = !bPastePossible;
516 // cell protection / multiple selection
518 if (!bDisable)
520 SCCOL nCol = GetViewData()->GetCurX();
521 SCROW nRow = GetViewData()->GetCurY();
522 SCTAB nTab = GetViewData()->GetTabNo();
523 ScDocument* pDoc = GetViewData()->GetDocShell()->GetDocument();
524 if (!pDoc->IsBlockEditable( nTab, nCol,nRow, nCol,nRow ))
525 bDisable = true;
527 if (!checkDestRanges(*GetViewData()))
528 bDisable = true;
531 if (bDisable)
533 rSet.DisableItem( SID_PASTE );
534 rSet.DisableItem( SID_PASTE_SPECIAL );
535 rSet.DisableItem( SID_PASTE_ONLY_VALUE );
536 rSet.DisableItem( SID_PASTE_ONLY_TEXT );
537 rSet.DisableItem( SID_PASTE_ONLY_FORMULA );
538 rSet.DisableItem( SID_CLIPBOARD_FORMAT_ITEMS );
540 else if ( rSet.GetItemState( SID_CLIPBOARD_FORMAT_ITEMS ) != SFX_ITEM_UNKNOWN )
542 SvxClipboardFmtItem aFormats( SID_CLIPBOARD_FORMAT_ITEMS );
543 GetPossibleClipboardFormats( aFormats );
544 rSet.Put( aFormats );
548 // only SID_HYPERLINK_GETLINK:
550 void ScCellShell::GetHLinkState( SfxItemSet& rSet )
552 // always return an item (or inserting will be disabled)
553 // if the cell at the cursor contains only a link, return that link
555 SvxHyperlinkItem aHLinkItem;
556 if ( !GetViewData()->GetView()->HasBookmarkAtCursor( &aHLinkItem ) )
558 //! put selected text into item?
561 rSet.Put(aHLinkItem);
564 void ScCellShell::GetState(SfxItemSet &rSet)
566 ScTabViewShell* pTabViewShell = GetViewData()->GetViewShell();
567 ScDocShell* pDocSh = GetViewData()->GetDocShell();
568 ScViewData* pData = GetViewData();
569 ScDocument* pDoc = pData->GetDocument();
570 ScMarkData& rMark = pData->GetMarkData();
571 SCCOL nPosX = pData->GetCurX();
572 SCROW nPosY = pData->GetCurY();
573 SCTAB nTab = pData->GetTabNo();
575 SCTAB nTabCount = pDoc->GetTableCount();
576 SCTAB nTabSelCount = rMark.GetSelectCount();
578 SfxWhichIter aIter(rSet);
579 sal_uInt16 nWhich = aIter.FirstWhich();
580 while ( nWhich )
582 switch ( nWhich )
584 case SID_DETECTIVE_REFRESH:
585 if (!pDoc->HasDetectiveOperations())
586 rSet.DisableItem( nWhich );
587 break;
589 case SID_RANGE_ADDRESS:
591 ScRange aRange;
592 if ( pData->GetSimpleArea( aRange ) == SC_MARK_SIMPLE )
594 sal_uInt16 nFlags = SCA_VALID | SCA_TAB_3D;
595 OUString aStr(aRange.Format(nFlags,pDoc));
596 rSet.Put( SfxStringItem( nWhich, aStr ) );
599 break;
601 case SID_RANGE_NOTETEXT:
603 // always take cursor position, do not use top-left cell of selection
604 OUString aNoteText;
605 if ( const ScPostIt* pNote = pDoc->GetNote(nPosX, nPosY, nTab) )
606 aNoteText = pNote->GetText();
607 rSet.Put( SfxStringItem( nWhich, aNoteText ) );
609 break;
611 case SID_RANGE_ROW:
612 rSet.Put( SfxInt32Item( nWhich, nPosY+1 ) );
613 break;
615 case SID_RANGE_COL:
616 rSet.Put( SfxInt16Item( nWhich, nPosX+1 ) );
617 break;
619 case SID_RANGE_TABLE:
620 rSet.Put( SfxInt16Item( nWhich, nTab+1 ) );
621 break;
623 case SID_RANGE_VALUE:
625 double nValue;
626 pDoc->GetValue( nPosX, nPosY, nTab, nValue );
627 rSet.Put( ScDoubleItem( nWhich, nValue ) );
629 break;
631 case SID_RANGE_FORMULA:
633 OUString aString;
634 pDoc->GetFormula( nPosX, nPosY, nTab, aString );
635 if( aString.isEmpty() )
637 pDoc->GetInputString( nPosX, nPosY, nTab, aString );
639 rSet.Put( SfxStringItem( nWhich, aString ) );
641 break;
643 case SID_RANGE_TEXTVALUE:
645 OUString aString = pDoc->GetString(nPosX, nPosY, nTab);
646 rSet.Put( SfxStringItem( nWhich, aString ) );
648 break;
650 case SID_STATUS_SELMODE:
652 /* 0: STD Click cancels Sel
653 * 1: ER Click extends selection
654 * 2: ERG Click defines further selection
656 sal_uInt16 nMode = pTabViewShell->GetLockedModifiers();
658 switch ( nMode )
660 case KEY_SHIFT: nMode = 1; break;
661 case KEY_MOD1: nMode = 2; break; // Control-key
662 case 0:
663 default:
664 nMode = 0;
667 rSet.Put( SfxUInt16Item( nWhich, nMode ) );
669 break;
671 case SID_STATUS_DOCPOS:
673 OUString aStr = ScGlobal::GetRscString( STR_TABLE ) +
674 " " + OUString::number( nTab + 1 ) +
675 " / " + OUString::number( nTabCount );
676 rSet.Put( SfxStringItem( nWhich, aStr ) );
678 break;
680 // calculations etc. with date/time/Fail/position&size together
682 // #i34458# The SfxStringItem belongs only into SID_TABLE_CELL. It no longer has to be
683 // duplicated in SID_ATTR_POSITION or SID_ATTR_SIZE for SvxPosSizeStatusBarControl.
684 case SID_TABLE_CELL:
686 // Test, if error under cursor
687 // (not pDoc->GetErrCode, to avoid erasing circular references)
689 // In interpreter may happen via rescheduled Basic
690 if ( pDoc->IsInInterpreter() )
691 rSet.Put( SfxStringItem( nWhich, OUString("...") ) );
692 else
694 sal_uInt16 nErrCode = 0;
695 ScFormulaCell* pCell = pDoc->GetFormulaCell(ScAddress(nPosX, nPosY, nTab));
696 if (pCell)
698 if (!pCell->IsRunning())
699 nErrCode = pCell->GetErrCode();
702 OUString aFuncStr;
703 if ( pTabViewShell->GetFunction( aFuncStr, nErrCode ) )
704 rSet.Put( SfxStringItem( nWhich, aFuncStr ) );
707 break;
709 case SID_DATA_SELECT:
710 // HasSelectionData includes column content and validity,
711 // page fields have to be checked separately.
712 if ( !pDoc->HasSelectionData( nPosX, nPosY, nTab ) &&
713 !pTabViewShell->HasPageFieldDataAtCursor() )
714 rSet.DisableItem( nWhich );
715 break;
717 case SID_STATUS_SUM:
719 OUString aFuncStr;
720 if ( pTabViewShell->GetFunction( aFuncStr ) )
721 rSet.Put( SfxStringItem( nWhich, aFuncStr ) );
723 break;
725 case FID_MERGE_ON:
726 if ( pDoc->GetChangeTrack() || !pTabViewShell->TestMergeCells() )
727 rSet.DisableItem( nWhich );
728 break;
730 case FID_MERGE_OFF:
731 if ( pDoc->GetChangeTrack() || !pTabViewShell->TestRemoveMerge() )
732 rSet.DisableItem( nWhich );
733 break;
735 case FID_MERGE_TOGGLE:
736 if ( pDoc->GetChangeTrack() )
737 rSet.DisableItem( nWhich );
738 else
740 bool bCanMerge = pTabViewShell->TestMergeCells();
741 bool bCanSplit = pTabViewShell->TestRemoveMerge();
742 if( !bCanMerge && !bCanSplit )
743 rSet.DisableItem( nWhich );
744 else
745 rSet.Put( SfxBoolItem( nWhich, bCanSplit ) );
747 break;
749 case FID_INS_ROWBRK:
750 if ( nPosY==0 || (pDoc->HasRowBreak(nPosY, nTab) & BREAK_MANUAL) )
751 rSet.DisableItem( nWhich );
752 break;
754 case FID_INS_COLBRK:
755 if ( nPosX==0 || (pDoc->HasColBreak(nPosX, nTab) & BREAK_MANUAL) )
756 rSet.DisableItem( nWhich );
757 break;
759 case FID_DEL_ROWBRK:
760 if ( nPosY==0 || (pDoc->HasRowBreak(nPosY, nTab) & BREAK_MANUAL) == 0 )
761 rSet.DisableItem( nWhich );
762 break;
764 case FID_DEL_COLBRK:
765 if ( nPosX==0 || (pDoc->HasColBreak(nPosX, nTab) & BREAK_MANUAL) == 0 )
766 rSet.DisableItem( nWhich );
767 break;
769 case FID_FILL_TAB:
770 if ( nTabSelCount < 2 )
771 rSet.DisableItem( nWhich );
772 break;
774 case SID_SELECT_SCENARIO:
776 std::vector<OUString> aList;
777 Color aDummyCol;
779 if ( !pDoc->IsScenario(nTab) )
781 OUString aStr;
782 sal_uInt16 nFlags;
783 SCTAB nScTab = nTab + 1;
784 bool bSheetProtected = pDoc->IsTabProtected(nTab);
786 while ( pDoc->IsScenario(nScTab) )
788 pDoc->GetName( nScTab, aStr );
789 aList.push_back(aStr);
790 pDoc->GetScenarioData( nScTab, aStr, aDummyCol, nFlags );
791 aList.push_back(aStr);
792 // Protection is sal_True if both Sheet and Scenario are protected
793 aList.push_back((bSheetProtected && (nFlags & SC_SCENARIO_PROTECT)) ? OUString("1") : OUString("0"));
794 ++nScTab;
797 else
799 OUString aComment;
800 sal_uInt16 nDummyFlags;
801 pDoc->GetScenarioData( nTab, aComment, aDummyCol, nDummyFlags );
802 OSL_ENSURE( aList.empty(), "List not empty!" );
803 aList.push_back(aComment);
806 rSet.Put( SfxStringListItem( nWhich, &aList ) );
808 break;
810 case FID_ROW_HIDE:
811 case FID_ROW_SHOW:
812 case FID_COL_HIDE:
813 case FID_COL_SHOW:
814 case FID_COL_OPT_WIDTH:
815 case FID_ROW_OPT_HEIGHT:
816 case FID_DELETE_CELL:
817 if ( pDoc->IsTabProtected(nTab) || pDocSh->IsReadOnly())
818 rSet.DisableItem( nWhich );
819 break;
821 case SID_OUTLINE_MAKE:
823 if ( GetViewData()->GetDocument()->GetDPAtCursor( GetViewData()->GetCurX(),
824 GetViewData()->GetCurY(), GetViewData()->GetTabNo() ) )
826 //! test for data pilot operation
828 else if (pDoc->GetChangeTrack()!=NULL || GetViewData()->IsMultiMarked())
830 rSet.DisableItem( nWhich );
833 break;
834 case SID_OUTLINE_SHOW:
835 if ( GetViewData()->GetDocument()->GetDPAtCursor( GetViewData()->GetCurX(),
836 GetViewData()->GetCurY(), GetViewData()->GetTabNo() ) )
838 //! test for data pilot operation
840 else if (!pTabViewShell->OutlinePossible(false))
841 rSet.DisableItem( nWhich );
842 break;
844 case SID_OUTLINE_HIDE:
845 if ( GetViewData()->GetDocument()->GetDPAtCursor( GetViewData()->GetCurX(),
846 GetViewData()->GetCurY(), GetViewData()->GetTabNo() ) )
848 //! test for data pilot operation
850 else if (!pTabViewShell->OutlinePossible(sal_True))
851 rSet.DisableItem( nWhich );
852 break;
854 case SID_OUTLINE_REMOVE:
856 if ( GetViewData()->GetDocument()->GetDPAtCursor( GetViewData()->GetCurX(),
857 GetViewData()->GetCurY(), GetViewData()->GetTabNo() ) )
859 //! test for data pilot operation
861 else
863 sal_Bool bCol, bRow;
864 pTabViewShell->TestRemoveOutline( bCol, bRow );
865 if ( !bCol && !bRow )
866 rSet.DisableItem( nWhich );
869 break;
871 case FID_COL_WIDTH:
873 //GetViewData()->GetCurX();
874 SfxUInt16Item aWidthItem( FID_COL_WIDTH, pDoc->GetColWidth( nPosX , nTab) );
875 rSet.Put( aWidthItem );
876 if ( pDocSh->IsReadOnly())
877 rSet.DisableItem( nWhich );
879 //XXX disable if not conclusive
881 break;
883 case FID_ROW_HEIGHT:
885 //GetViewData()->GetCurY();
886 SfxUInt16Item aHeightItem( FID_ROW_HEIGHT, pDoc->GetRowHeight( nPosY , nTab) );
887 rSet.Put( aHeightItem );
888 //XXX disable if not conclusive
889 if ( pDocSh->IsReadOnly())
890 rSet.DisableItem( nWhich );
892 break;
894 case SID_DETECTIVE_FILLMODE:
895 rSet.Put(SfxBoolItem( nWhich, pTabViewShell->IsAuditShell() ));
896 break;
898 case FID_INPUTLINE_STATUS:
899 OSL_FAIL( "Old update method. Use ScTabViewShell::UpdateInputHandler()." );
900 break;
902 case SID_SCENARIOS: // scenarios:
903 if (!(rMark.IsMarked() || rMark.IsMultiMarked())) // only, if something selected
904 rSet.DisableItem( nWhich );
905 break;
907 case FID_NOTE_VISIBLE:
909 const ScPostIt* pNote = pDoc->GetNote(nPosX, nPosY, nTab);
910 if ( pNote && pDoc->IsBlockEditable( nTab, nPosX,nPosY, nPosX,nPosY ) )
911 rSet.Put( SfxBoolItem( nWhich, pNote->IsCaptionShown() ) );
912 else
913 rSet.DisableItem( nWhich );
915 break;
917 case FID_HIDE_NOTE:
918 case FID_SHOW_NOTE:
920 bool bEnable = false;
921 bool bSearchForHidden = nWhich == FID_SHOW_NOTE;
922 if (!rMark.IsMarked() && !rMark.IsMultiMarked())
924 // Check current cell
925 const ScPostIt* pNote = pDoc->GetNote(nPosX, nPosY, nTab);
926 if ( pNote && pDoc->IsBlockEditable( nTab, nPosX,nPosY, nPosX,nPosY ) )
927 if ( pNote->IsCaptionShown() != bSearchForHidden)
928 bEnable = true;
930 else
932 // Check selection range
933 ScRangeListRef aRangesRef;
934 pData->GetMultiArea(aRangesRef);
935 ScRangeList aRanges = *aRangesRef;
936 std::vector<sc::NoteEntry> aNotes;
937 pDoc->GetNotesInRange(aRanges, aNotes);
938 for(std::vector<sc::NoteEntry>::const_iterator itr = aNotes.begin(),
939 itrEnd = aNotes.end(); itr != itrEnd; ++itr)
941 const ScAddress& rAdr = itr->maPos;
942 if( pDoc->IsBlockEditable( rAdr.Tab(), rAdr.Col(), rAdr.Row(), rAdr.Col(), rAdr.Row() ))
944 if (itr->mpNote->IsCaptionShown() != bSearchForHidden)
946 bEnable = true;
947 break;
953 if ( !bEnable )
954 rSet.DisableItem( nWhich );
956 break;
958 case SID_DELETE_NOTE:
960 bool bEnable = false;
961 if ( rMark.IsMarked() || rMark.IsMultiMarked() )
963 if ( pDoc->IsSelectionEditable( rMark ) )
965 // look for at least one note in selection
966 ScRangeList aRanges;
967 rMark.FillRangeListWithMarks( &aRanges, false );
968 bEnable = pDoc->ContainsNotesInRange( aRanges );
971 else
973 bEnable = pDoc->IsBlockEditable( nTab, nPosX,nPosY, nPosX,nPosY ) &&
974 pDoc->GetNote(nPosX, nPosY, nTab);
976 if ( !bEnable )
977 rSet.DisableItem( nWhich );
979 break;
981 case SID_OPENDLG_CONSOLIDATE:
982 case SCITEM_CONSOLIDATEDATA:
984 if(pDoc->GetChangeTrack()!=NULL)
985 rSet.DisableItem( nWhich);
987 break;
989 case SID_CHINESE_CONVERSION:
990 case SID_HANGUL_HANJA_CONVERSION:
991 ScViewUtil::HideDisabledSlot( rSet, pData->GetBindings(), nWhich );
992 break;
994 case FID_USE_NAME:
996 if ( pDocSh && pDocSh->IsDocShared() )
997 rSet.DisableItem( nWhich );
998 else
1000 ScRange aRange;
1001 if ( pData->GetSimpleArea( aRange ) != SC_MARK_SIMPLE )
1002 rSet.DisableItem( nWhich );
1005 break;
1007 case FID_DEFINE_NAME:
1008 case FID_INSERT_NAME:
1009 case FID_ADD_NAME:
1010 case SID_DEFINE_COLROWNAMERANGES:
1012 if ( pDocSh && pDocSh->IsDocShared() )
1014 rSet.DisableItem( nWhich );
1017 break;
1019 case SID_SPELL_DIALOG:
1021 if ( pDoc && pData && pDoc->IsTabProtected( pData->GetTabNo() ) )
1023 bool bVisible = false;
1024 SfxViewFrame* pViewFrame = ( pTabViewShell ? pTabViewShell->GetViewFrame() : NULL );
1025 if ( pViewFrame && pViewFrame->HasChildWindow( nWhich ) )
1027 SfxChildWindow* pChild = pViewFrame->GetChildWindow( nWhich );
1028 Window* pWin = ( pChild ? pChild->GetWindow() : NULL );
1029 if ( pWin && pWin->IsVisible() )
1031 bVisible = true;
1034 if ( !bVisible )
1036 rSet.DisableItem( nWhich );
1040 break;
1042 } // switch ( nWitch )
1043 nWhich = aIter.NextWhich();
1044 } // while ( nWitch )
1047 //------------------------------------------------------------------
1051 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */