Coverage Report

Created: 2026-02-14 09:37

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/sc/source/ui/view/cellsh.cxx
Line
Count
Source
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 <svtools/cliplistener.hxx>
26
#include <svtools/insdlg.hxx>
27
#include <sot/formats.hxx>
28
#include <svx/hlnkitem.hxx>
29
#include <sfx2/bindings.hxx>
30
#include <sfx2/childwin.hxx>
31
#include <sfx2/objface.hxx>
32
#include <sfx2/request.hxx>
33
#include <sfx2/viewfrm.hxx>
34
#include <vcl/EnumContext.hxx>
35
#include <vcl/svapp.hxx>
36
#include <vcl/weld/Dialog.hxx>
37
#include <svx/clipfmtitem.hxx>
38
#include <svx/statusitem.hxx>
39
40
#include <cellsh.hxx>
41
#include <sc.hrc>
42
#include <docsh.hxx>
43
#include <attrib.hxx>
44
#include <tabvwsh.hxx>
45
#include <formulacell.hxx>
46
#include <scmod.hxx>
47
#include <globstr.hrc>
48
#include <scresid.hxx>
49
#include <transobj.hxx>
50
#include <drwtrans.hxx>
51
#include <scabstdlg.hxx>
52
#include <postit.hxx>
53
#include <cliputil.hxx>
54
#include <clipparam.hxx>
55
#include <markdata.hxx>
56
#include <gridwin.hxx>
57
58
#define ShellClass_ScCellShell
59
#define ShellClass_CellMovement
60
#include <scslots.hxx>
61
62
63
SFX_IMPL_INTERFACE(ScCellShell, ScFormatShell)
64
65
void ScCellShell::InitInterface_Impl()
66
11
{
67
11
    GetStaticInterface()->RegisterObjectBar(SFX_OBJECTBAR_OBJECT,
68
11
                                            SfxVisibilityFlags::Standard | SfxVisibilityFlags::Server,
69
11
                                            ToolbarId::Objectbar_Format);
70
71
11
    GetStaticInterface()->RegisterPopupMenu(u"cell"_ustr);
72
11
}
73
74
ScCellShell::ScCellShell(ScViewData& rData, const VclPtr<vcl::Window>& frameWin) :
75
0
    ScFormatShell(rData),
76
0
    pImpl( new CellShell_Impl() ),
77
0
    bPastePossible(false),
78
0
    pFrameWin(frameWin)
79
0
{
80
0
    SetName(u"Cell"_ustr);
81
0
    SfxShell::SetContextName(vcl::EnumContext::GetContextName(vcl::EnumContext::Context::Cell));
82
0
}
83
84
ScCellShell::~ScCellShell()
85
0
{
86
0
    if ( pImpl->m_xClipEvtLstnr.is() )
87
0
    {
88
0
        pImpl->m_xClipEvtLstnr->RemoveListener( GetViewData().GetActiveWin() );
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_xClipEvtLstnr->ClearCallbackLink();
93
94
0
        pImpl->m_xClipEvtLstnr.clear();
95
0
    }
96
97
0
    pImpl->m_pLinkedDlg.disposeAndClear();
98
0
    delete pImpl->m_pRequest;
99
0
}
100
101
void ScCellShell::GetBlockState( SfxItemSet& rSet )
102
0
{
103
0
    ScTabViewShell* pTabViewShell   = GetViewData().GetViewShell();
104
0
    ScRange aMarkRange;
105
0
    ScMarkType eMarkType = GetViewData().GetSimpleArea( aMarkRange );
106
0
    bool bSimpleArea = (eMarkType == SC_MARK_SIMPLE);
107
0
    bool bOnlyNotBecauseOfMatrix;
108
0
    bool bEditable = pTabViewShell->SelectionEditable( &bOnlyNotBecauseOfMatrix );
109
0
    ScDocument& rDoc = GetViewData().GetDocument();
110
0
    ScDocShell* pDocShell = GetViewData().GetDocShell();
111
0
    ScMarkData& rMark = GetViewData().GetMarkData();
112
0
    SCCOL nCol1, nCol2;
113
0
    SCROW nRow1, nRow2;
114
0
    nCol1 = aMarkRange.aStart.Col();
115
0
    nRow1 = aMarkRange.aStart.Row();
116
0
    nCol2 = aMarkRange.aEnd.Col();
117
0
    nRow2 = aMarkRange.aEnd.Row();
118
0
    SCTAB nTab = GetViewData().CurrentTabForData();
119
120
0
    SfxWhichIter aIter(rSet);
121
0
    sal_uInt16 nWhich = aIter.FirstWhich();
122
0
    while ( nWhich )
123
0
    {
124
0
        bool bDisable = false;
125
0
        bool bNeedEdit = true;      // need selection be editable?
126
0
        switch ( nWhich )
127
0
        {
128
0
            case FID_FILL_TO_BOTTOM:    // fill to top / bottom
129
0
            {
130
0
                bDisable = !bSimpleArea || (nRow1 == 0 && nRow2 == 0);
131
0
                if (!bDisable && GetViewData().SelectionForbidsCellFill())
132
0
                    bDisable = true;
133
0
                if ( !bDisable && bEditable )
134
0
                {   // do not damage matrix
135
0
                    bDisable = rDoc.HasSelectedBlockMatrixFragment(
136
0
                        nCol1, nRow1, nCol2, nRow1, rMark );    // first row
137
0
                }
138
0
            }
139
0
            break;
140
0
            case FID_FILL_TO_TOP:
141
0
            {
142
0
                bDisable = (!bSimpleArea) || (nRow1 == rDoc.MaxRow() && nRow2 == rDoc.MaxRow());
143
0
                if (!bDisable && GetViewData().SelectionForbidsCellFill())
144
0
                    bDisable = true;
145
0
                if ( !bDisable && bEditable )
146
0
                {   // do not damage matrix
147
0
                    bDisable = rDoc.HasSelectedBlockMatrixFragment(
148
0
                        nCol1, nRow2, nCol2, nRow2, rMark );    // last row
149
0
                }
150
0
            }
151
0
            break;
152
0
            case FID_FILL_TO_RIGHT:     // fill to left / right
153
0
            {
154
0
                bDisable = !bSimpleArea || (nCol1 == 0 && nCol2 == 0);
155
0
                if (!bDisable && GetViewData().SelectionForbidsCellFill())
156
0
                    bDisable = true;
157
0
                if ( !bDisable && bEditable )
158
0
                {   // do not damage matrix
159
0
                    bDisable = rDoc.HasSelectedBlockMatrixFragment(
160
0
                            nCol1, nRow1, nCol1, nRow2, rMark );    // first column
161
0
                }
162
0
            }
163
0
            break;
164
0
            case FID_FILL_TO_LEFT:
165
0
            {
166
0
                bDisable = (!bSimpleArea) || (nCol1 == rDoc.MaxCol() && nCol2 == rDoc.MaxCol());
167
0
                if (!bDisable && GetViewData().SelectionForbidsCellFill())
168
0
                    bDisable = true;
169
0
                if ( !bDisable && bEditable )
170
0
                {   // do not damage matrix
171
0
                    bDisable = rDoc.HasSelectedBlockMatrixFragment(
172
0
                        nCol2, nRow1, nCol2, nRow2, rMark );    // last column
173
0
                }
174
0
            }
175
0
            break;
176
177
0
            case SID_RANDOM_NUMBER_GENERATOR_DIALOG:
178
0
                bDisable = !bSimpleArea || GetViewData().SelectionForbidsCellFill();
179
0
            break;
180
0
            case SID_SAMPLING_DIALOG:
181
0
            case SID_DESCRIPTIVE_STATISTICS_DIALOG:
182
0
            case SID_ANALYSIS_OF_VARIANCE_DIALOG:
183
0
            case SID_CORRELATION_DIALOG:
184
0
            case SID_COVARIANCE_DIALOG:
185
0
            case SID_INSERT_SPARKLINE:
186
0
            {
187
0
                bDisable = !bSimpleArea;
188
0
            }
189
0
            break;
190
0
            case SID_GROUP_SPARKLINES:
191
0
            case SID_UNGROUP_SPARKLINES:
192
0
            {
193
0
                bDisable = !bSimpleArea;
194
0
            }
195
0
            break;
196
197
0
            case SID_EDIT_SPARKLINE:
198
0
            {
199
0
                bDisable = !rDoc.HasSparkline(GetViewData().GetCurPos());
200
0
            }
201
0
            break;
202
203
0
            case SID_DELETE_SPARKLINE:
204
0
            case SID_EDIT_SPARKLINE_GROUP:
205
0
            case SID_DELETE_SPARKLINE_GROUP:
206
0
            {
207
0
                bDisable = !rDoc.HasOneSparklineGroup(ScRange(nCol1, nRow1, nTab, nCol2, nRow2, nTab));
208
0
            }
209
0
            break;
210
211
0
            case FID_FILL_SERIES:       // fill block
212
0
            case SID_OPENDLG_TABOP:     // multiple-cell operations, are at least 2 cells marked?
213
0
                if (rDoc.GetChangeTrack()!=nullptr &&nWhich ==SID_OPENDLG_TABOP)
214
0
                    bDisable = true;
215
0
                else
216
0
                    bDisable = (!bSimpleArea) || (nCol1 == nCol2 && nRow1 == nRow2);
217
218
0
                if (!bDisable && GetViewData().SelectionForbidsCellFill())
219
0
                    bDisable = true;
220
221
0
                if ( !bDisable && bEditable && nWhich == FID_FILL_SERIES )
222
0
                {   // do not damage matrix
223
0
                    bDisable = rDoc.HasSelectedBlockMatrixFragment(
224
0
                            nCol1, nRow1, nCol2, nRow1, rMark )     // first row
225
0
                        ||  rDoc.HasSelectedBlockMatrixFragment(
226
0
                            nCol1, nRow2, nCol2, nRow2, rMark )     // last row
227
0
                        ||  rDoc.HasSelectedBlockMatrixFragment(
228
0
                            nCol1, nRow1, nCol1, nRow2, rMark )     // first column
229
0
                        ||  rDoc.HasSelectedBlockMatrixFragment(
230
0
                            nCol2, nRow1, nCol2, nRow2, rMark );    // last column
231
0
                }
232
0
                break;
233
0
            case FID_FILL_SINGLE_EDIT:
234
0
                bDisable = false;
235
0
                break;
236
0
            case SID_CUT:               // cut
237
0
            case SID_COPYDELETE:
238
0
                bDisable = !bSimpleArea || GetObjectShell()->isContentExtractionLocked();
239
0
                break;
240
0
            case FID_INS_CELL:          // insert cells, just simple selection
241
0
                bDisable = (!bSimpleArea);
242
0
                break;
243
244
0
            case SID_PASTE:
245
0
            case SID_PASTE_SPECIAL:
246
0
            case SID_PASTE_UNFORMATTED:
247
0
            case SID_PASTE_ONLY_VALUE:
248
0
            case SID_PASTE_ONLY_TEXT:
249
0
            case SID_PASTE_ONLY_FORMULA:
250
0
            case SID_PASTE_TRANSPOSED:
251
0
            case SID_PASTE_AS_LINK:
252
0
            case SID_PASTE_TEXTIMPORT_DIALOG:
253
0
                bDisable = GetViewData().SelectionForbidsPaste();
254
0
                break;
255
256
0
            case FID_INS_ROW:
257
0
            case FID_INS_ROWS_BEFORE:           // insert rows
258
0
            case FID_INS_ROWS_AFTER:
259
0
            {
260
0
                sc::EditAction eAction = sc::EditAction::InsertRowsBefore;
261
0
                if (nWhich == FID_INS_ROWS_AFTER)
262
0
                    eAction = sc::EditAction::InsertRowsAfter;
263
264
0
                bDisable = (!bSimpleArea) || GetViewData().SimpleColMarked();
265
0
                if (!bEditable && nCol1 == 0 && nCol2 == rDoc.MaxCol())
266
0
                {
267
                    // See if row insertions are allowed.
268
0
                    bEditable = rDoc.IsEditActionAllowed(eAction, rMark, nCol1, nRow1, nCol2, nRow2);
269
0
                }
270
0
                break;
271
0
            }
272
0
            case FID_INS_CELLSDOWN:
273
0
                bDisable = (!bSimpleArea) || GetViewData().SimpleColMarked();
274
0
                break;
275
276
0
            case FID_INS_COLUMN:
277
0
            case FID_INS_COLUMNS_BEFORE:        // insert columns
278
0
            case FID_INS_COLUMNS_AFTER:
279
0
            {
280
0
                sc::EditAction eAction = sc::EditAction::InsertColumnsBefore;
281
0
                if (nWhich == FID_INS_COLUMNS_AFTER)
282
0
                    eAction = sc::EditAction::InsertColumnsAfter;
283
284
0
                bDisable = (!bSimpleArea && eMarkType != SC_MARK_SIMPLE_FILTERED)
285
0
                           || GetViewData().SimpleRowMarked();
286
0
                if (!bEditable && nRow1 == 0 && nRow2 == rDoc.MaxRow())
287
0
                {
288
                    // See if row insertions are allowed.
289
0
                    bEditable = rDoc.IsEditActionAllowed(eAction, rMark, nCol1, nRow1, nCol2, nRow2);
290
0
                }
291
0
                break;
292
0
            }
293
0
            case FID_INS_CELLSRIGHT:
294
0
                bDisable = (!bSimpleArea) || GetViewData().SimpleRowMarked();
295
0
                break;
296
297
0
            case SID_COPY:              // copy
298
0
            case SID_COPY_HYPERLINK_LOCATION:
299
                // not editable because of matrix only? Do not damage matrix
300
                //! is not called, when protected AND matrix, we will have
301
                //! to live with this... is caught in Copy-Routine, otherwise
302
                //! work is to be done once more
303
0
                if ( bEditable || !bOnlyNotBecauseOfMatrix )
304
0
                    bNeedEdit = false;          // allowed when protected/ReadOnly
305
0
                bDisable = GetObjectShell()->isContentExtractionLocked();
306
0
                break;
307
308
0
            case SID_AUTOFORMAT:        // Autoformat, at least 3x3 selected
309
0
                bDisable =    (!bSimpleArea)
310
0
                           || ((nCol2 - nCol1) < 2) || ((nRow2 - nRow1) < 2);
311
0
                break;
312
313
0
            case SID_CELL_FORMAT_RESET :
314
0
            case FID_CELL_FORMAT :
315
0
            case SID_ENABLE_HYPHENATION :
316
                // not editable because of matrix only? Attribute ok nonetheless
317
0
                if ( !bEditable && bOnlyNotBecauseOfMatrix )
318
0
                    bNeedEdit = false;
319
0
                break;
320
321
0
            case FID_CURRENTVALIDATION:
322
0
            case FID_VALIDATION:
323
0
                {
324
0
                    if ( pDocShell && pDocShell->IsDocShared() )
325
0
                    {
326
0
                        bDisable = true;
327
0
                    }
328
0
                }
329
0
                break;
330
0
            case SID_TRANSLITERATE_HALFWIDTH:
331
0
            case SID_TRANSLITERATE_FULLWIDTH:
332
0
            case SID_TRANSLITERATE_HIRAGANA:
333
0
            case SID_TRANSLITERATE_KATAKANA:
334
0
                ScViewUtil::HideDisabledSlot( rSet, GetViewData().GetBindings(), nWhich );
335
0
            break;
336
0
            case SID_CONVERT_FORMULA_TO_VALUE:
337
0
            {
338
                // Check and see if the marked range has at least one formula cell.
339
0
                bDisable = !rDoc.HasFormulaCell(aMarkRange);
340
0
            }
341
0
            break;
342
0
        }
343
0
        if (!bDisable && bNeedEdit && !bEditable)
344
0
            bDisable = true;
345
346
0
        if (bDisable)
347
0
            rSet.DisableItem(nWhich);
348
0
        else if (nWhich == SID_ENABLE_HYPHENATION)
349
0
        {
350
            // toggle slots need a bool item
351
0
            rSet.Put( SfxBoolItem( nWhich, false ) );
352
0
        }
353
0
        nWhich = aIter.NextWhich();
354
0
    }
355
0
}
356
357
// functions, disabled depending on cursor position
358
// Default:
359
//     SID_INSERT_POSTIT, SID_CHARMAP, SID_OPENDLG_FUNCTION
360
361
void ScCellShell::GetCellState( SfxItemSet& rSet )
362
0
{
363
0
    ScDocShell* pDocShell = GetViewData().GetDocShell();
364
0
    ScDocument& rDoc = GetViewData().GetDocShell()->GetDocument();
365
0
    ScAddress aCursor( GetViewData().GetCurX(), GetViewData().GetCurY(),
366
0
                        GetViewData().CurrentTabForData() );
367
0
    SfxWhichIter aIter(rSet);
368
0
    sal_uInt16 nWhich = aIter.FirstWhich();
369
0
    while ( nWhich )
370
0
    {
371
0
        bool bDisable = false;
372
0
        bool bNeedEdit = true;      // need cursor position be editable?
373
0
        switch ( nWhich )
374
0
        {
375
0
            case SID_THESAURUS:
376
0
                {
377
0
                    CellType eType = rDoc.GetCellType( aCursor );
378
0
                    bDisable = ( eType != CELLTYPE_STRING && eType != CELLTYPE_EDIT);
379
0
                    if (!bDisable)
380
0
                    {
381
                        //  test for available languages
382
0
                        LanguageType nLang = ScViewUtil::GetEffLanguage( rDoc, aCursor );
383
0
                        bDisable = !ScModule::HasThesaurusLanguage( nLang );
384
0
                    }
385
0
                }
386
0
                break;
387
0
            case SID_OPENDLG_FUNCTION:
388
0
                {
389
0
                    ScMarkData aMarkData = GetViewData().GetMarkData();
390
0
                    aMarkData.MarkToSimple();
391
0
                    const ScRange& aRange = aMarkData.GetMarkArea();
392
0
                    if(aMarkData.IsMarked())
393
0
                    {
394
0
                        if (!rDoc.IsBlockEditable( aCursor.Tab(), aRange.aStart.Col(),aRange.aStart.Row(),
395
0
                                            aRange.aEnd.Col(),aRange.aEnd.Row() ))
396
0
                        {
397
0
                            bDisable = true;
398
0
                        }
399
0
                        bNeedEdit=false;
400
0
                    }
401
402
0
                }
403
0
                break;
404
0
            case SID_INSERT_POSTIT:
405
0
                {
406
0
                    ScAddress aPos( GetViewData().GetCurX(), GetViewData().GetCurY(), GetViewData().CurrentTabForData() );
407
0
                    if( rDoc.GetNote(aPos) )
408
0
                    {
409
0
                        bDisable = true;
410
0
                    }
411
0
                    else
412
0
                    {
413
0
                        bDisable = false;
414
0
                        if ( pDocShell && pDocShell->IsDocShared() )
415
0
                        {
416
0
                            bDisable = true;
417
0
                        }
418
0
                    }
419
0
                }
420
0
                break;
421
0
            case SID_EDIT_POSTIT:
422
0
                {
423
0
                    ScAddress aPos( GetViewData().GetCurX(), GetViewData().GetCurY(), GetViewData().CurrentTabForData() );
424
0
                    bDisable = rDoc.GetNote(aPos) == nullptr;
425
0
                }
426
0
                break;
427
0
        }
428
0
        if (!bDisable && bNeedEdit)
429
0
            if (!rDoc.IsBlockEditable( aCursor.Tab(), aCursor.Col(),aCursor.Row(),
430
0
                                        aCursor.Col(),aCursor.Row() ))
431
0
                bDisable = true;
432
0
        if (bDisable)
433
0
            rSet.DisableItem(nWhich);
434
0
        nWhich = aIter.NextWhich();
435
0
    }
436
0
}
437
438
static bool lcl_TestFormat( SvxClipboardFormatItem& rFormats, const TransferableDataHelper& rDataHelper,
439
                        SotClipboardFormatId nFormatId )
440
0
{
441
0
    if ( rDataHelper.HasFormat( nFormatId ) )
442
0
    {
443
        //  translated format name strings are no longer inserted here,
444
        //  handled by "paste special" dialog / toolbox controller instead.
445
        //  Only the object type name has to be set here:
446
0
        OUString aStrVal;
447
0
        if ( nFormatId == SotClipboardFormatId::EMBED_SOURCE )
448
0
        {
449
0
            TransferableObjectDescriptor aDesc;
450
0
            if ( rDataHelper.GetTransferableObjectDescriptor(
451
0
                                        SotClipboardFormatId::OBJECTDESCRIPTOR, aDesc ) )
452
0
                aStrVal = aDesc.maTypeName;
453
0
        }
454
0
        else if ( nFormatId == SotClipboardFormatId::EMBED_SOURCE_OLE
455
0
          || nFormatId == SotClipboardFormatId::EMBEDDED_OBJ_OLE )
456
0
        {
457
0
            OUString aSource;
458
0
            SvPasteObjectHelper::GetEmbeddedName( rDataHelper, aStrVal, aSource, nFormatId );
459
0
        }
460
461
0
        if ( !aStrVal.isEmpty() )
462
0
            rFormats.AddClipbrdFormat( nFormatId, aStrVal );
463
0
        else
464
0
            rFormats.AddClipbrdFormat( nFormatId );
465
466
0
        return true;
467
0
    }
468
469
0
    return false;
470
0
}
471
472
void ScCellShell::GetPossibleClipboardFormats( SvxClipboardFormatItem& rFormats )
473
0
{
474
0
    vcl::Window* pWin = GetViewData().GetActiveWin();
475
0
    bool bDraw = ScDrawTransferObj::GetOwnClipboard(ScTabViewShell::GetClipData(pWin)) != nullptr;
476
477
0
    TransferableDataHelper aDataHelper( TransferableDataHelper::CreateFromSystemClipboard( pWin ) );
478
479
0
    lcl_TestFormat( rFormats, aDataHelper, SotClipboardFormatId::DRAWING );
480
0
    lcl_TestFormat( rFormats, aDataHelper, SotClipboardFormatId::SVXB );
481
0
    lcl_TestFormat( rFormats, aDataHelper, SotClipboardFormatId::GDIMETAFILE );
482
0
    lcl_TestFormat( rFormats, aDataHelper, SotClipboardFormatId::PNG );
483
0
    lcl_TestFormat( rFormats, aDataHelper, SotClipboardFormatId::BITMAP );
484
0
    lcl_TestFormat( rFormats, aDataHelper, SotClipboardFormatId::EMBED_SOURCE );
485
486
0
    if ( !bDraw )
487
0
    {
488
0
        lcl_TestFormat( rFormats, aDataHelper, SotClipboardFormatId::LINK );
489
0
        lcl_TestFormat( rFormats, aDataHelper, SotClipboardFormatId::STRING );
490
0
        lcl_TestFormat( rFormats, aDataHelper, SotClipboardFormatId::STRING_TSVC );
491
0
        lcl_TestFormat( rFormats, aDataHelper, SotClipboardFormatId::DIF );
492
0
        lcl_TestFormat( rFormats, aDataHelper, SotClipboardFormatId::RTF );
493
0
        lcl_TestFormat( rFormats, aDataHelper, SotClipboardFormatId::RICHTEXT );
494
0
        lcl_TestFormat( rFormats, aDataHelper, SotClipboardFormatId::HTML );
495
0
        lcl_TestFormat( rFormats, aDataHelper, SotClipboardFormatId::HTML_SIMPLE );
496
0
        lcl_TestFormat( rFormats, aDataHelper, SotClipboardFormatId::BIFF_12 );
497
0
        lcl_TestFormat( rFormats, aDataHelper, SotClipboardFormatId::BIFF_8 );
498
0
        lcl_TestFormat( rFormats, aDataHelper, SotClipboardFormatId::BIFF_5 );
499
0
    }
500
501
0
    if ( !lcl_TestFormat( rFormats, aDataHelper, SotClipboardFormatId::EMBED_SOURCE_OLE ) )
502
0
        lcl_TestFormat( rFormats, aDataHelper, SotClipboardFormatId::EMBEDDED_OBJ_OLE );
503
0
}
504
505
//  insert, insert contents
506
507
static bool lcl_IsCellPastePossible( const TransferableDataHelper& rData )
508
0
{
509
0
    bool bPossible = false;
510
0
    css::uno::Reference< css::datatransfer::XTransferable2 > xTransferable(rData.GetXTransferable(), css::uno::UNO_QUERY);
511
0
    if ( ScTransferObj::GetOwnClipboard(xTransferable) || ScDrawTransferObj::GetOwnClipboard(xTransferable) )
512
0
        bPossible = true;
513
0
    else
514
0
    {
515
0
        if ( rData.HasFormat( SotClipboardFormatId::PNG ) ||
516
0
             rData.HasFormat( SotClipboardFormatId::BITMAP ) ||
517
0
             rData.HasFormat( SotClipboardFormatId::GDIMETAFILE ) ||
518
0
             rData.HasFormat( SotClipboardFormatId::SVXB ) ||
519
0
             rData.HasFormat( SotClipboardFormatId::PRIVATE ) ||
520
0
             rData.HasFormat( SotClipboardFormatId::RTF ) ||
521
0
             rData.HasFormat( SotClipboardFormatId::RICHTEXT ) ||
522
0
             rData.HasFormat( SotClipboardFormatId::EMBED_SOURCE ) ||
523
0
             rData.HasFormat( SotClipboardFormatId::LINK_SOURCE ) ||
524
0
             rData.HasFormat( SotClipboardFormatId::EMBED_SOURCE_OLE ) ||
525
0
             rData.HasFormat( SotClipboardFormatId::LINK_SOURCE_OLE ) ||
526
0
             rData.HasFormat( SotClipboardFormatId::EMBEDDED_OBJ_OLE ) ||
527
0
             rData.HasFormat( SotClipboardFormatId::STRING ) ||
528
0
             rData.HasFormat( SotClipboardFormatId::STRING_TSVC ) ||
529
0
             rData.HasFormat( SotClipboardFormatId::SYLK ) ||
530
0
             rData.HasFormat( SotClipboardFormatId::LINK ) ||
531
0
             rData.HasFormat( SotClipboardFormatId::HTML ) ||
532
0
             rData.HasFormat( SotClipboardFormatId::HTML_SIMPLE ) ||
533
0
             rData.HasFormat( SotClipboardFormatId::DIF ) )
534
0
        {
535
0
            bPossible = true;
536
0
        }
537
0
    }
538
0
    return bPossible;
539
0
}
540
541
bool ScCellShell::HasClipboardFormat( SotClipboardFormatId nFormatId )
542
0
{
543
0
    vcl::Window* pWin = GetViewData().GetActiveWin();
544
0
    TransferableDataHelper aDataHelper( TransferableDataHelper::CreateFromSystemClipboard( pWin ));
545
0
    return aDataHelper.HasFormat( nFormatId );
546
0
}
547
548
IMPL_LINK( ScCellShell, ClipboardChanged, TransferableDataHelper*, pDataHelper, void )
549
0
{
550
0
    bPastePossible = lcl_IsCellPastePossible( *pDataHelper );
551
552
0
    SfxBindings& rBindings = GetViewData().GetBindings();
553
0
    rBindings.Invalidate( SID_PASTE );
554
0
    rBindings.Invalidate( SID_PASTE_SPECIAL );
555
0
    rBindings.Invalidate( SID_PASTE_UNFORMATTED );
556
0
    rBindings.Invalidate( SID_PASTE_ONLY_VALUE );
557
0
    rBindings.Invalidate( SID_PASTE_ONLY_TEXT );
558
0
    rBindings.Invalidate( SID_PASTE_ONLY_FORMULA );
559
0
    rBindings.Invalidate( SID_PASTE_TRANSPOSED );
560
0
    rBindings.Invalidate( SID_PASTE_AS_LINK );
561
0
    rBindings.Invalidate( SID_PASTE_TEXTIMPORT_DIALOG );
562
0
    rBindings.Invalidate( SID_CLIPBOARD_FORMAT_ITEMS );
563
0
}
564
565
namespace {
566
567
bool checkDestRanges(ScViewData& rViewData)
568
0
{
569
0
    ScRange aDummy;
570
0
    ScMarkType eMarkType = rViewData.GetSimpleArea( aDummy);
571
0
    if (eMarkType != SC_MARK_MULTI)
572
0
    {
573
        // Single destination range.
574
0
        if (eMarkType != SC_MARK_SIMPLE && eMarkType != SC_MARK_SIMPLE_FILTERED)
575
0
            return false;
576
0
    }
577
578
    // Multiple destination ranges.
579
580
    // Same as ScViewData::SelectionForbidsPaste() in
581
    // sc/source/ui/view/viewdata.cxx but different return details.
582
583
0
    vcl::Window* pWin = rViewData.GetActiveWin();
584
0
    if (!pWin)
585
0
        return false;
586
587
0
    const ScTransferObj* pOwnClip = ScTransferObj::GetOwnClipboard(ScTabViewShell::GetClipData(pWin));
588
0
    if (!pOwnClip)
589
        // If it's not a Calc document, we won't be picky.
590
0
        return true;
591
592
0
    ScDocument* pClipDoc = pOwnClip->GetDocument();
593
0
    if (!pClipDoc)
594
0
        return false;
595
596
0
    ScRange aSrcRange = pClipDoc->GetClipParam().getWholeRange();
597
0
    SCROW nRowSize = aSrcRange.aEnd.Row() - aSrcRange.aStart.Row() + 1;
598
0
    SCCOL nColSize = aSrcRange.aEnd.Col() - aSrcRange.aStart.Col() + 1;
599
600
0
    if (rViewData.SelectionForbidsPaste( nColSize, nRowSize))
601
0
        return false;
602
603
0
    ScMarkData aMark = rViewData.GetMarkData();
604
0
    ScRangeList aRanges;
605
0
    aMark.MarkToSimple();
606
0
    aMark.FillRangeListWithMarks(&aRanges, false);
607
608
0
    return ScClipUtil::CheckDestRanges(rViewData.GetDocument(), nColSize, nRowSize, aMark, aRanges);
609
0
}
610
611
}
612
613
void ScCellShell::GetClipState( SfxItemSet& rSet )
614
0
{
615
// SID_PASTE
616
// SID_PASTE_SPECIAL
617
// SID_PASTE_UNFORMATTED
618
// SID_CLIPBOARD_FORMAT_ITEMS
619
620
0
    if ( !pImpl->m_xClipEvtLstnr.is() )
621
0
    {
622
        // create listener
623
0
        pImpl->m_xClipEvtLstnr = new TransferableClipboardListener( LINK( this, ScCellShell, ClipboardChanged ) );
624
0
        vcl::Window* pWin = GetViewData().GetActiveWin();
625
0
        pImpl->m_xClipEvtLstnr->AddListener( pWin );
626
627
        // get initial state
628
0
        TransferableDataHelper aDataHelper( TransferableDataHelper::CreateFromSystemClipboard( pWin ) );
629
0
        bPastePossible = lcl_IsCellPastePossible( aDataHelper );
630
0
    }
631
632
0
    bool bDisable = !bPastePossible;
633
634
    //  cell protection / multiple selection
635
636
0
    if (!bDisable)
637
0
    {
638
0
        SCCOL nCol = GetViewData().GetCurX();
639
0
        SCROW nRow = GetViewData().GetCurY();
640
0
        SCTAB nTab = GetViewData().CurrentTabForData();
641
0
        ScDocument& rDoc = GetViewData().GetDocShell()->GetDocument();
642
0
        if (!rDoc.IsBlockEditable( nTab, nCol,nRow, nCol,nRow ))
643
0
            bDisable = true;
644
645
0
        if (!bDisable && !checkDestRanges(GetViewData()))
646
0
            bDisable = true;
647
0
    }
648
649
0
    if (!ScTransferObj::GetOwnClipboard(
650
0
        ScTabViewShell::GetClipData(GetViewData().GetActiveWin())))
651
0
    {
652
0
        rSet.DisableItem( SID_PASTE_TRANSPOSED );
653
0
    }
654
655
0
    if (bDisable)
656
0
    {
657
0
        rSet.DisableItem( SID_PASTE );
658
0
        rSet.DisableItem( SID_PASTE_SPECIAL );
659
0
        rSet.DisableItem( SID_PASTE_UNFORMATTED );
660
0
        rSet.DisableItem( SID_PASTE_ONLY_VALUE );
661
0
        rSet.DisableItem( SID_PASTE_ONLY_TEXT );
662
0
        rSet.DisableItem( SID_PASTE_ONLY_FORMULA );
663
0
        rSet.DisableItem( SID_PASTE_TRANSPOSED );
664
0
        rSet.DisableItem( SID_PASTE_AS_LINK );
665
0
        rSet.DisableItem( SID_PASTE_TEXTIMPORT_DIALOG );
666
0
        rSet.DisableItem( SID_CLIPBOARD_FORMAT_ITEMS );
667
0
    }
668
0
    else if ( rSet.GetItemState( SID_CLIPBOARD_FORMAT_ITEMS ) != SfxItemState::UNKNOWN )
669
0
    {
670
0
        SvxClipboardFormatItem aFormats( SID_CLIPBOARD_FORMAT_ITEMS );
671
0
        GetPossibleClipboardFormats( aFormats );
672
0
        rSet.Put( aFormats );
673
0
    }
674
0
}
675
676
//  only SID_HYPERLINK_GETLINK:
677
678
void ScCellShell::GetHLinkState( SfxItemSet& rSet )
679
0
{
680
    //  always return an item (or inserting will be disabled)
681
    //  if the cell at the cursor contains only a link, return that link
682
683
0
    SvxHyperlinkItem aHLinkItem;
684
0
    aHLinkItem.SetShowName(false);
685
0
    if ( !GetViewData().GetView()->HasBookmarkAtCursor( &aHLinkItem ) )
686
0
    {
687
        // tdf#80043 - put selected text into item
688
0
        ScViewData& rData       = GetViewData();
689
0
        ScDocument& rDoc        = rData.GetDocument();
690
0
        SCCOL       nPosX       = rData.GetCurX();
691
0
        SCROW       nPosY       = rData.GetCurY();
692
0
        SCTAB       nTab        = rData.CurrentTabForData();
693
0
        aHLinkItem.SetName(rDoc.GetString(nPosX, nPosY, nTab));
694
0
    }
695
696
0
    rSet.Put(aHLinkItem);
697
0
}
698
699
void ScCellShell::GetState(SfxItemSet &rSet)
700
0
{
701
0
    ScTabViewShell* pTabViewShell   = GetViewData().GetViewShell();
702
0
    ScDocShell* pDocSh = GetViewData().GetDocShell();
703
0
    ScViewData& rData       = GetViewData();
704
0
    ScDocument& rDoc        = rData.GetDocument();
705
0
    ScMarkData& rMark       = rData.GetMarkData();
706
0
    SCCOL       nPosX       = rData.GetCurX();
707
0
    SCROW       nPosY       = rData.GetCurY();
708
0
    SCTAB       nTab        = rData.CurrentTabForData();
709
710
0
    SCTAB nTabCount = rDoc.GetTableCount();
711
0
    SCTAB nTabSelCount = rMark.GetSelectCount();
712
713
0
    SfxWhichIter aIter(rSet);
714
0
    sal_uInt16 nWhich = aIter.FirstWhich();
715
0
    while ( nWhich )
716
0
    {
717
0
        switch ( nWhich )
718
0
        {
719
0
            case SID_DETECTIVE_REFRESH:
720
0
                if (!rDoc.HasDetectiveOperations())
721
0
                    rSet.DisableItem( nWhich );
722
0
                break;
723
724
0
            case SID_RANGE_ADDRESS:
725
0
                {
726
0
                    ScRange aRange;
727
0
                    if ( rData.GetSimpleArea( aRange ) == SC_MARK_SIMPLE )
728
0
                    {
729
0
                        OUString aStr(aRange.Format(rDoc, ScRefFlags::VALID | ScRefFlags::TAB_3D));
730
0
                        rSet.Put( SfxStringItem( nWhich, aStr ) );
731
0
                    }
732
0
                }
733
0
                break;
734
735
0
            case SID_RANGE_NOTETEXT:
736
0
                {
737
                    //  always take cursor position, do not use top-left cell of selection
738
0
                    OUString aNoteText;
739
0
                    if ( const ScPostIt* pNote = rDoc.GetNote(nPosX, nPosY, nTab) )
740
0
                        aNoteText = pNote->GetText();
741
0
                    rSet.Put( SfxStringItem( nWhich, aNoteText ) );
742
0
                }
743
0
                break;
744
745
0
            case SID_RANGE_ROW:
746
0
                rSet.Put( SfxInt32Item( SID_RANGE_ROW, nPosY+1 ) );
747
0
                break;
748
749
0
            case SID_RANGE_COL:
750
0
                rSet.Put( SfxInt16Item( SID_RANGE_COL, nPosX+1 ) );
751
0
                break;
752
753
0
            case SID_RANGE_TABLE:
754
0
                rSet.Put( SfxInt16Item( SID_RANGE_TABLE, nTab+1 ) );
755
0
                break;
756
757
0
            case SID_RANGE_FORMULA:
758
0
                {
759
0
                    OUString aString = rDoc.GetFormula( nPosX, nPosY, nTab );
760
0
                    if( aString.isEmpty() )
761
0
                    {
762
0
                        aString = rDoc.GetInputString( nPosX, nPosY, nTab );
763
0
                    }
764
0
                    rSet.Put( SfxStringItem( nWhich, aString ) );
765
0
                }
766
0
                break;
767
768
0
            case SID_RANGE_TEXTVALUE:
769
0
                {
770
0
                    OUString aString = rDoc.GetString(nPosX, nPosY, nTab);
771
0
                    rSet.Put( SfxStringItem( nWhich, aString ) );
772
0
                }
773
0
                break;
774
775
0
            case SID_STATUS_SELMODE:
776
0
                {
777
                    /* 0: STD   Click cancels Sel
778
                     * 1: ER    Click extends selection
779
                     * 2: ERG   Click defines further selection
780
                     */
781
0
                    sal_uInt16 nMode = pTabViewShell->GetLockedModifiers();
782
783
0
                    switch ( nMode )
784
0
                    {
785
0
                        case KEY_SHIFT: nMode = 1;  break;
786
0
                        case KEY_MOD1:  nMode = 2;  break; // Control-key
787
0
                        case 0:
788
0
                        default:
789
0
                            nMode = 0;
790
0
                    }
791
792
0
                    rSet.Put( SfxUInt16Item( nWhich, nMode ) );
793
0
                }
794
0
                break;
795
796
0
            case SID_STATUS_DOCPOS:
797
0
                {
798
0
                    OUString aStr = ScResId( STR_TABLE_COUNT );
799
800
0
                    aStr = aStr.replaceFirst("%1", OUString::number( nTab + 1  ) );
801
0
                    aStr = aStr.replaceFirst("%2", OUString::number( nTabCount ) );
802
803
0
                    rSet.Put( SfxStringItem( nWhich, aStr ) );                }
804
0
                break;
805
806
0
            case SID_ROWCOL_SELCOUNT:
807
0
                {
808
0
                    ScRangeListRef aMarkRanges;
809
0
                    GetViewData().GetMultiArea(aMarkRanges);
810
0
                    const SCCOL nCol1 = aMarkRanges->front().aStart.Col();
811
0
                    const SCROW nRow1 = aMarkRanges->front().aStart.Row();
812
0
                    const SCCOL nCol2 = aMarkRanges->front().aEnd.Col();
813
0
                    const SCROW nRow2 = aMarkRanges->front().aEnd.Row();
814
0
                    const size_t nRanges = aMarkRanges->size();
815
816
0
                    if ((nRanges == 1 && (nCol2 != nCol1 || nRow1 != nRow2)) || nRanges > 1)
817
0
                    {
818
0
                        bool bSameRows = true;
819
0
                        bool bSameCols = true;
820
0
                        SCROW nRowsSum = 0;
821
0
                        SCCOL nColsSum = 0;
822
0
                        for (size_t i = 0; i < nRanges; ++i)
823
0
                        {
824
0
                            const ScRange& rRange = (*aMarkRanges)[i];
825
0
                            const SCCOL nRangeCol1 = rRange.aStart.Col();
826
0
                            const SCROW nRangeRow1 = rRange.aStart.Row();
827
0
                            const SCCOL nRangeCol2 = rRange.aEnd.Col();
828
0
                            const SCROW nRangeRow2 = rRange.aEnd.Row();
829
0
                            bSameRows &= (nRow1 == nRangeRow1 && nRow2 == nRangeRow2);
830
0
                            bSameCols &= (nCol1 == nRangeCol1 && nCol2 == nRangeCol2);
831
                            // Sum rows if the number of cols is the same or
832
                            // sum columns if the number of rows is the same,
833
                            // otherwise do not show any count of selected cells.
834
0
                            if (bSameRows || bSameCols)
835
0
                            {
836
0
                                const auto nCols = nRangeCol2 - nRangeCol1 + 1;
837
0
                                const auto nRows = (bSameCols || nRowsSum == 0) ?
838
0
                                    rDoc.CountNonFilteredRows( nRangeRow1, nRangeRow2, rRange.aStart.Tab()) :
839
0
                                    nRowsSum;
840
0
                                if (bSameRows)
841
0
                                {
842
0
                                    nRowsSum = nRows;
843
0
                                    nColsSum += nCols;
844
0
                                }
845
0
                                else if (bSameCols)
846
0
                                {
847
0
                                    nRowsSum += nRows;
848
0
                                    nColsSum = nCols;
849
0
                                }
850
0
                            }
851
0
                            else
852
0
                                break;
853
0
                        }
854
                        // Either the rows or columns are the same among selections
855
0
                        if (bSameRows || bSameCols)
856
0
                        {
857
0
                            const LocaleDataWrapper& rLocaleData
858
0
                                = Application::GetSettings().GetUILocaleDataWrapper();
859
0
                            OUString aRowArg
860
0
                                = ScResId(STR_SELCOUNT_ROWARG, nRowsSum)
861
0
                                      .replaceAll("%d", rLocaleData.getNum(nRowsSum, 0));
862
0
                            OUString aColArg
863
0
                                = ScResId(STR_SELCOUNT_COLARG, nColsSum)
864
0
                                      .replaceAll("%d", rLocaleData.getNum(nColsSum, 0));
865
0
                            OUString aStr = ScResId(STR_SELCOUNT);
866
0
                            aStr = aStr.replaceAll("%1", aRowArg);
867
0
                            aStr = aStr.replaceAll("%2", aColArg);
868
0
                            rSet.Put(SfxStringItem(nWhich, aStr));
869
0
                        }
870
0
                    }
871
0
                    else
872
0
                    {
873
0
                        SCSIZE nSelected, nTotal;
874
0
                        rDoc.GetFilterSelCount( nPosX, nPosY, nTab, nSelected, nTotal );
875
0
                        if( nTotal && nSelected != SCSIZE_MAX )
876
0
                        {
877
0
                            OUString aStr = ScResId( STR_FILTER_SELCOUNT );
878
0
                            aStr = aStr.replaceAll( "%1", OUString::number( nSelected ) );
879
0
                            aStr = aStr.replaceAll( "%2", OUString::number( nTotal ) );
880
0
                            rSet.Put( SfxStringItem( nWhich, aStr ) );
881
0
                        }
882
0
                    }
883
0
                }
884
0
                break;
885
886
            //  calculations etc. with date/time/Fail/position&size together
887
888
            // #i34458# The SvxStatusItem belongs only into SID_TABLE_CELL. It no longer has to be
889
            // duplicated in SID_ATTR_POSITION or SID_ATTR_SIZE for SvxPosSizeStatusBarControl.
890
0
            case SID_TABLE_CELL:
891
0
                {
892
                    //  Test, if error under cursor
893
                    //  (not rDoc.GetErrCode, to avoid erasing circular references)
894
895
                    // In interpreter may happen via rescheduled Basic
896
0
                    if ( rDoc.IsInInterpreter() )
897
0
                        rSet.Put( SvxStatusItem( SID_TABLE_CELL, u"..."_ustr, StatusCategory::Formula ) );
898
0
                    else
899
0
                    {
900
0
                        FormulaError nErrCode = FormulaError::NONE;
901
0
                        ScFormulaCell* pCell = rDoc.GetFormulaCell(ScAddress(nPosX, nPosY, nTab));
902
0
                        if (pCell && !pCell->IsRunning())
903
0
                            nErrCode = pCell->GetErrCode();
904
905
0
                        OUString aFuncStr;
906
0
                        if ( pTabViewShell->GetFunction( aFuncStr, nErrCode ) )
907
0
                        {
908
0
                            rSet.Put( SvxStatusItem( SID_TABLE_CELL, aFuncStr, StatusCategory::Formula ) );
909
0
                        }
910
0
                    }
911
0
                }
912
0
                break;
913
914
0
            case SID_DATA_SELECT:
915
                // HasSelectionData includes column content and validity,
916
                // page fields have to be checked separately.
917
0
                if ( !rDoc.HasSelectionData( nPosX, nPosY, nTab ) &&
918
0
                     !pTabViewShell->HasPageFieldDataAtCursor() )
919
0
                    rSet.DisableItem( nWhich );
920
0
                break;
921
922
0
            case FID_CURRENTVALIDATION:
923
0
                if ( !rDoc.HasValidationData( nPosX, nPosY, nTab ))
924
0
                    rSet.DisableItem( nWhich );
925
0
                break;
926
927
0
            case SID_STATUS_SUM:
928
0
                {
929
0
                    OUString aFuncStr;
930
0
                    if ( pTabViewShell->GetFunction( aFuncStr, FormulaError::NONE ) )
931
0
                        rSet.Put( SfxStringItem( nWhich, aFuncStr ) );
932
0
                }
933
0
                break;
934
935
0
            case FID_MERGE_ON:
936
0
                if ( rDoc.GetChangeTrack() || !pTabViewShell->TestMergeCells() )
937
0
                    rSet.DisableItem( nWhich );
938
0
                break;
939
940
0
            case FID_MERGE_OFF:
941
0
                if ( rDoc.GetChangeTrack() || !pTabViewShell->TestRemoveMerge() )
942
0
                    rSet.DisableItem( nWhich );
943
0
                break;
944
945
0
            case FID_MERGE_TOGGLE:
946
0
                if ( rDoc.GetChangeTrack() )
947
0
                    rSet.DisableItem( nWhich );
948
0
                else
949
0
                {
950
0
                    bool bCanMerge = pTabViewShell->TestMergeCells();
951
0
                    bool bCanSplit = pTabViewShell->TestRemoveMerge();
952
0
                    if( !bCanMerge && !bCanSplit )
953
0
                        rSet.DisableItem( nWhich );
954
0
                    else
955
0
                        rSet.Put( SfxBoolItem( nWhich, bCanSplit ) );
956
0
                }
957
0
                break;
958
959
0
            case FID_INS_ROWBRK:
960
0
                if ( nPosY==0 || (rDoc.HasRowBreak(nPosY, nTab) & ScBreakType::Manual) || rDoc.IsTabProtected(nTab) )
961
0
                    rSet.DisableItem( nWhich );
962
0
                break;
963
964
0
            case FID_INS_COLBRK:
965
0
                if ( nPosX==0 || (rDoc.HasColBreak(nPosX, nTab) & ScBreakType::Manual) || rDoc.IsTabProtected(nTab) )
966
0
                    rSet.DisableItem( nWhich );
967
0
                break;
968
969
0
            case FID_DEL_ROWBRK:
970
0
                if ( nPosY==0 || !(rDoc.HasRowBreak(nPosY, nTab) & ScBreakType::Manual) || rDoc.IsTabProtected(nTab) )
971
0
                    rSet.DisableItem( nWhich );
972
0
                break;
973
974
0
            case FID_DEL_COLBRK:
975
0
                if ( nPosX==0 || !(rDoc.HasColBreak(nPosX, nTab) & ScBreakType::Manual) || rDoc.IsTabProtected(nTab) )
976
0
                    rSet.DisableItem( nWhich );
977
0
                break;
978
979
0
            case FID_FILL_TAB:
980
0
                if ( nTabSelCount < 2 )
981
0
                    rSet.DisableItem( nWhich );
982
0
                break;
983
984
0
            case SID_INSERT_CURRENT_DATE:
985
0
            case SID_INSERT_CURRENT_TIME:
986
0
                {
987
0
                    if ( rDoc.IsTabProtected(nTab) &&
988
0
                            rDoc.HasAttrib(nPosX, nPosY, nTab, nPosX, nPosY, nTab, HasAttrFlags::Protected))
989
0
                        rSet.DisableItem( nWhich );
990
0
                }
991
0
                break;
992
993
0
            case SID_SELECT_SCENARIO:
994
0
                {
995
0
                    std::vector<OUString> aList;
996
0
                    Color   aDummyCol;
997
998
0
                    if ( !rDoc.IsScenario(nTab) )
999
0
                    {
1000
0
                        OUString aStr;
1001
0
                        ScScenarioFlags nFlags;
1002
0
                        SCTAB nScTab = nTab + 1;
1003
0
                        bool bSheetProtected = rDoc.IsTabProtected(nTab);
1004
1005
0
                        while ( rDoc.IsScenario(nScTab) )
1006
0
                        {
1007
0
                            rDoc.GetName( nScTab, aStr );
1008
0
                            aList.push_back(aStr);
1009
0
                            rDoc.GetScenarioData( nScTab, aStr, aDummyCol, nFlags );
1010
0
                            aList.push_back(aStr);
1011
                            // Protection is sal_True if both Sheet and Scenario are protected
1012
0
                            aList.push_back((bSheetProtected && (nFlags & ScScenarioFlags::Protected)) ? u"1"_ustr : u"0"_ustr);
1013
0
                            ++nScTab;
1014
0
                        }
1015
0
                    }
1016
0
                    else
1017
0
                    {
1018
0
                        OUString aComment;
1019
0
                        ScScenarioFlags nDummyFlags;
1020
0
                        rDoc.GetScenarioData( nTab, aComment, aDummyCol, nDummyFlags );
1021
0
                        OSL_ENSURE( aList.empty(), "List not empty!" );
1022
0
                        aList.push_back(aComment);
1023
0
                    }
1024
1025
0
                    rSet.Put( SfxStringListItem( nWhich, &aList ) );
1026
0
                }
1027
0
                break;
1028
1029
0
            case FID_ROW_HIDE:
1030
0
            case FID_ROW_SHOW:
1031
0
            case FID_COL_HIDE:
1032
0
            case FID_COL_SHOW:
1033
0
            case FID_COL_OPT_WIDTH:
1034
0
            case FID_ROW_OPT_HEIGHT:
1035
0
            case FID_DELETE_CELL:
1036
0
                if ( rDoc.IsTabProtected(nTab) || pDocSh->IsReadOnly())
1037
0
                    rSet.DisableItem( nWhich );
1038
0
                break;
1039
1040
0
            case SID_OUTLINE_MAKE:
1041
0
                {
1042
0
                    if ( GetViewData().GetDocument().GetDPAtCursor( GetViewData().GetCurX(),
1043
0
                                            GetViewData().GetCurY(), GetViewData().CurrentTabForData() ) )
1044
0
                    {
1045
                        //! test for data pilot operation
1046
0
                    }
1047
0
                    else if (rDoc.GetChangeTrack()!=nullptr || GetViewData().IsMultiMarked())
1048
0
                    {
1049
0
                        rSet.DisableItem( nWhich );
1050
0
                    }
1051
0
                }
1052
0
                break;
1053
0
            case SID_OUTLINE_SHOW:
1054
0
                if ( GetViewData().GetDocument().GetDPAtCursor( GetViewData().GetCurX(),
1055
0
                                        GetViewData().GetCurY(), GetViewData().CurrentTabForData() ) )
1056
0
                {
1057
                    //! test for data pilot operation
1058
0
                }
1059
0
                else if (!pTabViewShell->OutlinePossible(false))
1060
0
                    rSet.DisableItem( nWhich );
1061
0
                break;
1062
1063
0
            case SID_OUTLINE_HIDE:
1064
0
                if ( GetViewData().GetDocument().GetDPAtCursor( GetViewData().GetCurX(),
1065
0
                                        GetViewData().GetCurY(), GetViewData().CurrentTabForData() ) )
1066
0
                {
1067
                    //! test for data pilot operation
1068
0
                }
1069
0
                else if (!pTabViewShell->OutlinePossible(true))
1070
0
                    rSet.DisableItem( nWhich );
1071
0
                break;
1072
1073
0
            case SID_OUTLINE_REMOVE:
1074
0
                {
1075
0
                    if ( GetViewData().GetDocument().GetDPAtCursor( GetViewData().GetCurX(),
1076
0
                                            GetViewData().GetCurY(), GetViewData().CurrentTabForData() ) )
1077
0
                    {
1078
                        //! test for data pilot operation
1079
0
                    }
1080
0
                    else
1081
0
                    {
1082
0
                        bool bCol, bRow;
1083
0
                        pTabViewShell->TestRemoveOutline( bCol, bRow );
1084
0
                        if ( !bCol && !bRow )
1085
0
                            rSet.DisableItem( nWhich );
1086
0
                    }
1087
0
                }
1088
0
                break;
1089
1090
0
            case FID_COL_WIDTH:
1091
0
                {
1092
0
                    SfxUInt16Item aWidthItem( FID_COL_WIDTH, rDoc.GetColWidth( nPosX , nTab) );
1093
0
                    rSet.Put( aWidthItem );
1094
0
                    if ( pDocSh->IsReadOnly())
1095
0
                        rSet.DisableItem( nWhich );
1096
1097
                    //XXX disable if not conclusive
1098
0
                }
1099
0
                break;
1100
1101
0
            case FID_ROW_HEIGHT:
1102
0
                {
1103
0
                    SfxUInt16Item aHeightItem( FID_ROW_HEIGHT, rDoc.GetRowHeight( nPosY , nTab) );
1104
0
                    rSet.Put( aHeightItem );
1105
                    //XXX disable if not conclusive
1106
0
                    if ( pDocSh->IsReadOnly())
1107
0
                        rSet.DisableItem( nWhich );
1108
0
                }
1109
0
                break;
1110
1111
0
            case SID_DETECTIVE_FILLMODE:
1112
0
                rSet.Put(SfxBoolItem( nWhich, pTabViewShell->IsAuditShell() ));
1113
0
                break;
1114
1115
0
            case FID_INPUTLINE_STATUS:
1116
0
                OSL_FAIL( "Old update method. Use ScTabViewShell::UpdateInputHandler()." );
1117
0
                break;
1118
1119
0
            case SID_SCENARIOS:                                     // scenarios:
1120
0
                if (!(rMark.IsMarked() || rMark.IsMultiMarked()))   // only, if something selected
1121
0
                    rSet.DisableItem( nWhich );
1122
0
                break;
1123
1124
0
            case FID_NOTE_VISIBLE:
1125
0
                {
1126
0
                    const ScPostIt* pNote = rDoc.GetNote(nPosX, nPosY, nTab);
1127
0
                    if ( pNote && rDoc.IsBlockEditable( nTab, nPosX,nPosY, nPosX,nPosY ) )
1128
0
                        rSet.Put( SfxBoolItem( nWhich, pNote->IsCaptionShown() ) );
1129
0
                    else
1130
0
                        rSet.DisableItem( nWhich );
1131
0
                }
1132
0
                break;
1133
1134
0
            case FID_HIDE_NOTE:
1135
0
            case FID_SHOW_NOTE:
1136
0
                {
1137
0
                    bool bEnable = false;
1138
0
                    bool bSearchForHidden = nWhich == FID_SHOW_NOTE;
1139
0
                    if (!rMark.IsMarked() && !rMark.IsMultiMarked())
1140
0
                    {
1141
                        // Check current cell
1142
0
                        const ScPostIt* pNote = rDoc.GetNote(nPosX, nPosY, nTab);
1143
0
                        if ( pNote && rDoc.IsBlockEditable( nTab, nPosX,nPosY, nPosX,nPosY ) )
1144
0
                            if ( pNote->IsCaptionShown() != bSearchForHidden)
1145
0
                                bEnable = true;
1146
0
                    }
1147
0
                    else
1148
0
                    {
1149
                        // Check selection range
1150
0
                        ScRangeListRef aRangesRef;
1151
0
                        rData.GetMultiArea(aRangesRef);
1152
0
                        ScRangeList aRanges = *aRangesRef;
1153
0
                        std::vector<sc::NoteEntry> aNotes;
1154
0
                        rDoc.GetNotesInRange(aRanges, aNotes);
1155
0
                        for(const auto& rNote : aNotes)
1156
0
                        {
1157
0
                            const ScAddress& rAdr = rNote.maPos;
1158
0
                            if( rDoc.IsBlockEditable( rAdr.Tab(), rAdr.Col(), rAdr.Row(), rAdr.Col(), rAdr.Row() ))
1159
0
                            {
1160
0
                                if (rNote.mpNote->IsCaptionShown() != bSearchForHidden)
1161
0
                                {
1162
0
                                    bEnable = true;
1163
0
                                    break;
1164
0
                                }
1165
0
                            }
1166
0
                        }
1167
1168
0
                    }
1169
0
                    if ( !bEnable )
1170
0
                        rSet.DisableItem( nWhich );
1171
0
                }
1172
0
                break;
1173
1174
0
            case FID_SHOW_ALL_NOTES:
1175
0
            case FID_HIDE_ALL_NOTES:
1176
0
            case FID_DELETE_ALL_NOTES:
1177
0
                {
1178
0
                    bool bHasNotes = false;
1179
1180
0
                    for (auto const& rTab : rMark.GetSelectedTabs())
1181
0
                    {
1182
0
                        if (rDoc.HasTabNotes( rTab ))
1183
0
                        {
1184
0
                            bHasNotes = true;
1185
0
                            break;
1186
0
                        }
1187
0
                    }
1188
1189
0
                    if ( !bHasNotes )
1190
0
                        rSet.DisableItem( nWhich );
1191
0
                }
1192
0
                break;
1193
1194
0
            case SID_TOGGLE_NOTES:
1195
0
                {
1196
0
                    bool bHasNotes = false;
1197
0
                    ScRangeList aRanges;
1198
1199
0
                    for (auto const& rTab : rMark.GetSelectedTabs())
1200
0
                    {
1201
0
                        if (rDoc.HasTabNotes( rTab ))
1202
0
                        {
1203
0
                            bHasNotes = true;
1204
0
                            aRanges.push_back(ScRange(0,0,rTab,rDoc.MaxCol(),rDoc.MaxRow(),rTab));
1205
0
                        }
1206
0
                    }
1207
1208
0
                    if ( !bHasNotes )
1209
0
                        rSet.DisableItem( nWhich );
1210
0
                    else
1211
0
                    {
1212
0
                         CommentCaptionState eState = rDoc.GetAllNoteCaptionsState( aRanges );
1213
0
                         bool bAllNotesInShown = (eState != ALLHIDDEN && eState != MIXED);
1214
0
                         rSet.Put( SfxBoolItem( SID_TOGGLE_NOTES, bAllNotesInShown) );
1215
0
                    }
1216
0
                }
1217
0
                break;
1218
1219
0
            case SID_DELETE_NOTE:
1220
0
                {
1221
0
                    bool bEnable = false;
1222
0
                    if ( rMark.IsMarked() || rMark.IsMultiMarked() )
1223
0
                    {
1224
0
                        if ( rDoc.IsSelectionEditable( rMark ) )
1225
0
                        {
1226
                            // look for at least one note in selection
1227
0
                            ScRangeList aRanges;
1228
0
                            rMark.FillRangeListWithMarks( &aRanges, false );
1229
0
                            bEnable = rDoc.ContainsNotesInRange( aRanges );
1230
0
                        }
1231
0
                    }
1232
0
                    else
1233
0
                    {
1234
0
                        bEnable = rDoc.IsBlockEditable( nTab, nPosX,nPosY, nPosX,nPosY ) &&
1235
0
                                  rDoc.GetNote(nPosX, nPosY, nTab);
1236
0
                    }
1237
0
                    if ( !bEnable )
1238
0
                        rSet.DisableItem( nWhich );
1239
0
                }
1240
0
                break;
1241
1242
0
            case SID_OPENDLG_CONSOLIDATE:
1243
0
            case SCITEM_CONSOLIDATEDATA:
1244
0
                {
1245
0
                    if (rDoc.GetChangeTrack()!=nullptr)
1246
0
                        rSet.DisableItem( nWhich);
1247
0
                }
1248
0
                break;
1249
1250
0
            case SID_CHINESE_CONVERSION:
1251
0
            case SID_HANGUL_HANJA_CONVERSION:
1252
0
                ScViewUtil::HideDisabledSlot( rSet, rData.GetBindings(), nWhich );
1253
0
            break;
1254
1255
0
            case FID_USE_NAME:
1256
0
                {
1257
0
                    if ( pDocSh->IsDocShared() )
1258
0
                        rSet.DisableItem( nWhich );
1259
0
                    else
1260
0
                    {
1261
0
                        ScRange aRange;
1262
0
                        if ( rData.GetSimpleArea( aRange ) != SC_MARK_SIMPLE )
1263
0
                            rSet.DisableItem( nWhich );
1264
0
                    }
1265
0
                }
1266
0
                break;
1267
1268
0
            case FID_DEFINE_NAME:
1269
0
            case FID_INSERT_NAME:
1270
0
            case FID_ADD_NAME:
1271
0
            case SID_DEFINE_COLROWNAMERANGES:
1272
0
                {
1273
0
                    if ( pDocSh->IsDocShared() )
1274
0
                    {
1275
0
                        rSet.DisableItem( nWhich );
1276
0
                    }
1277
0
                }
1278
0
                break;
1279
1280
0
            case FID_DEFINE_CURRENT_NAME:
1281
0
            {
1282
0
                ScAddress aCurrentAddress( nPosX, nPosY, nTab );
1283
1284
0
                if ( !rDoc.IsAddressInRangeName( RangeNameScope::GLOBAL, aCurrentAddress ) &&
1285
0
                     !rDoc.IsAddressInRangeName( RangeNameScope::SHEET, aCurrentAddress ))
1286
0
                {
1287
0
                    rSet.DisableItem( nWhich );
1288
0
                }
1289
0
            }
1290
0
            break;
1291
1292
0
            case SID_SPELL_DIALOG:
1293
0
                {
1294
0
                    if (rDoc.IsTabProtected(rData.CurrentTabForData()))
1295
0
                    {
1296
0
                        bool bVisible = false;
1297
0
                        SfxViewFrame* pViewFrame = ( pTabViewShell ? &pTabViewShell->GetViewFrame() : nullptr );
1298
0
                        if ( pViewFrame && pViewFrame->HasChildWindow( nWhich ) )
1299
0
                        {
1300
0
                            SfxChildWindow* pChild = pViewFrame->GetChildWindow( nWhich );
1301
0
                            std::shared_ptr<SfxDialogController> xController = pChild ? pChild->GetController() : nullptr;
1302
0
                            if (xController && xController->getDialog()->get_visible())
1303
0
                            {
1304
0
                                bVisible = true;
1305
0
                            }
1306
0
                        }
1307
0
                        if ( !bVisible )
1308
0
                        {
1309
0
                            rSet.DisableItem( nWhich );
1310
0
                        }
1311
0
                    }
1312
0
                }
1313
0
                break;
1314
1315
0
            case SID_OPENDLG_CURRENTCONDFRMT:
1316
0
            case SID_OPENDLG_CURRENTCONDFRMT_MANAGER:
1317
0
                {
1318
0
                    const ScCondFormatItem& rCondFormatItem = rDoc.GetAttr(nPosX, nPosY, nTab, ATTR_CONDITIONAL);
1319
1320
0
                    if ( rCondFormatItem.GetCondFormatData().empty() )
1321
0
                        rSet.DisableItem( nWhich );
1322
0
                    else if ( rCondFormatItem.GetCondFormatData().size() == 1 )
1323
0
                        rSet.DisableItem( SID_OPENDLG_CURRENTCONDFRMT_MANAGER );
1324
0
                    else if ( rCondFormatItem.GetCondFormatData().size() > 1 )
1325
0
                        rSet.DisableItem( SID_OPENDLG_CURRENTCONDFRMT );
1326
0
                }
1327
0
                break;
1328
1329
0
        } // switch ( nWitch )
1330
0
        nWhich = aIter.NextWhich();
1331
0
    } // while ( nWitch )
1332
0
}
1333
1334
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */