xref: /trunk/main/sc/source/ui/view/cellsh.cxx (revision a206ee71)
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