1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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>
45 #include "scresid.hxx"
46 #include "tabvwsh.hxx"
48 #include "formulacell.hxx"
50 #include "globstr.hrc"
51 #include "transobj.hxx"
52 #include "drwtrans.hxx"
53 #include "scabstdlg.hxx"
54 #include "dociter.hxx"
56 #include "cliputil.hxx"
57 #include "clipparam.hxx"
58 #include "markdata.hxx"
59 #include <gridwin.hxx>
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
) :
79 pImpl( new CellShell_Impl() ),
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
;
105 void ScCellShell::GetBlockState( SfxItemSet
& rSet
)
107 ScTabViewShell
* pTabViewShell
= GetViewData()->GetViewShell();
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();
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();
127 bool bDisable
= false;
128 bool bNeedEdit
= true; // need selection be editable?
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
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
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
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
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
;
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
)
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
202 case FID_FILL_SINGLE_EDIT
:
206 case FID_INS_CELL
: // insert cells, just simple selection
207 bDisable
= (!bSimpleArea
);
210 case FID_INS_ROW
: // insert rows
211 case FID_INS_CELLSDOWN
:
212 bDisable
= (!bSimpleArea
) || GetViewData()->SimpleColMarked();
215 case FID_INS_COLUMN
: // insert columns
216 case FID_INS_CELLSRIGHT
:
217 bDisable
= (!bSimpleArea
) || GetViewData()->SimpleRowMarked();
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
229 case SID_AUTOFORMAT
: // Autoformat, at least 3x3 selected
230 bDisable
= (!bSimpleArea
)
231 || ((nCol2
- nCol1
) < 2) || ((nRow2
- nRow1
) < 2);
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
)
244 if ( pDocShell
&& pDocShell
->IsDocShared() )
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
);
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
);
264 if (!bDisable
&& bNeedEdit
&& !bEditable
)
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
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();
293 bool bDisable
= false;
294 bool bNeedEdit
= true; // need cursor position be editable?
299 CellType eType
= rDoc
.GetCellType( aCursor
);
300 bDisable
= ( eType
!= CELLTYPE_STRING
&& eType
!= CELLTYPE_EDIT
);
303 // test for available languages
304 sal_uInt16 nLang
= ScViewUtil::GetEffLanguage( &rDoc
, aCursor
);
305 bDisable
= !ScModule::HasThesaurusLanguage( nLang
);
309 case SID_OPENDLG_FUNCTION
:
311 ScMarkData aMarkData
= GetViewData()->GetMarkData();
312 aMarkData
.MarkToSimple();
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() ))
327 case SID_INSERT_POSTIT
:
329 ScAddress
aPos( GetViewData()->GetCurX(), GetViewData()->GetCurY(), GetViewData()->GetTabNo() );
330 if( rDoc
.GetNote(aPos
) )
337 if ( pDocShell
&& pDocShell
->IsDocShared() )
344 case SID_EDIT_POSTIT
:
346 ScAddress
aPos( GetViewData()->GetCurX(), GetViewData()->GetCurY(), GetViewData()->GetTabNo() );
347 if( rDoc
.GetNote(aPos
) )
358 if (!bDisable
&& bNeedEdit
)
359 if (!rDoc
.IsBlockEditable( aCursor
.Tab(), aCursor
.Col(),aCursor
.Row(),
360 aCursor
.Col(),aCursor
.Row() ))
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:
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
)
388 SvPasteObjectHelper::GetEmbeddedName( rDataHelper
, aStrVal
, aSource
, nFormatId
);
391 if ( !aStrVal
.isEmpty() )
392 rFormats
.AddClipbrdFormat( nFormatId
, aStrVal
);
394 rFormats
.AddClipbrdFormat( nFormatId
);
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
);
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
) )
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
) )
465 IMPL_LINK( ScCellShell
, ClipboardChanged
, TransferableDataHelper
*, 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
);
484 bool checkDestRanges(ScViewData
& rViewData
)
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
)
495 // Multiple destination ranges.
497 ScDocument
* pDoc
= rViewData
.GetDocument();
498 vcl::Window
* pWin
= rViewData
.GetActiveWin();
502 ScTransferObj
* pOwnClip
= ScTransferObj::GetOwnClipboard(pWin
);
504 // If it's not a Calc document, we won't be picky.
507 ScDocument
* pClipDoc
= pOwnClip
->GetDocument();
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();
517 aMark
.MarkToSimple();
518 aMark
.FillRangeListWithMarks(&aRanges
, false);
520 return ScClipUtil::CheckDestRanges(pDoc
, nColSize
, nRowSize
, aMark
, aRanges
);
525 void ScCellShell::GetClipState( SfxItemSet
& rSet
)
529 // SID_CLIPBOARD_FORMAT_ITEMS
531 if ( !pImpl
->m_pClipEvtLstnr
)
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 );
540 TransferableDataHelper
aDataHelper( TransferableDataHelper::CreateFromSystemClipboard( pWin
) );
541 bPastePossible
= lcl_IsCellPastePossible( aDataHelper
);
544 bool bDisable
= !bPastePossible
;
546 // cell protection / multiple selection
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
))
557 if (!checkDestRanges(*GetViewData()))
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();
614 case SID_DETECTIVE_REFRESH
:
615 if (!pDoc
->HasDetectiveOperations())
616 rSet
.DisableItem( nWhich
);
619 case SID_RANGE_ADDRESS
:
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
) );
631 case SID_RANGE_NOTETEXT
:
633 // always take cursor position, do not use top-left cell of selection
635 if ( const ScPostIt
* pNote
= pDoc
->GetNote(nPosX
, nPosY
, nTab
) )
636 aNoteText
= pNote
->GetText();
637 rSet
.Put( SfxStringItem( nWhich
, aNoteText
) );
642 rSet
.Put( SfxInt32Item( nWhich
, nPosY
+1 ) );
646 rSet
.Put( SfxInt16Item( nWhich
, nPosX
+1 ) );
649 case SID_RANGE_TABLE
:
650 rSet
.Put( SfxInt16Item( nWhich
, nTab
+1 ) );
653 case SID_RANGE_VALUE
:
656 pDoc
->GetValue( nPosX
, nPosY
, nTab
, nValue
);
657 rSet
.Put( ScDoubleItem( nWhich
, nValue
) );
661 case SID_RANGE_FORMULA
:
664 pDoc
->GetFormula( nPosX
, nPosY
, nTab
, aString
);
665 if( aString
.isEmpty() )
667 pDoc
->GetInputString( nPosX
, nPosY
, nTab
, aString
);
669 rSet
.Put( SfxStringItem( nWhich
, aString
) );
673 case SID_RANGE_TEXTVALUE
:
675 OUString aString
= pDoc
->GetString(nPosX
, nPosY
, nTab
);
676 rSet
.Put( SfxStringItem( nWhich
, aString
) );
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();
690 case KEY_SHIFT
: nMode
= 1; break;
691 case KEY_MOD1
: nMode
= 2; break; // Control-key
697 rSet
.Put( SfxUInt16Item( nWhich
, nMode
) );
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
) ); }
711 case SID_ROWCOL_SELCOUNT
:
714 GetViewData()->GetSimpleArea( aMarkRange
);
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
) );
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.
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("...") ) );
745 sal_uInt16 nErrCode
= 0;
746 ScFormulaCell
* pCell
= pDoc
->GetFormulaCell(ScAddress(nPosX
, nPosY
, nTab
));
749 if (!pCell
->IsRunning())
750 nErrCode
= pCell
->GetErrCode();
754 if ( pTabViewShell
->GetFunction( aFuncStr
, nErrCode
) )
755 rSet
.Put( SfxStringItem( nWhich
, aFuncStr
) );
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
);
771 if ( pTabViewShell
->GetFunction( aFuncStr
) )
772 rSet
.Put( SfxStringItem( nWhich
, aFuncStr
) );
777 if ( pDoc
->GetChangeTrack() || !pTabViewShell
->TestMergeCells() )
778 rSet
.DisableItem( nWhich
);
782 if ( pDoc
->GetChangeTrack() || !pTabViewShell
->TestRemoveMerge() )
783 rSet
.DisableItem( nWhich
);
786 case FID_MERGE_TOGGLE
:
787 if ( pDoc
->GetChangeTrack() )
788 rSet
.DisableItem( nWhich
);
791 bool bCanMerge
= pTabViewShell
->TestMergeCells();
792 bool bCanSplit
= pTabViewShell
->TestRemoveMerge();
793 if( !bCanMerge
&& !bCanSplit
)
794 rSet
.DisableItem( nWhich
);
796 rSet
.Put( SfxBoolItem( nWhich
, bCanSplit
) );
801 if ( nPosY
==0 || (pDoc
->HasRowBreak(nPosY
, nTab
) & BREAK_MANUAL
) )
802 rSet
.DisableItem( nWhich
);
806 if ( nPosX
==0 || (pDoc
->HasColBreak(nPosX
, nTab
) & BREAK_MANUAL
) )
807 rSet
.DisableItem( nWhich
);
811 if ( nPosY
==0 || (pDoc
->HasRowBreak(nPosY
, nTab
) & BREAK_MANUAL
) == 0 )
812 rSet
.DisableItem( nWhich
);
816 if ( nPosX
==0 || (pDoc
->HasColBreak(nPosX
, nTab
) & BREAK_MANUAL
) == 0 )
817 rSet
.DisableItem( nWhich
);
821 if ( nTabSelCount
< 2 )
822 rSet
.DisableItem( nWhich
);
825 case SID_SELECT_SCENARIO
:
827 std::vector
<OUString
> aList
;
830 if ( !pDoc
->IsScenario(nTab
) )
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"));
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
) );
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
);
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
);
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
);
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
);
905 case SID_OUTLINE_REMOVE
:
907 if ( GetViewData()->GetDocument()->GetDPAtCursor( GetViewData()->GetCurX(),
908 GetViewData()->GetCurY(), GetViewData()->GetTabNo() ) )
910 //! test for data pilot operation
915 pTabViewShell
->TestRemoveOutline( bCol
, bRow
);
916 if ( !bCol
&& !bRow
)
917 rSet
.DisableItem( nWhich
);
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
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
);
945 case SID_DETECTIVE_FILLMODE
:
946 rSet
.Put(SfxBoolItem( nWhich
, pTabViewShell
->IsAuditShell() ));
949 case FID_INPUTLINE_STATUS
:
950 OSL_FAIL( "Old update method. Use ScTabViewShell::UpdateInputHandler()." );
953 case SID_SCENARIOS
: // scenarios:
954 if (!(rMark
.IsMarked() || rMark
.IsMultiMarked())) // only, if something selected
955 rSet
.DisableItem( nWhich
);
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() ) );
964 rSet
.DisableItem( nWhich
);
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
)
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
)
1005 rSet
.DisableItem( nWhich
);
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
);
1024 bEnable
= pDoc
->IsBlockEditable( nTab
, nPosX
,nPosY
, nPosX
,nPosY
) &&
1025 pDoc
->GetNote(nPosX
, nPosY
, nTab
);
1028 rSet
.DisableItem( nWhich
);
1032 case SID_OPENDLG_CONSOLIDATE
:
1033 case SCITEM_CONSOLIDATEDATA
:
1035 if(pDoc
->GetChangeTrack()!=NULL
)
1036 rSet
.DisableItem( nWhich
);
1040 case SID_CHINESE_CONVERSION
:
1041 case SID_HANGUL_HANJA_CONVERSION
:
1042 ScViewUtil::HideDisabledSlot( rSet
, pData
->GetBindings(), nWhich
);
1047 if ( pDocSh
&& pDocSh
->IsDocShared() )
1048 rSet
.DisableItem( nWhich
);
1052 if ( pData
->GetSimpleArea( aRange
) != SC_MARK_SIMPLE
)
1053 rSet
.DisableItem( nWhich
);
1058 case FID_DEFINE_NAME
:
1059 case FID_INSERT_NAME
:
1061 case SID_DEFINE_COLROWNAMERANGES
:
1063 if ( pDocSh
&& pDocSh
->IsDocShared() )
1065 rSet
.DisableItem( nWhich
);
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() )
1087 rSet
.DisableItem( nWhich
);
1093 } // switch ( nWitch )
1094 nWhich
= aIter
.NextWhich();
1095 } // while ( nWitch )
1098 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */