update dev300-m58
[ooovba.git] / sc / source / ui / view / cellsh.cxx
blobe206b8a7b790d7b6d948f3ae1d0ecb65057fdf40
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: cellsh.cxx,v $
10 * $Revision: 1.48.126.3 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sc.hxx"
34 //------------------------------------------------------------------
36 #include "scitems.hxx"
38 #include <svtools/slstitm.hxx>
39 #include <svtools/stritem.hxx>
40 #include <svtools/whiter.hxx>
41 #include <svtools/moduleoptions.hxx>
42 #include <svtools/cliplistener.hxx>
43 #include <svtools/insdlg.hxx>
44 #include <sot/formats.hxx>
45 #include <svx/hlnkitem.hxx>
46 #include <sfx2/app.hxx>
47 #include <sfx2/bindings.hxx>
48 #include <sfx2/objface.hxx>
49 #include <sfx2/request.hxx>
50 #include <sfx2/viewfrm.hxx>
51 #include <svx/clipfmtitem.hxx>
52 #include <svx/langitem.hxx>
54 #include "cellsh.hxx"
55 #include "sc.hrc"
56 #include "docsh.hxx"
57 #include "attrib.hxx"
58 #include "scresid.hxx"
59 #include "tabvwsh.hxx"
60 #include "impex.hxx"
61 #include "cell.hxx"
62 #include "scmod.hxx"
63 #include "globstr.hrc"
64 #include "transobj.hxx"
65 #include "drwtrans.hxx"
66 #include "scabstdlg.hxx"
67 #include "dociter.hxx"
68 #include "postit.hxx"
70 //------------------------------------------------------------------
72 #define ScCellShell
73 #define CellMovement
74 #include "scslots.hxx"
76 #define SearchSettings
77 #include <svx/svxslots.hxx>
79 TYPEINIT1( ScCellShell, ScFormatShell );
81 SFX_IMPL_INTERFACE(ScCellShell, ScFormatShell , ScResId(SCSTR_CELLSHELL) )
83 SFX_OBJECTBAR_REGISTRATION( SFX_OBJECTBAR_OBJECT | SFX_VISIBILITY_STANDARD |
84 SFX_VISIBILITY_SERVER,
85 ScResId(RID_OBJECTBAR_FORMAT));
86 SFX_POPUPMENU_REGISTRATION(ScResId(RID_POPUP_CELLS));
90 ScCellShell::ScCellShell(ScViewData* pData) :
91 ScFormatShell(pData),
92 pImpl( new CellShell_Impl() ),
93 bPastePossible(FALSE)
95 SetHelpId(HID_SCSHELL_CELLSH);
96 SetName(String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("Cell")));
99 ScCellShell::~ScCellShell()
101 if ( pImpl->m_pClipEvtLstnr )
103 pImpl->m_pClipEvtLstnr->AddRemoveListener( GetViewData()->GetActiveWin(), FALSE );
105 // #103849# The listener may just now be waiting for the SolarMutex and call the link
106 // afterwards, in spite of RemoveListener. So the link has to be reset, too.
107 pImpl->m_pClipEvtLstnr->ClearCallbackLink();
109 pImpl->m_pClipEvtLstnr->release();
112 delete pImpl->m_pLinkedDlg;
113 delete pImpl->m_pRequest;
114 delete pImpl;
117 //------------------------------------------------------------------
119 void ScCellShell::GetBlockState( SfxItemSet& rSet )
121 ScTabViewShell* pTabViewShell = GetViewData()->GetViewShell();
122 ScRange aMarkRange;
123 ScMarkType eMarkType = GetViewData()->GetSimpleArea( aMarkRange );
124 BOOL bSimpleArea = (eMarkType == SC_MARK_SIMPLE);
125 BOOL bOnlyNotBecauseOfMatrix;
126 BOOL bEditable = pTabViewShell->SelectionEditable( &bOnlyNotBecauseOfMatrix );
127 ScDocument* pDoc = GetViewData()->GetDocument();
128 ScDocShell* pDocShell = GetViewData()->GetDocShell();
129 ScMarkData& rMark = GetViewData()->GetMarkData();
130 SCCOL nCol1, nCol2;
131 SCROW nRow1, nRow2;
132 nCol1 = aMarkRange.aStart.Col();
133 nRow1 = aMarkRange.aStart.Row();
134 nCol2 = aMarkRange.aEnd.Col();
135 nRow2 = aMarkRange.aEnd.Row();
137 SfxWhichIter aIter(rSet);
138 USHORT nWhich = aIter.FirstWhich();
139 while ( nWhich )
141 BOOL bDisable = FALSE;
142 BOOL bNeedEdit = TRUE; // muss Selektion editierbar sein?
143 switch ( nWhich )
145 case FID_FILL_TO_BOTTOM: // Fuellen oben/unten
146 case FID_FILL_TO_TOP: // mind. 2 Zeilen markiert?
147 bDisable = (!bSimpleArea) || (nRow1 == nRow2);
148 if ( !bDisable && bEditable )
149 { // Matrix nicht zerreissen
150 if ( nWhich == FID_FILL_TO_BOTTOM )
151 bDisable = pDoc->HasSelectedBlockMatrixFragment(
152 nCol1, nRow1, nCol2, nRow1, rMark ); // erste Zeile
153 else
154 bDisable = pDoc->HasSelectedBlockMatrixFragment(
155 nCol1, nRow2, nCol2, nRow2, rMark ); // letzte Zeile
157 break;
159 case FID_FILL_TO_RIGHT: // Fuellen links/rechts
160 case FID_FILL_TO_LEFT: // mind. 2 Spalten markiert?
161 bDisable = (!bSimpleArea) || (nCol1 == nCol2);
162 if ( !bDisable && bEditable )
163 { // Matrix nicht zerreissen
164 if ( nWhich == FID_FILL_TO_RIGHT )
165 bDisable = pDoc->HasSelectedBlockMatrixFragment(
166 nCol1, nRow1, nCol1, nRow2, rMark ); // erste Spalte
167 else
168 bDisable = pDoc->HasSelectedBlockMatrixFragment(
169 nCol2, nRow1, nCol2, nRow2, rMark ); // letzte Spalte
171 break;
173 case FID_FILL_SERIES: // Block fuellen
174 case SID_OPENDLG_TABOP: // Mehrfachoperationen, mind. 2 Zellen markiert?
175 if (pDoc->GetChangeTrack()!=NULL &&nWhich ==SID_OPENDLG_TABOP)
176 bDisable = TRUE;
177 else
178 bDisable = (!bSimpleArea) || (nCol1 == nCol2 && nRow1 == nRow2);
180 if ( !bDisable && bEditable && nWhich == FID_FILL_SERIES )
181 { // Matrix nicht zerreissen
182 bDisable = pDoc->HasSelectedBlockMatrixFragment(
183 nCol1, nRow1, nCol2, nRow1, rMark ) // erste Zeile
184 || pDoc->HasSelectedBlockMatrixFragment(
185 nCol1, nRow2, nCol2, nRow2, rMark ) // letzte Zeile
186 || pDoc->HasSelectedBlockMatrixFragment(
187 nCol1, nRow1, nCol1, nRow2, rMark ) // erste Spalte
188 || pDoc->HasSelectedBlockMatrixFragment(
189 nCol2, nRow1, nCol2, nRow2, rMark ); // letzte Spalte
191 break;
193 case SID_CUT: // Ausschneiden,
194 case FID_INS_CELL: // Zellen einfuegen, nur einf. Selektion
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: // Kopieren
209 // nur wegen Matrix nicht editierbar? Matrix nicht zerreissen
210 //! schlaegt nicht zu, wenn geschuetzt UND Matrix, aber damit
211 //! muss man leben.. wird in Copy-Routine abgefangen, sonst
212 //! muesste hier nochmal Aufwand getrieben werden
213 if ( !(!bEditable && bOnlyNotBecauseOfMatrix) )
214 bNeedEdit = FALSE; // erlaubt, wenn geschuetzt/ReadOnly
215 break;
217 case SID_AUTOFORMAT: // Autoformat, mind. 3x3 selektiert
218 bDisable = (!bSimpleArea)
219 || ((nCol2 - nCol1) < 2) || ((nRow2 - nRow1) < 2);
220 break;
222 case SID_OPENDLG_CONDFRMT :
224 if ( !bEditable && bOnlyNotBecauseOfMatrix )
226 bNeedEdit = FALSE;
228 if ( pDocShell && pDocShell->IsDocShared() )
230 bDisable = TRUE;
233 break;
235 case FID_CONDITIONAL_FORMAT :
236 case SID_CELL_FORMAT_RESET :
237 case FID_CELL_FORMAT :
238 case SID_ENABLE_HYPHENATION :
239 // nur wegen Matrix nicht editierbar? Attribute trotzdem ok
240 if ( !bEditable && bOnlyNotBecauseOfMatrix )
241 bNeedEdit = FALSE;
242 break;
244 case FID_VALIDATION:
246 if ( pDocShell && pDocShell->IsDocShared() )
248 bDisable = TRUE;
251 break;
253 case SID_TRANSLITERATE_HALFWIDTH:
254 case SID_TRANSLITERATE_FULLWIDTH:
255 case SID_TRANSLITERATE_HIRAGANA:
256 case SID_TRANSLITERATE_KATAGANA:
257 ScViewUtil::HideDisabledSlot( rSet, GetViewData()->GetBindings(), nWhich );
258 break;
260 if (!bDisable && bNeedEdit && !bEditable)
261 bDisable = TRUE;
263 if (bDisable)
264 rSet.DisableItem(nWhich);
265 else if (nWhich == SID_ENABLE_HYPHENATION)
267 // toggle slots need a bool item
268 rSet.Put( SfxBoolItem( nWhich, FALSE ) );
270 nWhich = aIter.NextWhich();
274 // Funktionen, die je nach Cursorposition disabled sind
275 // Default:
276 // SID_INSERT_POSTIT, SID_CHARMAP, SID_OPENDLG_FUNCTION
278 void ScCellShell::GetCellState( SfxItemSet& rSet )
280 ScDocShell* pDocShell = GetViewData()->GetDocShell();
281 ScDocument* pDoc = GetViewData()->GetDocShell()->GetDocument();
282 ScAddress aCursor( GetViewData()->GetCurX(), GetViewData()->GetCurY(),
283 GetViewData()->GetTabNo() );
285 SfxWhichIter aIter(rSet);
286 USHORT nWhich = aIter.FirstWhich();
287 while ( nWhich )
289 BOOL bDisable = FALSE;
290 BOOL bNeedEdit = TRUE; // muss Cursorposition editierbar sein?
291 switch ( nWhich )
293 case SID_THESAURUS:
295 CellType eType = pDoc->GetCellType( aCursor );
296 bDisable = ( eType != CELLTYPE_STRING && eType != CELLTYPE_EDIT);
297 if (!bDisable)
299 // test for available languages
300 USHORT nLang = ScViewUtil::GetEffLanguage( pDoc, aCursor );
301 bDisable = !ScModule::HasThesaurusLanguage( nLang );
304 break;
305 case SID_OPENDLG_FUNCTION:
307 ScMarkData aMarkData=GetViewData()->GetMarkData();
308 aMarkData.MarkToSimple();
309 ScRange aRange;
310 aMarkData.GetMarkArea(aRange);
311 if(aMarkData.IsMarked())
313 if (!pDoc->IsBlockEditable( aCursor.Tab(), aRange.aStart.Col(),aRange.aStart.Row(),
314 aRange.aEnd.Col(),aRange.aEnd.Row() ))
316 bDisable = TRUE;
318 bNeedEdit=FALSE;
322 break;
323 case SID_INSERT_POSTIT:
325 if ( pDocShell && pDocShell->IsDocShared() )
327 bDisable = TRUE;
330 break;
332 if (!bDisable && bNeedEdit)
333 if (!pDoc->IsBlockEditable( aCursor.Tab(), aCursor.Col(),aCursor.Row(),
334 aCursor.Col(),aCursor.Row() ))
335 bDisable = TRUE;
336 if (bDisable)
337 rSet.DisableItem(nWhich);
338 nWhich = aIter.NextWhich();
342 sal_Bool lcl_TestFormat( SvxClipboardFmtItem& rFormats, const TransferableDataHelper& rDataHelper,
343 SotFormatStringId nFormatId )
345 if ( rDataHelper.HasFormat( nFormatId ) )
347 // #90675# translated format name strings are no longer inserted here,
348 // handled by "paste special" dialog / toolbox controller instead.
349 // Only the object type name has to be set here:
350 String aStrVal;
351 if ( nFormatId == SOT_FORMATSTR_ID_EMBED_SOURCE )
353 TransferableObjectDescriptor aDesc;
354 if ( ((TransferableDataHelper&)rDataHelper).GetTransferableObjectDescriptor(
355 SOT_FORMATSTR_ID_OBJECTDESCRIPTOR, aDesc ) )
356 aStrVal = aDesc.maTypeName;
358 else if ( nFormatId == SOT_FORMATSTR_ID_EMBED_SOURCE_OLE
359 || nFormatId == SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE )
361 String aSource;
362 SvPasteObjectHelper::GetEmbeddedName( rDataHelper, aStrVal, aSource, nFormatId );
365 if ( aStrVal.Len() )
366 rFormats.AddClipbrdFormat( nFormatId, aStrVal );
367 else
368 rFormats.AddClipbrdFormat( nFormatId );
370 return sal_True;
373 return sal_False;
376 void ScCellShell::GetPossibleClipboardFormats( SvxClipboardFmtItem& rFormats )
378 Window* pWin = GetViewData()->GetActiveWin();
379 BOOL bDraw = ( ScDrawTransferObj::GetOwnClipboard( pWin ) != NULL );
381 TransferableDataHelper aDataHelper( TransferableDataHelper::CreateFromSystemClipboard( pWin ) );
383 lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_DRAWING );
384 lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_SVXB );
385 lcl_TestFormat( rFormats, aDataHelper, SOT_FORMAT_GDIMETAFILE );
386 lcl_TestFormat( rFormats, aDataHelper, SOT_FORMAT_BITMAP );
387 lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_EMBED_SOURCE );
389 if ( !bDraw )
391 lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_LINK );
392 lcl_TestFormat( rFormats, aDataHelper, SOT_FORMAT_STRING );
393 lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_DIF );
394 lcl_TestFormat( rFormats, aDataHelper, SOT_FORMAT_RTF );
395 lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_HTML );
396 lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_HTML_SIMPLE );
397 lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_BIFF_8 );
398 lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_BIFF_5 );
401 if ( !lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_EMBED_SOURCE_OLE ) )
402 lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE );
405 // Einfuegen, Inhalte einfuegen
407 BOOL lcl_IsCellPastePossible( const TransferableDataHelper& rData )
409 BOOL bPossible = FALSE;
410 if ( ScTransferObj::GetOwnClipboard( NULL ) || ScDrawTransferObj::GetOwnClipboard( NULL ) )
411 bPossible = TRUE;
412 else
414 if ( rData.HasFormat( SOT_FORMAT_BITMAP ) ||
415 rData.HasFormat( SOT_FORMAT_GDIMETAFILE ) ||
416 rData.HasFormat( SOT_FORMATSTR_ID_SVXB ) ||
417 rData.HasFormat( FORMAT_PRIVATE ) ||
418 rData.HasFormat( SOT_FORMAT_RTF ) ||
419 rData.HasFormat( SOT_FORMATSTR_ID_EMBED_SOURCE ) ||
420 rData.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE ) ||
421 rData.HasFormat( SOT_FORMATSTR_ID_EMBED_SOURCE_OLE ) ||
422 rData.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE_OLE ) ||
423 rData.HasFormat( SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE ) ||
424 rData.HasFormat( SOT_FORMAT_STRING ) ||
425 rData.HasFormat( SOT_FORMATSTR_ID_SYLK ) ||
426 rData.HasFormat( SOT_FORMATSTR_ID_LINK ) ||
427 rData.HasFormat( SOT_FORMATSTR_ID_HTML ) ||
428 rData.HasFormat( SOT_FORMATSTR_ID_HTML_SIMPLE ) ||
429 rData.HasFormat( SOT_FORMATSTR_ID_DIF ) )
431 bPossible = TRUE;
434 return bPossible;
437 IMPL_LINK( ScCellShell, ClipboardChanged, TransferableDataHelper*, pDataHelper )
439 if ( pDataHelper )
441 bPastePossible = lcl_IsCellPastePossible( *pDataHelper );
443 SfxBindings& rBindings = GetViewData()->GetBindings();
444 rBindings.Invalidate( SID_PASTE );
445 rBindings.Invalidate( FID_PASTE_CONTENTS );
446 rBindings.Invalidate( SID_CLIPBOARD_FORMAT_ITEMS );
448 return 0;
452 void __EXPORT ScCellShell::GetClipState( SfxItemSet& rSet )
454 // SID_PASTE
455 // FID_PASTE_CONTENTS
456 // SID_CLIPBOARD_FORMAT_ITEMS
458 if ( !pImpl->m_pClipEvtLstnr )
460 // create listener
461 pImpl->m_pClipEvtLstnr = new TransferableClipboardListener( LINK( this, ScCellShell, ClipboardChanged ) );
462 pImpl->m_pClipEvtLstnr->acquire();
463 Window* pWin = GetViewData()->GetActiveWin();
464 pImpl->m_pClipEvtLstnr->AddRemoveListener( pWin, TRUE );
466 // get initial state
467 TransferableDataHelper aDataHelper( TransferableDataHelper::CreateFromSystemClipboard( pWin ) );
468 bPastePossible = lcl_IsCellPastePossible( aDataHelper );
471 BOOL bDisable = !bPastePossible;
473 // Zellschutz / Multiselektion
475 if (!bDisable)
477 SCCOL nCol = GetViewData()->GetCurX();
478 SCROW nRow = GetViewData()->GetCurY();
479 SCTAB nTab = GetViewData()->GetTabNo();
480 ScDocument* pDoc = GetViewData()->GetDocShell()->GetDocument();
481 if (!pDoc->IsBlockEditable( nTab, nCol,nRow, nCol,nRow ))
482 bDisable = TRUE;
483 ScRange aDummy;
484 ScMarkType eMarkType = GetViewData()->GetSimpleArea( aDummy);
485 if (eMarkType != SC_MARK_SIMPLE && eMarkType != SC_MARK_SIMPLE_FILTERED)
486 bDisable = TRUE;
489 if (bDisable)
491 rSet.DisableItem( SID_PASTE );
492 rSet.DisableItem( FID_PASTE_CONTENTS );
493 rSet.DisableItem( SID_CLIPBOARD_FORMAT_ITEMS );
495 else if ( rSet.GetItemState( SID_CLIPBOARD_FORMAT_ITEMS ) != SFX_ITEM_UNKNOWN )
497 SvxClipboardFmtItem aFormats( SID_CLIPBOARD_FORMAT_ITEMS );
498 GetPossibleClipboardFormats( aFormats );
499 rSet.Put( aFormats );
503 // only SID_HYPERLINK_GETLINK:
505 void ScCellShell::GetHLinkState( SfxItemSet& rSet )
507 // always return an item (or inserting will be disabled)
508 // if the cell at the cursor contains only a link, return that link
510 SvxHyperlinkItem aHLinkItem;
511 if ( !GetViewData()->GetView()->HasBookmarkAtCursor( &aHLinkItem ) )
513 //! put selected text into item?
516 rSet.Put(aHLinkItem);
519 void ScCellShell::GetState(SfxItemSet &rSet)
521 // removed: SID_BORDER_OBJECT (old Basic)
523 ScTabViewShell* pTabViewShell = GetViewData()->GetViewShell();
524 // BOOL bOle = pTabViewShell->GetViewFrame()->GetFrame()->IsInPlace();
525 // BOOL bTabProt = GetViewData()->GetDocument()->IsTabProtected(GetViewData()->GetTabNo());
526 ScDocShell* pDocSh = GetViewData()->GetDocShell();
527 ScViewData* pData = GetViewData();
528 ScDocument* pDoc = pData->GetDocument();
529 ScMarkData& rMark = pData->GetMarkData();
530 SCCOL nPosX = pData->GetCurX();
531 SCROW nPosY = pData->GetCurY();
532 SCTAB nTab = pData->GetTabNo();
534 SCTAB nTabCount = pDoc->GetTableCount();
535 SCTAB nTabSelCount = rMark.GetSelectCount();
539 SfxWhichIter aIter(rSet);
540 USHORT nWhich = aIter.FirstWhich();
541 while ( nWhich )
543 switch ( nWhich )
545 case SID_DETECTIVE_REFRESH:
546 if (!pDoc->HasDetectiveOperations())
547 rSet.DisableItem( nWhich );
548 break;
550 case SID_RANGE_ADDRESS:
552 ScRange aRange;
553 if ( pData->GetSimpleArea( aRange ) == SC_MARK_SIMPLE )
555 String aStr;
556 USHORT nFlags = SCA_VALID | SCA_TAB_3D;
557 aRange.Format(aStr,nFlags,pDoc);
558 rSet.Put( SfxStringItem( nWhich, aStr ) );
561 break;
563 case SID_RANGE_NOTETEXT:
565 // #43343# always take cursor position, do not use top-left cell of selection
566 ScAddress aPos( nPosX, nPosY, nTab );
567 String aNoteText;
568 if ( const ScPostIt* pNote = pDoc->GetNote( aPos ) )
569 aNoteText = pNote->GetText();
570 rSet.Put( SfxStringItem( nWhich, aNoteText ) );
572 break;
574 case SID_RANGE_ROW:
575 rSet.Put( SfxInt32Item( nWhich, nPosY+1 ) );
576 break;
578 case SID_RANGE_COL:
579 rSet.Put( SfxInt16Item( nWhich, nPosX+1 ) );
580 break;
582 case SID_RANGE_TABLE:
583 rSet.Put( SfxInt16Item( nWhich, nTab+1 ) );
584 break;
586 case SID_RANGE_VALUE:
588 double nValue;
589 pDoc->GetValue( nPosX, nPosY, nTab, nValue );
590 rSet.Put( ScDoubleItem( nWhich, nValue ) );
592 break;
594 case SID_RANGE_FORMULA:
596 String aString;
597 pDoc->GetFormula( nPosX, nPosY, nTab, aString );
598 if( aString.Len() == 0 )
600 pDoc->GetInputString( nPosX, nPosY, nTab, aString );
602 rSet.Put( SfxStringItem( nWhich, aString ) );
604 break;
606 case SID_RANGE_TEXTVALUE:
608 String aString;
609 pDoc->GetString( nPosX, nPosY, nTab, aString );
610 rSet.Put( SfxStringItem( nWhich, aString ) );
612 break;
614 case SID_STATUS_SELMODE:
616 /* 0: STD Click hebt Sel auf
617 * 1: ER Click erweitert Selektion
618 * 2: ERG Click definiert weitere Selektion
620 USHORT nMode = pTabViewShell->GetLockedModifiers();
622 switch ( nMode )
624 case KEY_SHIFT: nMode = 1; break;
625 case KEY_MOD1: nMode = 2; break; // Control-Taste
626 case 0:
627 default:
628 nMode = 0;
631 rSet.Put( SfxUInt16Item( nWhich, nMode ) );
633 break;
635 case SID_STATUS_DOCPOS:
637 String aStr( ScGlobal::GetRscString( STR_TABLE ) );
639 aStr += ' ';
640 aStr += String::CreateFromInt32( nTab + 1 );
641 aStr.AppendAscii(RTL_CONSTASCII_STRINGPARAM( " / " ));
642 aStr += String::CreateFromInt32( nTabCount );
643 rSet.Put( SfxStringItem( nWhich, aStr ) );
645 break;
647 // Summe etc. mit Datum/Zeit/Fehler/Pos&Groesse zusammengefasst
649 // #i34458# The SfxStringItem belongs only into SID_TABLE_CELL. It no longer has to be
650 // duplicated in SID_ATTR_POSITION or SID_ATTR_SIZE for SvxPosSizeStatusBarControl.
651 case SID_TABLE_CELL:
653 // Testen, ob Fehler unter Cursor
654 // (nicht pDoc->GetErrCode, um keine zirkulaeren Referenzen auszuloesen)
656 // In interpreter may happen via rescheduled Basic
657 if ( pDoc->IsInInterpreter() )
658 rSet.Put( SfxStringItem( nWhich,
659 String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("...")) ) );
660 else
662 USHORT nErrCode = 0;
663 ScBaseCell* pCell;
664 pDoc->GetCell( nPosX, nPosY, nTab, pCell );
665 if ( pCell && pCell->GetCellType() == CELLTYPE_FORMULA )
667 ScFormulaCell* pFCell = (ScFormulaCell*) pCell;
668 if (!pFCell->IsRunning())
669 nErrCode = pFCell->GetErrCode();
672 String aFuncStr;
673 if ( pTabViewShell->GetFunction( aFuncStr, nErrCode ) )
674 rSet.Put( SfxStringItem( nWhich, aFuncStr ) );
677 break;
679 case SID_DATA_SELECT:
680 // HasSelectionData includes column content and validity,
681 // page fields have to be checked separately.
682 if ( !pDoc->HasSelectionData( nPosX, nPosY, nTab ) &&
683 !pTabViewShell->HasPageFieldDataAtCursor() )
684 rSet.DisableItem( nWhich );
685 break;
687 case SID_STATUS_SUM:
689 String aFuncStr;
690 if ( pTabViewShell->GetFunction( aFuncStr ) )
691 rSet.Put( SfxStringItem( nWhich, aFuncStr ) );
693 break;
695 case FID_MERGE_ON:
696 if ( pDoc->GetChangeTrack() || !pTabViewShell->TestMergeCells() )
697 rSet.DisableItem( nWhich );
698 break;
700 case FID_MERGE_OFF:
701 if ( pDoc->GetChangeTrack() || !pTabViewShell->TestRemoveMerge() )
702 rSet.DisableItem( nWhich );
703 break;
705 case FID_MERGE_TOGGLE:
706 if ( pDoc->GetChangeTrack() )
707 rSet.DisableItem( nWhich );
708 else
710 bool bCanMerge = pTabViewShell->TestMergeCells();
711 bool bCanSplit = pTabViewShell->TestRemoveMerge();
712 if( !bCanMerge && !bCanSplit )
713 rSet.DisableItem( nWhich );
714 else
715 rSet.Put( SfxBoolItem( nWhich, bCanSplit ) );
717 break;
719 case FID_INS_ROWBRK:
720 if ( nPosY==0 || (pDoc->HasRowBreak(nPosY, nTab) & BREAK_MANUAL) )
721 rSet.DisableItem( nWhich );
722 break;
724 case FID_INS_COLBRK:
725 if ( nPosX==0 || (pDoc->HasColBreak(nPosX, nTab) & BREAK_MANUAL) )
726 rSet.DisableItem( nWhich );
727 break;
729 case FID_DEL_ROWBRK:
730 if ( nPosY==0 || (pDoc->HasRowBreak(nPosY, nTab) & BREAK_MANUAL) == 0 )
731 rSet.DisableItem( nWhich );
732 break;
734 case FID_DEL_COLBRK:
735 if ( nPosX==0 || (pDoc->HasColBreak(nPosX, nTab) & BREAK_MANUAL) == 0 )
736 rSet.DisableItem( nWhich );
737 break;
739 case FID_FILL_TAB:
740 if ( nTabSelCount < 2 )
741 rSet.DisableItem( nWhich );
742 break;
744 case SID_SELECT_SCENARIO:
746 // ScDocument* pDoc = GetViewData()->GetDocument();
747 // SCTAB nTab = GetViewData()->GetTabNo();
748 List aList;
750 Color aDummyCol;
752 if ( !pDoc->IsScenario(nTab) )
754 String aStr;
755 USHORT nFlags;
756 SCTAB nScTab = nTab + 1;
757 String aProtect;
758 bool bSheetProtected = pDoc->IsTabProtected(nTab);
760 while ( pDoc->IsScenario(nScTab) )
762 pDoc->GetName( nScTab, aStr );
763 aList.Insert( new String( aStr ), LIST_APPEND );
764 pDoc->GetScenarioData( nScTab, aStr, aDummyCol, nFlags );
765 aList.Insert( new String( aStr ), LIST_APPEND );
766 // Protection is TRUE if both Sheet and Scenario are protected
767 aProtect = (bSheetProtected && (nFlags & SC_SCENARIO_PROTECT)) ? '1' : '0';
768 aList.Insert( new String( aProtect), LIST_APPEND );
769 ++nScTab;
772 else
774 String aComment;
775 USHORT nDummyFlags;
776 pDoc->GetScenarioData( nTab, aComment, aDummyCol, nDummyFlags );
777 DBG_ASSERT( aList.Count() == 0, "List not empty!" );
778 aList.Insert( new String( aComment ) );
781 rSet.Put( SfxStringListItem( nWhich, &aList ) );
783 ULONG nCount = aList.Count();
784 for ( ULONG i=0; i<nCount; i++ )
785 delete (String*) aList.GetObject(i);
787 break;
789 case FID_ROW_HIDE:
790 case FID_ROW_SHOW:
791 case FID_COL_HIDE:
792 case FID_COL_SHOW:
793 case FID_COL_OPT_WIDTH:
794 case FID_ROW_OPT_HEIGHT:
795 case FID_DELETE_CELL:
796 if ( pDoc->IsTabProtected(nTab) || pDocSh->IsReadOnly())
797 rSet.DisableItem( nWhich );
798 break;
800 /* Zellschutz bei selektierten Zellen wird bei anderen Funktionen auch nicht abgefragt...
801 case SID_DELETE:
803 if ( pDoc->IsTabProtected(nTab) )
805 const SfxItemSet& rAttrSet = GetSelectionPattern()->GetItemSet();
806 const ScProtectionAttr& rProtAttr = (const ScProtectionAttr&)rAttrSet.Get( ATTR_PROTECTION, TRUE );
807 if ( rProtAttr.GetProtection() )
808 rSet.DisableItem( nWhich );
811 break;
813 case SID_OUTLINE_MAKE:
815 if ( GetViewData()->GetDocument()->GetDPAtCursor( GetViewData()->GetCurX(),
816 GetViewData()->GetCurY(), GetViewData()->GetTabNo() ) )
818 //! test for data pilot operation
820 else if (pDoc->GetChangeTrack()!=NULL || GetViewData()->IsMultiMarked())
822 rSet.DisableItem( nWhich );
825 break;
826 case SID_OUTLINE_SHOW:
827 if ( GetViewData()->GetDocument()->GetDPAtCursor( GetViewData()->GetCurX(),
828 GetViewData()->GetCurY(), GetViewData()->GetTabNo() ) )
830 //! test for data pilot operation
832 else if (!pTabViewShell->OutlinePossible(FALSE))
833 rSet.DisableItem( nWhich );
834 break;
836 case SID_OUTLINE_HIDE:
837 if ( GetViewData()->GetDocument()->GetDPAtCursor( GetViewData()->GetCurX(),
838 GetViewData()->GetCurY(), GetViewData()->GetTabNo() ) )
840 //! test for data pilot operation
842 else if (!pTabViewShell->OutlinePossible(TRUE))
843 rSet.DisableItem( nWhich );
844 break;
846 case SID_OUTLINE_REMOVE:
848 if ( GetViewData()->GetDocument()->GetDPAtCursor( GetViewData()->GetCurX(),
849 GetViewData()->GetCurY(), GetViewData()->GetTabNo() ) )
851 //! test for data pilot operation
853 else
855 BOOL bCol, bRow;
856 pTabViewShell->TestRemoveOutline( bCol, bRow );
857 if ( !bCol && !bRow )
858 rSet.DisableItem( nWhich );
861 break;
863 case FID_COL_WIDTH:
865 //GetViewData()->GetCurX();
866 SfxUInt16Item aWidthItem( FID_COL_WIDTH, pDoc->GetColWidth( nPosX , nTab) );
867 rSet.Put( aWidthItem );
868 if ( pDocSh->IsReadOnly())
869 rSet.DisableItem( nWhich );
871 //XXX Disablen wenn nicht eindeutig
873 break;
875 case FID_ROW_HEIGHT:
877 //GetViewData()->GetCurY();
878 SfxUInt16Item aHeightItem( FID_ROW_HEIGHT, pDoc->GetRowHeight( nPosY , nTab) );
879 rSet.Put( aHeightItem );
880 //XXX Disablen wenn nicht eindeutig
881 if ( pDocSh->IsReadOnly())
882 rSet.DisableItem( nWhich );
884 break;
886 case SID_DETECTIVE_FILLMODE:
887 rSet.Put(SfxBoolItem( nWhich, pTabViewShell->IsAuditShell() ));
888 break;
890 case FID_INPUTLINE_STATUS:
891 DBG_ERROR( "Old update method. Use ScTabViewShell::UpdateInputHandler()." );
892 break;
894 case SID_SCENARIOS: // Szenarios:
895 if (!(rMark.IsMarked() || rMark.IsMultiMarked())) // nur, wenn etwas selektiert
896 rSet.DisableItem( nWhich );
897 break;
899 case FID_NOTE_VISIBLE:
901 const ScPostIt* pNote = pDoc->GetNote( ScAddress( nPosX, nPosY, nTab ) );
902 if ( pNote && pDoc->IsBlockEditable( nTab, nPosX,nPosY, nPosX,nPosY ) )
903 rSet.Put( SfxBoolItem( nWhich, pNote->IsCaptionShown() ) );
904 else
905 rSet.DisableItem( nWhich );
907 break;
909 case SID_DELETE_NOTE:
911 BOOL bEnable = FALSE;
912 if ( rMark.IsMarked() || rMark.IsMultiMarked() )
914 if ( pDoc->IsSelectionEditable( rMark ) )
916 // look for at least one note in selection
917 ScRangeList aRanges;
918 rMark.FillRangeListWithMarks( &aRanges, FALSE );
919 ULONG nCount = aRanges.Count();
920 for (ULONG nPos=0; nPos<nCount && !bEnable; nPos++)
922 ScCellIterator aCellIter( pDoc, *aRanges.GetObject(nPos) );
923 for( ScBaseCell* pCell = aCellIter.GetFirst(); pCell && !bEnable; pCell = aCellIter.GetNext() )
924 if ( pCell->HasNote() )
925 bEnable = TRUE; // note found
929 else
931 bEnable = pDoc->IsBlockEditable( nTab, nPosX,nPosY, nPosX,nPosY ) &&
932 pDoc->GetNote( ScAddress( nPosX, nPosY, nTab ) );
934 if ( !bEnable )
935 rSet.DisableItem( nWhich );
937 break;
939 case SID_OPENDLG_CONSOLIDATE:
940 case SCITEM_CONSOLIDATEDATA:
942 if(pDoc->GetChangeTrack()!=NULL)
943 rSet.DisableItem( nWhich);
945 break;
947 case SID_CHINESE_CONVERSION:
948 case SID_HANGUL_HANJA_CONVERSION:
949 ScViewUtil::HideDisabledSlot( rSet, pData->GetBindings(), nWhich );
950 break;
952 case FID_USE_NAME:
954 if ( pDocSh && pDocSh->IsDocShared() )
955 rSet.DisableItem( nWhich );
956 else
958 ScRange aRange;
959 if ( pData->GetSimpleArea( aRange ) != SC_MARK_SIMPLE )
960 rSet.DisableItem( nWhich );
963 break;
965 case FID_DEFINE_NAME:
966 case FID_INSERT_NAME:
967 case SID_DEFINE_COLROWNAMERANGES:
969 if ( pDocSh && pDocSh->IsDocShared() )
971 rSet.DisableItem( nWhich );
974 break;
976 } // switch ( nWitch )
977 nWhich = aIter.NextWhich();
978 } // while ( nWitch )
981 //------------------------------------------------------------------