xref: /trunk/main/sc/source/ui/view/cellsh.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_sc.hxx"
30 
31 //------------------------------------------------------------------
32 
33 #include "scitems.hxx"
34 
35 #include <svl/slstitm.hxx>
36 #include <svl/stritem.hxx>
37 #include <svl/whiter.hxx>
38 #include <unotools/moduleoptions.hxx>
39 #include <svtools/cliplistener.hxx>
40 #include <svtools/insdlg.hxx>
41 #include <sot/formats.hxx>
42 #include <svx/hlnkitem.hxx>
43 #include <sfx2/app.hxx>
44 #include <sfx2/bindings.hxx>
45 #include <sfx2/childwin.hxx>
46 #include <sfx2/objface.hxx>
47 #include <sfx2/request.hxx>
48 #include <sfx2/viewfrm.hxx>
49 #include <svx/clipfmtitem.hxx>
50 #include <editeng/langitem.hxx>
51 
52 #include "cellsh.hxx"
53 #include "sc.hrc"
54 #include "docsh.hxx"
55 #include "attrib.hxx"
56 #include "scresid.hxx"
57 #include "tabvwsh.hxx"
58 #include "impex.hxx"
59 #include "cell.hxx"
60 #include "scmod.hxx"
61 #include "globstr.hrc"
62 #include "transobj.hxx"
63 #include "drwtrans.hxx"
64 #include "scabstdlg.hxx"
65 #include "dociter.hxx"
66 #include "postit.hxx"
67 
68 //------------------------------------------------------------------
69 
70 #define ScCellShell
71 #define CellMovement
72 #include "scslots.hxx"
73 
74 TYPEINIT1( ScCellShell, ScFormatShell );
75 
76 SFX_IMPL_INTERFACE(ScCellShell, ScFormatShell , ScResId(SCSTR_CELLSHELL) )
77 {
78     SFX_OBJECTBAR_REGISTRATION( SFX_OBJECTBAR_OBJECT | SFX_VISIBILITY_STANDARD |
79                                 SFX_VISIBILITY_SERVER,
80                                 ScResId(RID_OBJECTBAR_FORMAT));
81     SFX_POPUPMENU_REGISTRATION(ScResId(RID_POPUP_CELLS));
82 }
83 
84 
85 ScCellShell::ScCellShell(ScViewData* pData) :
86     ScFormatShell(pData),
87     pImpl( new CellShell_Impl() ),
88     bPastePossible(sal_False)
89 {
90     SetHelpId(HID_SCSHELL_CELLSH);
91     SetName(String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("Cell")));
92 }
93 
94 ScCellShell::~ScCellShell()
95 {
96     if ( pImpl->m_pClipEvtLstnr )
97     {
98         pImpl->m_pClipEvtLstnr->AddRemoveListener( GetViewData()->GetActiveWin(), sal_False );
99 
100         //  #103849# The listener may just now be waiting for the SolarMutex and call the link
101         //  afterwards, in spite of RemoveListener. So the link has to be reset, too.
102         pImpl->m_pClipEvtLstnr->ClearCallbackLink();
103 
104         pImpl->m_pClipEvtLstnr->release();
105     }
106 
107     delete pImpl->m_pLinkedDlg;
108     delete pImpl->m_pRequest;
109     delete pImpl;
110 }
111 
112 //------------------------------------------------------------------
113 
114 void ScCellShell::GetBlockState( SfxItemSet& rSet )
115 {
116     ScTabViewShell* pTabViewShell   = GetViewData()->GetViewShell();
117     ScRange aMarkRange;
118     ScMarkType eMarkType = GetViewData()->GetSimpleArea( aMarkRange );
119     sal_Bool bSimpleArea = (eMarkType == SC_MARK_SIMPLE);
120     sal_Bool bOnlyNotBecauseOfMatrix;
121     sal_Bool bEditable = pTabViewShell->SelectionEditable( &bOnlyNotBecauseOfMatrix );
122     ScDocument* pDoc = GetViewData()->GetDocument();
123     ScDocShell* pDocShell = GetViewData()->GetDocShell();
124     ScMarkData& rMark = GetViewData()->GetMarkData();
125     SCCOL nCol1, nCol2;
126     SCROW nRow1, nRow2;
127     nCol1 = aMarkRange.aStart.Col();
128     nRow1 = aMarkRange.aStart.Row();
129     nCol2 = aMarkRange.aEnd.Col();
130     nRow2 = aMarkRange.aEnd.Row();
131 
132     SfxWhichIter aIter(rSet);
133     sal_uInt16 nWhich = aIter.FirstWhich();
134     while ( nWhich )
135     {
136         sal_Bool bDisable = sal_False;
137         sal_Bool bNeedEdit = sal_True;      // muss Selektion editierbar sein?
138         switch ( nWhich )
139         {
140             case FID_FILL_TO_BOTTOM:    // Fuellen oben/unten
141             case FID_FILL_TO_TOP:       // mind. 2 Zeilen markiert?
142                 bDisable = (!bSimpleArea) || (nRow1 == nRow2);
143                 if ( !bDisable && bEditable )
144                 {   // Matrix nicht zerreissen
145                     if ( nWhich == FID_FILL_TO_BOTTOM )
146                         bDisable = pDoc->HasSelectedBlockMatrixFragment(
147                             nCol1, nRow1, nCol2, nRow1, rMark );    // erste Zeile
148                     else
149                         bDisable = pDoc->HasSelectedBlockMatrixFragment(
150                             nCol1, nRow2, nCol2, nRow2, rMark );    // letzte Zeile
151                 }
152                 break;
153 
154             case FID_FILL_TO_RIGHT:     // Fuellen links/rechts
155             case FID_FILL_TO_LEFT:      // mind. 2 Spalten markiert?
156                 bDisable = (!bSimpleArea) || (nCol1 == nCol2);
157                 if ( !bDisable && bEditable )
158                 {   // Matrix nicht zerreissen
159                     if ( nWhich == FID_FILL_TO_RIGHT )
160                         bDisable = pDoc->HasSelectedBlockMatrixFragment(
161                             nCol1, nRow1, nCol1, nRow2, rMark );    // erste Spalte
162                     else
163                         bDisable = pDoc->HasSelectedBlockMatrixFragment(
164                             nCol2, nRow1, nCol2, nRow2, rMark );    // letzte Spalte
165                 }
166                 break;
167 
168             case FID_FILL_SERIES:       // Block fuellen
169             case SID_OPENDLG_TABOP:     // Mehrfachoperationen, mind. 2 Zellen markiert?
170                 if (pDoc->GetChangeTrack()!=NULL &&nWhich ==SID_OPENDLG_TABOP)
171                     bDisable = sal_True;
172                 else
173                     bDisable = (!bSimpleArea) || (nCol1 == nCol2 && nRow1 == nRow2);
174 
175                 if ( !bDisable && bEditable && nWhich == FID_FILL_SERIES )
176                 {   // Matrix nicht zerreissen
177                     bDisable = pDoc->HasSelectedBlockMatrixFragment(
178                             nCol1, nRow1, nCol2, nRow1, rMark ) // erste Zeile
179                         ||  pDoc->HasSelectedBlockMatrixFragment(
180                             nCol1, nRow2, nCol2, nRow2, rMark ) // letzte Zeile
181                         ||  pDoc->HasSelectedBlockMatrixFragment(
182                             nCol1, nRow1, nCol1, nRow2, rMark ) // erste Spalte
183                         ||  pDoc->HasSelectedBlockMatrixFragment(
184                             nCol2, nRow1, nCol2, nRow2, rMark );    // letzte Spalte
185                 }
186                 break;
187 
188             case SID_CUT:               // Ausschneiden,
189             case FID_INS_CELL:          // Zellen einfuegen, nur einf. Selektion
190                 bDisable = (!bSimpleArea);
191                 break;
192 
193             case FID_INS_ROW:           // insert rows
194             case FID_INS_CELLSDOWN:
195                 bDisable = (!bSimpleArea) || GetViewData()->SimpleColMarked();
196                 break;
197 
198             case FID_INS_COLUMN:        // insert columns
199             case FID_INS_CELLSRIGHT:
200                 bDisable = (!bSimpleArea) || GetViewData()->SimpleRowMarked();
201                 break;
202 
203             case SID_COPY:                      // Kopieren
204                 // nur wegen Matrix nicht editierbar? Matrix nicht zerreissen
205                 //! schlaegt nicht zu, wenn geschuetzt UND Matrix, aber damit
206                 //! muss man leben.. wird in Copy-Routine abgefangen, sonst
207                 //! muesste hier nochmal Aufwand getrieben werden
208                 if ( !(!bEditable && bOnlyNotBecauseOfMatrix) )
209                     bNeedEdit = sal_False;          // erlaubt, wenn geschuetzt/ReadOnly
210                 break;
211 
212             case SID_AUTOFORMAT:        // Autoformat, mind. 3x3 selektiert
213                 bDisable =    (!bSimpleArea)
214                            || ((nCol2 - nCol1) < 2) || ((nRow2 - nRow1) < 2);
215                 break;
216 
217             case SID_OPENDLG_CONDFRMT :
218                 {
219                     if ( !bEditable && bOnlyNotBecauseOfMatrix )
220                     {
221                         bNeedEdit = sal_False;
222                     }
223                     if ( pDocShell && pDocShell->IsDocShared() )
224                     {
225                         bDisable = sal_True;
226                     }
227                 }
228                 break;
229 
230             case FID_CONDITIONAL_FORMAT :
231             case SID_CELL_FORMAT_RESET :
232             case FID_CELL_FORMAT :
233             case SID_ENABLE_HYPHENATION :
234                 // nur wegen Matrix nicht editierbar? Attribute trotzdem ok
235                 if ( !bEditable && bOnlyNotBecauseOfMatrix )
236                     bNeedEdit = sal_False;
237                 break;
238 
239             case FID_VALIDATION:
240                 {
241                     if ( pDocShell && pDocShell->IsDocShared() )
242                     {
243                         bDisable = sal_True;
244                     }
245                 }
246                 break;
247 
248             case SID_TRANSLITERATE_HALFWIDTH:
249             case SID_TRANSLITERATE_FULLWIDTH:
250             case SID_TRANSLITERATE_HIRAGANA:
251             case SID_TRANSLITERATE_KATAGANA:
252                 ScViewUtil::HideDisabledSlot( rSet, GetViewData()->GetBindings(), nWhich );
253             break;
254         }
255         if (!bDisable && bNeedEdit && !bEditable)
256             bDisable = sal_True;
257 
258         if (bDisable)
259             rSet.DisableItem(nWhich);
260         else if (nWhich == SID_ENABLE_HYPHENATION)
261         {
262             // toggle slots need a bool item
263             rSet.Put( SfxBoolItem( nWhich, sal_False ) );
264         }
265         nWhich = aIter.NextWhich();
266     }
267 }
268 
269 //  Funktionen, die je nach Cursorposition disabled sind
270 //  Default:
271 //      SID_INSERT_POSTIT, SID_CHARMAP, SID_OPENDLG_FUNCTION
272 
273 void ScCellShell::GetCellState( SfxItemSet& rSet )
274 {
275     ScDocShell* pDocShell = GetViewData()->GetDocShell();
276     ScDocument* pDoc = GetViewData()->GetDocShell()->GetDocument();
277     ScAddress aCursor( GetViewData()->GetCurX(), GetViewData()->GetCurY(),
278                         GetViewData()->GetTabNo() );
279 
280     SfxWhichIter aIter(rSet);
281     sal_uInt16 nWhich = aIter.FirstWhich();
282     while ( nWhich )
283     {
284         sal_Bool bDisable = sal_False;
285         sal_Bool bNeedEdit = sal_True;      // muss Cursorposition editierbar sein?
286         switch ( nWhich )
287         {
288             case SID_THESAURUS:
289                 {
290                     CellType eType = pDoc->GetCellType( aCursor );
291                     bDisable = ( eType != CELLTYPE_STRING && eType != CELLTYPE_EDIT);
292                     if (!bDisable)
293                     {
294                         //  test for available languages
295                         sal_uInt16 nLang = ScViewUtil::GetEffLanguage( pDoc, aCursor );
296                         bDisable = !ScModule::HasThesaurusLanguage( nLang );
297                     }
298                 }
299                 break;
300             case SID_OPENDLG_FUNCTION:
301                 {
302                     ScMarkData aMarkData=GetViewData()->GetMarkData();
303                     aMarkData.MarkToSimple();
304                     ScRange aRange;
305                     aMarkData.GetMarkArea(aRange);
306                     if(aMarkData.IsMarked())
307                     {
308                         if (!pDoc->IsBlockEditable( aCursor.Tab(), aRange.aStart.Col(),aRange.aStart.Row(),
309                                             aRange.aEnd.Col(),aRange.aEnd.Row() ))
310                         {
311                             bDisable = sal_True;
312                         }
313                         bNeedEdit=sal_False;
314                     }
315 
316                 }
317                 break;
318             case SID_INSERT_POSTIT:
319                 {
320                     if ( pDocShell && pDocShell->IsDocShared() )
321                     {
322                         bDisable = sal_True;
323                     }
324                 }
325                 break;
326         }
327         if (!bDisable && bNeedEdit)
328             if (!pDoc->IsBlockEditable( aCursor.Tab(), aCursor.Col(),aCursor.Row(),
329                                         aCursor.Col(),aCursor.Row() ))
330                 bDisable = sal_True;
331         if (bDisable)
332             rSet.DisableItem(nWhich);
333         nWhich = aIter.NextWhich();
334     }
335 }
336 
337 sal_Bool lcl_TestFormat( SvxClipboardFmtItem& rFormats, const TransferableDataHelper& rDataHelper,
338                         SotFormatStringId nFormatId )
339 {
340     if ( rDataHelper.HasFormat( nFormatId ) )
341     {
342         //  #90675# translated format name strings are no longer inserted here,
343         //  handled by "paste special" dialog / toolbox controller instead.
344         //  Only the object type name has to be set here:
345         String aStrVal;
346         if ( nFormatId == SOT_FORMATSTR_ID_EMBED_SOURCE )
347         {
348             TransferableObjectDescriptor aDesc;
349             if ( ((TransferableDataHelper&)rDataHelper).GetTransferableObjectDescriptor(
350                                         SOT_FORMATSTR_ID_OBJECTDESCRIPTOR, aDesc ) )
351                 aStrVal = aDesc.maTypeName;
352         }
353         else if ( nFormatId == SOT_FORMATSTR_ID_EMBED_SOURCE_OLE
354           || nFormatId == SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE )
355         {
356             String aSource;
357             SvPasteObjectHelper::GetEmbeddedName( rDataHelper, aStrVal, aSource, nFormatId );
358         }
359 
360         if ( aStrVal.Len() )
361             rFormats.AddClipbrdFormat( nFormatId, aStrVal );
362         else
363             rFormats.AddClipbrdFormat( nFormatId );
364 
365         return sal_True;
366     }
367 
368     return sal_False;
369 }
370 
371 void ScCellShell::GetPossibleClipboardFormats( SvxClipboardFmtItem& rFormats )
372 {
373     Window* pWin = GetViewData()->GetActiveWin();
374     sal_Bool bDraw = ( ScDrawTransferObj::GetOwnClipboard( pWin ) != NULL );
375 
376     TransferableDataHelper aDataHelper( TransferableDataHelper::CreateFromSystemClipboard( pWin ) );
377 
378     lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_DRAWING );
379     lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_SVXB );
380     lcl_TestFormat( rFormats, aDataHelper, SOT_FORMAT_GDIMETAFILE );
381     lcl_TestFormat( rFormats, aDataHelper, SOT_FORMAT_BITMAP );
382     lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_EMBED_SOURCE );
383 
384     if ( !bDraw )
385     {
386         lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_LINK );
387         lcl_TestFormat( rFormats, aDataHelper, SOT_FORMAT_STRING );
388         lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_DIF );
389         lcl_TestFormat( rFormats, aDataHelper, SOT_FORMAT_RTF );
390         lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_HTML );
391         lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_HTML_SIMPLE );
392         lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_BIFF_8 );
393         lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_BIFF_5 );
394     }
395 
396     if ( !lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_EMBED_SOURCE_OLE ) )
397         lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE );
398 }
399 
400 //  Einfuegen, Inhalte einfuegen
401 
402 sal_Bool lcl_IsCellPastePossible( const TransferableDataHelper& rData )
403 {
404     sal_Bool bPossible = sal_False;
405     if ( ScTransferObj::GetOwnClipboard( NULL ) || ScDrawTransferObj::GetOwnClipboard( NULL ) )
406         bPossible = sal_True;
407     else
408     {
409         if ( rData.HasFormat( SOT_FORMAT_BITMAP ) ||
410              rData.HasFormat( SOT_FORMAT_GDIMETAFILE ) ||
411              rData.HasFormat( SOT_FORMATSTR_ID_SVXB ) ||
412              rData.HasFormat( FORMAT_PRIVATE ) ||
413              rData.HasFormat( SOT_FORMAT_RTF ) ||
414              rData.HasFormat( SOT_FORMATSTR_ID_EMBED_SOURCE ) ||
415              rData.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE ) ||
416              rData.HasFormat( SOT_FORMATSTR_ID_EMBED_SOURCE_OLE ) ||
417              rData.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE_OLE ) ||
418              rData.HasFormat( SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE ) ||
419              rData.HasFormat( SOT_FORMAT_STRING ) ||
420              rData.HasFormat( SOT_FORMATSTR_ID_SYLK ) ||
421              rData.HasFormat( SOT_FORMATSTR_ID_LINK ) ||
422              rData.HasFormat( SOT_FORMATSTR_ID_HTML ) ||
423              rData.HasFormat( SOT_FORMATSTR_ID_HTML_SIMPLE ) ||
424              rData.HasFormat( SOT_FORMATSTR_ID_DIF ) )
425         {
426             bPossible = sal_True;
427         }
428     }
429     return bPossible;
430 }
431 
432 IMPL_LINK( ScCellShell, ClipboardChanged, TransferableDataHelper*, pDataHelper )
433 {
434     if ( pDataHelper )
435     {
436         bPastePossible = lcl_IsCellPastePossible( *pDataHelper );
437 
438         SfxBindings& rBindings = GetViewData()->GetBindings();
439         rBindings.Invalidate( SID_PASTE );
440         rBindings.Invalidate( SID_PASTE_SPECIAL );
441         rBindings.Invalidate( SID_CLIPBOARD_FORMAT_ITEMS );
442     }
443     return 0;
444 }
445 
446 
447 void __EXPORT ScCellShell::GetClipState( SfxItemSet& rSet )
448 {
449 // SID_PASTE
450 // SID_PASTE_SPECIAL
451 // SID_CLIPBOARD_FORMAT_ITEMS
452 
453     if ( !pImpl->m_pClipEvtLstnr )
454     {
455         // create listener
456         pImpl->m_pClipEvtLstnr = new TransferableClipboardListener( LINK( this, ScCellShell, ClipboardChanged ) );
457         pImpl->m_pClipEvtLstnr->acquire();
458         Window* pWin = GetViewData()->GetActiveWin();
459         pImpl->m_pClipEvtLstnr->AddRemoveListener( pWin, sal_True );
460 
461         // get initial state
462         TransferableDataHelper aDataHelper( TransferableDataHelper::CreateFromSystemClipboard( pWin ) );
463         bPastePossible = lcl_IsCellPastePossible( aDataHelper );
464     }
465 
466     sal_Bool bDisable = !bPastePossible;
467 
468     //  Zellschutz / Multiselektion
469 
470     if (!bDisable)
471     {
472         SCCOL nCol = GetViewData()->GetCurX();
473         SCROW nRow = GetViewData()->GetCurY();
474         SCTAB nTab = GetViewData()->GetTabNo();
475         ScDocument* pDoc = GetViewData()->GetDocShell()->GetDocument();
476         if (!pDoc->IsBlockEditable( nTab, nCol,nRow, nCol,nRow ))
477             bDisable = sal_True;
478         ScRange aDummy;
479         ScMarkType eMarkType = GetViewData()->GetSimpleArea( aDummy);
480         if (eMarkType != SC_MARK_SIMPLE && eMarkType != SC_MARK_SIMPLE_FILTERED)
481             bDisable = sal_True;
482     }
483 
484     if (bDisable)
485     {
486         rSet.DisableItem( SID_PASTE );
487         rSet.DisableItem( SID_PASTE_SPECIAL );
488         rSet.DisableItem( SID_CLIPBOARD_FORMAT_ITEMS );
489     }
490     else if ( rSet.GetItemState( SID_CLIPBOARD_FORMAT_ITEMS ) != SFX_ITEM_UNKNOWN )
491     {
492         SvxClipboardFmtItem aFormats( SID_CLIPBOARD_FORMAT_ITEMS );
493         GetPossibleClipboardFormats( aFormats );
494         rSet.Put( aFormats );
495     }
496 }
497 
498 //  only SID_HYPERLINK_GETLINK:
499 
500 void ScCellShell::GetHLinkState( SfxItemSet& rSet )
501 {
502     //  always return an item (or inserting will be disabled)
503     //  if the cell at the cursor contains only a link, return that link
504 
505     SvxHyperlinkItem aHLinkItem;
506     if ( !GetViewData()->GetView()->HasBookmarkAtCursor( &aHLinkItem ) )
507     {
508         //! put selected text into item?
509     }
510 
511     rSet.Put(aHLinkItem);
512 }
513 
514 void ScCellShell::GetState(SfxItemSet &rSet)
515 {
516     // removed: SID_BORDER_OBJECT (old Basic)
517 
518     ScTabViewShell* pTabViewShell   = GetViewData()->GetViewShell();
519 //     sal_Bool bOle = pTabViewShell->GetViewFrame()->GetFrame().IsInPlace();
520 //  sal_Bool bTabProt = GetViewData()->GetDocument()->IsTabProtected(GetViewData()->GetTabNo());
521     ScDocShell* pDocSh = GetViewData()->GetDocShell();
522     ScViewData* pData       = GetViewData();
523     ScDocument* pDoc        = pData->GetDocument();
524     ScMarkData& rMark       = pData->GetMarkData();
525     SCCOL       nPosX       = pData->GetCurX();
526     SCROW       nPosY       = pData->GetCurY();
527     SCTAB       nTab        = pData->GetTabNo();
528 
529     SCTAB nTabCount = pDoc->GetTableCount();
530     SCTAB nTabSelCount = rMark.GetSelectCount();
531 
532 
533 
534     SfxWhichIter aIter(rSet);
535     sal_uInt16 nWhich = aIter.FirstWhich();
536     while ( nWhich )
537     {
538         switch ( nWhich )
539         {
540             case SID_DETECTIVE_REFRESH:
541                 if (!pDoc->HasDetectiveOperations())
542                     rSet.DisableItem( nWhich );
543                 break;
544 
545             case SID_RANGE_ADDRESS:
546                 {
547                     ScRange aRange;
548                     if ( pData->GetSimpleArea( aRange ) == SC_MARK_SIMPLE )
549                     {
550                         String aStr;
551                         sal_uInt16 nFlags = SCA_VALID | SCA_TAB_3D;
552                         aRange.Format(aStr,nFlags,pDoc);
553                         rSet.Put( SfxStringItem( nWhich, aStr ) );
554                     }
555                 }
556                 break;
557 
558             case SID_RANGE_NOTETEXT:
559                 {
560                     //  #43343# always take cursor position, do not use top-left cell of selection
561                     ScAddress aPos( nPosX, nPosY, nTab );
562                     String aNoteText;
563                     if ( const ScPostIt* pNote = pDoc->GetNote( aPos ) )
564                         aNoteText = pNote->GetText();
565                     rSet.Put( SfxStringItem( nWhich, aNoteText ) );
566                 }
567                 break;
568 
569             case SID_RANGE_ROW:
570                 rSet.Put( SfxInt32Item( nWhich, nPosY+1 ) );
571                 break;
572 
573             case SID_RANGE_COL:
574                 rSet.Put( SfxInt16Item( nWhich, nPosX+1 ) );
575                 break;
576 
577             case SID_RANGE_TABLE:
578                 rSet.Put( SfxInt16Item( nWhich, nTab+1 ) );
579                 break;
580 
581             case SID_RANGE_VALUE:
582                 {
583                     double nValue;
584                     pDoc->GetValue( nPosX, nPosY, nTab, nValue );
585                     rSet.Put( ScDoubleItem( nWhich, nValue ) );
586                 }
587                 break;
588 
589             case SID_RANGE_FORMULA:
590                 {
591                     String aString;
592                     pDoc->GetFormula( nPosX, nPosY, nTab, aString );
593                     if( aString.Len() == 0 )
594                     {
595                         pDoc->GetInputString( nPosX, nPosY, nTab, aString );
596                     }
597                     rSet.Put( SfxStringItem( nWhich, aString ) );
598                 }
599                 break;
600 
601             case SID_RANGE_TEXTVALUE:
602                 {
603                     String aString;
604                     pDoc->GetString( nPosX, nPosY, nTab, aString );
605                     rSet.Put( SfxStringItem( nWhich, aString ) );
606                 }
607                 break;
608 
609             case SID_STATUS_SELMODE:
610                 {
611                     /* 0: STD   Click hebt Sel auf
612                      * 1: ER    Click erweitert Selektion
613                      * 2: ERG   Click definiert weitere Selektion
614                      */
615                     sal_uInt16 nMode = pTabViewShell->GetLockedModifiers();
616 
617                     switch ( nMode )
618                     {
619                         case KEY_SHIFT: nMode = 1;  break;
620                         case KEY_MOD1:  nMode = 2;  break; // Control-Taste
621                         case 0:
622                         default:
623                             nMode = 0;
624                     }
625 
626                     rSet.Put( SfxUInt16Item( nWhich, nMode ) );
627                 }
628                 break;
629 
630             case SID_STATUS_DOCPOS:
631                 {
632                     String  aStr( ScGlobal::GetRscString( STR_TABLE ) );
633 
634                     aStr += ' ';
635                     aStr += String::CreateFromInt32( nTab + 1 );
636                     aStr.AppendAscii(RTL_CONSTASCII_STRINGPARAM( " / " ));
637                     aStr += String::CreateFromInt32( nTabCount );
638                     rSet.Put( SfxStringItem( nWhich, aStr ) );
639                 }
640                 break;
641 
642             //  Summe etc. mit Datum/Zeit/Fehler/Pos&Groesse zusammengefasst
643 
644             // #i34458# The SfxStringItem belongs only into SID_TABLE_CELL. It no longer has to be
645             // duplicated in SID_ATTR_POSITION or SID_ATTR_SIZE for SvxPosSizeStatusBarControl.
646             case SID_TABLE_CELL:
647                 {
648                     //  Testen, ob Fehler unter Cursor
649                     //  (nicht pDoc->GetErrCode, um keine zirkulaeren Referenzen auszuloesen)
650 
651                     // In interpreter may happen via rescheduled Basic
652                     if ( pDoc->IsInInterpreter() )
653                         rSet.Put( SfxStringItem( nWhich,
654                             String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("...")) ) );
655                     else
656                     {
657                         sal_uInt16 nErrCode = 0;
658                         ScBaseCell* pCell;
659                         pDoc->GetCell( nPosX, nPosY, nTab, pCell );
660                         if ( pCell && pCell->GetCellType() == CELLTYPE_FORMULA )
661                         {
662                             ScFormulaCell* pFCell = (ScFormulaCell*) pCell;
663                             if (!pFCell->IsRunning())
664                                 nErrCode = pFCell->GetErrCode();
665                         }
666 
667                         String aFuncStr;
668                         if ( pTabViewShell->GetFunction( aFuncStr, nErrCode ) )
669                             rSet.Put( SfxStringItem( nWhich, aFuncStr ) );
670                     }
671                 }
672                 break;
673 
674             case SID_DATA_SELECT:
675                 // HasSelectionData includes column content and validity,
676                 // page fields have to be checked separately.
677                 if ( !pDoc->HasSelectionData( nPosX, nPosY, nTab ) &&
678                      !pTabViewShell->HasPageFieldDataAtCursor() )
679                     rSet.DisableItem( nWhich );
680                 break;
681 
682             case SID_STATUS_SUM:
683                 {
684                     String aFuncStr;
685                     if ( pTabViewShell->GetFunction( aFuncStr ) )
686                         rSet.Put( SfxStringItem( nWhich, aFuncStr ) );
687                 }
688                 break;
689 
690             case FID_MERGE_ON:
691                 if ( pDoc->GetChangeTrack() || !pTabViewShell->TestMergeCells() )
692                     rSet.DisableItem( nWhich );
693                 break;
694 
695             case FID_MERGE_OFF:
696                 if ( pDoc->GetChangeTrack() || !pTabViewShell->TestRemoveMerge() )
697                     rSet.DisableItem( nWhich );
698                 break;
699 
700             case FID_MERGE_TOGGLE:
701                 if ( pDoc->GetChangeTrack() )
702                     rSet.DisableItem( nWhich );
703                 else
704                 {
705                     bool bCanMerge = pTabViewShell->TestMergeCells();
706                     bool bCanSplit = pTabViewShell->TestRemoveMerge();
707                     if( !bCanMerge && !bCanSplit )
708                         rSet.DisableItem( nWhich );
709                     else
710                         rSet.Put( SfxBoolItem( nWhich, bCanSplit ) );
711                 }
712                 break;
713 
714             case FID_INS_ROWBRK:
715                 if ( nPosY==0 || (pDoc->HasRowBreak(nPosY, nTab) & BREAK_MANUAL) )
716                     rSet.DisableItem( nWhich );
717                 break;
718 
719             case FID_INS_COLBRK:
720                 if ( nPosX==0 || (pDoc->HasColBreak(nPosX, nTab) & BREAK_MANUAL) )
721                     rSet.DisableItem( nWhich );
722                 break;
723 
724             case FID_DEL_ROWBRK:
725                 if ( nPosY==0 || (pDoc->HasRowBreak(nPosY, nTab) & BREAK_MANUAL) == 0 )
726                     rSet.DisableItem( nWhich );
727                 break;
728 
729             case FID_DEL_COLBRK:
730                 if ( nPosX==0 || (pDoc->HasColBreak(nPosX, nTab) & BREAK_MANUAL) == 0 )
731                     rSet.DisableItem( nWhich );
732                 break;
733 
734             case FID_FILL_TAB:
735                 if ( nTabSelCount < 2 )
736                     rSet.DisableItem( nWhich );
737                 break;
738 
739             case SID_SELECT_SCENARIO:
740                 {
741                     // ScDocument* pDoc = GetViewData()->GetDocument();
742                     // SCTAB       nTab = GetViewData()->GetTabNo();
743                     List        aList;
744 
745                     Color   aDummyCol;
746 
747                     if ( !pDoc->IsScenario(nTab) )
748                     {
749                         String aStr;
750                         sal_uInt16 nFlags;
751                         SCTAB nScTab = nTab + 1;
752                         String aProtect;
753                         bool bSheetProtected = pDoc->IsTabProtected(nTab);
754 
755                         while ( pDoc->IsScenario(nScTab) )
756                         {
757                             pDoc->GetName( nScTab, aStr );
758                             aList.Insert( new String( aStr ), LIST_APPEND );
759                             pDoc->GetScenarioData( nScTab, aStr, aDummyCol, nFlags );
760                             aList.Insert( new String( aStr ), LIST_APPEND );
761                             // Protection is sal_True if both Sheet and Scenario are protected
762                             aProtect = (bSheetProtected && (nFlags & SC_SCENARIO_PROTECT)) ? '1' : '0';
763                             aList.Insert( new String( aProtect), LIST_APPEND );
764                             ++nScTab;
765                         }
766                     }
767                     else
768                     {
769                         String  aComment;
770                         sal_uInt16  nDummyFlags;
771                         pDoc->GetScenarioData( nTab, aComment, aDummyCol, nDummyFlags );
772                         DBG_ASSERT( aList.Count() == 0, "List not empty!" );
773                         aList.Insert( new String( aComment ) );
774                     }
775 
776                     rSet.Put( SfxStringListItem( nWhich, &aList ) );
777 
778                     sal_uLong nCount = aList.Count();
779                     for ( sal_uLong i=0; i<nCount; i++ )
780                         delete (String*) aList.GetObject(i);
781                 }
782                 break;
783 
784             case FID_ROW_HIDE:
785             case FID_ROW_SHOW:
786             case FID_COL_HIDE:
787             case FID_COL_SHOW:
788             case FID_COL_OPT_WIDTH:
789             case FID_ROW_OPT_HEIGHT:
790             case FID_DELETE_CELL:
791                 if ( pDoc->IsTabProtected(nTab) || pDocSh->IsReadOnly())
792                     rSet.DisableItem( nWhich );
793                 break;
794 
795 /*  Zellschutz bei selektierten Zellen wird bei anderen Funktionen auch nicht abgefragt...
796             case SID_DELETE:
797                 {
798                     if ( pDoc->IsTabProtected(nTab) )
799                     {
800                         const SfxItemSet&       rAttrSet  = GetSelectionPattern()->GetItemSet();
801                         const ScProtectionAttr& rProtAttr = (const ScProtectionAttr&)rAttrSet.Get( ATTR_PROTECTION, sal_True );
802                         if ( rProtAttr.GetProtection() )
803                             rSet.DisableItem( nWhich );
804                     }
805                 }
806                 break;
807 */
808             case SID_OUTLINE_MAKE:
809                 {
810                     if ( GetViewData()->GetDocument()->GetDPAtCursor( GetViewData()->GetCurX(),
811                                             GetViewData()->GetCurY(), GetViewData()->GetTabNo() ) )
812                     {
813                         //! test for data pilot operation
814                     }
815                     else if (pDoc->GetChangeTrack()!=NULL || GetViewData()->IsMultiMarked())
816                     {
817                         rSet.DisableItem( nWhich );
818                     }
819                 }
820                 break;
821             case SID_OUTLINE_SHOW:
822                 if ( GetViewData()->GetDocument()->GetDPAtCursor( GetViewData()->GetCurX(),
823                                         GetViewData()->GetCurY(), GetViewData()->GetTabNo() ) )
824                 {
825                     //! test for data pilot operation
826                 }
827                 else if (!pTabViewShell->OutlinePossible(sal_False))
828                     rSet.DisableItem( nWhich );
829                 break;
830 
831             case SID_OUTLINE_HIDE:
832                 if ( GetViewData()->GetDocument()->GetDPAtCursor( GetViewData()->GetCurX(),
833                                         GetViewData()->GetCurY(), GetViewData()->GetTabNo() ) )
834                 {
835                     //! test for data pilot operation
836                 }
837                 else if (!pTabViewShell->OutlinePossible(sal_True))
838                     rSet.DisableItem( nWhich );
839                 break;
840 
841             case SID_OUTLINE_REMOVE:
842                 {
843                     if ( GetViewData()->GetDocument()->GetDPAtCursor( GetViewData()->GetCurX(),
844                                             GetViewData()->GetCurY(), GetViewData()->GetTabNo() ) )
845                     {
846                         //! test for data pilot operation
847                     }
848                     else
849                     {
850                         sal_Bool bCol, bRow;
851                         pTabViewShell->TestRemoveOutline( bCol, bRow );
852                         if ( !bCol && !bRow )
853                             rSet.DisableItem( nWhich );
854                     }
855                 }
856                 break;
857 
858             case FID_COL_WIDTH:
859                 {
860                     //GetViewData()->GetCurX();
861                     SfxUInt16Item aWidthItem( FID_COL_WIDTH, pDoc->GetColWidth( nPosX , nTab) );
862                     rSet.Put( aWidthItem );
863                     if ( pDocSh->IsReadOnly())
864                         rSet.DisableItem( nWhich );
865 
866                     //XXX Disablen wenn nicht eindeutig
867                 }
868                 break;
869 
870             case FID_ROW_HEIGHT:
871                 {
872                     //GetViewData()->GetCurY();
873                     SfxUInt16Item aHeightItem( FID_ROW_HEIGHT, pDoc->GetRowHeight( nPosY , nTab) );
874                     rSet.Put( aHeightItem );
875                     //XXX Disablen wenn nicht eindeutig
876                     if ( pDocSh->IsReadOnly())
877                         rSet.DisableItem( nWhich );
878                 }
879                 break;
880 
881             case SID_DETECTIVE_FILLMODE:
882                 rSet.Put(SfxBoolItem( nWhich, pTabViewShell->IsAuditShell() ));
883                 break;
884 
885             case FID_INPUTLINE_STATUS:
886                 DBG_ERROR( "Old update method. Use ScTabViewShell::UpdateInputHandler()." );
887                 break;
888 
889             case SID_SCENARIOS:                                     // Szenarios:
890                 if (!(rMark.IsMarked() || rMark.IsMultiMarked()))   // nur, wenn etwas selektiert
891                     rSet.DisableItem( nWhich );
892                 break;
893 
894             case FID_NOTE_VISIBLE:
895                 {
896                     const ScPostIt* pNote = pDoc->GetNote( ScAddress( nPosX, nPosY, nTab ) );
897                     if ( pNote && pDoc->IsBlockEditable( nTab, nPosX,nPosY, nPosX,nPosY ) )
898                         rSet.Put( SfxBoolItem( nWhich, pNote->IsCaptionShown() ) );
899                     else
900                         rSet.DisableItem( nWhich );
901                 }
902                 break;
903 
904             case SID_DELETE_NOTE:
905                 {
906                     sal_Bool bEnable = sal_False;
907                     if ( rMark.IsMarked() || rMark.IsMultiMarked() )
908                     {
909                         if ( pDoc->IsSelectionEditable( rMark ) )
910                         {
911                             // look for at least one note in selection
912                             ScRangeList aRanges;
913                             rMark.FillRangeListWithMarks( &aRanges, sal_False );
914                             sal_uLong nCount = aRanges.Count();
915                             for (sal_uLong nPos=0; nPos<nCount && !bEnable; nPos++)
916                             {
917                                 ScCellIterator aCellIter( pDoc, *aRanges.GetObject(nPos) );
918                                 for( ScBaseCell* pCell = aCellIter.GetFirst(); pCell && !bEnable; pCell = aCellIter.GetNext() )
919                                     if ( pCell->HasNote() )
920                                         bEnable = sal_True;             // note found
921                             }
922                         }
923                     }
924                     else
925                     {
926                         bEnable = pDoc->IsBlockEditable( nTab, nPosX,nPosY, nPosX,nPosY ) &&
927                                   pDoc->GetNote( ScAddress( nPosX, nPosY, nTab ) );
928                     }
929                     if ( !bEnable )
930                         rSet.DisableItem( nWhich );
931                 }
932                 break;
933 
934             case SID_OPENDLG_CONSOLIDATE:
935             case SCITEM_CONSOLIDATEDATA:
936                 {
937                     if(pDoc->GetChangeTrack()!=NULL)
938                                 rSet.DisableItem( nWhich);
939                 }
940                 break;
941 
942             case SID_CHINESE_CONVERSION:
943             case SID_HANGUL_HANJA_CONVERSION:
944                 ScViewUtil::HideDisabledSlot( rSet, pData->GetBindings(), nWhich );
945             break;
946 
947             case FID_USE_NAME:
948                 {
949                     if ( pDocSh && pDocSh->IsDocShared() )
950                         rSet.DisableItem( nWhich );
951                     else
952                     {
953                         ScRange aRange;
954                         if ( pData->GetSimpleArea( aRange ) != SC_MARK_SIMPLE )
955                             rSet.DisableItem( nWhich );
956                     }
957                 }
958                 break;
959 
960             case FID_DEFINE_NAME:
961             case FID_INSERT_NAME:
962             case SID_DEFINE_COLROWNAMERANGES:
963                 {
964                     if ( pDocSh && pDocSh->IsDocShared() )
965                     {
966                         rSet.DisableItem( nWhich );
967                     }
968                 }
969                 break;
970 
971             case SID_SPELL_DIALOG:
972                 {
973                     if ( pDoc && pData && pDoc->IsTabProtected( pData->GetTabNo() ) )
974                     {
975                         bool bVisible = false;
976                         SfxViewFrame* pViewFrame = ( pTabViewShell ? pTabViewShell->GetViewFrame() : NULL );
977                         if ( pViewFrame && pViewFrame->HasChildWindow( nWhich ) )
978                         {
979                             SfxChildWindow* pChild = pViewFrame->GetChildWindow( nWhich );
980                             Window* pWin = ( pChild ? pChild->GetWindow() : NULL );
981                             if ( pWin && pWin->IsVisible() )
982                             {
983                                 bVisible = true;
984                             }
985                         }
986                         if ( !bVisible )
987                         {
988                             rSet.DisableItem( nWhich );
989                         }
990                     }
991                 }
992                 break;
993 
994         } // switch ( nWitch )
995         nWhich = aIter.NextWhich();
996     } // while ( nWitch )
997 }
998 
999 //------------------------------------------------------------------
1000 
1001 
1002 
1003