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"
60 //------------------------------------------------------------------
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
) :
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 //------------------------------------------------------------------
107 void ScCellShell::GetBlockState( SfxItemSet
& rSet
)
109 ScTabViewShell
* pTabViewShell
= GetViewData()->GetViewShell();
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();
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();
129 bool bDisable
= false;
130 bool bNeedEdit
= true; // need selection be editable?
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
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
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
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
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
)
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
194 case FID_INS_CELL
: // insert cells, just simple selection
195 bDisable
= (!bSimpleArea
);
198 case FID_INS_ROW
: // insert rows
199 case FID_INS_CELLSDOWN
:
200 bDisable
= (!bSimpleArea
) || GetViewData()->SimpleColMarked();
203 case FID_INS_COLUMN
: // insert columns
204 case FID_INS_CELLSRIGHT
:
205 bDisable
= (!bSimpleArea
) || GetViewData()->SimpleRowMarked();
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
217 case SID_AUTOFORMAT
: // Autoformat, at least 3x3 selected
218 bDisable
= (!bSimpleArea
)
219 || ((nCol2
- nCol1
) < 2) || ((nRow2
- nRow1
) < 2);
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
)
232 if ( pDocShell
&& pDocShell
->IsDocShared() )
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
);
246 if (!bDisable
&& bNeedEdit
&& !bEditable
)
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
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();
275 sal_Bool bDisable
= false;
276 sal_Bool bNeedEdit
= sal_True
; // need cursor position be editable?
281 CellType eType
= pDoc
->GetCellType( aCursor
);
282 bDisable
= ( eType
!= CELLTYPE_STRING
&& eType
!= CELLTYPE_EDIT
);
285 // test for available languages
286 sal_uInt16 nLang
= ScViewUtil::GetEffLanguage( pDoc
, aCursor
);
287 bDisable
= !ScModule::HasThesaurusLanguage( nLang
);
291 case SID_OPENDLG_FUNCTION
:
293 ScMarkData aMarkData
=GetViewData()->GetMarkData();
294 aMarkData
.MarkToSimple();
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() ))
309 case SID_INSERT_POSTIT
:
311 if ( pDocShell
&& pDocShell
->IsDocShared() )
318 if (!bDisable
&& bNeedEdit
)
319 if (!pDoc
->IsBlockEditable( aCursor
.Tab(), aCursor
.Col(),aCursor
.Row(),
320 aCursor
.Col(),aCursor
.Row() ))
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:
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
)
348 SvPasteObjectHelper::GetEmbeddedName( rDataHelper
, aStrVal
, aSource
, nFormatId
);
352 rFormats
.AddClipbrdFormat( nFormatId
, aStrVal
);
354 rFormats
.AddClipbrdFormat( nFormatId
);
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
);
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
;
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
;
423 IMPL_LINK( ScCellShell
, ClipboardChanged
, TransferableDataHelper
*, 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
);
442 bool checkDestRanges(ScViewData
& rViewData
)
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
)
453 // Multiple destination ranges.
455 ScDocument
* pDoc
= rViewData
.GetDocument();
456 Window
* pWin
= rViewData
.GetActiveWin();
460 ScTransferObj
* pOwnClip
= ScTransferObj::GetOwnClipboard(pWin
);
462 // If it's not a Calc document, we won't be picky.
465 ScDocument
* pClipDoc
= pOwnClip
->GetDocument();
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();
475 aMark
.MarkToSimple();
476 aMark
.FillRangeListWithMarks(&aRanges
, false);
478 return ScClipUtil::CheckDestRanges(pDoc
, nColSize
, nRowSize
, aMark
, aRanges
);
483 void ScCellShell::GetClipState( SfxItemSet
& rSet
)
487 // SID_CLIPBOARD_FORMAT_ITEMS
489 if ( !pImpl
->m_pClipEvtLstnr
)
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
);
498 TransferableDataHelper
aDataHelper( TransferableDataHelper::CreateFromSystemClipboard( pWin
) );
499 bPastePossible
= lcl_IsCellPastePossible( aDataHelper
);
502 bool bDisable
= !bPastePossible
;
504 // cell protection / multiple selection
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
))
515 if (!checkDestRanges(*GetViewData()))
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();
572 case SID_DETECTIVE_REFRESH
:
573 if (!pDoc
->HasDetectiveOperations())
574 rSet
.DisableItem( nWhich
);
577 case SID_RANGE_ADDRESS
:
580 if ( pData
->GetSimpleArea( aRange
) == SC_MARK_SIMPLE
)
583 sal_uInt16 nFlags
= SCA_VALID
| SCA_TAB_3D
;
584 aRange
.Format(aStr
,nFlags
,pDoc
);
585 rSet
.Put( SfxStringItem( nWhich
, aStr
) );
590 case SID_RANGE_NOTETEXT
:
592 // always take cursor position, do not use top-left cell of selection
594 if ( const ScPostIt
* pNote
= pDoc
->GetNotes(nTab
)->findByAddress(nPosX
, nPosY
) )
595 aNoteText
= pNote
->GetText();
596 rSet
.Put( SfxStringItem( nWhich
, aNoteText
) );
601 rSet
.Put( SfxInt32Item( nWhich
, nPosY
+1 ) );
605 rSet
.Put( SfxInt16Item( nWhich
, nPosX
+1 ) );
608 case SID_RANGE_TABLE
:
609 rSet
.Put( SfxInt16Item( nWhich
, nTab
+1 ) );
612 case SID_RANGE_VALUE
:
615 pDoc
->GetValue( nPosX
, nPosY
, nTab
, nValue
);
616 rSet
.Put( ScDoubleItem( nWhich
, nValue
) );
620 case SID_RANGE_FORMULA
:
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
) );
632 case SID_RANGE_TEXTVALUE
:
634 OUString aString
= pDoc
->GetString(nPosX
, nPosY
, nTab
);
635 rSet
.Put( SfxStringItem( nWhich
, aString
) );
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();
649 case KEY_SHIFT
: nMode
= 1; break;
650 case KEY_MOD1
: nMode
= 2; break; // Control-key
656 rSet
.Put( SfxUInt16Item( nWhich
, nMode
) );
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
) );
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.
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("...") ) );
683 sal_uInt16 nErrCode
= 0;
684 ScFormulaCell
* pCell
= pDoc
->GetFormulaCell(ScAddress(nPosX
, nPosY
, nTab
));
687 if (!pCell
->IsRunning())
688 nErrCode
= pCell
->GetErrCode();
692 if ( pTabViewShell
->GetFunction( aFuncStr
, nErrCode
) )
693 rSet
.Put( SfxStringItem( nWhich
, aFuncStr
) );
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
);
709 if ( pTabViewShell
->GetFunction( aFuncStr
) )
710 rSet
.Put( SfxStringItem( nWhich
, aFuncStr
) );
715 if ( pDoc
->GetChangeTrack() || !pTabViewShell
->TestMergeCells() )
716 rSet
.DisableItem( nWhich
);
720 if ( pDoc
->GetChangeTrack() || !pTabViewShell
->TestRemoveMerge() )
721 rSet
.DisableItem( nWhich
);
724 case FID_MERGE_TOGGLE
:
725 if ( pDoc
->GetChangeTrack() )
726 rSet
.DisableItem( nWhich
);
729 bool bCanMerge
= pTabViewShell
->TestMergeCells();
730 bool bCanSplit
= pTabViewShell
->TestRemoveMerge();
731 if( !bCanMerge
&& !bCanSplit
)
732 rSet
.DisableItem( nWhich
);
734 rSet
.Put( SfxBoolItem( nWhich
, bCanSplit
) );
739 if ( nPosY
==0 || (pDoc
->HasRowBreak(nPosY
, nTab
) & BREAK_MANUAL
) )
740 rSet
.DisableItem( nWhich
);
744 if ( nPosX
==0 || (pDoc
->HasColBreak(nPosX
, nTab
) & BREAK_MANUAL
) )
745 rSet
.DisableItem( nWhich
);
749 if ( nPosY
==0 || (pDoc
->HasRowBreak(nPosY
, nTab
) & BREAK_MANUAL
) == 0 )
750 rSet
.DisableItem( nWhich
);
754 if ( nPosX
==0 || (pDoc
->HasColBreak(nPosX
, nTab
) & BREAK_MANUAL
) == 0 )
755 rSet
.DisableItem( nWhich
);
759 if ( nTabSelCount
< 2 )
760 rSet
.DisableItem( nWhich
);
763 case SID_SELECT_SCENARIO
:
765 std::vector
<String
> aList
;
768 if ( !pDoc
->IsScenario(nTab
) )
772 SCTAB nScTab
= nTab
+ 1;
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
);
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
) );
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
);
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
);
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
);
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
);
845 case SID_OUTLINE_REMOVE
:
847 if ( GetViewData()->GetDocument()->GetDPAtCursor( GetViewData()->GetCurX(),
848 GetViewData()->GetCurY(), GetViewData()->GetTabNo() ) )
850 //! test for data pilot operation
855 pTabViewShell
->TestRemoveOutline( bCol
, bRow
);
856 if ( !bCol
&& !bRow
)
857 rSet
.DisableItem( nWhich
);
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
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
);
885 case SID_DETECTIVE_FILLMODE
:
886 rSet
.Put(SfxBoolItem( nWhich
, pTabViewShell
->IsAuditShell() ));
889 case FID_INPUTLINE_STATUS
:
890 OSL_FAIL( "Old update method. Use ScTabViewShell::UpdateInputHandler()." );
893 case SID_SCENARIOS
: // scenarios:
894 if (!(rMark
.IsMarked() || rMark
.IsMultiMarked())) // only, if something selected
895 rSet
.DisableItem( nWhich
);
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() ) );
904 rSet
.DisableItem( nWhich
);
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
)
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
)
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
980 rSet
.DisableItem( nWhich
);
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
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
1015 bEnable
= pDoc
->IsBlockEditable( nTab
, nPosX
,nPosY
, nPosX
,nPosY
) &&
1016 pDoc
->GetNotes(nTab
)->findByAddress( nPosX
, nPosY
);
1019 rSet
.DisableItem( nWhich
);
1023 case SID_OPENDLG_CONSOLIDATE
:
1024 case SCITEM_CONSOLIDATEDATA
:
1026 if(pDoc
->GetChangeTrack()!=NULL
)
1027 rSet
.DisableItem( nWhich
);
1031 case SID_CHINESE_CONVERSION
:
1032 case SID_HANGUL_HANJA_CONVERSION
:
1033 ScViewUtil::HideDisabledSlot( rSet
, pData
->GetBindings(), nWhich
);
1038 if ( pDocSh
&& pDocSh
->IsDocShared() )
1039 rSet
.DisableItem( nWhich
);
1043 if ( pData
->GetSimpleArea( aRange
) != SC_MARK_SIMPLE
)
1044 rSet
.DisableItem( nWhich
);
1049 case FID_DEFINE_NAME
:
1050 case FID_INSERT_NAME
:
1052 case SID_DEFINE_COLROWNAMERANGES
:
1054 if ( pDocSh
&& pDocSh
->IsDocShared() )
1056 rSet
.DisableItem( nWhich
);
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() )
1078 rSet
.DisableItem( nWhich
);
1084 } // switch ( nWitch )
1085 nWhich
= aIter
.NextWhich();
1086 } // while ( nWitch )
1089 //------------------------------------------------------------------
1093 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */