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