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