bump product version to 4.1.6.2
[LibreOffice.git] / sc / source / ui / view / cellsh.cxx
blob06856778bbf9653c01151d645fd19977a9ffdb09
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;
173 case FID_FILL_SERIES: // fill block
174 case SID_OPENDLG_TABOP: // multiple-cell operations, are at least 2 cells marked?
175 if (pDoc->GetChangeTrack()!=NULL &&nWhich ==SID_OPENDLG_TABOP)
176 bDisable = sal_True;
177 else
178 bDisable = (!bSimpleArea) || (nCol1 == nCol2 && nRow1 == nRow2);
180 if ( !bDisable && bEditable && nWhich == FID_FILL_SERIES )
181 { // do not damage matrix
182 bDisable = pDoc->HasSelectedBlockMatrixFragment(
183 nCol1, nRow1, nCol2, nRow1, rMark ) // first row
184 || pDoc->HasSelectedBlockMatrixFragment(
185 nCol1, nRow2, nCol2, nRow2, rMark ) // last row
186 || pDoc->HasSelectedBlockMatrixFragment(
187 nCol1, nRow1, nCol1, nRow2, rMark ) // first column
188 || pDoc->HasSelectedBlockMatrixFragment(
189 nCol2, nRow1, nCol2, nRow2, rMark ); // last column
191 break;
193 case SID_CUT: // cut
194 case FID_INS_CELL: // insert cells, just simple selection
195 bDisable = (!bSimpleArea);
196 break;
198 case FID_INS_ROW: // insert rows
199 case FID_INS_CELLSDOWN:
200 bDisable = (!bSimpleArea) || GetViewData()->SimpleColMarked();
201 break;
203 case FID_INS_COLUMN: // insert columns
204 case FID_INS_CELLSRIGHT:
205 bDisable = (!bSimpleArea) || GetViewData()->SimpleRowMarked();
206 break;
208 case SID_COPY: // copy
209 // not editable because of matrix only? Do not damage matrix
210 //! is not called, when protected AND matrix, we will have
211 //! to live with this... is caught in Copy-Routine, otherwise
212 //! work is to be done once more
213 if ( !(!bEditable && bOnlyNotBecauseOfMatrix) )
214 bNeedEdit = false; // allowed when protected/ReadOnly
215 break;
217 case SID_AUTOFORMAT: // Autoformat, at least 3x3 selected
218 bDisable = (!bSimpleArea)
219 || ((nCol2 - nCol1) < 2) || ((nRow2 - nRow1) < 2);
220 break;
222 case SID_CELL_FORMAT_RESET :
223 case FID_CELL_FORMAT :
224 case SID_ENABLE_HYPHENATION :
225 // not editable because of matrix only? Attribute ok nonetheless
226 if ( !bEditable && bOnlyNotBecauseOfMatrix )
227 bNeedEdit = false;
228 break;
230 case FID_VALIDATION:
232 if ( pDocShell && pDocShell->IsDocShared() )
234 bDisable = sal_True;
237 break;
239 case SID_TRANSLITERATE_HALFWIDTH:
240 case SID_TRANSLITERATE_FULLWIDTH:
241 case SID_TRANSLITERATE_HIRAGANA:
242 case SID_TRANSLITERATE_KATAGANA:
243 ScViewUtil::HideDisabledSlot( rSet, GetViewData()->GetBindings(), nWhich );
244 break;
246 if (!bDisable && bNeedEdit && !bEditable)
247 bDisable = sal_True;
249 if (bDisable)
250 rSet.DisableItem(nWhich);
251 else if (nWhich == SID_ENABLE_HYPHENATION)
253 // toggle slots need a bool item
254 rSet.Put( SfxBoolItem( nWhich, false ) );
256 nWhich = aIter.NextWhich();
260 // functionen, disabled depending on cursor position
261 // Default:
262 // SID_INSERT_POSTIT, SID_CHARMAP, SID_OPENDLG_FUNCTION
264 void ScCellShell::GetCellState( SfxItemSet& rSet )
266 ScDocShell* pDocShell = GetViewData()->GetDocShell();
267 ScDocument* pDoc = GetViewData()->GetDocShell()->GetDocument();
268 ScAddress aCursor( GetViewData()->GetCurX(), GetViewData()->GetCurY(),
269 GetViewData()->GetTabNo() );
271 SfxWhichIter aIter(rSet);
272 sal_uInt16 nWhich = aIter.FirstWhich();
273 while ( nWhich )
275 sal_Bool bDisable = false;
276 sal_Bool bNeedEdit = sal_True; // need cursor position be editable?
277 switch ( nWhich )
279 case SID_THESAURUS:
281 CellType eType = pDoc->GetCellType( aCursor );
282 bDisable = ( eType != CELLTYPE_STRING && eType != CELLTYPE_EDIT);
283 if (!bDisable)
285 // test for available languages
286 sal_uInt16 nLang = ScViewUtil::GetEffLanguage( pDoc, aCursor );
287 bDisable = !ScModule::HasThesaurusLanguage( nLang );
290 break;
291 case SID_OPENDLG_FUNCTION:
293 ScMarkData aMarkData=GetViewData()->GetMarkData();
294 aMarkData.MarkToSimple();
295 ScRange aRange;
296 aMarkData.GetMarkArea(aRange);
297 if(aMarkData.IsMarked())
299 if (!pDoc->IsBlockEditable( aCursor.Tab(), aRange.aStart.Col(),aRange.aStart.Row(),
300 aRange.aEnd.Col(),aRange.aEnd.Row() ))
302 bDisable = sal_True;
304 bNeedEdit=false;
308 break;
309 case SID_INSERT_POSTIT:
311 if ( pDocShell && pDocShell->IsDocShared() )
313 bDisable = sal_True;
316 break;
318 if (!bDisable && bNeedEdit)
319 if (!pDoc->IsBlockEditable( aCursor.Tab(), aCursor.Col(),aCursor.Row(),
320 aCursor.Col(),aCursor.Row() ))
321 bDisable = sal_True;
322 if (bDisable)
323 rSet.DisableItem(nWhich);
324 nWhich = aIter.NextWhich();
328 static sal_Bool lcl_TestFormat( SvxClipboardFmtItem& rFormats, const TransferableDataHelper& rDataHelper,
329 SotFormatStringId nFormatId )
331 if ( rDataHelper.HasFormat( nFormatId ) )
333 // translated format name strings are no longer inserted here,
334 // handled by "paste special" dialog / toolbox controller instead.
335 // Only the object type name has to be set here:
336 String aStrVal;
337 if ( nFormatId == SOT_FORMATSTR_ID_EMBED_SOURCE )
339 TransferableObjectDescriptor aDesc;
340 if ( ((TransferableDataHelper&)rDataHelper).GetTransferableObjectDescriptor(
341 SOT_FORMATSTR_ID_OBJECTDESCRIPTOR, aDesc ) )
342 aStrVal = aDesc.maTypeName;
344 else if ( nFormatId == SOT_FORMATSTR_ID_EMBED_SOURCE_OLE
345 || nFormatId == SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE )
347 String aSource;
348 SvPasteObjectHelper::GetEmbeddedName( rDataHelper, aStrVal, aSource, nFormatId );
351 if ( aStrVal.Len() )
352 rFormats.AddClipbrdFormat( nFormatId, aStrVal );
353 else
354 rFormats.AddClipbrdFormat( nFormatId );
356 return sal_True;
359 return false;
362 void ScCellShell::GetPossibleClipboardFormats( SvxClipboardFmtItem& rFormats )
364 Window* pWin = GetViewData()->GetActiveWin();
365 sal_Bool bDraw = ( ScDrawTransferObj::GetOwnClipboard( pWin ) != NULL );
367 TransferableDataHelper aDataHelper( TransferableDataHelper::CreateFromSystemClipboard( pWin ) );
369 lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_DRAWING );
370 lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_SVXB );
371 lcl_TestFormat( rFormats, aDataHelper, SOT_FORMAT_GDIMETAFILE );
372 lcl_TestFormat( rFormats, aDataHelper, SOT_FORMAT_BITMAP );
373 lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_EMBED_SOURCE );
375 if ( !bDraw )
377 lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_LINK );
378 lcl_TestFormat( rFormats, aDataHelper, SOT_FORMAT_STRING );
379 lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_DIF );
380 lcl_TestFormat( rFormats, aDataHelper, SOT_FORMAT_RTF );
381 lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_HTML );
382 lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_HTML_SIMPLE );
383 lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_BIFF_8 );
384 lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_BIFF_5 );
387 if ( !lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_EMBED_SOURCE_OLE ) )
388 lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE );
391 // insert, insert contents
393 static sal_Bool lcl_IsCellPastePossible( const TransferableDataHelper& rData )
395 sal_Bool bPossible = false;
396 if ( ScTransferObj::GetOwnClipboard( NULL ) || ScDrawTransferObj::GetOwnClipboard( NULL ) )
397 bPossible = sal_True;
398 else
400 if ( rData.HasFormat( SOT_FORMAT_BITMAP ) ||
401 rData.HasFormat( SOT_FORMAT_GDIMETAFILE ) ||
402 rData.HasFormat( SOT_FORMATSTR_ID_SVXB ) ||
403 rData.HasFormat( FORMAT_PRIVATE ) ||
404 rData.HasFormat( SOT_FORMAT_RTF ) ||
405 rData.HasFormat( SOT_FORMATSTR_ID_EMBED_SOURCE ) ||
406 rData.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE ) ||
407 rData.HasFormat( SOT_FORMATSTR_ID_EMBED_SOURCE_OLE ) ||
408 rData.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE_OLE ) ||
409 rData.HasFormat( SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE ) ||
410 rData.HasFormat( SOT_FORMAT_STRING ) ||
411 rData.HasFormat( SOT_FORMATSTR_ID_SYLK ) ||
412 rData.HasFormat( SOT_FORMATSTR_ID_LINK ) ||
413 rData.HasFormat( SOT_FORMATSTR_ID_HTML ) ||
414 rData.HasFormat( SOT_FORMATSTR_ID_HTML_SIMPLE ) ||
415 rData.HasFormat( SOT_FORMATSTR_ID_DIF ) )
417 bPossible = sal_True;
420 return bPossible;
423 IMPL_LINK( ScCellShell, ClipboardChanged, TransferableDataHelper*, pDataHelper )
425 if ( pDataHelper )
427 bPastePossible = lcl_IsCellPastePossible( *pDataHelper );
429 SfxBindings& rBindings = GetViewData()->GetBindings();
430 rBindings.Invalidate( SID_PASTE );
431 rBindings.Invalidate( SID_PASTE_SPECIAL );
432 rBindings.Invalidate( SID_PASTE_ONLY_VALUE );
433 rBindings.Invalidate( SID_PASTE_ONLY_TEXT );
434 rBindings.Invalidate( SID_PASTE_ONLY_FORMULA );
435 rBindings.Invalidate( SID_CLIPBOARD_FORMAT_ITEMS );
437 return 0;
440 namespace {
442 bool checkDestRanges(ScViewData& rViewData)
444 ScRange aDummy;
445 ScMarkType eMarkType = rViewData.GetSimpleArea( aDummy);
446 if (eMarkType != SC_MARK_MULTI)
448 // Single destination range.
449 if (eMarkType != SC_MARK_SIMPLE && eMarkType != SC_MARK_SIMPLE_FILTERED)
450 return false;
453 // Multiple destination ranges.
455 ScDocument* pDoc = rViewData.GetDocument();
456 Window* pWin = rViewData.GetActiveWin();
457 if (!pWin)
458 return false;
460 ScTransferObj* pOwnClip = ScTransferObj::GetOwnClipboard(pWin);
461 if (!pOwnClip)
462 // If it's not a Calc document, we won't be picky.
463 return true;
465 ScDocument* pClipDoc = pOwnClip->GetDocument();
466 if (!pClipDoc)
467 return false;
469 ScRange aSrcRange = pClipDoc->GetClipParam().getWholeRange();
470 SCROW nRowSize = aSrcRange.aEnd.Row() - aSrcRange.aStart.Row() + 1;
471 SCCOL nColSize = aSrcRange.aEnd.Col() - aSrcRange.aStart.Col() + 1;
473 ScMarkData aMark = rViewData.GetMarkData();
474 ScRangeList aRanges;
475 aMark.MarkToSimple();
476 aMark.FillRangeListWithMarks(&aRanges, false);
478 return ScClipUtil::CheckDestRanges(pDoc, nColSize, nRowSize, aMark, aRanges);
483 void ScCellShell::GetClipState( SfxItemSet& rSet )
485 // SID_PASTE
486 // SID_PASTE_SPECIAL
487 // SID_CLIPBOARD_FORMAT_ITEMS
489 if ( !pImpl->m_pClipEvtLstnr )
491 // create listener
492 pImpl->m_pClipEvtLstnr = new TransferableClipboardListener( LINK( this, ScCellShell, ClipboardChanged ) );
493 pImpl->m_pClipEvtLstnr->acquire();
494 Window* pWin = GetViewData()->GetActiveWin();
495 pImpl->m_pClipEvtLstnr->AddRemoveListener( pWin, sal_True );
497 // get initial state
498 TransferableDataHelper aDataHelper( TransferableDataHelper::CreateFromSystemClipboard( pWin ) );
499 bPastePossible = lcl_IsCellPastePossible( aDataHelper );
502 bool bDisable = !bPastePossible;
504 // cell protection / multiple selection
506 if (!bDisable)
508 SCCOL nCol = GetViewData()->GetCurX();
509 SCROW nRow = GetViewData()->GetCurY();
510 SCTAB nTab = GetViewData()->GetTabNo();
511 ScDocument* pDoc = GetViewData()->GetDocShell()->GetDocument();
512 if (!pDoc->IsBlockEditable( nTab, nCol,nRow, nCol,nRow ))
513 bDisable = true;
515 if (!checkDestRanges(*GetViewData()))
516 bDisable = true;
519 if (bDisable)
521 rSet.DisableItem( SID_PASTE );
522 rSet.DisableItem( SID_PASTE_SPECIAL );
523 rSet.DisableItem( SID_PASTE_ONLY_VALUE );
524 rSet.DisableItem( SID_PASTE_ONLY_TEXT );
525 rSet.DisableItem( SID_PASTE_ONLY_FORMULA );
526 rSet.DisableItem( SID_CLIPBOARD_FORMAT_ITEMS );
528 else if ( rSet.GetItemState( SID_CLIPBOARD_FORMAT_ITEMS ) != SFX_ITEM_UNKNOWN )
530 SvxClipboardFmtItem aFormats( SID_CLIPBOARD_FORMAT_ITEMS );
531 GetPossibleClipboardFormats( aFormats );
532 rSet.Put( aFormats );
536 // only SID_HYPERLINK_GETLINK:
538 void ScCellShell::GetHLinkState( SfxItemSet& rSet )
540 // always return an item (or inserting will be disabled)
541 // if the cell at the cursor contains only a link, return that link
543 SvxHyperlinkItem aHLinkItem;
544 if ( !GetViewData()->GetView()->HasBookmarkAtCursor( &aHLinkItem ) )
546 //! put selected text into item?
549 rSet.Put(aHLinkItem);
552 void ScCellShell::GetState(SfxItemSet &rSet)
554 ScTabViewShell* pTabViewShell = GetViewData()->GetViewShell();
555 ScDocShell* pDocSh = GetViewData()->GetDocShell();
556 ScViewData* pData = GetViewData();
557 ScDocument* pDoc = pData->GetDocument();
558 ScMarkData& rMark = pData->GetMarkData();
559 SCCOL nPosX = pData->GetCurX();
560 SCROW nPosY = pData->GetCurY();
561 SCTAB nTab = pData->GetTabNo();
563 SCTAB nTabCount = pDoc->GetTableCount();
564 SCTAB nTabSelCount = rMark.GetSelectCount();
566 SfxWhichIter aIter(rSet);
567 sal_uInt16 nWhich = aIter.FirstWhich();
568 while ( nWhich )
570 switch ( nWhich )
572 case SID_DETECTIVE_REFRESH:
573 if (!pDoc->HasDetectiveOperations())
574 rSet.DisableItem( nWhich );
575 break;
577 case SID_RANGE_ADDRESS:
579 ScRange aRange;
580 if ( pData->GetSimpleArea( aRange ) == SC_MARK_SIMPLE )
582 String aStr;
583 sal_uInt16 nFlags = SCA_VALID | SCA_TAB_3D;
584 aRange.Format(aStr,nFlags,pDoc);
585 rSet.Put( SfxStringItem( nWhich, aStr ) );
588 break;
590 case SID_RANGE_NOTETEXT:
592 // always take cursor position, do not use top-left cell of selection
593 String aNoteText;
594 if ( const ScPostIt* pNote = pDoc->GetNotes(nTab)->findByAddress(nPosX, nPosY) )
595 aNoteText = pNote->GetText();
596 rSet.Put( SfxStringItem( nWhich, aNoteText ) );
598 break;
600 case SID_RANGE_ROW:
601 rSet.Put( SfxInt32Item( nWhich, nPosY+1 ) );
602 break;
604 case SID_RANGE_COL:
605 rSet.Put( SfxInt16Item( nWhich, nPosX+1 ) );
606 break;
608 case SID_RANGE_TABLE:
609 rSet.Put( SfxInt16Item( nWhich, nTab+1 ) );
610 break;
612 case SID_RANGE_VALUE:
614 double nValue;
615 pDoc->GetValue( nPosX, nPosY, nTab, nValue );
616 rSet.Put( ScDoubleItem( nWhich, nValue ) );
618 break;
620 case SID_RANGE_FORMULA:
622 String aString;
623 pDoc->GetFormula( nPosX, nPosY, nTab, aString );
624 if( aString.Len() == 0 )
626 pDoc->GetInputString( nPosX, nPosY, nTab, aString );
628 rSet.Put( SfxStringItem( nWhich, aString ) );
630 break;
632 case SID_RANGE_TEXTVALUE:
634 OUString aString = pDoc->GetString(nPosX, nPosY, nTab);
635 rSet.Put( SfxStringItem( nWhich, aString ) );
637 break;
639 case SID_STATUS_SELMODE:
641 /* 0: STD Click cancels Sel
642 * 1: ER Click extends selection
643 * 2: ERG Click defines further selection
645 sal_uInt16 nMode = pTabViewShell->GetLockedModifiers();
647 switch ( nMode )
649 case KEY_SHIFT: nMode = 1; break;
650 case KEY_MOD1: nMode = 2; break; // Control-key
651 case 0:
652 default:
653 nMode = 0;
656 rSet.Put( SfxUInt16Item( nWhich, nMode ) );
658 break;
660 case SID_STATUS_DOCPOS:
662 OUString aStr = ScGlobal::GetRscString( STR_TABLE ) +
663 " " + OUString::number( nTab + 1 ) +
664 " / " + OUString::number( nTabCount );
665 rSet.Put( SfxStringItem( nWhich, aStr ) );
667 break;
669 // calculations etc. with date/time/Fail/position&size together
671 // #i34458# The SfxStringItem belongs only into SID_TABLE_CELL. It no longer has to be
672 // duplicated in SID_ATTR_POSITION or SID_ATTR_SIZE for SvxPosSizeStatusBarControl.
673 case SID_TABLE_CELL:
675 // Test, if error under cursor
676 // (not pDoc->GetErrCode, to avoid erasing circular references)
678 // In interpreter may happen via rescheduled Basic
679 if ( pDoc->IsInInterpreter() )
680 rSet.Put( SfxStringItem( nWhich, OUString("...") ) );
681 else
683 sal_uInt16 nErrCode = 0;
684 ScFormulaCell* pCell = pDoc->GetFormulaCell(ScAddress(nPosX, nPosY, nTab));
685 if (pCell)
687 if (!pCell->IsRunning())
688 nErrCode = pCell->GetErrCode();
691 String aFuncStr;
692 if ( pTabViewShell->GetFunction( aFuncStr, nErrCode ) )
693 rSet.Put( SfxStringItem( nWhich, aFuncStr ) );
696 break;
698 case SID_DATA_SELECT:
699 // HasSelectionData includes column content and validity,
700 // page fields have to be checked separately.
701 if ( !pDoc->HasSelectionData( nPosX, nPosY, nTab ) &&
702 !pTabViewShell->HasPageFieldDataAtCursor() )
703 rSet.DisableItem( nWhich );
704 break;
706 case SID_STATUS_SUM:
708 String aFuncStr;
709 if ( pTabViewShell->GetFunction( aFuncStr ) )
710 rSet.Put( SfxStringItem( nWhich, aFuncStr ) );
712 break;
714 case FID_MERGE_ON:
715 if ( pDoc->GetChangeTrack() || !pTabViewShell->TestMergeCells() )
716 rSet.DisableItem( nWhich );
717 break;
719 case FID_MERGE_OFF:
720 if ( pDoc->GetChangeTrack() || !pTabViewShell->TestRemoveMerge() )
721 rSet.DisableItem( nWhich );
722 break;
724 case FID_MERGE_TOGGLE:
725 if ( pDoc->GetChangeTrack() )
726 rSet.DisableItem( nWhich );
727 else
729 bool bCanMerge = pTabViewShell->TestMergeCells();
730 bool bCanSplit = pTabViewShell->TestRemoveMerge();
731 if( !bCanMerge && !bCanSplit )
732 rSet.DisableItem( nWhich );
733 else
734 rSet.Put( SfxBoolItem( nWhich, bCanSplit ) );
736 break;
738 case FID_INS_ROWBRK:
739 if ( nPosY==0 || (pDoc->HasRowBreak(nPosY, nTab) & BREAK_MANUAL) )
740 rSet.DisableItem( nWhich );
741 break;
743 case FID_INS_COLBRK:
744 if ( nPosX==0 || (pDoc->HasColBreak(nPosX, nTab) & BREAK_MANUAL) )
745 rSet.DisableItem( nWhich );
746 break;
748 case FID_DEL_ROWBRK:
749 if ( nPosY==0 || (pDoc->HasRowBreak(nPosY, nTab) & BREAK_MANUAL) == 0 )
750 rSet.DisableItem( nWhich );
751 break;
753 case FID_DEL_COLBRK:
754 if ( nPosX==0 || (pDoc->HasColBreak(nPosX, nTab) & BREAK_MANUAL) == 0 )
755 rSet.DisableItem( nWhich );
756 break;
758 case FID_FILL_TAB:
759 if ( nTabSelCount < 2 )
760 rSet.DisableItem( nWhich );
761 break;
763 case SID_SELECT_SCENARIO:
765 std::vector<String> aList;
766 Color aDummyCol;
768 if ( !pDoc->IsScenario(nTab) )
770 OUString aStr;
771 sal_uInt16 nFlags;
772 SCTAB nScTab = nTab + 1;
773 String aProtect;
774 bool bSheetProtected = pDoc->IsTabProtected(nTab);
776 while ( pDoc->IsScenario(nScTab) )
778 pDoc->GetName( nScTab, aStr );
779 aList.push_back(aStr);
780 pDoc->GetScenarioData( nScTab, aStr, aDummyCol, nFlags );
781 aList.push_back(aStr);
782 // Protection is sal_True if both Sheet and Scenario are protected
783 aProtect = (bSheetProtected && (nFlags & SC_SCENARIO_PROTECT)) ? '1' : '0';
784 aList.push_back(aProtect);
785 ++nScTab;
788 else
790 OUString aComment;
791 sal_uInt16 nDummyFlags;
792 pDoc->GetScenarioData( nTab, aComment, aDummyCol, nDummyFlags );
793 OSL_ENSURE( aList.empty(), "List not empty!" );
794 aList.push_back(aComment);
797 rSet.Put( SfxStringListItem( nWhich, &aList ) );
799 break;
801 case FID_ROW_HIDE:
802 case FID_ROW_SHOW:
803 case FID_COL_HIDE:
804 case FID_COL_SHOW:
805 case FID_COL_OPT_WIDTH:
806 case FID_ROW_OPT_HEIGHT:
807 case FID_DELETE_CELL:
808 if ( pDoc->IsTabProtected(nTab) || pDocSh->IsReadOnly())
809 rSet.DisableItem( nWhich );
810 break;
812 case SID_OUTLINE_MAKE:
814 if ( GetViewData()->GetDocument()->GetDPAtCursor( GetViewData()->GetCurX(),
815 GetViewData()->GetCurY(), GetViewData()->GetTabNo() ) )
817 //! test for data pilot operation
819 else if (pDoc->GetChangeTrack()!=NULL || GetViewData()->IsMultiMarked())
821 rSet.DisableItem( nWhich );
824 break;
825 case SID_OUTLINE_SHOW:
826 if ( GetViewData()->GetDocument()->GetDPAtCursor( GetViewData()->GetCurX(),
827 GetViewData()->GetCurY(), GetViewData()->GetTabNo() ) )
829 //! test for data pilot operation
831 else if (!pTabViewShell->OutlinePossible(false))
832 rSet.DisableItem( nWhich );
833 break;
835 case SID_OUTLINE_HIDE:
836 if ( GetViewData()->GetDocument()->GetDPAtCursor( GetViewData()->GetCurX(),
837 GetViewData()->GetCurY(), GetViewData()->GetTabNo() ) )
839 //! test for data pilot operation
841 else if (!pTabViewShell->OutlinePossible(sal_True))
842 rSet.DisableItem( nWhich );
843 break;
845 case SID_OUTLINE_REMOVE:
847 if ( GetViewData()->GetDocument()->GetDPAtCursor( GetViewData()->GetCurX(),
848 GetViewData()->GetCurY(), GetViewData()->GetTabNo() ) )
850 //! test for data pilot operation
852 else
854 sal_Bool bCol, bRow;
855 pTabViewShell->TestRemoveOutline( bCol, bRow );
856 if ( !bCol && !bRow )
857 rSet.DisableItem( nWhich );
860 break;
862 case FID_COL_WIDTH:
864 //GetViewData()->GetCurX();
865 SfxUInt16Item aWidthItem( FID_COL_WIDTH, pDoc->GetColWidth( nPosX , nTab) );
866 rSet.Put( aWidthItem );
867 if ( pDocSh->IsReadOnly())
868 rSet.DisableItem( nWhich );
870 //XXX disable if not conclusive
872 break;
874 case FID_ROW_HEIGHT:
876 //GetViewData()->GetCurY();
877 SfxUInt16Item aHeightItem( FID_ROW_HEIGHT, pDoc->GetRowHeight( nPosY , nTab) );
878 rSet.Put( aHeightItem );
879 //XXX disable if not conclusive
880 if ( pDocSh->IsReadOnly())
881 rSet.DisableItem( nWhich );
883 break;
885 case SID_DETECTIVE_FILLMODE:
886 rSet.Put(SfxBoolItem( nWhich, pTabViewShell->IsAuditShell() ));
887 break;
889 case FID_INPUTLINE_STATUS:
890 OSL_FAIL( "Old update method. Use ScTabViewShell::UpdateInputHandler()." );
891 break;
893 case SID_SCENARIOS: // scenarios:
894 if (!(rMark.IsMarked() || rMark.IsMultiMarked())) // only, if something selected
895 rSet.DisableItem( nWhich );
896 break;
898 case FID_NOTE_VISIBLE:
900 const ScPostIt* pNote = pDoc->GetNotes(nTab)->findByAddress(nPosX, nPosY);
901 if ( pNote && pDoc->IsBlockEditable( nTab, nPosX,nPosY, nPosX,nPosY ) )
902 rSet.Put( SfxBoolItem( nWhich, pNote->IsCaptionShown() ) );
903 else
904 rSet.DisableItem( nWhich );
906 break;
908 case FID_HIDE_NOTE:
909 case FID_SHOW_NOTE:
911 bool bEnable = false;
912 bool bSearchForHidden = nWhich == FID_SHOW_NOTE;
913 if (!rMark.IsMarked() && !rMark.IsMultiMarked())
915 // Check current cell
916 const ScPostIt* pNote = pDoc->GetNotes(nTab)->findByAddress(nPosX, nPosY);
917 if ( pNote && pDoc->IsBlockEditable( nTab, nPosX,nPosY, nPosX,nPosY ) )
918 if ( pNote->IsCaptionShown() != bSearchForHidden)
919 bEnable = true;
921 else
923 // Check selection range
924 ScRangeListRef aRangesRef;
925 pData->GetMultiArea(aRangesRef);
926 ScRangeList aRanges = *aRangesRef;
927 size_t nRangeSize = aRanges.size();
929 for ( size_t i = 0; i < nRangeSize && !bEnable; ++i )
931 const ScRange * pRange = aRanges[i];
932 const SCROW nRow0 = pRange->aStart.Row();
933 const SCROW nRow1 = pRange->aEnd.Row();
934 const SCCOL nCol0 = pRange->aStart.Col();
935 const SCCOL nCol1 = pRange->aEnd.Col();
936 const SCTAB nRangeTab = pRange->aStart.Tab();
937 const size_t nCellNumber = ( nRow1 - nRow0 ) * ( nCol1 - nCol0 );
938 const ScNotes *pNotes = pDoc->GetNotes(nRangeTab);
940 if ( nCellNumber < pNotes->size() )
942 // Check by each cell
943 for ( SCROW nRow = nRow0; nRow <= nRow1 && !bEnable; ++nRow )
945 for ( SCCOL nCol = nCol0; nCol <= nCol1; ++nCol )
947 const ScPostIt* pNote = pNotes->findByAddress(nCol, nRow);
948 if ( pNote && pDoc->IsBlockEditable( nRangeTab, nCol,nRow, nCol,nRow ) )
950 if ( pNote->IsCaptionShown() != bSearchForHidden)
952 bEnable = true;
953 break;
959 else
961 // Check by each document note
962 for (ScNotes::const_iterator itr = pNotes->begin(); itr != pNotes->end(); ++itr)
964 SCCOL nCol = itr->first.first;
965 SCROW nRow = itr->first.second;
967 if ( nCol <= nCol1 && nRow <= nRow1 && nCol >= nCol0 && nRow >= nRow0 )
969 if ( itr->second->IsCaptionShown() != bSearchForHidden)
971 bEnable = true; //note found
972 break;
979 if ( !bEnable )
980 rSet.DisableItem( nWhich );
982 break;
984 case SID_DELETE_NOTE:
986 bool bEnable = false;
987 if ( rMark.IsMarked() || rMark.IsMultiMarked() )
989 if ( pDoc->IsSelectionEditable( rMark ) )
991 // look for at least one note in selection
992 ScRangeList aRanges;
993 rMark.FillRangeListWithMarks( &aRanges, false );
994 size_t nCount = aRanges.size();
995 for (size_t nPos = 0; nPos < nCount && !bEnable; ++nPos)
997 ScNotes* pNotes = pDoc->GetNotes( aRanges[nPos]->aStart.Tab() );
998 for (ScNotes::const_iterator itr = pNotes->begin(); itr != pNotes->end(); ++itr)
1000 SCCOL nCol = itr->first.first;
1001 SCROW nRow = itr->first.second;
1003 if ( nCol <= aRanges[nPos]->aEnd.Col() && nRow <= aRanges[nPos]->aEnd.Row()
1004 && nCol >= aRanges[nPos]->aStart.Col() && nRow >= aRanges[nPos]->aStart.Row() )
1006 bEnable = true; //note found
1007 break;
1013 else
1015 bEnable = pDoc->IsBlockEditable( nTab, nPosX,nPosY, nPosX,nPosY ) &&
1016 pDoc->GetNotes(nTab)->findByAddress( nPosX, nPosY );
1018 if ( !bEnable )
1019 rSet.DisableItem( nWhich );
1021 break;
1023 case SID_OPENDLG_CONSOLIDATE:
1024 case SCITEM_CONSOLIDATEDATA:
1026 if(pDoc->GetChangeTrack()!=NULL)
1027 rSet.DisableItem( nWhich);
1029 break;
1031 case SID_CHINESE_CONVERSION:
1032 case SID_HANGUL_HANJA_CONVERSION:
1033 ScViewUtil::HideDisabledSlot( rSet, pData->GetBindings(), nWhich );
1034 break;
1036 case FID_USE_NAME:
1038 if ( pDocSh && pDocSh->IsDocShared() )
1039 rSet.DisableItem( nWhich );
1040 else
1042 ScRange aRange;
1043 if ( pData->GetSimpleArea( aRange ) != SC_MARK_SIMPLE )
1044 rSet.DisableItem( nWhich );
1047 break;
1049 case FID_DEFINE_NAME:
1050 case FID_INSERT_NAME:
1051 case FID_ADD_NAME:
1052 case SID_DEFINE_COLROWNAMERANGES:
1054 if ( pDocSh && pDocSh->IsDocShared() )
1056 rSet.DisableItem( nWhich );
1059 break;
1061 case SID_SPELL_DIALOG:
1063 if ( pDoc && pData && pDoc->IsTabProtected( pData->GetTabNo() ) )
1065 bool bVisible = false;
1066 SfxViewFrame* pViewFrame = ( pTabViewShell ? pTabViewShell->GetViewFrame() : NULL );
1067 if ( pViewFrame && pViewFrame->HasChildWindow( nWhich ) )
1069 SfxChildWindow* pChild = pViewFrame->GetChildWindow( nWhich );
1070 Window* pWin = ( pChild ? pChild->GetWindow() : NULL );
1071 if ( pWin && pWin->IsVisible() )
1073 bVisible = true;
1076 if ( !bVisible )
1078 rSet.DisableItem( nWhich );
1082 break;
1084 } // switch ( nWitch )
1085 nWhich = aIter.NextWhich();
1086 } // while ( nWitch )
1089 //------------------------------------------------------------------
1093 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */