xref: /AOO41X/main/sc/source/ui/view/cellsh.cxx (revision a206ee714f966ac34d586aa0448e90cdf7eed74e)
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 
SFX_IMPL_INTERFACE(ScCellShell,ScFormatShell,ScResId (SCSTR_CELLSHELL))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 
ScCellShell(ScViewData * pData)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 
~ScCellShell()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 
GetBlockState(SfxItemSet & rSet)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 
GetCellState(SfxItemSet & rSet)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 
lcl_TestFormat(SvxClipboardFmtItem & rFormats,const TransferableDataHelper & rDataHelper,SotFormatStringId nFormatId)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 
GetPossibleClipboardFormats(SvxClipboardFmtItem & rFormats)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_FORMATSTR_ID_PNG );
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 
lcl_IsCellPastePossible(const TransferableDataHelper & rData)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_FORMATSTR_ID_PNG ) ||
410              rData.HasFormat( SOT_FORMAT_BITMAP ) ||
411              rData.HasFormat( SOT_FORMAT_GDIMETAFILE ) ||
412              rData.HasFormat( SOT_FORMATSTR_ID_SVXB ) ||
413              rData.HasFormat( FORMAT_PRIVATE ) ||
414              rData.HasFormat( SOT_FORMAT_RTF ) ||
415              rData.HasFormat( SOT_FORMATSTR_ID_EMBED_SOURCE ) ||
416              rData.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE ) ||
417              rData.HasFormat( SOT_FORMATSTR_ID_EMBED_SOURCE_OLE ) ||
418              rData.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE_OLE ) ||
419              rData.HasFormat( SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE ) ||
420              rData.HasFormat( SOT_FORMAT_STRING ) ||
421              rData.HasFormat( SOT_FORMATSTR_ID_SYLK ) ||
422              rData.HasFormat( SOT_FORMATSTR_ID_LINK ) ||
423              rData.HasFormat( SOT_FORMATSTR_ID_HTML ) ||
424              rData.HasFormat( SOT_FORMATSTR_ID_HTML_SIMPLE ) ||
425              rData.HasFormat( SOT_FORMATSTR_ID_DIF ) )
426         {
427             bPossible = sal_True;
428         }
429     }
430     return bPossible;
431 }
432 
IMPL_LINK(ScCellShell,ClipboardChanged,TransferableDataHelper *,pDataHelper)433 IMPL_LINK( ScCellShell, ClipboardChanged, TransferableDataHelper*, pDataHelper )
434 {
435     if ( pDataHelper )
436     {
437         bPastePossible = lcl_IsCellPastePossible( *pDataHelper );
438 
439         SfxBindings& rBindings = GetViewData()->GetBindings();
440         rBindings.Invalidate( SID_PASTE );
441         rBindings.Invalidate( SID_PASTE_SPECIAL );
442         rBindings.Invalidate( SID_CLIPBOARD_FORMAT_ITEMS );
443     }
444     return 0;
445 }
446 
447 
GetClipState(SfxItemSet & rSet)448 void __EXPORT ScCellShell::GetClipState( SfxItemSet& rSet )
449 {
450 // SID_PASTE
451 // SID_PASTE_SPECIAL
452 // SID_CLIPBOARD_FORMAT_ITEMS
453 
454     if ( !pImpl->m_pClipEvtLstnr )
455     {
456         // create listener
457         pImpl->m_pClipEvtLstnr = new TransferableClipboardListener( LINK( this, ScCellShell, ClipboardChanged ) );
458         pImpl->m_pClipEvtLstnr->acquire();
459         Window* pWin = GetViewData()->GetActiveWin();
460         pImpl->m_pClipEvtLstnr->AddRemoveListener( pWin, sal_True );
461 
462         // get initial state
463         TransferableDataHelper aDataHelper( TransferableDataHelper::CreateFromSystemClipboard( pWin ) );
464         bPastePossible = lcl_IsCellPastePossible( aDataHelper );
465     }
466 
467     sal_Bool bDisable = !bPastePossible;
468 
469     //  Zellschutz / Multiselektion
470 
471     if (!bDisable)
472     {
473         SCCOL nCol = GetViewData()->GetCurX();
474         SCROW nRow = GetViewData()->GetCurY();
475         SCTAB nTab = GetViewData()->GetTabNo();
476         ScDocument* pDoc = GetViewData()->GetDocShell()->GetDocument();
477         if (!pDoc->IsBlockEditable( nTab, nCol,nRow, nCol,nRow ))
478             bDisable = sal_True;
479         ScRange aDummy;
480         ScMarkType eMarkType = GetViewData()->GetSimpleArea( aDummy);
481         if (eMarkType != SC_MARK_SIMPLE && eMarkType != SC_MARK_SIMPLE_FILTERED)
482             bDisable = sal_True;
483     }
484 
485     if (bDisable)
486     {
487         rSet.DisableItem( SID_PASTE );
488         rSet.DisableItem( SID_PASTE_SPECIAL );
489         rSet.DisableItem( SID_CLIPBOARD_FORMAT_ITEMS );
490     }
491     else if ( rSet.GetItemState( SID_CLIPBOARD_FORMAT_ITEMS ) != SFX_ITEM_UNKNOWN )
492     {
493         SvxClipboardFmtItem aFormats( SID_CLIPBOARD_FORMAT_ITEMS );
494         GetPossibleClipboardFormats( aFormats );
495         rSet.Put( aFormats );
496     }
497 }
498 
499 //  only SID_HYPERLINK_GETLINK:
500 
GetHLinkState(SfxItemSet & rSet)501 void ScCellShell::GetHLinkState( SfxItemSet& rSet )
502 {
503     //  always return an item (or inserting will be disabled)
504     //  if the cell at the cursor contains only a link, return that link
505 
506     SvxHyperlinkItem aHLinkItem;
507     if ( !GetViewData()->GetView()->HasBookmarkAtCursor( &aHLinkItem ) )
508     {
509         //! put selected text into item?
510     }
511 
512     rSet.Put(aHLinkItem);
513 }
514 
GetState(SfxItemSet & rSet)515 void ScCellShell::GetState(SfxItemSet &rSet)
516 {
517     // removed: SID_BORDER_OBJECT (old Basic)
518 
519     ScTabViewShell* pTabViewShell   = GetViewData()->GetViewShell();
520 //     sal_Bool bOle = pTabViewShell->GetViewFrame()->GetFrame().IsInPlace();
521 //  sal_Bool bTabProt = GetViewData()->GetDocument()->IsTabProtected(GetViewData()->GetTabNo());
522     ScDocShell* pDocSh = GetViewData()->GetDocShell();
523     ScViewData* pData       = GetViewData();
524     ScDocument* pDoc        = pData->GetDocument();
525     ScMarkData& rMark       = pData->GetMarkData();
526     SCCOL       nPosX       = pData->GetCurX();
527     SCROW       nPosY       = pData->GetCurY();
528     SCTAB       nTab        = pData->GetTabNo();
529 
530     SCTAB nTabCount = pDoc->GetTableCount();
531     SCTAB nTabSelCount = rMark.GetSelectCount();
532 
533 
534 
535     SfxWhichIter aIter(rSet);
536     sal_uInt16 nWhich = aIter.FirstWhich();
537     while ( nWhich )
538     {
539         switch ( nWhich )
540         {
541             case SID_DETECTIVE_REFRESH:
542                 if (!pDoc->HasDetectiveOperations())
543                     rSet.DisableItem( nWhich );
544                 break;
545 
546             case SID_RANGE_ADDRESS:
547                 {
548                     ScRange aRange;
549                     if ( pData->GetSimpleArea( aRange ) == SC_MARK_SIMPLE )
550                     {
551                         String aStr;
552                         sal_uInt16 nFlags = SCA_VALID | SCA_TAB_3D;
553                         aRange.Format(aStr,nFlags,pDoc);
554                         rSet.Put( SfxStringItem( nWhich, aStr ) );
555                     }
556                 }
557                 break;
558 
559             case SID_RANGE_NOTETEXT:
560                 {
561                     //  #43343# always take cursor position, do not use top-left cell of selection
562                     ScAddress aPos( nPosX, nPosY, nTab );
563                     String aNoteText;
564                     if ( const ScPostIt* pNote = pDoc->GetNote( aPos ) )
565                         aNoteText = pNote->GetText();
566                     rSet.Put( SfxStringItem( nWhich, aNoteText ) );
567                 }
568                 break;
569 
570             case SID_RANGE_ROW:
571                 rSet.Put( SfxInt32Item( nWhich, nPosY+1 ) );
572                 break;
573 
574             case SID_RANGE_COL:
575                 rSet.Put( SfxInt16Item( nWhich, nPosX+1 ) );
576                 break;
577 
578             case SID_RANGE_TABLE:
579                 rSet.Put( SfxInt16Item( nWhich, nTab+1 ) );
580                 break;
581 
582             case SID_RANGE_VALUE:
583                 {
584                     double nValue;
585                     pDoc->GetValue( nPosX, nPosY, nTab, nValue );
586                     rSet.Put( ScDoubleItem( nWhich, nValue ) );
587                 }
588                 break;
589 
590             case SID_RANGE_FORMULA:
591                 {
592                     String aString;
593                     pDoc->GetFormula( nPosX, nPosY, nTab, aString );
594                     if( aString.Len() == 0 )
595                     {
596                         pDoc->GetInputString( nPosX, nPosY, nTab, aString );
597                     }
598                     rSet.Put( SfxStringItem( nWhich, aString ) );
599                 }
600                 break;
601 
602             case SID_RANGE_TEXTVALUE:
603                 {
604                     String aString;
605                     pDoc->GetString( nPosX, nPosY, nTab, aString );
606                     rSet.Put( SfxStringItem( nWhich, aString ) );
607                 }
608                 break;
609 
610             case SID_STATUS_SELMODE:
611                 {
612                     /* 0: STD   Click hebt Sel auf
613                      * 1: ER    Click erweitert Selektion
614                      * 2: ERG   Click definiert weitere Selektion
615                      */
616                     sal_uInt16 nMode = pTabViewShell->GetLockedModifiers();
617 
618                     switch ( nMode )
619                     {
620                         case KEY_SHIFT: nMode = 1;  break;
621                         case KEY_MOD1:  nMode = 2;  break; // Control-Taste
622                         case 0:
623                         default:
624                             nMode = 0;
625                     }
626 
627                     rSet.Put( SfxUInt16Item( nWhich, nMode ) );
628                 }
629                 break;
630 
631             case SID_STATUS_DOCPOS:
632                 {
633                     String  aStr( ScGlobal::GetRscString( STR_TABLE ) );
634 
635                     aStr += ' ';
636                     aStr += String::CreateFromInt32( nTab + 1 );
637                     aStr.AppendAscii(RTL_CONSTASCII_STRINGPARAM( " / " ));
638                     aStr += String::CreateFromInt32( nTabCount );
639                     rSet.Put( SfxStringItem( nWhich, aStr ) );
640                 }
641                 break;
642 
643             //  Summe etc. mit Datum/Zeit/Fehler/Pos&Groesse zusammengefasst
644 
645             // #i34458# The SfxStringItem belongs only into SID_TABLE_CELL. It no longer has to be
646             // duplicated in SID_ATTR_POSITION or SID_ATTR_SIZE for SvxPosSizeStatusBarControl.
647             case SID_TABLE_CELL:
648                 {
649                     //  Testen, ob Fehler unter Cursor
650                     //  (nicht pDoc->GetErrCode, um keine zirkulaeren Referenzen auszuloesen)
651 
652                     // In interpreter may happen via rescheduled Basic
653                     if ( pDoc->IsInInterpreter() )
654                         rSet.Put( SfxStringItem( nWhich,
655                             String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("...")) ) );
656                     else
657                     {
658                         sal_uInt16 nErrCode = 0;
659                         ScBaseCell* pCell;
660                         pDoc->GetCell( nPosX, nPosY, nTab, pCell );
661                         if ( pCell && pCell->GetCellType() == CELLTYPE_FORMULA )
662                         {
663                             ScFormulaCell* pFCell = (ScFormulaCell*) pCell;
664                             if (!pFCell->IsRunning())
665                                 nErrCode = pFCell->GetErrCode();
666                         }
667 
668                         String aFuncStr;
669                         if ( pTabViewShell->GetFunction( aFuncStr, nErrCode ) )
670                             rSet.Put( SfxStringItem( nWhich, aFuncStr ) );
671                     }
672                 }
673                 break;
674 
675             case SID_DATA_SELECT:
676                 // HasSelectionData includes column content and validity,
677                 // page fields have to be checked separately.
678                 if ( !pDoc->HasSelectionData( nPosX, nPosY, nTab ) &&
679                      !pTabViewShell->HasPageFieldDataAtCursor() )
680                     rSet.DisableItem( nWhich );
681                 break;
682 
683             case SID_STATUS_SUM:
684                 {
685                     String aFuncStr;
686                     if ( pTabViewShell->GetFunction( aFuncStr ) )
687                         rSet.Put( SfxStringItem( nWhich, aFuncStr ) );
688                 }
689                 break;
690 
691             case FID_MERGE_ON:
692                 if ( pDoc->GetChangeTrack() || !pTabViewShell->TestMergeCells() )
693                     rSet.DisableItem( nWhich );
694                 break;
695 
696             case FID_MERGE_OFF:
697                 if ( pDoc->GetChangeTrack() || !pTabViewShell->TestRemoveMerge() )
698                     rSet.DisableItem( nWhich );
699                 break;
700 
701             case FID_MERGE_TOGGLE:
702                 if ( pDoc->GetChangeTrack() )
703                     rSet.DisableItem( nWhich );
704                 else
705                 {
706                     bool bCanMerge = pTabViewShell->TestMergeCells();
707                     bool bCanSplit = pTabViewShell->TestRemoveMerge();
708                     if( !bCanMerge && !bCanSplit )
709                         rSet.DisableItem( nWhich );
710                     else
711                         rSet.Put( SfxBoolItem( nWhich, bCanSplit ) );
712                 }
713                 break;
714 
715             case FID_INS_ROWBRK:
716                 if ( nPosY==0 || (pDoc->HasRowBreak(nPosY, nTab) & BREAK_MANUAL) )
717                     rSet.DisableItem( nWhich );
718                 break;
719 
720             case FID_INS_COLBRK:
721                 if ( nPosX==0 || (pDoc->HasColBreak(nPosX, nTab) & BREAK_MANUAL) )
722                     rSet.DisableItem( nWhich );
723                 break;
724 
725             case FID_DEL_ROWBRK:
726                 if ( nPosY==0 || (pDoc->HasRowBreak(nPosY, nTab) & BREAK_MANUAL) == 0 )
727                     rSet.DisableItem( nWhich );
728                 break;
729 
730             case FID_DEL_COLBRK:
731                 if ( nPosX==0 || (pDoc->HasColBreak(nPosX, nTab) & BREAK_MANUAL) == 0 )
732                     rSet.DisableItem( nWhich );
733                 break;
734 
735             case FID_FILL_TAB:
736                 if ( nTabSelCount < 2 )
737                     rSet.DisableItem( nWhich );
738                 break;
739 
740             case SID_SELECT_SCENARIO:
741                 {
742                     // ScDocument* pDoc = GetViewData()->GetDocument();
743                     // SCTAB       nTab = GetViewData()->GetTabNo();
744                     List        aList;
745 
746                     Color   aDummyCol;
747 
748                     if ( !pDoc->IsScenario(nTab) )
749                     {
750                         String aStr;
751                         sal_uInt16 nFlags;
752                         SCTAB nScTab = nTab + 1;
753                         String aProtect;
754                         bool bSheetProtected = pDoc->IsTabProtected(nTab);
755 
756                         while ( pDoc->IsScenario(nScTab) )
757                         {
758                             pDoc->GetName( nScTab, aStr );
759                             aList.Insert( new String( aStr ), LIST_APPEND );
760                             pDoc->GetScenarioData( nScTab, aStr, aDummyCol, nFlags );
761                             aList.Insert( new String( aStr ), LIST_APPEND );
762                             // Protection is sal_True if both Sheet and Scenario are protected
763                             aProtect = (bSheetProtected && (nFlags & SC_SCENARIO_PROTECT)) ? '1' : '0';
764                             aList.Insert( new String( aProtect), LIST_APPEND );
765                             ++nScTab;
766                         }
767                     }
768                     else
769                     {
770                         String  aComment;
771                         sal_uInt16  nDummyFlags;
772                         pDoc->GetScenarioData( nTab, aComment, aDummyCol, nDummyFlags );
773                         DBG_ASSERT( aList.Count() == 0, "List not empty!" );
774                         aList.Insert( new String( aComment ) );
775                     }
776 
777                     rSet.Put( SfxStringListItem( nWhich, &aList ) );
778 
779                     sal_uLong nCount = aList.Count();
780                     for ( sal_uLong i=0; i<nCount; i++ )
781                         delete (String*) aList.GetObject(i);
782                 }
783                 break;
784 
785             case FID_ROW_HIDE:
786             case FID_ROW_SHOW:
787             case FID_COL_HIDE:
788             case FID_COL_SHOW:
789             case FID_COL_OPT_WIDTH:
790             case FID_ROW_OPT_HEIGHT:
791             case FID_DELETE_CELL:
792                 if ( pDoc->IsTabProtected(nTab) || pDocSh->IsReadOnly())
793                     rSet.DisableItem( nWhich );
794                 break;
795 
796 /*  Zellschutz bei selektierten Zellen wird bei anderen Funktionen auch nicht abgefragt...
797             case SID_DELETE:
798                 {
799                     if ( pDoc->IsTabProtected(nTab) )
800                     {
801                         const SfxItemSet&       rAttrSet  = GetSelectionPattern()->GetItemSet();
802                         const ScProtectionAttr& rProtAttr = (const ScProtectionAttr&)rAttrSet.Get( ATTR_PROTECTION, sal_True );
803                         if ( rProtAttr.GetProtection() )
804                             rSet.DisableItem( nWhich );
805                     }
806                 }
807                 break;
808 */
809             case SID_OUTLINE_MAKE:
810                 {
811                     if ( GetViewData()->GetDocument()->GetDPAtCursor( GetViewData()->GetCurX(),
812                                             GetViewData()->GetCurY(), GetViewData()->GetTabNo() ) )
813                     {
814                         //! test for data pilot operation
815                     }
816                     else if (pDoc->GetChangeTrack()!=NULL || GetViewData()->IsMultiMarked())
817                     {
818                         rSet.DisableItem( nWhich );
819                     }
820                 }
821                 break;
822             case SID_OUTLINE_SHOW:
823                 if ( GetViewData()->GetDocument()->GetDPAtCursor( GetViewData()->GetCurX(),
824                                         GetViewData()->GetCurY(), GetViewData()->GetTabNo() ) )
825                 {
826                     //! test for data pilot operation
827                 }
828                 else if (!pTabViewShell->OutlinePossible(sal_False))
829                     rSet.DisableItem( nWhich );
830                 break;
831 
832             case SID_OUTLINE_HIDE:
833                 if ( GetViewData()->GetDocument()->GetDPAtCursor( GetViewData()->GetCurX(),
834                                         GetViewData()->GetCurY(), GetViewData()->GetTabNo() ) )
835                 {
836                     //! test for data pilot operation
837                 }
838                 else if (!pTabViewShell->OutlinePossible(sal_True))
839                     rSet.DisableItem( nWhich );
840                 break;
841 
842             case SID_OUTLINE_REMOVE:
843                 {
844                     if ( GetViewData()->GetDocument()->GetDPAtCursor( GetViewData()->GetCurX(),
845                                             GetViewData()->GetCurY(), GetViewData()->GetTabNo() ) )
846                     {
847                         //! test for data pilot operation
848                     }
849                     else
850                     {
851                         sal_Bool bCol, bRow;
852                         pTabViewShell->TestRemoveOutline( bCol, bRow );
853                         if ( !bCol && !bRow )
854                             rSet.DisableItem( nWhich );
855                     }
856                 }
857                 break;
858 
859             case FID_COL_WIDTH:
860                 {
861                     //GetViewData()->GetCurX();
862                     SfxUInt16Item aWidthItem( FID_COL_WIDTH, pDoc->GetColWidth( nPosX , nTab) );
863                     rSet.Put( aWidthItem );
864                     if ( pDocSh->IsReadOnly())
865                         rSet.DisableItem( nWhich );
866 
867                     //XXX Disablen wenn nicht eindeutig
868                 }
869                 break;
870 
871             case FID_ROW_HEIGHT:
872                 {
873                     //GetViewData()->GetCurY();
874                     SfxUInt16Item aHeightItem( FID_ROW_HEIGHT, pDoc->GetRowHeight( nPosY , nTab) );
875                     rSet.Put( aHeightItem );
876                     //XXX Disablen wenn nicht eindeutig
877                     if ( pDocSh->IsReadOnly())
878                         rSet.DisableItem( nWhich );
879                 }
880                 break;
881 
882             case SID_DETECTIVE_FILLMODE:
883                 rSet.Put(SfxBoolItem( nWhich, pTabViewShell->IsAuditShell() ));
884                 break;
885 
886             case FID_INPUTLINE_STATUS:
887                 DBG_ERROR( "Old update method. Use ScTabViewShell::UpdateInputHandler()." );
888                 break;
889 
890             case SID_SCENARIOS:                                     // Szenarios:
891                 if (!(rMark.IsMarked() || rMark.IsMultiMarked()))   // nur, wenn etwas selektiert
892                     rSet.DisableItem( nWhich );
893                 break;
894 
895             case FID_NOTE_VISIBLE:
896                 {
897                     const ScPostIt* pNote = pDoc->GetNote( ScAddress( nPosX, nPosY, nTab ) );
898                     if ( pNote && pDoc->IsBlockEditable( nTab, nPosX,nPosY, nPosX,nPosY ) )
899                         rSet.Put( SfxBoolItem( nWhich, pNote->IsCaptionShown() ) );
900                     else
901                         rSet.DisableItem( nWhich );
902                 }
903                 break;
904 
905             case SID_DELETE_NOTE:
906                 {
907                     sal_Bool bEnable = sal_False;
908                     if ( rMark.IsMarked() || rMark.IsMultiMarked() )
909                     {
910                         if ( pDoc->IsSelectionEditable( rMark ) )
911                         {
912                             // look for at least one note in selection
913                             ScRangeList aRanges;
914                             rMark.FillRangeListWithMarks( &aRanges, sal_False );
915                             sal_uLong nCount = aRanges.Count();
916                             for (sal_uLong nPos=0; nPos<nCount && !bEnable; nPos++)
917                             {
918                                 ScCellIterator aCellIter( pDoc, *aRanges.GetObject(nPos) );
919                                 for( ScBaseCell* pCell = aCellIter.GetFirst(); pCell && !bEnable; pCell = aCellIter.GetNext() )
920                                     if ( pCell->HasNote() )
921                                         bEnable = sal_True;             // note found
922                             }
923                         }
924                     }
925                     else
926                     {
927                         bEnable = pDoc->IsBlockEditable( nTab, nPosX,nPosY, nPosX,nPosY ) &&
928                                   pDoc->GetNote( ScAddress( nPosX, nPosY, nTab ) );
929                     }
930                     if ( !bEnable )
931                         rSet.DisableItem( nWhich );
932                 }
933                 break;
934 
935             case SID_OPENDLG_CONSOLIDATE:
936             case SCITEM_CONSOLIDATEDATA:
937                 {
938                     if(pDoc->GetChangeTrack()!=NULL)
939                                 rSet.DisableItem( nWhich);
940                 }
941                 break;
942 
943             case SID_CHINESE_CONVERSION:
944             case SID_HANGUL_HANJA_CONVERSION:
945                 ScViewUtil::HideDisabledSlot( rSet, pData->GetBindings(), nWhich );
946             break;
947 
948             case FID_USE_NAME:
949                 {
950                     if ( pDocSh && pDocSh->IsDocShared() )
951                         rSet.DisableItem( nWhich );
952                     else
953                     {
954                         ScRange aRange;
955                         if ( pData->GetSimpleArea( aRange ) != SC_MARK_SIMPLE )
956                             rSet.DisableItem( nWhich );
957                     }
958                 }
959                 break;
960 
961             case FID_DEFINE_NAME:
962             case FID_INSERT_NAME:
963             case SID_DEFINE_COLROWNAMERANGES:
964                 {
965                     if ( pDocSh && pDocSh->IsDocShared() )
966                     {
967                         rSet.DisableItem( nWhich );
968                     }
969                 }
970                 break;
971 
972             case SID_SPELL_DIALOG:
973                 {
974                     if ( pDoc && pData && pDoc->IsTabProtected( pData->GetTabNo() ) )
975                     {
976                         bool bVisible = false;
977                         SfxViewFrame* pViewFrame = ( pTabViewShell ? pTabViewShell->GetViewFrame() : NULL );
978                         if ( pViewFrame && pViewFrame->HasChildWindow( nWhich ) )
979                         {
980                             SfxChildWindow* pChild = pViewFrame->GetChildWindow( nWhich );
981                             Window* pWin = ( pChild ? pChild->GetWindow() : NULL );
982                             if ( pWin && pWin->IsVisible() )
983                             {
984                                 bVisible = true;
985                             }
986                         }
987                         if ( !bVisible )
988                         {
989                             rSet.DisableItem( nWhich );
990                         }
991                     }
992                 }
993                 break;
994 
995         } // switch ( nWitch )
996         nWhich = aIter.NextWhich();
997     } // while ( nWitch )
998 }
999 
1000 //------------------------------------------------------------------
1001 
1002 
1003 
1004