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