Coverage Report

Created: 2026-03-31 11:00

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/sc/source/ui/unoobj/viewuno.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 <com/sun/star/awt/MouseButton.hpp>
21
#include <com/sun/star/drawing/ShapeCollection.hpp>
22
#include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
23
#include <com/sun/star/script/vba/XVBAEventProcessor.hpp>
24
#include <com/sun/star/util/VetoException.hpp>
25
#include <com/sun/star/view/DocumentZoomType.hpp>
26
27
#include <editeng/outliner.hxx>
28
#include <svx/svditer.hxx>
29
#include <svx/svdmark.hxx>
30
#include <svx/svdpage.hxx>
31
#include <svx/svdpagv.hxx>
32
#include <svx/svdview.hxx>
33
#include <svx/unoshape.hxx>
34
#include <svx/fmshell.hxx>
35
#include <sfx2/bindings.hxx>
36
#include <sfx2/dispatch.hxx>
37
#include <sfx2/request.hxx>
38
#include <sfx2/viewfrm.hxx>
39
#include <comphelper/profilezone.hxx>
40
#include <comphelper/processfactory.hxx>
41
#include <comphelper/sequence.hxx>
42
#include <cppuhelper/supportsservice.hxx>
43
#include <cppuhelper/queryinterface.hxx>
44
#include <toolkit/helper/vclunohelper.hxx>
45
#include <vcl/svapp.hxx>
46
#include <vcl/unohelp.hxx>
47
#include <tools/multisel.hxx>
48
49
#include <drawsh.hxx>
50
#include <drtxtob.hxx>
51
#include <transobj.hxx>
52
#include <editsh.hxx>
53
#include <viewuno.hxx>
54
#include <cellsuno.hxx>
55
#include <miscuno.hxx>
56
#include <tabvwsh.hxx>
57
#include <prevwsh.hxx>
58
#include <docsh.hxx>
59
#include <drwlayer.hxx>
60
#include <attrib.hxx>
61
#include <drawview.hxx>
62
#include <fupoor.hxx>
63
#include <sc.hrc>
64
#include <unonames.hxx>
65
#include <scmod.hxx>
66
#include <appoptio.hxx>
67
#include <gridwin.hxx>
68
#include <sheetevents.hxx>
69
#include <markdata.hxx>
70
#include <scextopt.hxx>
71
#include <preview.hxx>
72
#include <inputhdl.hxx>
73
#include <inputwin.hxx>
74
#include <svx/sdrhittesthelper.hxx>
75
#include <formatsh.hxx>
76
#include <sfx2/app.hxx>
77
#include <scitems.hxx>
78
79
using namespace com::sun::star;
80
81
//! Clipping Marks
82
83
//  no Which-ID here, Map only for PropertySetInfo
84
85
static std::span<const SfxItemPropertyMapEntry> lcl_GetViewOptPropertyMap()
86
0
{
87
0
    static const SfxItemPropertyMapEntry aViewOptPropertyMap_Impl[] =
88
0
    {
89
0
        { OLD_UNO_COLROWHDR,   0,  cppu::UnoType<bool>::get(),          0, 0},
90
0
        { SC_UNO_GRIDCOLOR,    0,  cppu::UnoType<sal_Int32>::get(),    0, 0},
91
0
        { SC_UNO_COLROWHDR,    0,  cppu::UnoType<bool>::get(),          0, 0},
92
0
        { SC_UNO_HORSCROLL,    0,  cppu::UnoType<bool>::get(),          0, 0},
93
0
        { SC_UNO_SHEETTABS,    0,  cppu::UnoType<bool>::get(),          0, 0},
94
0
        { SC_UNO_VERTSCROLL,   0,  cppu::UnoType<bool>::get(),          0, 0},
95
0
        { SC_UNO_HIDESPELL,    0,  cppu::UnoType<bool>::get(),          0, 0},  /* deprecated #i91949 */
96
0
        { OLD_UNO_HORSCROLL,   0,  cppu::UnoType<bool>::get(),          0, 0},
97
0
        { SC_UNO_OUTLSYMB,     0,  cppu::UnoType<bool>::get(),          0, 0},
98
0
        { SC_UNO_VALUEHIGH,    0,  cppu::UnoType<bool>::get(),          0, 0},
99
0
        { OLD_UNO_OUTLSYMB,    0,  cppu::UnoType<bool>::get(),          0, 0},
100
0
        { OLD_UNO_SHEETTABS,   0,  cppu::UnoType<bool>::get(),          0, 0},
101
0
        { SC_UNO_SHOWANCHOR,   0,  cppu::UnoType<bool>::get(),          0, 0},
102
0
        { SC_UNO_SHOWCHARTS,   0,  cppu::UnoType<sal_Int16>::get(),    0, 0},
103
0
        { SC_UNO_SHOWDRAW,     0,  cppu::UnoType<sal_Int16>::get(),    0, 0},
104
0
        { SC_UNO_SHOWFORM,     0,  cppu::UnoType<bool>::get(),          0, 0},
105
0
        { SC_UNO_SHOWGRID,     0,  cppu::UnoType<bool>::get(),          0, 0},
106
0
        { SC_UNO_SHOWHELP,     0,  cppu::UnoType<bool>::get(),          0, 0},
107
0
        { SC_UNO_SHOWNOTES,    0,  cppu::UnoType<bool>::get(),          0, 0},
108
0
        { SC_UNO_SHOWNOTEAUTHOR,    0,  cppu::UnoType<bool>::get(),          0, 0},
109
0
        { SC_UNO_SHOWFORMULASMARKS,    0,  cppu::UnoType<bool>::get(),          0, 0},
110
0
        { SC_UNO_SHOWOBJ,      0,  cppu::UnoType<sal_Int16>::get(),    0, 0},
111
0
        { SC_UNO_SHOWPAGEBR,   0,  cppu::UnoType<bool>::get(),          0, 0},
112
0
        { SC_UNO_SHOWZERO,     0,  cppu::UnoType<bool>::get(),          0, 0},
113
0
        { OLD_UNO_VALUEHIGH,   0,  cppu::UnoType<bool>::get(),          0, 0},
114
0
        { OLD_UNO_VERTSCROLL,  0,  cppu::UnoType<bool>::get(),          0, 0},
115
0
        { SC_UNO_VISAREA,      0,  cppu::UnoType<awt::Rectangle>::get(), 0, 0},
116
0
        { SC_UNO_ZOOMTYPE,     0,  cppu::UnoType<sal_Int16>::get(),    0, 0},
117
0
        { SC_UNO_ZOOMVALUE,    0,  cppu::UnoType<sal_Int16>::get(),    0, 0},
118
0
        { SC_UNO_VISAREASCREEN,0,  cppu::UnoType<awt::Rectangle>::get(), 0, 0},
119
0
        { SC_UNO_FORMULABARHEIGHT,0,cppu::UnoType<sal_Int16>::get(),     0, 0},
120
0
    };
121
0
    return aViewOptPropertyMap_Impl;
122
0
}
123
124
constexpr OUString SCTABVIEWOBJ_SERVICE = u"com.sun.star.sheet.SpreadsheetView"_ustr;
125
constexpr OUString SCVIEWSETTINGS_SERVICE = u"com.sun.star.sheet.SpreadsheetViewSettings"_ustr;
126
127
SC_SIMPLE_SERVICE_INFO( ScViewPaneBase, u"ScViewPaneObj"_ustr, u"com.sun.star.sheet.SpreadsheetViewPane"_ustr )
128
129
ScViewPaneBase::ScViewPaneBase(ScTabViewShell* pViewSh, sal_uInt16 nP) :
130
0
    pViewShell( pViewSh ),
131
0
    nPane( nP )
132
0
{
133
0
    if (pViewShell)
134
0
        StartListening(*pViewShell);
135
0
}
136
137
ScViewPaneBase::~ScViewPaneBase()
138
0
{
139
0
    SolarMutexGuard g;
140
141
0
    if (pViewShell)
142
0
        EndListening(*pViewShell);
143
0
}
144
145
void ScViewPaneBase::Notify( SfxBroadcaster&, const SfxHint& rHint )
146
0
{
147
0
    if ( rHint.GetId() == SfxHintId::Dying )
148
0
        pViewShell = nullptr;
149
0
}
150
151
uno::Any SAL_CALL ScViewPaneBase::queryInterface( const uno::Type& rType )
152
0
{
153
0
    uno::Any aReturn = ::cppu::queryInterface(rType,
154
0
                    static_cast<sheet::XViewPane*>(this),
155
0
                    static_cast<sheet::XCellRangeReferrer*>(this),
156
0
                    static_cast<view::XFormLayerAccess*>(this),
157
0
                    static_cast<view::XControlAccess*>(this),
158
0
                    static_cast<lang::XServiceInfo*>(this),
159
0
                    static_cast<lang::XTypeProvider*>(this));
160
0
    if ( aReturn.hasValue() )
161
0
        return aReturn;
162
163
0
    return uno::Any();          // OWeakObject is in derived objects
164
0
}
165
166
uno::Sequence<uno::Type> SAL_CALL ScViewPaneBase::getTypes()
167
0
{
168
0
    static const uno::Sequence<uno::Type> aTypes
169
0
    {
170
0
        cppu::UnoType<sheet::XViewPane>::get(),
171
0
        cppu::UnoType<sheet::XCellRangeReferrer>::get(),
172
0
        cppu::UnoType<view::XFormLayerAccess>::get(),
173
0
        cppu::UnoType<lang::XServiceInfo>::get(),
174
0
        cppu::UnoType<lang::XTypeProvider>::get(),
175
0
    };
176
0
    return aTypes;
177
0
}
178
179
uno::Sequence<sal_Int8> SAL_CALL ScViewPaneBase::getImplementationId()
180
0
{
181
0
    return css::uno::Sequence<sal_Int8>();
182
0
}
183
184
// XViewPane
185
186
sal_Int32 SAL_CALL ScViewPaneBase::getFirstVisibleColumn()
187
0
{
188
0
    SolarMutexGuard aGuard;
189
0
    if (pViewShell)
190
0
    {
191
0
        ScViewData& rViewData = pViewShell->GetViewData();
192
0
        ScSplitPos eWhich = ( nPane == SC_VIEWPANE_ACTIVE ) ?
193
0
                                rViewData.GetActivePart() :
194
0
                                static_cast<ScSplitPos>(nPane);
195
0
        ScHSplitPos eWhichH = WhichH( eWhich );
196
197
0
        return rViewData.GetPosX( eWhichH );
198
0
    }
199
0
    OSL_FAIL("no View ?!?"); //! Exception?
200
0
    return 0;
201
0
}
202
203
void SAL_CALL ScViewPaneBase::setFirstVisibleColumn(sal_Int32 nFirstVisibleColumn)
204
0
{
205
0
    SolarMutexGuard aGuard;
206
0
    if (pViewShell)
207
0
    {
208
0
        ScViewData& rViewData = pViewShell->GetViewData();
209
0
        ScSplitPos eWhich = ( nPane == SC_VIEWPANE_ACTIVE ) ?
210
0
                                rViewData.GetActivePart() :
211
0
                                static_cast<ScSplitPos>(nPane);
212
0
        ScHSplitPos eWhichH = WhichH( eWhich );
213
214
0
        tools::Long nDeltaX = static_cast<tools::Long>(nFirstVisibleColumn) - rViewData.GetPosX( eWhichH );
215
0
        pViewShell->ScrollX( nDeltaX, eWhichH );
216
0
    }
217
0
}
218
219
sal_Int32 SAL_CALL ScViewPaneBase::getFirstVisibleRow()
220
0
{
221
0
    SolarMutexGuard aGuard;
222
0
    if (pViewShell)
223
0
    {
224
0
        ScViewData& rViewData = pViewShell->GetViewData();
225
0
        ScSplitPos eWhich = ( nPane == SC_VIEWPANE_ACTIVE ) ?
226
0
                                rViewData.GetActivePart() :
227
0
                                static_cast<ScSplitPos>(nPane);
228
0
        ScVSplitPos eWhichV = WhichV( eWhich );
229
230
0
        return rViewData.GetPosY( eWhichV );
231
0
    }
232
0
    OSL_FAIL("no View ?!?"); //! Exception?
233
0
    return 0;
234
0
}
235
236
void SAL_CALL ScViewPaneBase::setFirstVisibleRow( sal_Int32 nFirstVisibleRow )
237
0
{
238
0
    SolarMutexGuard aGuard;
239
0
    if (pViewShell)
240
0
    {
241
0
        ScViewData& rViewData = pViewShell->GetViewData();
242
0
        ScSplitPos eWhich = ( nPane == SC_VIEWPANE_ACTIVE ) ?
243
0
                                rViewData.GetActivePart() :
244
0
                                static_cast<ScSplitPos>(nPane);
245
0
        ScVSplitPos eWhichV = WhichV( eWhich );
246
247
0
        tools::Long nDeltaY = static_cast<tools::Long>(nFirstVisibleRow) - rViewData.GetPosY( eWhichV );
248
0
        pViewShell->ScrollY( nDeltaY, eWhichV );
249
0
    }
250
0
}
251
252
table::CellRangeAddress SAL_CALL ScViewPaneBase::getVisibleRange()
253
0
{
254
0
    SolarMutexGuard aGuard;
255
0
    table::CellRangeAddress aAdr;
256
0
    if (pViewShell)
257
0
    {
258
0
        ScViewData& rViewData = pViewShell->GetViewData();
259
0
        ScSplitPos eWhich = ( nPane == SC_VIEWPANE_ACTIVE ) ?
260
0
                                rViewData.GetActivePart() :
261
0
                                static_cast<ScSplitPos>(nPane);
262
0
        ScHSplitPos eWhichH = WhichH( eWhich );
263
0
        ScVSplitPos eWhichV = WhichV( eWhich );
264
265
        //  VisibleCellsX returns only completely visible cells
266
        //  VisibleRange in Excel also partially visible ones
267
        //! do the same ???
268
269
0
        SCCOL nVisX = rViewData.VisibleCellsX( eWhichH );
270
0
        SCROW nVisY = rViewData.VisibleCellsY( eWhichV );
271
0
        if (!nVisX) nVisX = 1;  // there has to be something in the range
272
0
        if (!nVisY) nVisY = 1;
273
0
        aAdr.Sheet       = rViewData.CurrentTabForData();
274
0
        aAdr.StartColumn = rViewData.GetPosX( eWhichH );
275
0
        aAdr.StartRow    = rViewData.GetPosY( eWhichV );
276
0
        aAdr.EndColumn   = aAdr.StartColumn + nVisX - 1;
277
0
        aAdr.EndRow      = aAdr.StartRow    + nVisY - 1;
278
0
    }
279
0
    return aAdr;
280
0
}
281
282
// XCellRangeSource
283
284
uno::Reference<table::XCellRange> SAL_CALL ScViewPaneBase::getReferredCells()
285
0
{
286
0
    SolarMutexGuard aGuard;
287
0
    if (pViewShell)
288
0
    {
289
0
        ScDocShell* pDocSh = pViewShell->GetViewData().GetDocShell();
290
291
0
        table::CellRangeAddress aAdr(getVisibleRange());        //! helper function with ScRange?
292
0
        ScRange aRange( static_cast<SCCOL>(aAdr.StartColumn), static_cast<SCROW>(aAdr.StartRow), aAdr.Sheet,
293
0
                        static_cast<SCCOL>(aAdr.EndColumn), static_cast<SCROW>(aAdr.EndRow), aAdr.Sheet );
294
0
        if ( aRange.aStart == aRange.aEnd )
295
0
            return new ScCellObj( pDocSh, aRange.aStart );
296
0
        else
297
0
            return new ScCellRangeObj( pDocSh, aRange );
298
0
    }
299
300
0
    return nullptr;
301
0
}
302
303
namespace
304
{
305
    bool lcl_prepareFormShellCall( ScTabViewShell* _pViewShell, sal_uInt16 _nPane, FmFormShell*& _rpFormShell, vcl::Window*& _rpWindow, SdrView*& _rpSdrView )
306
0
    {
307
0
        if ( !_pViewShell )
308
0
            return false;
309
310
0
        ScViewData& rViewData = _pViewShell->GetViewData();
311
0
        ScSplitPos eWhich = ( _nPane == SC_VIEWPANE_ACTIVE ) ?
312
0
                                rViewData.GetActivePart() :
313
0
                                static_cast<ScSplitPos>(_nPane);
314
0
        _rpWindow = _pViewShell->GetWindowByPos( eWhich );
315
0
        _rpSdrView = _pViewShell->GetScDrawView();
316
0
        _rpFormShell = _pViewShell->GetFormShell();
317
0
        return ( _rpFormShell != nullptr ) && ( _rpSdrView != nullptr )&& ( _rpWindow != nullptr );
318
0
    }
319
}
320
321
// XFormLayerAccess
322
uno::Reference< form::runtime::XFormController > SAL_CALL ScViewPaneBase::getFormController( const uno::Reference< form::XForm >& Form )
323
0
{
324
0
    SolarMutexGuard aGuard;
325
326
0
    uno::Reference< form::runtime::XFormController > xController;
327
328
0
    vcl::Window* pWindow( nullptr );
329
0
    SdrView* pSdrView( nullptr );
330
0
    FmFormShell* pFormShell( nullptr );
331
0
    if ( lcl_prepareFormShellCall( pViewShell, nPane, pFormShell, pWindow, pSdrView ) )
332
0
        xController = FmFormShell::GetFormController( Form, *pSdrView, *pWindow->GetOutDev() );
333
334
0
    return xController;
335
0
}
336
337
sal_Bool SAL_CALL ScViewPaneBase::isFormDesignMode(  )
338
0
{
339
0
    SolarMutexGuard aGuard;
340
341
0
    bool bIsFormDesignMode( true );
342
343
0
    FmFormShell* pFormShell( pViewShell ? pViewShell->GetFormShell() : nullptr );
344
0
    if ( pFormShell )
345
0
        bIsFormDesignMode = pFormShell->IsDesignMode();
346
347
0
    return bIsFormDesignMode;
348
0
}
349
350
void SAL_CALL ScViewPaneBase::setFormDesignMode( sal_Bool DesignMode )
351
0
{
352
0
    SolarMutexGuard aGuard;
353
354
0
    vcl::Window* pWindow( nullptr );
355
0
    SdrView* pSdrView( nullptr );
356
0
    FmFormShell* pFormShell( nullptr );
357
0
    if ( lcl_prepareFormShellCall( pViewShell, nPane, pFormShell, pWindow, pSdrView ) )
358
0
        pFormShell->SetDesignMode( DesignMode );
359
0
}
360
361
// XControlAccess
362
363
uno::Reference<awt::XControl> SAL_CALL ScViewPaneBase::getControl(
364
                            const uno::Reference<awt::XControlModel>& xModel )
365
0
{
366
0
    SolarMutexGuard aGuard;
367
368
0
    uno::Reference<awt::XControl> xRet;
369
370
0
    vcl::Window* pWindow( nullptr );
371
0
    SdrView* pSdrView( nullptr );
372
0
    FmFormShell* pFormShell( nullptr );
373
0
    if ( lcl_prepareFormShellCall( pViewShell, nPane, pFormShell, pWindow, pSdrView ) )
374
0
        pFormShell->GetFormControl( xModel, *pSdrView, *pWindow->GetOutDev(), xRet );
375
376
0
    if ( !xRet.is() )
377
0
        throw container::NoSuchElementException();      // no control found
378
379
0
    return xRet;
380
0
}
381
382
awt::Rectangle ScViewPaneBase::GetVisArea() const
383
0
{
384
0
    awt::Rectangle aVisArea;
385
0
    if (pViewShell)
386
0
    {
387
0
        ScSplitPos eWhich = ( nPane == SC_VIEWPANE_ACTIVE ) ?
388
0
                                pViewShell->GetViewData().GetActivePart() :
389
0
                                static_cast<ScSplitPos>(nPane);
390
0
        ScGridWindow* pWindow = static_cast<ScGridWindow*>(pViewShell->GetWindowByPos(eWhich));
391
0
        ScDocument& rDoc = pViewShell->GetViewData().GetDocument();
392
0
        if (pWindow)
393
0
        {
394
0
            ScHSplitPos eWhichH = ((eWhich == SC_SPLIT_TOPLEFT) || (eWhich == SC_SPLIT_BOTTOMLEFT)) ?
395
0
                                    SC_SPLIT_LEFT : SC_SPLIT_RIGHT;
396
0
            ScVSplitPos eWhichV = ((eWhich == SC_SPLIT_TOPLEFT) || (eWhich == SC_SPLIT_TOPRIGHT)) ?
397
0
                                    SC_SPLIT_TOP : SC_SPLIT_BOTTOM;
398
0
            ScAddress aCell(pViewShell->GetViewData().GetPosX(eWhichH),
399
0
                pViewShell->GetViewData().GetPosY(eWhichV),
400
0
                pViewShell->GetViewData().CurrentTabForData());
401
0
            tools::Rectangle aCellRect( rDoc.GetMMRect( aCell.Col(), aCell.Row(), aCell.Col(), aCell.Row(), aCell.Tab() ) );
402
0
            Size aVisSize( pWindow->PixelToLogic( pWindow->GetSizePixel(), pWindow->GetDrawMapMode( true ) ) );
403
0
            Point aVisPos( aCellRect.TopLeft() );
404
0
            if ( rDoc.IsLayoutRTL( aCell.Tab() ) )
405
0
            {
406
0
                aVisPos = aCellRect.TopRight();
407
0
                aVisPos.AdjustX( -(aVisSize.Width()) );
408
0
            }
409
0
            tools::Rectangle aVisRect( aVisPos, aVisSize );
410
0
            aVisArea = vcl::unohelper::ConvertToAWTRect(aVisRect);
411
0
        }
412
0
    }
413
0
    return aVisArea;
414
0
}
415
416
ScViewPaneObj::ScViewPaneObj(ScTabViewShell* pViewSh, sal_uInt16 nP) :
417
0
    ScViewPaneBase( pViewSh, nP )
418
0
{
419
0
}
420
421
ScViewPaneObj::~ScViewPaneObj()
422
0
{
423
0
}
424
425
uno::Any SAL_CALL ScViewPaneObj::queryInterface( const uno::Type& rType )
426
0
{
427
    //  ScViewPaneBase has everything except OWeakObject
428
429
0
    uno::Any aRet(ScViewPaneBase::queryInterface( rType ));
430
0
    if (!aRet.hasValue())
431
0
        aRet = OWeakObject::queryInterface( rType );
432
0
    return aRet;
433
0
}
434
435
void SAL_CALL ScViewPaneObj::acquire() noexcept
436
0
{
437
0
    OWeakObject::acquire();
438
0
}
439
440
void SAL_CALL ScViewPaneObj::release() noexcept
441
0
{
442
0
    OWeakObject::release();
443
0
}
444
445
//  We need default ctor for SMART_REFLECTION_IMPLEMENTATION
446
447
ScTabViewObj::ScTabViewObj( ScTabViewShell* pViewSh ) :
448
0
    ScViewPaneBase( pViewSh, SC_VIEWPANE_ACTIVE ),
449
0
    SfxBaseController( pViewSh ),
450
0
    aPropSet( lcl_GetViewOptPropertyMap() ),
451
0
    aMouseClickHandlers( 0 ),
452
0
    aActivationListeners( 0 ),
453
0
    nPreviousTab( 0 ),
454
0
    bDrawSelModeSet(false),
455
0
    bFilteredRangeSelection(false),
456
0
    mbLeftMousePressed(false)
457
0
{
458
0
    if (pViewSh)
459
0
        nPreviousTab = pViewSh->GetViewData().CurrentTabForData();
460
0
}
461
462
ScTabViewObj::~ScTabViewObj()
463
0
{
464
    //! Listening or something along that line
465
0
    if (!aMouseClickHandlers.empty())
466
0
    {
467
0
        acquire();
468
0
        EndMouseListening();
469
0
    }
470
0
    if (!aActivationListeners.empty())
471
0
    {
472
0
        acquire();
473
0
        EndActivationListening();
474
0
    }
475
0
}
476
477
uno::Any SAL_CALL ScTabViewObj::queryInterface( const uno::Type& rType )
478
0
{
479
0
    uno::Any aReturn = ::cppu::queryInterface(rType,
480
0
                    static_cast<sheet::XSpreadsheetView*>(this),
481
0
                    static_cast<sheet::XEnhancedMouseClickBroadcaster*>(this),
482
0
                    static_cast<sheet::XActivationBroadcaster*>(this),
483
0
                    static_cast<container::XEnumerationAccess*>(this),
484
0
                    static_cast<container::XIndexAccess*>(this),
485
0
                    static_cast<container::XElementAccess*>(static_cast<container::XIndexAccess*>(this)),
486
0
                    static_cast<view::XSelectionSupplier*>(this),
487
0
                    static_cast<beans::XPropertySet*>(this),
488
0
                    static_cast<sheet::XViewSplitable*>(this),
489
0
                    static_cast<sheet::XViewFreezable*>(this),
490
0
                    static_cast<sheet::XRangeSelection*>(this),
491
0
                    static_cast<sheet::XSheetRange*>(this),
492
0
                    static_cast<sheet::XSelectedSheetsSupplier*>(this),
493
0
                    static_cast<datatransfer::XTransferableSupplier*>(this));
494
0
    if ( aReturn.hasValue() )
495
0
        return aReturn;
496
497
0
    uno::Any aRet(ScViewPaneBase::queryInterface( rType ));
498
0
    if (!aRet.hasValue())
499
0
        aRet = SfxBaseController::queryInterface( rType );
500
0
    return aRet;
501
0
}
502
503
void SAL_CALL ScTabViewObj::acquire() noexcept
504
0
{
505
0
    SfxBaseController::acquire();
506
0
}
507
508
void SAL_CALL ScTabViewObj::release() noexcept
509
0
{
510
0
    SfxBaseController::release();
511
0
}
512
513
static void lcl_CallActivate( ScDocShell* pDocSh, SCTAB nTab, ScSheetEventId nEvent )
514
0
{
515
0
    ScDocument& rDoc = pDocSh->GetDocument();
516
    // when deleting a sheet, nPreviousTab can be invalid
517
    // (could be handled with reference updates)
518
0
    if (!rDoc.HasTable(nTab))
519
0
        return;
520
521
0
    const ScSheetEvents* pEvents = rDoc.GetSheetEvents(nTab);
522
0
    if (pEvents)
523
0
    {
524
0
        const OUString* pScript = pEvents->GetScript(nEvent);
525
0
        if (pScript)
526
0
        {
527
0
            uno::Any aRet;
528
0
            uno::Sequence<uno::Any> aParams;
529
0
            uno::Sequence<sal_Int16> aOutArgsIndex;
530
0
            uno::Sequence<uno::Any> aOutArgs;
531
0
            /*ErrCode eRet =*/ pDocSh->CallXScript( *pScript, aParams, aRet, aOutArgsIndex, aOutArgs );
532
0
        }
533
0
    }
534
535
    // execute VBA event handlers
536
0
    try
537
0
    {
538
0
        uno::Reference< script::vba::XVBAEventProcessor > xVbaEvents( rDoc.GetVbaEventProcessor(), uno::UNO_SET_THROW );
539
        // the parameter is the clicked object, as in the mousePressed call above
540
0
        uno::Sequence< uno::Any > aArgs{ uno::Any(nTab) };
541
0
        xVbaEvents->processVbaEvent( ScSheetEvents::GetVbaSheetEventId( nEvent ), aArgs );
542
0
    }
543
0
    catch( uno::Exception& )
544
0
    {
545
0
    }
546
0
}
547
548
void ScTabViewObj::SheetChanged( bool bSameTabButMoved )
549
0
{
550
0
    if ( !GetViewShell() )
551
0
        return;
552
553
0
    ScViewData& rViewData = GetViewShell()->GetViewData();
554
0
    ScDocShell* pDocSh = rViewData.GetDocShell();
555
0
    if (!aActivationListeners.empty())
556
0
    {
557
0
        sheet::ActivationEvent aEvent;
558
0
        uno::Reference< sheet::XSpreadsheetView > xView(this);
559
0
        aEvent.Source.set(xView, uno::UNO_QUERY);
560
0
        aEvent.ActiveSheet = new ScTableSheetObj(pDocSh, rViewData.CurrentTabForData());
561
        // Listener's handler may remove it from the listeners list
562
0
        for (size_t i = aActivationListeners.size(); i > 0; --i)
563
0
        {
564
0
            try
565
0
            {
566
0
                aActivationListeners[i - 1]->activeSpreadsheetChanged( aEvent );
567
0
            }
568
0
            catch( uno::Exception& )
569
0
            {
570
0
                aActivationListeners.erase(aActivationListeners.begin() + (i - 1));
571
0
            }
572
0
        }
573
0
    }
574
575
    /*  Handle sheet events, but do not trigger event handlers, if the old
576
        active sheet gets re-activated after inserting/deleting/moving a sheet. */
577
0
    SCTAB nNewTab = rViewData.CurrentTabForData();
578
0
    if ( !bSameTabButMoved && (nNewTab != nPreviousTab) )
579
0
    {
580
0
        lcl_CallActivate( pDocSh, nPreviousTab, ScSheetEventId::UNFOCUS );
581
0
        lcl_CallActivate( pDocSh, nNewTab, ScSheetEventId::FOCUS );
582
0
    }
583
0
    nPreviousTab = nNewTab;
584
0
}
585
586
uno::Sequence<uno::Type> SAL_CALL ScTabViewObj::getTypes()
587
0
{
588
0
    return comphelper::concatSequences(
589
0
        ScViewPaneBase::getTypes(),
590
0
        SfxBaseController::getTypes(),
591
0
        uno::Sequence<uno::Type>
592
0
        {
593
0
            cppu::UnoType<sheet::XSpreadsheetView>::get(),
594
0
            cppu::UnoType<container::XEnumerationAccess>::get(),
595
0
            cppu::UnoType<container::XIndexAccess>::get(),
596
0
            cppu::UnoType<view::XSelectionSupplier>::get(),
597
0
            cppu::UnoType<beans::XPropertySet>::get(),
598
0
            cppu::UnoType<sheet::XViewSplitable>::get(),
599
0
            cppu::UnoType<sheet::XViewFreezable>::get(),
600
0
            cppu::UnoType<sheet::XRangeSelection>::get(),
601
0
            cppu::UnoType<sheet::XSheetRange>::get(),
602
0
            cppu::UnoType<lang::XUnoTunnel>::get(),
603
0
            cppu::UnoType<sheet::XEnhancedMouseClickBroadcaster>::get(),
604
0
            cppu::UnoType<sheet::XActivationBroadcaster>::get(),
605
0
            cppu::UnoType<datatransfer::XTransferableSupplier>::get()
606
0
        } );
607
0
}
608
609
uno::Sequence<sal_Int8> SAL_CALL ScTabViewObj::getImplementationId()
610
0
{
611
0
    return css::uno::Sequence<sal_Int8>();
612
0
}
613
614
// XDocumentView
615
616
static bool lcl_TabInRanges( SCTAB nTab, const ScRangeList& rRanges )
617
0
{
618
0
    for (size_t i = 0, nCount = rRanges.size(); i < nCount; ++i)
619
0
    {
620
0
        const ScRange & rRange = rRanges[ i ];
621
0
        if ( nTab >= rRange.aStart.Tab() && nTab <= rRange.aEnd.Tab() )
622
0
            return true;
623
0
    }
624
0
    return false;
625
0
}
626
627
static void lcl_ShowObject( ScTabViewShell& rViewSh, const ScDrawView& rDrawView, const SdrObject* pSelObj )
628
0
{
629
0
    bool bFound = false;
630
0
    SCTAB nObjectTab = 0;
631
632
0
    SdrModel& rModel = rDrawView.GetModel();
633
0
    sal_uInt16 nPageCount = rModel.GetPageCount();
634
0
    for (sal_uInt16 i=0; i<nPageCount && !bFound; i++)
635
0
    {
636
0
        SdrPage* pPage = rModel.GetPage(i);
637
0
        if (pPage)
638
0
        {
639
0
            SdrObjListIter aIter( pPage, SdrIterMode::DeepWithGroups );
640
0
            SdrObject* pObject = aIter.Next();
641
0
            while (pObject && !bFound)
642
0
            {
643
0
                if ( pObject == pSelObj )
644
0
                {
645
0
                    bFound = true;
646
0
                    nObjectTab = static_cast<SCTAB>(i);
647
0
                }
648
0
                pObject = aIter.Next();
649
0
            }
650
0
        }
651
0
    }
652
653
0
    if (bFound)
654
0
    {
655
0
        rViewSh.SetTabNo( nObjectTab );
656
0
        rViewSh.ScrollToObject( pSelObj );
657
0
    }
658
0
}
659
660
sal_Bool SAL_CALL ScTabViewObj::select( const uno::Any& aSelection )
661
0
{
662
0
    SolarMutexGuard aGuard;
663
0
    ScTabViewShell* pViewSh = GetViewShell();
664
665
0
    if ( !pViewSh )
666
0
        return false;
667
668
    //! Type of aSelection can be some specific interface instead of XInterface
669
670
0
    bool bRet = false;
671
0
    uno::Reference<uno::XInterface> xInterface(aSelection, uno::UNO_QUERY);
672
0
    if ( !xInterface.is() )  //clear all selections
673
0
    {
674
0
        ScDrawView* pDrawView = pViewSh->GetScDrawView();
675
0
        if (pDrawView)
676
0
        {
677
0
            pDrawView->ScEndTextEdit();
678
0
            pDrawView->UnmarkAll();
679
0
        }
680
0
        else //#102232#; if there is  no DrawView remove range selection
681
0
            pViewSh->Unmark();
682
0
        bRet = true;
683
0
    }
684
685
0
    if (bDrawSelModeSet) // remove DrawSelMode if set by API; if necessary it will be set again later
686
0
    {
687
0
        pViewSh->SetDrawSelMode(false);
688
0
        pViewSh->UpdateLayerLocks();
689
0
        bDrawSelModeSet = false;
690
0
    }
691
692
0
    if (bRet)
693
0
        return bRet;
694
695
0
    ScCellRangesBase* pRangesImp = dynamic_cast<ScCellRangesBase*>( xInterface.get() );
696
0
    uno::Reference<drawing::XShapes> xShapeColl( xInterface, uno::UNO_QUERY );
697
0
    uno::Reference<drawing::XShape> xShapeSel( xInterface, uno::UNO_QUERY );
698
0
    SvxShape* pShapeImp = comphelper::getFromUnoTunnel<SvxShape>( xShapeSel );
699
700
0
    if (pRangesImp)                                     // Cell ranges
701
0
    {
702
0
        ScViewData& rViewData = pViewSh->GetViewData();
703
0
        if ( rViewData.GetDocShell() == pRangesImp->GetDocShell() )
704
0
        {
705
            //  perhaps remove drawing selection first
706
            //  (MarkListHasChanged removes sheet selection)
707
708
0
            ScDrawView* pDrawView = pViewSh->GetScDrawView();
709
0
            if (pDrawView)
710
0
            {
711
0
                pDrawView->ScEndTextEdit();
712
0
                pDrawView->UnmarkAll();
713
0
            }
714
0
            FuPoor* pFunc = pViewSh->GetDrawFuncPtr();
715
0
            if ( pFunc && pFunc->GetSlotID() != SID_OBJECT_SELECT )
716
0
            {
717
                //  execute the slot of drawing function again -> switch off
718
0
                SfxDispatcher* pDisp = pViewSh->GetDispatcher();
719
0
                if (pDisp)
720
0
                    pDisp->Execute( pFunc->GetSlotID(), SfxCallMode::SYNCHRON );
721
0
            }
722
0
            pViewSh->SetDrawShell(false);
723
0
            pViewSh->SetDrawSelMode(false); // after Dispatcher-Execute
724
725
            //  select ranges
726
727
0
            const ScRangeList& rRanges = pRangesImp->GetRangeList();
728
0
            size_t nRangeCount = rRanges.size();
729
            // for empty range list, remove selection (cursor remains where it was)
730
0
            if ( nRangeCount == 0 )
731
0
                pViewSh->Unmark();
732
0
            else if ( nRangeCount == 1 )
733
0
                pViewSh->MarkRange( rRanges[ 0 ] );
734
0
            else
735
0
            {
736
                // multiselection
737
738
0
                const ScRange & rFirst = rRanges[ 0 ];
739
0
                if ( !lcl_TabInRanges( rViewData.CurrentTabForData(), rRanges ) )
740
0
                    pViewSh->SetTabNo( rFirst.aStart.Tab() );
741
0
                pViewSh->DoneBlockMode();
742
0
                pViewSh->InitOwnBlockMode( rFirst );    /* TODO: or even the overall range? */
743
0
                rViewData.GetMarkData().MarkFromRangeList( rRanges, true );
744
0
                pViewSh->MarkDataChanged();
745
0
                rViewData.GetDocShell()->PostPaintGridAll();   // Marks (old&new)
746
0
                pViewSh->AlignToCursor( rFirst.aStart.Col(), rFirst.aStart.Row(),
747
0
                                            SC_FOLLOW_JUMP );
748
0
                pViewSh->SetCursor( rFirst.aStart.Col(), rFirst.aStart.Row() );
749
750
                //! method of the view to select RangeList
751
0
            }
752
0
            bRet = true;
753
0
        }
754
0
    }
755
0
    else if ( pShapeImp || xShapeColl.is() )            // Drawing-Layer
756
0
    {
757
0
        ScDrawView* pDrawView = pViewSh->GetScDrawView();
758
0
        if (pDrawView)
759
0
        {
760
0
            pDrawView->ScEndTextEdit();
761
0
            pDrawView->UnmarkAll();
762
763
0
            if (pShapeImp)      // single shape
764
0
            {
765
0
                SdrObject *pObj = pShapeImp->GetSdrObject();
766
0
                if (pObj)
767
0
                {
768
0
                    lcl_ShowObject( *pViewSh, *pDrawView, pObj );
769
0
                    SdrPageView* pPV = pDrawView->GetSdrPageView();
770
0
                    if ( pPV && pObj->getSdrPageFromSdrObject() == pPV->GetPage() )
771
0
                    {
772
0
                        pDrawView->MarkObj( pObj, pPV );
773
0
                        bRet = true;
774
0
                    }
775
0
                }
776
0
            }
777
0
            else                // Shape-Collection (xShapeColl is not 0)
778
0
            {
779
                //  We'll switch to the sheet where the first object is
780
                //  and select all objects on that sheet
781
                //!?throw exception when objects are on different sheets?
782
783
0
                tools::Long nCount = xShapeColl->getCount();
784
0
                if (nCount)
785
0
                {
786
0
                    SdrPageView* pPV = nullptr;
787
0
                    bool bAllMarked(true);
788
0
                    for ( tools::Long i = 0; i < nCount; i++ )
789
0
                    {
790
0
                        uno::Reference<drawing::XShape> xShapeInt(xShapeColl->getByIndex(i), uno::UNO_QUERY);
791
0
                        if (xShapeInt.is())
792
0
                        {
793
0
                            SdrObject* pObj = SdrObject::getSdrObjectFromXShape( xShapeInt );
794
0
                            if (pObj)
795
0
                            {
796
0
                                if (!bDrawSelModeSet && (pObj->GetLayer() == SC_LAYER_BACK))
797
0
                                {
798
0
                                    pViewSh->SetDrawSelMode(true);
799
0
                                    pViewSh->UpdateLayerLocks();
800
0
                                    bDrawSelModeSet = true;
801
0
                                }
802
0
                                if (!pPV)               // first object
803
0
                                {
804
0
                                    lcl_ShowObject( *pViewSh, *pDrawView, pObj );
805
0
                                    pPV = pDrawView->GetSdrPageView();
806
0
                                }
807
0
                                if ( pPV && pObj->getSdrPageFromSdrObject() == pPV->GetPage() )
808
0
                                {
809
0
                                    if (pDrawView->IsObjMarkable( pObj, pPV ))
810
0
                                        pDrawView->MarkObj( pObj, pPV );
811
0
                                    else
812
0
                                        bAllMarked = false;
813
0
                                }
814
0
                            }
815
0
                        }
816
0
                    }
817
0
                    if (bAllMarked)
818
0
                        bRet = true;
819
0
                }
820
0
                else
821
0
                    bRet = true; // empty XShapes (all shapes are deselected)
822
0
            }
823
824
0
            if (bRet)
825
0
                pViewSh->SetDrawShell(true);
826
0
        }
827
0
    }
828
829
0
    if (!bRet)
830
0
        throw lang::IllegalArgumentException();
831
832
0
    return bRet;
833
0
}
834
835
uno::Reference<drawing::XShapes> ScTabViewShell::getSelectedXShapes()
836
0
{
837
0
    uno::Reference<drawing::XShapes> xShapes;
838
0
    SdrView* pSdrView = GetScDrawView();
839
0
    if (pSdrView)
840
0
    {
841
0
        const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList();
842
0
        const size_t nMarkCount = rMarkList.GetMarkCount();
843
0
        if (nMarkCount)
844
0
        {
845
            //  generate ShapeCollection (like in SdXImpressView::getSelection in Draw)
846
            //  XInterfaceRef will be returned and it has to be UsrObject-XInterface
847
0
            xShapes = drawing::ShapeCollection::create(comphelper::getProcessComponentContext());
848
849
0
            for (size_t i = 0; i < nMarkCount; ++i)
850
0
            {
851
0
                SdrObject* pDrawObj = rMarkList.GetMark(i)->GetMarkedSdrObj();
852
0
                if (pDrawObj)
853
0
                {
854
0
                    uno::Reference<drawing::XShape> xShape( pDrawObj->getUnoShape(), uno::UNO_QUERY );
855
0
                    if (xShape.is())
856
0
                        xShapes->add(xShape);
857
0
                }
858
0
            }
859
0
        }
860
0
    }
861
0
    return xShapes;
862
0
}
863
864
uno::Any SAL_CALL ScTabViewObj::getSelection()
865
0
{
866
0
    SolarMutexGuard aGuard;
867
0
    ScTabViewShell* pViewSh = GetViewShell();
868
0
    rtl::Reference<ScCellRangesBase> pObj;
869
0
    if (pViewSh)
870
0
    {
871
        //  is something selected in drawing layer?
872
0
        uno::Reference<uno::XInterface> xRet(pViewSh->getSelectedXShapes());
873
0
        if (xRet.is())
874
0
            return uno::Any(xRet);
875
876
        //  otherwise sheet (cell) selection
877
878
0
        ScViewData& rViewData = pViewSh->GetViewData();
879
0
        ScDocShell* pDocSh = rViewData.GetDocShell();
880
881
0
        const ScMarkData& rMark = rViewData.GetMarkData();
882
0
        SCTAB nTabs = rMark.GetSelectCount();
883
884
0
        ScRange aRange;
885
0
        ScMarkType eMarkType = rViewData.GetSimpleArea(aRange);
886
0
        if ( nTabs == 1 && (eMarkType == SC_MARK_SIMPLE) )
887
0
        {
888
            // tdf#154803 - check if range is entirely merged
889
0
            ScDocument& rDoc = pDocSh->GetDocument();
890
0
            const ScMergeAttr& rMergeAttr = rDoc.GetAttr(aRange.aStart, ATTR_MERGE);
891
0
            SCCOL nColSpan = 1;
892
0
            SCROW nRowSpan = 1;
893
0
            if (rMergeAttr.IsMerged())
894
0
            {
895
0
                nColSpan = rMergeAttr.GetColMerge();
896
0
                nRowSpan = rMergeAttr.GetRowMerge();
897
0
            }
898
            // tdf#147122 - return cell object when a simple selection is entirely merged
899
0
            if (aRange.aStart == aRange.aEnd
900
0
                || (aRange.aEnd.Col() - aRange.aStart.Col() == nColSpan - 1
901
0
                    && aRange.aEnd.Row() - aRange.aStart.Row() == nRowSpan - 1))
902
0
                pObj = new ScCellObj( pDocSh, aRange.aStart );
903
0
            else
904
0
                pObj = new ScCellRangeObj( pDocSh, aRange );
905
0
        }
906
0
        else if ( nTabs == 1 && (eMarkType == SC_MARK_SIMPLE_FILTERED) )
907
0
        {
908
0
            ScMarkData aFilteredMark( rMark );
909
0
            ScViewUtil::UnmarkFiltered( aFilteredMark, pDocSh->GetDocument());
910
0
            ScRangeList aRangeList;
911
0
            aFilteredMark.FillRangeListWithMarks( &aRangeList, false);
912
            // Theoretically a selection may start and end on a filtered row.
913
0
            switch ( aRangeList.size() )
914
0
            {
915
0
                case 0:
916
                    // No unfiltered row, we have to return some object, so
917
                    // here is one with no ranges.
918
0
                    pObj = new ScCellRangesObj( pDocSh, aRangeList );
919
0
                    break;
920
0
                case 1:
921
0
                    {
922
0
                        const ScRange& rRange = aRangeList[ 0 ];
923
0
                        if (rRange.aStart == rRange.aEnd)
924
0
                            pObj = new ScCellObj( pDocSh, rRange.aStart );
925
0
                        else
926
0
                            pObj = new ScCellRangeObj( pDocSh, rRange );
927
0
                    }
928
0
                    break;
929
0
                default:
930
0
                    pObj = new ScCellRangesObj( pDocSh, aRangeList );
931
0
            }
932
0
        }
933
0
        else            //  multiselection
934
0
        {
935
0
            ScRangeListRef xRanges;
936
0
            rViewData.GetMultiArea( xRanges );
937
938
            //  if there are more sheets, copy ranges
939
            //! should this happen in ScMarkData::FillRangeListWithMarks already?
940
0
            if ( nTabs > 1 )
941
0
                rMark.ExtendRangeListTables( xRanges.get() );
942
943
0
            pObj = new ScCellRangesObj( pDocSh, *xRanges );
944
0
        }
945
946
0
        if ( !rMark.IsMarked() && !rMark.IsMultiMarked() )
947
0
        {
948
            //  remember if the selection was from the cursor position without anything selected
949
            //  (used when rendering the selection)
950
951
0
            pObj->SetCursorOnly( true );
952
0
        }
953
0
    }
954
955
0
    return uno::Any(uno::Reference(cppu::getXWeak(pObj.get())));
956
0
}
957
958
uno::Any SAL_CALL ScTabViewObj::getSelectionFromString( const OUString& aStrRange )
959
0
{
960
0
    ScDocShell* pDocSh = GetViewShell()->GetViewData().GetDocShell();
961
0
    const sal_Int16 nTabCount = pDocSh->GetDocument().GetTableCount();
962
963
0
    StringRangeEnumerator aRangeEnum(aStrRange , 0, nTabCount-1);
964
965
    // iterate through sheet range
966
967
0
    StringRangeEnumerator::Iterator aIter = aRangeEnum.begin();
968
0
    StringRangeEnumerator::Iterator aEnd  = aRangeEnum.end();
969
970
0
    ScRangeListRef aRangeList = new ScRangeList;
971
972
0
    while ( aIter != aEnd )
973
0
    {
974
0
        ScRange currentTab(SCCOL(0), SCROW(0), SCTAB(*aIter));
975
0
        aRangeList->push_back(currentTab);
976
0
        ++aIter;
977
0
    }
978
979
0
    rtl::Reference<ScCellRangesBase> pObj = new ScCellRangesObj(pDocSh, *aRangeList);
980
981
    // SetCursorOnly tells the range the specific cells selected are irrelevant - maybe could rename?
982
0
    pObj->SetCursorOnly(true);
983
984
0
    return uno::Any(uno::Reference<uno::XInterface>(static_cast<cppu::OWeakObject*>(pObj.get())));
985
0
}
986
987
// XEnumerationAccess
988
989
uno::Reference<container::XEnumeration> SAL_CALL ScTabViewObj::createEnumeration()
990
0
{
991
0
    SolarMutexGuard aGuard;
992
0
    return new ScIndexEnumeration(this, u"com.sun.star.sheet.SpreadsheetViewPanesEnumeration"_ustr);
993
0
}
994
995
// XIndexAccess
996
997
sal_Int32 SAL_CALL ScTabViewObj::getCount()
998
0
{
999
0
    SolarMutexGuard aGuard;
1000
0
    ScTabViewShell* pViewSh = GetViewShell();
1001
0
    sal_uInt16 nPanes = 0;
1002
0
    if (pViewSh)
1003
0
    {
1004
0
        nPanes = 1;
1005
0
        ScViewData& rViewData = pViewSh->GetViewData();
1006
0
        if ( rViewData.GetHSplitMode() != SC_SPLIT_NONE )
1007
0
            nPanes *= 2;
1008
0
        if ( rViewData.GetVSplitMode() != SC_SPLIT_NONE )
1009
0
            nPanes *= 2;
1010
0
    }
1011
0
    return nPanes;
1012
0
}
1013
1014
uno::Any SAL_CALL ScTabViewObj::getByIndex( sal_Int32 nIndex )
1015
0
{
1016
0
    SolarMutexGuard aGuard;
1017
0
    rtl::Reference<ScViewPaneObj> xPane(GetObjectByIndex_Impl(static_cast<sal_uInt16>(nIndex)));
1018
0
    if (!xPane.is())
1019
0
        throw lang::IndexOutOfBoundsException();
1020
1021
0
    return uno::Any(uno::Reference<sheet::XViewPane>(xPane));
1022
0
}
1023
1024
uno::Type SAL_CALL ScTabViewObj::getElementType()
1025
0
{
1026
0
    return cppu::UnoType<sheet::XViewPane>::get();
1027
0
}
1028
1029
sal_Bool SAL_CALL ScTabViewObj::hasElements()
1030
0
{
1031
0
    SolarMutexGuard aGuard;
1032
0
    return ( getCount() != 0 );
1033
0
}
1034
1035
// XSpreadsheetView
1036
1037
rtl::Reference<ScViewPaneObj> ScTabViewObj::GetObjectByIndex_Impl(sal_uInt16 nIndex) const
1038
0
{
1039
0
    static const ScSplitPos ePosHV[4] =
1040
0
        { SC_SPLIT_TOPLEFT, SC_SPLIT_BOTTOMLEFT, SC_SPLIT_TOPRIGHT, SC_SPLIT_BOTTOMRIGHT };
1041
1042
0
    ScTabViewShell* pViewSh = GetViewShell();
1043
0
    if (pViewSh)
1044
0
    {
1045
0
        ScSplitPos eWhich = SC_SPLIT_BOTTOMLEFT;    // default position
1046
0
        bool bError = false;
1047
0
        ScViewData& rViewData = pViewSh->GetViewData();
1048
0
        bool bHor = ( rViewData.GetHSplitMode() != SC_SPLIT_NONE );
1049
0
        bool bVer = ( rViewData.GetVSplitMode() != SC_SPLIT_NONE );
1050
0
        if ( bHor && bVer )
1051
0
        {
1052
            //  bottom left, bottom right, top left, top right - like in Excel
1053
0
            if ( nIndex < 4 )
1054
0
                eWhich = ePosHV[nIndex];
1055
0
            else
1056
0
                bError = true;
1057
0
        }
1058
0
        else if ( bHor )
1059
0
        {
1060
0
            if ( nIndex > 1 )
1061
0
                bError = true;
1062
0
            else if ( nIndex == 1 )
1063
0
                eWhich = SC_SPLIT_BOTTOMRIGHT;
1064
            // otherwise SC_SPLIT_BOTTOMLEFT
1065
0
        }
1066
0
        else if ( bVer )
1067
0
        {
1068
0
            if ( nIndex > 1 )
1069
0
                bError = true;
1070
0
            else if ( nIndex == 0 )
1071
0
                eWhich = SC_SPLIT_TOPLEFT;
1072
            // otherwise SC_SPLIT_BOTTOMLEFT
1073
0
        }
1074
0
        else if ( nIndex > 0 )
1075
0
            bError = true;          // not split: only 0 is valid
1076
1077
0
        if (!bError)
1078
0
            return new ScViewPaneObj( pViewSh, sal::static_int_cast<sal_uInt16>(eWhich) );
1079
0
    }
1080
1081
0
    return nullptr;
1082
0
}
1083
1084
uno::Reference<sheet::XSpreadsheet> SAL_CALL ScTabViewObj::getActiveSheet()
1085
0
{
1086
0
    return getActiveScSheet();
1087
0
}
1088
1089
rtl::Reference<ScTableSheetObj> ScTabViewObj::getActiveScSheet()
1090
0
{
1091
0
    SolarMutexGuard aGuard;
1092
0
    ScTabViewShell* pViewSh = GetViewShell();
1093
0
    if (pViewSh)
1094
0
    {
1095
0
        ScViewData& rViewData = pViewSh->GetViewData();
1096
0
        SCTAB nTab = rViewData.CurrentTabForData();
1097
0
        return new ScTableSheetObj( rViewData.GetDocShell(), nTab );
1098
0
    }
1099
0
    return nullptr;
1100
0
}
1101
1102
// support expand (but not replace) the active sheet
1103
void SAL_CALL ScTabViewObj::setActiveSheet( const uno::Reference<sheet::XSpreadsheet>& xActiveSheet )
1104
0
{
1105
0
    SolarMutexGuard aGuard;
1106
0
    comphelper::ProfileZone aZone("setActiveSheet");
1107
1108
0
    ScTabViewShell* pViewSh = GetViewShell();
1109
0
    if ( !(pViewSh && xActiveSheet.is()) )
1110
0
        return;
1111
1112
    //  XSpreadsheet and ScCellRangesBase -> has to be the same sheet
1113
1114
0
    ScCellRangesBase* pRangesImp = dynamic_cast<ScCellRangesBase*>( xActiveSheet.get() );
1115
0
    if ( pRangesImp && pViewSh->GetViewData().GetDocShell() == pRangesImp->GetDocShell() )
1116
0
    {
1117
0
        const ScRangeList& rRanges = pRangesImp->GetRangeList();
1118
0
        if ( rRanges.size() == 1 )
1119
0
        {
1120
0
            SCTAB nNewTab = rRanges[ 0 ].aStart.Tab();
1121
0
            if ( pViewSh->GetViewData().GetDocument().HasTable(nNewTab) )
1122
0
                pViewSh->SetTabNo( nNewTab );
1123
0
        }
1124
0
    }
1125
0
}
1126
1127
uno::Reference< uno::XInterface > ScTabViewObj::GetClickedObject(const Point& rPoint) const
1128
0
{
1129
0
    uno::Reference< uno::XInterface > xTarget;
1130
0
    if (GetViewShell())
1131
0
    {
1132
0
        SCCOL nX;
1133
0
        SCROW nY;
1134
0
        ScViewData& rData = GetViewShell()->GetViewData();
1135
0
        ScSplitPos eSplitMode = rData.GetActivePart();
1136
0
        SCTAB nTab(rData.CurrentTabForData());
1137
0
        rData.GetPosFromPixel( rPoint.X(), rPoint.Y(), eSplitMode, nX, nY);
1138
1139
0
        ScAddress aCellPos (nX, nY, nTab);
1140
0
        rtl::Reference<ScCellObj> pCellObj = new ScCellObj(rData.GetDocShell(), aCellPos);
1141
1142
0
        xTarget.set(uno::Reference<table::XCell>(pCellObj), uno::UNO_QUERY);
1143
1144
0
        ScDocument& rDoc = rData.GetDocument();
1145
0
        if (ScDrawLayer* pDrawLayer = rDoc.GetDrawLayer())
1146
0
        {
1147
0
            SdrPage* pDrawPage = nullptr;
1148
0
            if (pDrawLayer->HasObjects() && (pDrawLayer->GetPageCount() > nTab))
1149
0
                pDrawPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nTab));
1150
1151
0
            SdrView* pDrawView = GetViewShell()->GetScDrawView();
1152
1153
0
            if (pDrawPage && pDrawView && pDrawView->GetSdrPageView())
1154
0
            {
1155
0
                vcl::Window* pActiveWin = rData.GetActiveWin();
1156
0
                Point aPos = pActiveWin->PixelToLogic(rPoint);
1157
1158
0
                double fHitLog = pActiveWin->PixelToLogic(Size(pDrawView->GetHitTolerancePixel(),0)).Width();
1159
1160
0
                for (const rtl::Reference<SdrObject>& pObj : *pDrawPage)
1161
0
                {
1162
0
                    if (SdrObjectPrimitiveHit(*pObj, aPos, {fHitLog, fHitLog}, *pDrawView->GetSdrPageView(), nullptr, false))
1163
0
                    {
1164
0
                        xTarget.set(pObj->getUnoShape(), uno::UNO_QUERY);
1165
0
                        break;
1166
0
                    }
1167
0
                }
1168
0
            }
1169
0
        }
1170
0
    }
1171
0
    return xTarget;
1172
0
}
1173
1174
bool ScTabViewObj::IsMouseListening() const
1175
0
{
1176
0
    if ( !aMouseClickHandlers.empty() )
1177
0
        return true;
1178
1179
    // also include sheet events, because MousePressed must be called for them
1180
0
    ScViewData& rViewData = GetViewShell()->GetViewData();
1181
0
    ScDocument& rDoc = rViewData.GetDocument();
1182
0
    SCTAB nTab = rViewData.CurrentTabForData();
1183
0
    return
1184
0
        rDoc.HasSheetEventScript( nTab, ScSheetEventId::RIGHTCLICK, true ) ||
1185
0
        rDoc.HasSheetEventScript( nTab, ScSheetEventId::DOUBLECLICK, true ) ||
1186
0
        rDoc.HasSheetEventScript( nTab, ScSheetEventId::SELECT, true );
1187
1188
0
}
1189
1190
bool ScTabViewObj::MousePressed( const awt::MouseEvent& e )
1191
0
{
1192
0
    bool bReturn(false);
1193
0
    if ( e.Buttons == css::awt::MouseButton::LEFT )
1194
0
        mbLeftMousePressed = true;
1195
1196
0
    uno::Reference< uno::XInterface > xTarget = GetClickedObject(Point(e.X, e.Y));
1197
0
    if (!aMouseClickHandlers.empty() && xTarget.is())
1198
0
    {
1199
0
        awt::EnhancedMouseEvent aMouseEvent;
1200
1201
0
        aMouseEvent.Buttons = e.Buttons;
1202
0
        aMouseEvent.X = e.X;
1203
0
        aMouseEvent.Y = e.Y;
1204
0
        aMouseEvent.ClickCount = e.ClickCount;
1205
0
        aMouseEvent.PopupTrigger = e.PopupTrigger;
1206
0
        aMouseEvent.Target = xTarget;
1207
0
        aMouseEvent.Modifiers = e.Modifiers;
1208
1209
        // Listener's handler may remove it from the listeners list
1210
0
        for (size_t i = aMouseClickHandlers.size(); i > 0; --i)
1211
0
        {
1212
0
            try
1213
0
            {
1214
0
                if (!aMouseClickHandlers[i - 1]->mousePressed(aMouseEvent))
1215
0
                    bReturn = true;
1216
0
            }
1217
0
            catch ( uno::Exception& )
1218
0
            {
1219
0
                aMouseClickHandlers.erase(aMouseClickHandlers.begin() + (i - 1));
1220
0
            }
1221
0
        }
1222
0
    }
1223
1224
    // handle sheet events
1225
0
    bool bDoubleClick = ( e.Buttons == awt::MouseButton::LEFT && e.ClickCount == 2 );
1226
0
    bool bRightClick = ( e.Buttons == awt::MouseButton::RIGHT && e.ClickCount == 1 );
1227
0
    if ( ( bDoubleClick || bRightClick ) && !bReturn && xTarget.is())
1228
0
    {
1229
0
        ScSheetEventId nEvent = bDoubleClick ? ScSheetEventId::DOUBLECLICK : ScSheetEventId::RIGHTCLICK;
1230
1231
0
        ScTabViewShell* pViewSh = GetViewShell();
1232
0
        ScViewData& rViewData = pViewSh->GetViewData();
1233
0
        ScDocShell* pDocSh = rViewData.GetDocShell();
1234
0
        ScDocument& rDoc = pDocSh->GetDocument();
1235
0
        SCTAB nTab = rViewData.CurrentTabForData();
1236
0
        const ScSheetEvents* pEvents = rDoc.GetSheetEvents(nTab);
1237
0
        if (pEvents)
1238
0
        {
1239
0
            const OUString* pScript = pEvents->GetScript(nEvent);
1240
0
            if (pScript)
1241
0
            {
1242
                // the macro parameter is the clicked object, as in the mousePressed call above
1243
0
                uno::Sequence<uno::Any> aParams{ uno::Any(xTarget) };
1244
1245
0
                uno::Any aRet;
1246
0
                uno::Sequence<sal_Int16> aOutArgsIndex;
1247
0
                uno::Sequence<uno::Any> aOutArgs;
1248
1249
                /*ErrCode eRet =*/ pDocSh->CallXScript( *pScript, aParams, aRet, aOutArgsIndex, aOutArgs );
1250
1251
                // look for a boolean return value of true
1252
0
                bool bRetValue = false;
1253
0
                if ((aRet >>= bRetValue) && bRetValue)
1254
0
                    bReturn = true;
1255
0
            }
1256
0
        }
1257
1258
        // execute VBA event handler
1259
0
        if (!bReturn && xTarget.is()) try
1260
0
        {
1261
0
            uno::Reference< script::vba::XVBAEventProcessor > xVbaEvents( rDoc.GetVbaEventProcessor(), uno::UNO_SET_THROW );
1262
            // the parameter is the clicked object, as in the mousePressed call above
1263
0
            uno::Sequence< uno::Any > aArgs{ uno::Any(xTarget) };
1264
0
            xVbaEvents->processVbaEvent( ScSheetEvents::GetVbaSheetEventId( nEvent ), aArgs );
1265
0
        }
1266
0
        catch( util::VetoException& )
1267
0
        {
1268
0
            bReturn = true;
1269
0
        }
1270
0
        catch( uno::Exception& )
1271
0
        {
1272
0
        }
1273
0
    }
1274
1275
0
    return bReturn;
1276
0
}
1277
1278
bool ScTabViewObj::MouseReleased( const awt::MouseEvent& e )
1279
0
{
1280
0
    if ( e.Buttons == css::awt::MouseButton::LEFT )
1281
0
    {
1282
0
        try
1283
0
        {
1284
0
            ScTabViewShell* pViewSh = GetViewShell();
1285
0
            ScViewData& rViewData = pViewSh->GetViewData();
1286
0
            ScDocShell* pDocSh = rViewData.GetDocShell();
1287
0
            ScDocument& rDoc = pDocSh->GetDocument();
1288
0
            uno::Reference< script::vba::XVBAEventProcessor > xVbaEvents( rDoc.GetVbaEventProcessor(), uno::UNO_SET_THROW );
1289
0
            uno::Sequence< uno::Any > aArgs{ getSelection() };
1290
0
            xVbaEvents->processVbaEvent( ScSheetEvents::GetVbaSheetEventId( ScSheetEventId::SELECT ), aArgs );
1291
0
        }
1292
0
        catch( uno::Exception& )
1293
0
        {
1294
0
        }
1295
0
        mbLeftMousePressed = false;
1296
0
    }
1297
1298
0
    bool bReturn(false);
1299
1300
0
    if (!aMouseClickHandlers.empty())
1301
0
    {
1302
0
        uno::Reference< uno::XInterface > xTarget = GetClickedObject(Point(e.X, e.Y));
1303
1304
0
        if (xTarget.is())
1305
0
        {
1306
0
            awt::EnhancedMouseEvent aMouseEvent;
1307
1308
0
            aMouseEvent.Buttons = e.Buttons;
1309
0
            aMouseEvent.X = e.X;
1310
0
            aMouseEvent.Y = e.Y;
1311
0
            aMouseEvent.ClickCount = e.ClickCount;
1312
0
            aMouseEvent.PopupTrigger = e.PopupTrigger;
1313
0
            aMouseEvent.Target = std::move(xTarget);
1314
0
            aMouseEvent.Modifiers = e.Modifiers;
1315
1316
            // Listener's handler may remove it from the listeners list
1317
0
            for (size_t i = aMouseClickHandlers.size(); i > 0; --i)
1318
0
            {
1319
0
                try
1320
0
                {
1321
0
                    if (!aMouseClickHandlers[i - 1]->mouseReleased( aMouseEvent ))
1322
0
                        bReturn = true;
1323
0
                }
1324
0
                catch ( uno::Exception& )
1325
0
                {
1326
0
                    aMouseClickHandlers.erase(aMouseClickHandlers.begin() + (i - 1));
1327
0
                }
1328
0
            }
1329
0
        }
1330
0
    }
1331
0
    return bReturn;
1332
0
}
1333
1334
// XEnhancedMouseClickBroadcaster
1335
1336
void ScTabViewObj::EndMouseListening()
1337
0
{
1338
0
    lang::EventObject aEvent;
1339
0
    aEvent.Source = getXWeak();
1340
0
    for (const auto& rListener : aMouseClickHandlers)
1341
0
    {
1342
0
        try
1343
0
        {
1344
0
            rListener->disposing(aEvent);
1345
0
        }
1346
0
        catch ( uno::Exception& )
1347
0
        {
1348
0
        }
1349
0
    }
1350
0
    aMouseClickHandlers.clear();
1351
0
}
1352
1353
void ScTabViewObj::EndActivationListening()
1354
0
{
1355
0
    lang::EventObject aEvent;
1356
0
    aEvent.Source = getXWeak();
1357
0
    for (const auto& rListener : aActivationListeners)
1358
0
    {
1359
0
        try
1360
0
        {
1361
0
            rListener->disposing(aEvent);
1362
0
        }
1363
0
        catch ( uno::Exception& )
1364
0
        {
1365
0
        }
1366
0
    }
1367
0
    aActivationListeners.clear();
1368
0
}
1369
1370
void SAL_CALL ScTabViewObj::addEnhancedMouseClickHandler( const uno::Reference< awt::XEnhancedMouseClickHandler >& aListener )
1371
0
{
1372
0
    SolarMutexGuard aGuard;
1373
1374
0
    if (aListener.is())
1375
0
    {
1376
0
        aMouseClickHandlers.push_back( aListener );
1377
0
    }
1378
0
}
1379
1380
void SAL_CALL ScTabViewObj::removeEnhancedMouseClickHandler( const uno::Reference< awt::XEnhancedMouseClickHandler >& aListener )
1381
0
{
1382
0
    SolarMutexGuard aGuard;
1383
0
    sal_uInt16 nCount = aMouseClickHandlers.size();
1384
0
    std::erase(aMouseClickHandlers, aListener);
1385
0
    if (aMouseClickHandlers.empty() && (nCount > 0)) // only if last listener removed
1386
0
        EndMouseListening();
1387
0
}
1388
1389
// XActivationBroadcaster
1390
1391
void SAL_CALL ScTabViewObj::addActivationEventListener( const uno::Reference< sheet::XActivationEventListener >& aListener )
1392
0
{
1393
0
    SolarMutexGuard aGuard;
1394
1395
0
    if (aListener.is())
1396
0
    {
1397
0
        aActivationListeners.push_back( aListener );
1398
0
    }
1399
0
}
1400
1401
void SAL_CALL ScTabViewObj::removeActivationEventListener( const uno::Reference< sheet::XActivationEventListener >& aListener )
1402
0
{
1403
0
    SolarMutexGuard aGuard;
1404
0
    sal_uInt16 nCount = aActivationListeners.size();
1405
0
    std::erase(aActivationListeners, aListener);
1406
0
    if (aActivationListeners.empty() && (nCount > 0)) // only if last listener removed
1407
0
        EndActivationListening();
1408
0
}
1409
1410
sal_Int16 ScTabViewObj::GetZoom() const
1411
0
{
1412
0
    ScTabViewShell* pViewSh = GetViewShell();
1413
0
    if (pViewSh)
1414
0
    {
1415
0
        double fZoomY = pViewSh->GetViewData().GetZoomY();    // Y will be shown
1416
0
        return static_cast<sal_Int16>(tools::Long( fZoomY * 100 ));
1417
0
    }
1418
0
    return 0;
1419
0
}
1420
1421
void ScTabViewObj::SetZoom(sal_Int16 nZoom)
1422
0
{
1423
0
    ScTabViewShell* pViewSh = GetViewShell();
1424
0
    if (!pViewSh)
1425
0
        return;
1426
1427
0
    if ( nZoom != GetZoom() && nZoom != 0 )
1428
0
    {
1429
0
        if (!pViewSh->GetViewData().IsPagebreakMode())
1430
0
        {
1431
0
            ScModule* pScMod = ScModule::get();
1432
0
            ScAppOptions aNewOpt(pScMod->GetAppOptions());
1433
0
            aNewOpt.SetZoom( nZoom );
1434
0
            aNewOpt.SetZoomType( pViewSh->GetViewData().GetView()->GetZoomType() );
1435
0
            pScMod->SetAppOptions( aNewOpt );
1436
0
        }
1437
0
    }
1438
0
    double fFract = double(nZoom) / 100 ;
1439
0
    pViewSh->SetZoom( fFract, fFract, true );
1440
0
    pViewSh->PaintGrid();
1441
0
    pViewSh->PaintTop();
1442
0
    pViewSh->PaintLeft();
1443
0
    pViewSh->GetViewFrame().GetBindings().Invalidate( SID_ATTR_ZOOM );
1444
0
    pViewSh->GetViewFrame().GetBindings().Invalidate( SID_ATTR_ZOOMSLIDER );
1445
0
    pViewSh->GetViewFrame().GetBindings().Invalidate(SID_ZOOM_IN);
1446
0
    pViewSh->GetViewFrame().GetBindings().Invalidate(SID_ZOOM_OUT);
1447
0
}
1448
1449
sal_Int16 ScTabViewObj::GetZoomType() const
1450
0
{
1451
0
    sal_Int16 aZoomType = view::DocumentZoomType::OPTIMAL;
1452
0
    ScTabViewShell* pViewSh = GetViewShell();
1453
0
    if (pViewSh)
1454
0
    {
1455
0
        SvxZoomType eZoomType = pViewSh->GetViewData().GetView()->GetZoomType();
1456
0
        switch (eZoomType)
1457
0
        {
1458
0
        case SvxZoomType::PERCENT:
1459
0
            aZoomType = view::DocumentZoomType::BY_VALUE;
1460
0
            break;
1461
0
        case SvxZoomType::OPTIMAL:
1462
0
            aZoomType = view::DocumentZoomType::OPTIMAL;
1463
0
            break;
1464
0
        case SvxZoomType::WHOLEPAGE:
1465
0
            aZoomType = view::DocumentZoomType::ENTIRE_PAGE;
1466
0
            break;
1467
0
        case SvxZoomType::PAGEWIDTH:
1468
0
            aZoomType = view::DocumentZoomType::PAGE_WIDTH;
1469
0
            break;
1470
0
        case SvxZoomType::PAGEWIDTH_NOBORDER:
1471
0
            aZoomType = view::DocumentZoomType::PAGE_WIDTH_EXACT;
1472
0
            break;
1473
0
        }
1474
0
    }
1475
0
    return aZoomType;
1476
0
}
1477
1478
void ScTabViewObj::SetZoomType(sal_Int16 aZoomType)
1479
0
{
1480
0
    ScTabViewShell* pViewSh = GetViewShell();
1481
0
    if (!pViewSh)
1482
0
        return;
1483
1484
0
    ScDBFunc* pView = pViewSh->GetViewData().GetView();
1485
0
    if (!pView)
1486
0
        return;
1487
1488
0
    SvxZoomType eZoomType;
1489
0
    switch (aZoomType)
1490
0
    {
1491
0
    case view::DocumentZoomType::BY_VALUE:
1492
0
        eZoomType = SvxZoomType::PERCENT;
1493
0
        break;
1494
0
    case view::DocumentZoomType::OPTIMAL:
1495
0
        eZoomType = SvxZoomType::OPTIMAL;
1496
0
        break;
1497
0
    case view::DocumentZoomType::ENTIRE_PAGE:
1498
0
        eZoomType = SvxZoomType::WHOLEPAGE;
1499
0
        break;
1500
0
    case view::DocumentZoomType::PAGE_WIDTH:
1501
0
        eZoomType = SvxZoomType::PAGEWIDTH;
1502
0
        break;
1503
0
    case view::DocumentZoomType::PAGE_WIDTH_EXACT:
1504
0
        eZoomType = SvxZoomType::PAGEWIDTH_NOBORDER;
1505
0
        break;
1506
0
    default:
1507
0
        eZoomType = SvxZoomType::OPTIMAL;
1508
0
    }
1509
0
    sal_Int16 nZoom(GetZoom());
1510
0
    sal_Int16 nOldZoom(nZoom);
1511
0
    if ( eZoomType == SvxZoomType::PERCENT )
1512
0
    {
1513
0
        if ( nZoom < MINZOOM )  nZoom = MINZOOM;
1514
0
        if ( nZoom > MAXZOOM )  nZoom = MAXZOOM;
1515
0
    }
1516
0
    else
1517
0
        nZoom = pView->CalcZoom( eZoomType, nOldZoom );
1518
1519
0
    switch ( eZoomType )
1520
0
    {
1521
0
        case SvxZoomType::WHOLEPAGE:
1522
0
        case SvxZoomType::PAGEWIDTH:
1523
0
            pView->SetZoomType( eZoomType, true );
1524
0
            break;
1525
1526
0
        default:
1527
0
            pView->SetZoomType( SvxZoomType::PERCENT, true );
1528
0
    }
1529
0
    SetZoom( nZoom );
1530
0
}
1531
1532
sal_Bool SAL_CALL ScTabViewObj::getIsWindowSplit()
1533
0
{
1534
0
    SolarMutexGuard aGuard;
1535
    //  what menu slot SID_WINDOW_SPLIT does
1536
1537
0
    ScTabViewShell* pViewSh = GetViewShell();
1538
0
    if (pViewSh)
1539
0
    {
1540
0
        ScViewData& rViewData = pViewSh->GetViewData();
1541
0
        return ( rViewData.GetHSplitMode() == SC_SPLIT_NORMAL ||
1542
0
                 rViewData.GetVSplitMode() == SC_SPLIT_NORMAL );
1543
0
    }
1544
1545
0
    return false;
1546
0
}
1547
1548
sal_Bool SAL_CALL ScTabViewObj::hasFrozenPanes()
1549
0
{
1550
0
    SolarMutexGuard aGuard;
1551
    //  what menu slot SID_WINDOW_FIX does
1552
1553
0
    ScTabViewShell* pViewSh = GetViewShell();
1554
0
    if (pViewSh)
1555
0
    {
1556
0
        ScViewData& rViewData = pViewSh->GetViewData();
1557
0
        return ( rViewData.GetHSplitMode() == SC_SPLIT_FIX ||
1558
0
                 rViewData.GetVSplitMode() == SC_SPLIT_FIX );
1559
0
    }
1560
1561
0
    return false;
1562
0
}
1563
1564
sal_Int32 SAL_CALL ScTabViewObj::getSplitHorizontal()
1565
0
{
1566
0
    SolarMutexGuard aGuard;
1567
0
    ScTabViewShell* pViewSh = GetViewShell();
1568
0
    if (pViewSh)
1569
0
    {
1570
0
        ScViewData& rViewData = pViewSh->GetViewData();
1571
0
        if ( rViewData.GetHSplitMode() != SC_SPLIT_NONE )
1572
0
            return rViewData.GetHSplitPos();
1573
0
    }
1574
0
    return 0;
1575
0
}
1576
1577
sal_Int32 SAL_CALL ScTabViewObj::getSplitVertical()
1578
0
{
1579
0
    SolarMutexGuard aGuard;
1580
0
    ScTabViewShell* pViewSh = GetViewShell();
1581
0
    if (pViewSh)
1582
0
    {
1583
0
        ScViewData& rViewData = pViewSh->GetViewData();
1584
0
        if ( rViewData.GetVSplitMode() != SC_SPLIT_NONE )
1585
0
            return rViewData.GetVSplitPos();
1586
0
    }
1587
0
    return 0;
1588
0
}
1589
1590
sal_Int32 SAL_CALL ScTabViewObj::getSplitColumn()
1591
0
{
1592
0
    SolarMutexGuard aGuard;
1593
0
    ScTabViewShell* pViewSh = GetViewShell();
1594
0
    if (pViewSh)
1595
0
    {
1596
0
        ScViewData& rViewData = pViewSh->GetViewData();
1597
0
        if ( rViewData.GetHSplitMode() != SC_SPLIT_NONE )
1598
0
        {
1599
0
            tools::Long nSplit = rViewData.GetHSplitPos();
1600
1601
0
            ScSplitPos ePos = SC_SPLIT_BOTTOMLEFT;
1602
0
            if ( rViewData.GetVSplitMode() != SC_SPLIT_NONE )
1603
0
                ePos = SC_SPLIT_TOPLEFT;
1604
1605
0
            SCCOL nCol;
1606
0
            SCROW nRow;
1607
0
            rViewData.GetPosFromPixel( nSplit, 0, ePos, nCol, nRow, false );
1608
0
            if ( nCol > 0 )
1609
0
                return nCol;
1610
0
        }
1611
0
    }
1612
0
    return 0;
1613
0
}
1614
1615
sal_Int32 SAL_CALL ScTabViewObj::getSplitRow()
1616
0
{
1617
0
    SolarMutexGuard aGuard;
1618
0
    ScTabViewShell* pViewSh = GetViewShell();
1619
0
    if (pViewSh)
1620
0
    {
1621
0
        ScViewData& rViewData = pViewSh->GetViewData();
1622
0
        if ( rViewData.GetVSplitMode() != SC_SPLIT_NONE )
1623
0
        {
1624
0
            tools::Long nSplit = rViewData.GetVSplitPos();
1625
1626
            // split vertically
1627
0
            SCCOL nCol;
1628
0
            SCROW nRow;
1629
0
            rViewData.GetPosFromPixel( 0, nSplit, SC_SPLIT_TOPLEFT, nCol, nRow, false );
1630
0
            if ( nRow > 0 )
1631
0
                return nRow;
1632
0
        }
1633
0
    }
1634
0
    return 0;
1635
0
}
1636
1637
void SAL_CALL ScTabViewObj::splitAtPosition( sal_Int32 nPixelX, sal_Int32 nPixelY )
1638
0
{
1639
0
    SolarMutexGuard aGuard;
1640
0
    ScTabViewShell* pViewSh = GetViewShell();
1641
0
    if (pViewSh)
1642
0
    {
1643
0
        pViewSh->SplitAtPixel( Point( nPixelX, nPixelY ) );
1644
0
        pViewSh->FreezeSplitters( false );
1645
0
        pViewSh->InvalidateSplit();
1646
0
    }
1647
0
}
1648
1649
void SAL_CALL ScTabViewObj::freezeAtPosition( sal_Int32 nColumns, sal_Int32 nRows )
1650
0
{
1651
0
    SolarMutexGuard aGuard;
1652
0
    ScTabViewShell* pViewSh = GetViewShell();
1653
0
    if (!pViewSh)
1654
0
        return;
1655
1656
    //  first, remove them all -> no stress with scrolling in the meantime
1657
1658
0
    pViewSh->RemoveSplit();
1659
1660
0
    Point aWinStart;
1661
0
    vcl::Window* pWin = pViewSh->GetWindowByPos( SC_SPLIT_BOTTOMLEFT );
1662
0
    if (pWin)
1663
0
        aWinStart = pWin->GetPosPixel();
1664
1665
0
    ScViewData& rViewData = pViewSh->GetViewData();
1666
0
    Point aSplit(rViewData.GetScrPos( static_cast<SCCOL>(nColumns), static_cast<SCROW>(nRows), SC_SPLIT_BOTTOMLEFT, true ));
1667
0
    aSplit += aWinStart;
1668
1669
0
    pViewSh->SplitAtPixel( aSplit );
1670
0
    pViewSh->FreezeSplitters( true );
1671
0
    pViewSh->InvalidateSplit();
1672
0
}
1673
1674
void SAL_CALL ScTabViewObj::addSelectionChangeListener(
1675
    const uno::Reference<view::XSelectionChangeListener>& xListener )
1676
0
{
1677
0
    SolarMutexGuard aGuard;
1678
0
    aSelectionChgListeners.push_back( xListener );
1679
0
}
1680
1681
void SAL_CALL ScTabViewObj::removeSelectionChangeListener(
1682
                const uno::Reference< view::XSelectionChangeListener >& xListener )
1683
0
{
1684
0
    SolarMutexGuard aGuard;
1685
0
    auto it = std::find(aSelectionChgListeners.begin(), aSelectionChgListeners.end(), xListener); //! why the hassle with queryInterface?
1686
0
    if (it != aSelectionChgListeners.end())
1687
0
        aSelectionChgListeners.erase(it);
1688
0
}
1689
1690
void ScTabViewObj::SelectionChanged()
1691
0
{
1692
    // Selection changed so end any style preview
1693
    // Note: executing this slot through the dispatcher
1694
    // will cause the style dialog to be raised so we go
1695
    // direct here
1696
0
    ScFormatShell aShell( GetViewShell()->GetViewData() );
1697
0
    SfxAllItemSet reqList( SfxGetpApp()->GetPool() );
1698
0
    SfxRequest aReq( SID_STYLE_END_PREVIEW, SfxCallMode::SLOT, reqList );
1699
0
    aShell.ExecuteStyle( aReq );
1700
0
    lang::EventObject aEvent;
1701
0
    aEvent.Source.set(getXWeak());
1702
0
    for (const auto& rListener : aSelectionChgListeners)
1703
0
        rListener->selectionChanged( aEvent );
1704
1705
    // handle sheet events
1706
0
    ScTabViewShell* pViewSh = GetViewShell();
1707
0
    ScViewData& rViewData = pViewSh->GetViewData();
1708
0
    ScDocShell* pDocSh = rViewData.GetDocShell();
1709
0
    ScDocument& rDoc = pDocSh->GetDocument();
1710
0
    SCTAB nTab = rViewData.CurrentTabForData();
1711
0
    const ScSheetEvents* pEvents = rDoc.GetSheetEvents(nTab);
1712
0
    if (pEvents)
1713
0
    {
1714
0
        const OUString* pScript = pEvents->GetScript(ScSheetEventId::SELECT);
1715
0
        if (pScript)
1716
0
        {
1717
            // the macro parameter is the selection as returned by getSelection
1718
0
            uno::Sequence<uno::Any> aParams{ getSelection() };
1719
0
            uno::Any aRet;
1720
0
            uno::Sequence<sal_Int16> aOutArgsIndex;
1721
0
            uno::Sequence<uno::Any> aOutArgs;
1722
0
            /*ErrCode eRet =*/ pDocSh->CallXScript( *pScript, aParams, aRet, aOutArgsIndex, aOutArgs );
1723
0
        }
1724
0
    }
1725
1726
0
    SfxApplication::Get()->Broadcast( SfxHint( SfxHintId::ScSelectionChanged ) );
1727
1728
0
    if ( mbLeftMousePressed ) // selection still in progress
1729
0
        return;
1730
1731
0
    try
1732
0
    {
1733
0
        uno::Reference< script::vba::XVBAEventProcessor > xVbaEvents( rDoc.GetVbaEventProcessor(), uno::UNO_SET_THROW );
1734
0
        uno::Sequence< uno::Any > aArgs{ getSelection() };
1735
0
        xVbaEvents->processVbaEvent( ScSheetEvents::GetVbaSheetEventId( ScSheetEventId::SELECT ), aArgs );
1736
0
    }
1737
0
    catch( uno::Exception& )
1738
0
    {
1739
0
    }
1740
0
}
1741
1742
//  XPropertySet (view options)
1743
//! provide those also in application?
1744
1745
uno::Reference<beans::XPropertySetInfo> SAL_CALL ScTabViewObj::getPropertySetInfo()
1746
0
{
1747
0
    SolarMutexGuard aGuard;
1748
0
    static uno::Reference<beans::XPropertySetInfo> aRef(
1749
0
        new SfxItemPropertySetInfo( aPropSet.getPropertyMap() ));
1750
0
    return aRef;
1751
0
}
1752
1753
void SAL_CALL ScTabViewObj::setPropertyValue(
1754
                        const OUString& aPropertyName, const uno::Any& aValue )
1755
0
{
1756
0
    SolarMutexGuard aGuard;
1757
1758
0
    if ( aPropertyName == SC_UNO_FILTERED_RANGE_SELECTION )
1759
0
    {
1760
0
        bFilteredRangeSelection = ScUnoHelpFunctions::GetBoolFromAny(aValue);
1761
0
        return;
1762
0
    }
1763
1764
0
    ScTabViewShell* pViewSh = GetViewShell();
1765
0
    if (!pViewSh)
1766
0
        return;
1767
1768
0
    ScViewData& rViewData = pViewSh->GetViewData();
1769
0
    const ScViewOptions& rOldOpt = pViewSh->GetViewData().GetOptions();
1770
0
    ScViewOptions aNewOpt(rOldOpt);
1771
1772
0
    if ( aPropertyName == SC_UNO_COLROWHDR || aPropertyName == OLD_UNO_COLROWHDR )
1773
0
        aNewOpt.SetOption(sc::ViewOption::HEADER, ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
1774
0
    else if ( aPropertyName == SC_UNO_HORSCROLL || aPropertyName == OLD_UNO_HORSCROLL )
1775
0
        aNewOpt.SetOption(sc::ViewOption::HSCROLL, ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
1776
0
    else if ( aPropertyName == SC_UNO_OUTLSYMB || aPropertyName == OLD_UNO_OUTLSYMB )
1777
0
        aNewOpt.SetOption(sc::ViewOption::OUTLINER, ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
1778
0
    else if ( aPropertyName == SC_UNO_SHEETTABS || aPropertyName == OLD_UNO_SHEETTABS )
1779
0
        aNewOpt.SetOption(sc::ViewOption::TABCONTROLS, ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
1780
0
    else if ( aPropertyName == SC_UNO_SHOWANCHOR )
1781
0
        aNewOpt.SetOption(sc::ViewOption::ANCHOR, ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
1782
0
    else if ( aPropertyName == SC_UNO_SHOWFORM )
1783
0
        aNewOpt.SetOption(sc::ViewOption::FORMULAS, ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
1784
0
    else if ( aPropertyName == SC_UNO_SHOWGRID )
1785
0
        aNewOpt.SetOption(sc::ViewOption::GRID, ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
1786
0
    else if ( aPropertyName == SC_UNO_SHOWHELP )
1787
0
        aNewOpt.SetOption(sc::ViewOption::HELPLINES, ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
1788
0
    else if ( aPropertyName == SC_UNO_SHOWNOTES )
1789
0
        aNewOpt.SetOption(sc::ViewOption::NOTES, ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
1790
0
    else if ( aPropertyName == SC_UNO_SHOWNOTEAUTHOR )
1791
0
        aNewOpt.SetOption(sc::ViewOption::NOTEAUTHOR, ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
1792
0
    else if ( aPropertyName == SC_UNO_SHOWFORMULASMARKS )
1793
0
        aNewOpt.SetOption(sc::ViewOption::FORMULAS_MARKS, ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
1794
0
    else if ( aPropertyName == SC_UNO_SHOWPAGEBR )
1795
0
        aNewOpt.SetOption(sc::ViewOption::PAGEBREAKS, ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
1796
0
    else if ( aPropertyName == SC_UNO_SHOWZERO )
1797
0
        aNewOpt.SetOption(sc::ViewOption::NULLVALS, ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
1798
0
    else if ( aPropertyName == SC_UNO_VALUEHIGH || aPropertyName == OLD_UNO_VALUEHIGH )
1799
0
        aNewOpt.SetOption(sc::ViewOption::SYNTAX, ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
1800
0
    else if ( aPropertyName == SC_UNO_VERTSCROLL || aPropertyName == OLD_UNO_VERTSCROLL )
1801
0
        aNewOpt.SetOption(sc::ViewOption::VSCROLL, ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
1802
0
    else if ( aPropertyName == SC_UNO_SHOWOBJ )
1803
0
    {
1804
0
        sal_Int16 nIntVal = 0;
1805
0
        if ( aValue >>= nIntVal )
1806
0
        {
1807
            //#i80528# adapt to new range eventually
1808
0
            if(sal_Int16(VOBJ_MODE_HIDE) < nIntVal) nIntVal = sal_Int16(VOBJ_MODE_SHOW);
1809
1810
0
            aNewOpt.SetObjMode(sc::ViewObjectType::OLE, static_cast<ScVObjMode>(nIntVal));
1811
0
        }
1812
0
    }
1813
0
    else if ( aPropertyName == SC_UNO_SHOWCHARTS )
1814
0
    {
1815
0
        sal_Int16 nIntVal = 0;
1816
0
        if ( aValue >>= nIntVal )
1817
0
        {
1818
            //#i80528# adapt to new range eventually
1819
0
            if(sal_Int16(VOBJ_MODE_HIDE) < nIntVal) nIntVal = sal_Int16(VOBJ_MODE_SHOW);
1820
1821
0
            aNewOpt.SetObjMode(sc::ViewObjectType::CHART, static_cast<ScVObjMode>(nIntVal));
1822
0
        }
1823
0
    }
1824
0
    else if ( aPropertyName == SC_UNO_SHOWDRAW )
1825
0
    {
1826
0
        sal_Int16 nIntVal = 0;
1827
0
        if ( aValue >>= nIntVal )
1828
0
        {
1829
            //#i80528# adapt to new range eventually
1830
0
            if(sal_Int16(VOBJ_MODE_HIDE) < nIntVal) nIntVal = sal_Int16(VOBJ_MODE_SHOW);
1831
1832
0
            aNewOpt.SetObjMode(sc::ViewObjectType::DRAW, static_cast<ScVObjMode>(nIntVal));
1833
0
        }
1834
0
    }
1835
0
    else if ( aPropertyName == SC_UNO_GRIDCOLOR )
1836
0
    {
1837
0
        Color nIntVal;
1838
0
        if ( aValue >>= nIntVal )
1839
0
            aNewOpt.SetGridColor( nIntVal, OUString() );
1840
0
    }
1841
0
    else if ( aPropertyName == SC_UNO_ZOOMTYPE )
1842
0
    {
1843
0
        sal_Int16 nIntVal = 0;
1844
0
        if ( aValue >>= nIntVal )
1845
0
            SetZoomType(nIntVal);
1846
0
    }
1847
0
    else if ( aPropertyName == SC_UNO_ZOOMVALUE )
1848
0
    {
1849
0
        sal_Int16 nIntVal = 0;
1850
0
        if ( aValue >>= nIntVal )
1851
0
            SetZoom(nIntVal);
1852
0
    }
1853
0
    else if ( aPropertyName == SC_UNO_FORMULABARHEIGHT )
1854
0
    {
1855
0
        sal_Int16 nIntVal = ScUnoHelpFunctions::GetInt16FromAny(aValue);
1856
0
        if (nIntVal > 0)
1857
0
        {
1858
0
            rViewData.SetFormulaBarLines(nIntVal);
1859
            // Notify formula bar about changed lines
1860
0
            ScInputHandler* pInputHdl = ScModule::get()->GetInputHdl();
1861
0
            if (pInputHdl)
1862
0
            {
1863
0
                ScInputWindow* pInputWin = pInputHdl->GetInputWindow();
1864
0
                if (pInputWin)
1865
0
                    pInputWin->NumLinesChanged();
1866
0
            }
1867
0
        }
1868
0
    }
1869
1870
    //  Options are set on the view and document (for new views),
1871
    //  so that they remain during saving.
1872
    //! In the app (module) we need an extra options to tune that
1873
    //! (for new documents)
1874
1875
0
    if ( aNewOpt == rOldOpt )
1876
0
        return;
1877
1878
0
    rViewData.SetOptions( aNewOpt );
1879
0
    rViewData.GetDocument().SetViewOptions( aNewOpt );
1880
0
    rViewData.GetDocShell()->SetDocumentModified();    //! really?
1881
1882
0
    pViewSh->UpdateFixPos();
1883
0
    pViewSh->PaintGrid();
1884
0
    pViewSh->PaintTop();
1885
0
    pViewSh->PaintLeft();
1886
0
    pViewSh->PaintExtras();
1887
0
    pViewSh->InvalidateBorder();
1888
1889
0
    SfxBindings& rBindings = pViewSh->GetViewFrame().GetBindings();
1890
0
    rBindings.Invalidate( FID_TOGGLEHEADERS ); // -> check in menu
1891
0
    rBindings.Invalidate( FID_TOGGLESYNTAX );
1892
0
}
1893
1894
uno::Any SAL_CALL ScTabViewObj::getPropertyValue( const OUString& aPropertyName )
1895
0
{
1896
0
    SolarMutexGuard aGuard;
1897
0
    uno::Any aRet;
1898
1899
0
    if ( aPropertyName == SC_UNO_FILTERED_RANGE_SELECTION )
1900
0
    {
1901
0
        aRet <<= bFilteredRangeSelection;
1902
0
        return aRet;
1903
0
    }
1904
1905
0
    ScTabViewShell* pViewSh = GetViewShell();
1906
0
    if (pViewSh)
1907
0
    {
1908
0
        ScViewData& rViewData = pViewSh->GetViewData();
1909
0
        const ScViewOptions& rOpt = rViewData.GetOptions();
1910
1911
0
        if ( aPropertyName == SC_UNO_COLROWHDR || aPropertyName == OLD_UNO_COLROWHDR )
1912
0
            aRet <<= rOpt.GetOption(sc::ViewOption::HEADER);
1913
0
        else if ( aPropertyName == SC_UNO_HORSCROLL || aPropertyName == OLD_UNO_HORSCROLL )
1914
0
            aRet <<= rOpt.GetOption(sc::ViewOption::HSCROLL);
1915
0
        else if ( aPropertyName == SC_UNO_OUTLSYMB || aPropertyName == OLD_UNO_OUTLSYMB )
1916
0
            aRet <<= rOpt.GetOption(sc::ViewOption::OUTLINER);
1917
0
        else if ( aPropertyName == SC_UNO_SHEETTABS || aPropertyName == OLD_UNO_SHEETTABS )
1918
0
            aRet <<= rOpt.GetOption(sc::ViewOption::TABCONTROLS);
1919
0
        else if ( aPropertyName == SC_UNO_SHOWANCHOR ) aRet <<= rOpt.GetOption(sc::ViewOption::ANCHOR);
1920
0
        else if ( aPropertyName == SC_UNO_SHOWFORM )   aRet <<= rOpt.GetOption(sc::ViewOption::FORMULAS);
1921
0
        else if ( aPropertyName == SC_UNO_SHOWGRID )   aRet <<= rOpt.GetOption(sc::ViewOption::GRID);
1922
0
        else if ( aPropertyName == SC_UNO_SHOWHELP )   aRet <<= rOpt.GetOption(sc::ViewOption::HELPLINES);
1923
0
        else if ( aPropertyName == SC_UNO_SHOWNOTES )  aRet <<= rOpt.GetOption(sc::ViewOption::NOTES);
1924
0
        else if ( aPropertyName == SC_UNO_SHOWNOTEAUTHOR )  aRet <<= rOpt.GetOption(sc::ViewOption::NOTEAUTHOR);
1925
0
        else if ( aPropertyName == SC_UNO_SHOWFORMULASMARKS )  aRet <<= rOpt.GetOption(sc::ViewOption::FORMULAS_MARKS);
1926
0
        else if ( aPropertyName == SC_UNO_SHOWPAGEBR ) aRet <<= rOpt.GetOption(sc::ViewOption::PAGEBREAKS);
1927
0
        else if ( aPropertyName == SC_UNO_SHOWZERO )   aRet <<= rOpt.GetOption(sc::ViewOption::NULLVALS);
1928
0
        else if ( aPropertyName == SC_UNO_VALUEHIGH || aPropertyName == OLD_UNO_VALUEHIGH )
1929
0
            aRet <<= rOpt.GetOption(sc::ViewOption::SYNTAX);
1930
0
        else if ( aPropertyName == SC_UNO_VERTSCROLL || aPropertyName == OLD_UNO_VERTSCROLL )
1931
0
            aRet <<= rOpt.GetOption(sc::ViewOption::VSCROLL);
1932
0
        else if ( aPropertyName == SC_UNO_SHOWOBJ )    aRet <<= static_cast<sal_Int16>( rOpt.GetObjMode(sc::ViewObjectType::OLE) );
1933
0
        else if ( aPropertyName == SC_UNO_SHOWCHARTS ) aRet <<= static_cast<sal_Int16>( rOpt.GetObjMode(sc::ViewObjectType::CHART) );
1934
0
        else if ( aPropertyName == SC_UNO_SHOWDRAW )   aRet <<= static_cast<sal_Int16>( rOpt.GetObjMode(sc::ViewObjectType::DRAW) );
1935
0
        else if ( aPropertyName == SC_UNO_GRIDCOLOR )  aRet <<= rOpt.GetGridColor();
1936
0
        else if ( aPropertyName == SC_UNO_VISAREA ) aRet <<= GetVisArea();
1937
0
        else if ( aPropertyName == SC_UNO_ZOOMTYPE ) aRet <<= GetZoomType();
1938
0
        else if ( aPropertyName == SC_UNO_ZOOMVALUE ) aRet <<= GetZoom();
1939
0
        else if ( aPropertyName == SC_UNO_FORMULABARHEIGHT ) aRet <<= rViewData.GetFormulaBarLines();
1940
0
        else if ( aPropertyName == SC_UNO_VISAREASCREEN )
1941
0
        {
1942
0
            vcl::Window* pActiveWin = rViewData.GetActiveWin();
1943
0
            if ( pActiveWin )
1944
0
            {
1945
0
                AbsoluteScreenPixelRectangle aRect = pActiveWin->GetWindowExtentsAbsolute();
1946
0
                aRet <<= vcl::unohelper::ConvertToAWTRect(aRect);
1947
0
            }
1948
0
        }
1949
0
    }
1950
1951
0
    return aRet;
1952
0
}
1953
1954
void SAL_CALL ScTabViewObj::addPropertyChangeListener( const OUString& /* aPropertyName */,
1955
    const uno::Reference<beans::XPropertyChangeListener >& xListener )
1956
0
{
1957
0
    SolarMutexGuard aGuard;
1958
0
    aPropertyChgListeners.push_back( xListener );
1959
0
}
1960
1961
void SAL_CALL ScTabViewObj::removePropertyChangeListener( const OUString& /* aPropertyName */,
1962
                                    const uno::Reference<beans::XPropertyChangeListener >& xListener )
1963
0
{
1964
0
    SolarMutexGuard aGuard;
1965
0
    auto it = std::find(aPropertyChgListeners.begin(), aPropertyChgListeners.end(), xListener); //! Why the nonsense with queryInterface?
1966
0
    if (it != aPropertyChgListeners.end())
1967
0
        aPropertyChgListeners.erase(it);
1968
0
}
1969
1970
void SAL_CALL ScTabViewObj::addVetoableChangeListener( const OUString& /* PropertyName */,
1971
                                    const uno::Reference<beans::XVetoableChangeListener >& /* aListener */ )
1972
0
{
1973
0
}
1974
1975
void SAL_CALL ScTabViewObj::removeVetoableChangeListener( const OUString& /* PropertyName */,
1976
                                    const uno::Reference<beans::XVetoableChangeListener >& /* aListener */ )
1977
0
{
1978
0
}
1979
1980
void ScTabViewObj::VisAreaChanged()
1981
0
{
1982
0
    beans::PropertyChangeEvent aEvent;
1983
0
    aEvent.Source.set(getXWeak());
1984
0
    for (const auto& rListener : aPropertyChgListeners)
1985
0
        rListener->propertyChange( aEvent );
1986
0
}
1987
1988
// XRangeSelection
1989
1990
void SAL_CALL ScTabViewObj::startRangeSelection(
1991
                                const uno::Sequence<beans::PropertyValue>& aArguments )
1992
0
{
1993
0
    SolarMutexGuard aGuard;
1994
0
    ScTabViewShell* pViewSh = GetViewShell();
1995
0
    if (!pViewSh)
1996
0
        return;
1997
1998
0
    OUString aInitVal, aTitle;
1999
0
    bool bCloseOnButtonUp = false;
2000
0
    bool bSingleCell = false;
2001
0
    bool bMultiSelection = false;
2002
2003
0
    OUString aStrVal;
2004
0
    for (const beans::PropertyValue& rProp : aArguments)
2005
0
    {
2006
0
        OUString aPropName(rProp.Name);
2007
2008
0
        if (aPropName == SC_UNONAME_CLOSEONUP )
2009
0
            bCloseOnButtonUp = ScUnoHelpFunctions::GetBoolFromAny( rProp.Value );
2010
0
        else if (aPropName == SC_UNONAME_TITLE )
2011
0
        {
2012
0
            if ( rProp.Value >>= aStrVal )
2013
0
                aTitle = aStrVal;
2014
0
        }
2015
0
        else if (aPropName == SC_UNONAME_INITVAL )
2016
0
        {
2017
0
            if ( rProp.Value >>= aStrVal )
2018
0
                aInitVal = aStrVal;
2019
0
        }
2020
0
        else if (aPropName == SC_UNONAME_SINGLECELL )
2021
0
            bSingleCell = ScUnoHelpFunctions::GetBoolFromAny( rProp.Value );
2022
0
        else if (aPropName == SC_UNONAME_MULTISEL )
2023
0
            bMultiSelection = ScUnoHelpFunctions::GetBoolFromAny( rProp.Value );
2024
0
    }
2025
2026
0
    pViewSh->StartSimpleRefDialog( aTitle, aInitVal, bCloseOnButtonUp, bSingleCell, bMultiSelection );
2027
0
}
2028
2029
void SAL_CALL ScTabViewObj::abortRangeSelection()
2030
0
{
2031
0
    SolarMutexGuard aGuard;
2032
0
    ScTabViewShell* pViewSh = GetViewShell();
2033
0
    if (pViewSh)
2034
0
        pViewSh->StopSimpleRefDialog();
2035
0
}
2036
2037
void SAL_CALL ScTabViewObj::addRangeSelectionListener(
2038
    const uno::Reference<sheet::XRangeSelectionListener>& xListener )
2039
0
{
2040
0
    SolarMutexGuard aGuard;
2041
0
    aRangeSelListeners.push_back( xListener );
2042
0
}
2043
2044
void SAL_CALL ScTabViewObj::removeRangeSelectionListener(
2045
                                const uno::Reference<sheet::XRangeSelectionListener>& xListener )
2046
0
{
2047
0
    SolarMutexGuard aGuard;
2048
0
    auto it = std::find(aRangeSelListeners.begin(), aRangeSelListeners.end(), xListener);
2049
0
    if (it != aRangeSelListeners.end())
2050
0
        aRangeSelListeners.erase(it);
2051
0
}
2052
2053
void SAL_CALL ScTabViewObj::addRangeSelectionChangeListener(
2054
    const uno::Reference<sheet::XRangeSelectionChangeListener>& xListener )
2055
0
{
2056
0
    SolarMutexGuard aGuard;
2057
0
    aRangeChgListeners.push_back( xListener );
2058
0
}
2059
2060
void SAL_CALL ScTabViewObj::removeRangeSelectionChangeListener(
2061
                                const uno::Reference<sheet::XRangeSelectionChangeListener>& xListener )
2062
0
{
2063
0
    SolarMutexGuard aGuard;
2064
0
    auto it = std::find(aRangeChgListeners.begin(), aRangeChgListeners.end(), xListener);
2065
0
    if (it != aRangeChgListeners.end())
2066
0
        aRangeChgListeners.erase(it);
2067
0
}
2068
2069
void ScTabViewObj::RangeSelDone( const OUString& rText )
2070
0
{
2071
0
    sheet::RangeSelectionEvent aEvent;
2072
0
    aEvent.Source.set(getXWeak());
2073
0
    aEvent.RangeDescriptor = rText;
2074
2075
    // copy on the stack because listener could remove itself
2076
0
    const RangeSelListeners listeners(aRangeSelListeners);
2077
2078
0
    for (const auto& rListener : listeners)
2079
0
        rListener->done( aEvent );
2080
0
}
2081
2082
void ScTabViewObj::RangeSelAborted( const OUString& rText )
2083
0
{
2084
0
    sheet::RangeSelectionEvent aEvent;
2085
0
    aEvent.Source.set(getXWeak());
2086
0
    aEvent.RangeDescriptor = rText;
2087
2088
    // copy on the stack because listener could remove itself
2089
0
    const RangeSelListeners listeners(aRangeSelListeners);
2090
2091
0
    for (const auto& rListener : listeners)
2092
0
        rListener->aborted( aEvent );
2093
0
}
2094
2095
void ScTabViewObj::RangeSelChanged( const OUString& rText )
2096
0
{
2097
0
    sheet::RangeSelectionEvent aEvent;
2098
0
    aEvent.Source.set(getXWeak());
2099
0
    aEvent.RangeDescriptor = rText;
2100
2101
    // copy on the stack because listener could remove itself
2102
0
    const std::vector<css::uno::Reference<css::sheet::XRangeSelectionChangeListener>> listener(aRangeChgListeners);
2103
0
    for (const auto& rListener : listener)
2104
0
        rListener->descriptorChanged( aEvent );
2105
0
}
2106
2107
// XServiceInfo
2108
OUString SAL_CALL ScTabViewObj::getImplementationName()
2109
0
{
2110
0
    return u"ScTabViewObj"_ustr;
2111
0
}
2112
2113
sal_Bool SAL_CALL ScTabViewObj::supportsService( const OUString& rServiceName )
2114
0
{
2115
0
    return cppu::supportsService(this, rServiceName);
2116
0
}
2117
2118
uno::Sequence<OUString> SAL_CALL ScTabViewObj::getSupportedServiceNames()
2119
0
{
2120
0
    return {SCTABVIEWOBJ_SERVICE, SCVIEWSETTINGS_SERVICE};
2121
0
}
2122
2123
// XUnoTunnel
2124
2125
css::uno::Reference< css::datatransfer::XTransferable > SAL_CALL ScTabViewObj::getTransferable()
2126
0
{
2127
0
    SolarMutexGuard aGuard;
2128
0
    ScEditShell* pShell = dynamic_cast<ScEditShell*>( GetViewShell()->GetViewFrame().GetDispatcher()->GetShell(0)  );
2129
0
    if (pShell)
2130
0
        return pShell->GetEditView()->GetTransferable();
2131
2132
0
    ScDrawTextObjectBar* pTextShell = dynamic_cast<ScDrawTextObjectBar*>( GetViewShell()->GetViewFrame().GetDispatcher()->GetShell(0)  );
2133
0
    if (pTextShell)
2134
0
    {
2135
0
        ScViewData& rViewData = GetViewShell()->GetViewData();
2136
0
        ScDrawView* pView = rViewData.GetScDrawView();
2137
0
        OutlinerView* pOutView = pView->GetTextEditOutlinerView();
2138
0
        if (pOutView)
2139
0
            return pOutView->GetEditView().GetTransferable();
2140
0
    }
2141
2142
0
    ScDrawShell* pDrawShell = dynamic_cast<ScDrawShell*>( GetViewShell()->GetViewFrame().GetDispatcher()->GetShell(0)  );
2143
0
    if (pDrawShell)
2144
0
        return pDrawShell->GetDrawView()->CopyToTransferable();
2145
2146
0
    return GetViewShell()->CopyToTransferable();
2147
0
}
2148
2149
void SAL_CALL ScTabViewObj::insertTransferable( const css::uno::Reference< css::datatransfer::XTransferable >& xTrans )
2150
0
{
2151
0
    SolarMutexGuard aGuard;
2152
0
    ScEditShell* pShell = dynamic_cast<ScEditShell*>( GetViewShell()->GetViewFrame().GetDispatcher()->GetShell(0)  );
2153
0
    if (pShell)
2154
0
        pShell->GetEditView()->InsertText( xTrans, OUString(), false );
2155
0
    else
2156
0
    {
2157
0
        ScDrawTextObjectBar* pTextShell = dynamic_cast<ScDrawTextObjectBar*>( GetViewShell()->GetViewFrame().GetDispatcher()->GetShell(0)  );
2158
0
        if (pTextShell)
2159
0
        {
2160
0
            ScViewData& rViewData = GetViewShell()->GetViewData();
2161
0
            ScDrawView* pView = rViewData.GetScDrawView();
2162
0
            OutlinerView* pOutView = pView->GetTextEditOutlinerView();
2163
0
            if ( pOutView )
2164
0
            {
2165
0
                pOutView->GetEditView().InsertText( xTrans, OUString(), false );
2166
0
                return;
2167
0
            }
2168
0
        }
2169
2170
0
        GetViewShell()->PasteFromTransferable( xTrans );
2171
0
    }
2172
0
}
2173
2174
namespace {
2175
2176
uno::Sequence<sal_Int32> toSequence(const ScMarkData::MarkedTabsType& rSelected)
2177
0
{
2178
0
    uno::Sequence<sal_Int32> aRet(rSelected.size());
2179
0
    auto aRetRange = asNonConstRange(aRet);
2180
0
    size_t i = 0;
2181
0
    for (const auto& rTab : rSelected)
2182
0
    {
2183
0
        aRetRange[i] = static_cast<sal_Int32>(rTab);
2184
0
        ++i;
2185
0
    }
2186
2187
0
    return aRet;
2188
0
}
2189
2190
}
2191
2192
uno::Sequence<sal_Int32> ScTabViewObj::getSelectedSheets()
2193
0
{
2194
0
    ScTabViewShell* pViewSh = GetViewShell();
2195
0
    if (!pViewSh)
2196
0
        return uno::Sequence<sal_Int32>();
2197
2198
0
    ScViewData& rViewData = pViewSh->GetViewData();
2199
2200
    // #i95280# when printing from the shell, the view is never activated,
2201
    // so Excel view settings must also be evaluated here.
2202
0
    ScExtDocOptions* pExtOpt = rViewData.GetDocument().GetExtDocOptions();
2203
0
    if (pExtOpt && pExtOpt->IsChanged())
2204
0
    {
2205
0
        pViewSh->GetViewData().ReadExtOptions(*pExtOpt);        // Excel view settings
2206
0
        pViewSh->SetTabNo(pViewSh->GetViewData().CurrentTabForData(), true);
2207
0
        pExtOpt->SetChanged(false);
2208
0
    }
2209
2210
0
    return toSequence(rViewData.GetMarkData().GetSelectedTabs());
2211
0
}
2212
2213
ScPreviewObj::ScPreviewObj(ScPreviewShell* pViewSh) :
2214
0
    SfxBaseController(pViewSh),
2215
0
    mpViewShell(pViewSh)
2216
0
{
2217
0
    if (mpViewShell)
2218
0
        StartListening(*mpViewShell);
2219
0
}
2220
2221
ScPreviewObj::~ScPreviewObj()
2222
0
{
2223
0
    if (mpViewShell)
2224
0
        EndListening(*mpViewShell);
2225
0
}
2226
2227
uno::Any ScPreviewObj::queryInterface(const uno::Type& rType)
2228
0
{
2229
0
    uno::Any aReturn = ::cppu::queryInterface(rType,
2230
0
                    static_cast<sheet::XSelectedSheetsSupplier*>(this));
2231
0
    if ( aReturn.hasValue() )
2232
0
        return aReturn;
2233
0
    return SfxBaseController::queryInterface(rType);
2234
0
}
2235
2236
void ScPreviewObj::acquire() noexcept
2237
0
{
2238
0
    SfxBaseController::acquire();
2239
0
}
2240
2241
void ScPreviewObj::release() noexcept
2242
0
{
2243
0
    SfxBaseController::release();
2244
0
}
2245
2246
void ScPreviewObj::Notify(SfxBroadcaster&, const SfxHint& rHint)
2247
0
{
2248
0
    if (rHint.GetId() == SfxHintId::Dying)
2249
0
        mpViewShell = nullptr;
2250
0
}
2251
2252
uno::Sequence<sal_Int32> ScPreviewObj::getSelectedSheets()
2253
0
{
2254
0
    ScPreview* p = mpViewShell ? mpViewShell->GetPreview() : nullptr;
2255
0
    if (!p)
2256
0
        return uno::Sequence<sal_Int32>();
2257
2258
0
    return toSequence(p->GetSelectedTabs());
2259
0
}
2260
2261
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */