Coverage Report

Created: 2026-04-09 11:41

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/sfx2/source/view/viewfrm2.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
21
#include "impviewframe.hxx"
22
#include <statcach.hxx>
23
#include <workwin.hxx>
24
25
#include <sfx2/app.hxx>
26
#include <sfx2/bindings.hxx>
27
#include <sfx2/ctrlitem.hxx>
28
#include <sfx2/dispatch.hxx>
29
#include <sfx2/docfac.hxx>
30
#include <sfx2/docfile.hxx>
31
#include <sfx2/objitem.hxx>
32
#include <sfx2/objsh.hxx>
33
#include <sfx2/request.hxx>
34
#include <sfx2/sfxsids.hrc>
35
#include <sfx2/viewfrm.hxx>
36
#include <sfx2/viewsh.hxx>
37
#include <com/sun/star/lang/DisposedException.hpp>
38
#include <com/sun/star/util/CloseVetoException.hpp>
39
#include <com/sun/star/util/XCloseable.hpp>
40
#include <com/sun/star/embed/VerbDescriptor.hpp>
41
42
#include <osl/diagnose.h>
43
#include <svl/eitem.hxx>
44
#include <svl/stritem.hxx>
45
#include <tools/urlobj.hxx>
46
#include <sal/log.hxx>
47
48
using namespace ::com::sun::star;
49
using namespace ::com::sun::star::uno;
50
using namespace ::com::sun::star::util;
51
52
53
void SfxFrameViewWindow_Impl::StateChanged( StateChangedType nStateChange )
54
3.93k
{
55
3.93k
    if ( nStateChange == StateChangedType::InitShow )
56
0
    {
57
0
        SfxObjectShell* pDoc = pFrame->GetObjectShell();
58
0
        if ( pDoc && !pFrame->IsVisible() )
59
0
            pFrame->Show();
60
61
0
        pFrame->Resize();
62
0
    }
63
3.93k
    else
64
3.93k
        Window::StateChanged( nStateChange );
65
3.93k
}
66
67
void SfxFrameViewWindow_Impl::Resize()
68
3.93k
{
69
3.93k
    if ( IsReallyVisible() || IsReallyShown() || GetOutputSizePixel().Width() )
70
0
        pFrame->Resize();
71
3.93k
}
72
73
74
void SfxViewFrame::UpdateTitle()
75
76
/*  [Description]
77
78
    With this method, can the SfxViewFrame be forced to immediately provide
79
    the new title from the <SfxObjectShell>.
80
81
    [Note]
82
83
    This is for example necessary if one listens to the SfxObjectShell as
84
    SfxListener and then react on the <SfxSimpleHint> SfxHintId::TitleChanged,
85
    then query the title of his views. However these views (SfxTopViewFrames)
86
    are  also SfxListener and because the order of notifications might not be
87
    fixed, the title update will be enforced in advance.
88
89
    [Example]
90
91
    void SwDocShell::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
92
    {
93
        if ( dynamic_cast<const SfxSimpleHint *>(&rHint) != nullptr )
94
        {
95
            switch( ( (SfxSimpleHint&) rHint ).GetId() )
96
            {
97
                case SfxHintId::TitleChanged:
98
                    for ( SfxViewFrame *pTop = SfxViewFrame::GetFirst( this );
99
                          pTop;
100
                          pTop = SfxViewFrame::GetNext( this );
101
                    {
102
                        pTop->UpdateTitle();
103
                        ... pTop->GetName() ...
104
                    }
105
                    break;
106
                ...
107
            }
108
        }
109
    }
110
*/
111
112
19.6k
{
113
114
19.6k
    const SfxObjectFactory &rFact = GetObjectShell()->GetFactory();
115
19.6k
    m_pImpl->aFactoryName = rFact.GetFactoryName();
116
117
19.6k
    SfxObjectShell *pObjSh = GetObjectShell();
118
19.6k
    if ( !pObjSh )
119
0
        return;
120
121
122
19.6k
    const SfxMedium *pMedium = pObjSh->GetMedium();
123
19.6k
    OUString aURL;
124
19.6k
    GetFrame();  // -Wall required??
125
19.6k
    if ( pObjSh->HasName() )
126
0
    {
127
0
        INetURLObject aTmp( pMedium->GetName() );
128
0
        aURL = aTmp.getName( INetURLObject::LAST_SEGMENT, true, INetURLObject::DecodeMechanism::WithCharset );
129
0
    }
130
131
19.6k
    if ( aURL != m_pImpl->aActualURL )
132
        // URL has changed
133
0
        m_pImpl->aActualURL = aURL;
134
135
    // SbxObjects name
136
19.6k
    OUString aSbxName = pObjSh->SfxShell::GetName();
137
19.6k
    if ( IsVisible() )
138
15.7k
    {
139
15.7k
        aSbxName += ":" + OUString::number(m_pImpl->nDocViewNo);
140
15.7k
    }
141
142
19.6k
    SetName( aSbxName );
143
19.6k
    GetBindings().Invalidate( SID_CURRENT_URL );
144
19.6k
    GetBindings().Invalidate( SID_NEWDOCDIRECT );
145
19.6k
}
146
147
void SfxViewFrame::Exec_Impl(SfxRequest &rReq )
148
0
{
149
    // If presently the shells are replaced...
150
0
    if ( !GetObjectShell() || !GetViewShell() )
151
0
        return;
152
153
0
    switch ( rReq.GetSlot() )
154
0
    {
155
0
        case SID_SHOWPOPUPS :
156
0
        {
157
0
            const SfxBoolItem* pShowItem = rReq.GetArg<SfxBoolItem>(SID_SHOWPOPUPS);
158
0
            bool bShow = pShowItem == nullptr || pShowItem->GetValue();
159
160
0
            SfxWorkWindow *pWorkWin = GetFrame().GetWorkWindow_Impl();
161
0
            if ( bShow )
162
0
            {
163
                // First, make the floats viewable
164
0
                pWorkWin->MakeChildrenVisible_Impl(true);
165
0
                GetDispatcher()->Update_Impl( true );
166
167
                // Then view it
168
0
                GetBindings().HidePopups(false);
169
0
            }
170
0
            else
171
0
            {
172
0
                pWorkWin->HidePopups_Impl(true);
173
0
                pWorkWin->MakeChildrenVisible_Impl(false);
174
0
            }
175
176
0
            Invalidate( rReq.GetSlot() );
177
0
            rReq.Done();
178
0
            break;
179
0
        }
180
181
0
        case SID_ACTIVATE:
182
0
        {
183
0
            MakeActive_Impl( true );
184
0
            rReq.SetReturnValue(SfxObjectItem(0, this));
185
0
            break;
186
0
        }
187
188
0
        case SID_NEWDOCDIRECT :
189
0
        {
190
0
            const SfxStringItem* pFactoryItem = rReq.GetArg(SID_NEWDOCDIRECT);
191
0
            OUString aFactName;
192
0
            if ( pFactoryItem )
193
0
                aFactName = pFactoryItem->GetValue();
194
0
            else if ( !m_pImpl->aFactoryName.isEmpty() )
195
0
                aFactName = m_pImpl->aFactoryName;
196
0
            else
197
0
            {
198
0
                SAL_WARN("sfx.view", "Missing argument!");
199
0
                break;
200
0
            }
201
202
0
            SfxRequest aReq( SID_OPENDOC, SfxCallMode::SYNCHRON, GetPool() );
203
0
            const OUString aFact("private:factory/" + aFactName);
204
0
            aReq.AppendItem( SfxStringItem( SID_FILE_NAME, aFact ) );
205
0
            aReq.AppendItem( SfxFrameItem( SID_DOCFRAME, &GetFrame() ) );
206
0
            aReq.AppendItem( SfxStringItem( SID_TARGETNAME, u"_blank"_ustr ) );
207
0
            SfxGetpApp()->ExecuteSlot( aReq );
208
209
0
            const SfxViewFrameItem* pItem(dynamic_cast<const SfxViewFrameItem*>(aReq.GetReturnValue().getItem()));
210
0
            if (nullptr != pItem)
211
0
                rReq.SetReturnValue(SfxFrameItem(0, pItem->GetFrame()));
212
0
            break;
213
0
        }
214
215
0
        case SID_CLOSEWIN:
216
0
        {
217
            // disable CloseWin, if frame is not a task
218
0
            Reference < XCloseable > xTask( GetFrame().GetFrameInterface(),  UNO_QUERY );
219
0
            if ( !xTask.is() )
220
0
                break;
221
222
0
            if ( GetViewShell()->PrepareClose() )
223
0
            {
224
                // More Views on the same Document?
225
0
                SfxObjectShell *pDocSh = GetObjectShell();
226
0
                bool bOther = false;
227
0
                for ( const SfxViewFrame* pFrame = SfxViewFrame::GetFirst( pDocSh );
228
0
                      !bOther && pFrame;
229
0
                      pFrame = SfxViewFrame::GetNext( *pFrame, pDocSh ) )
230
0
                    bOther = (pFrame != this);
231
232
                // Document only needs to be queried, if no other View present.
233
0
                bool bClosed = false;
234
0
                if ( bOther || pDocSh->PrepareClose( true/*bUI*/ ) )
235
0
                {
236
0
                    if ( !bOther )
237
0
                        pDocSh->SetModified( false );
238
0
                    rReq.Done(); // Must call this before Close()!
239
0
                    bClosed = false;
240
0
                    try
241
0
                    {
242
0
                        xTask->close(true);
243
0
                        bClosed = true;
244
0
                    }
245
0
                    catch (css::lang::DisposedException &) {
246
                        // already closed; ignore
247
0
                    }
248
0
                    catch( CloseVetoException& )
249
0
                    {
250
0
                        bClosed = false;
251
0
                    }
252
0
                }
253
254
0
                rReq.SetReturnValue(SfxBoolItem(rReq.GetSlot(), bClosed));
255
0
            }
256
0
            return;
257
0
        }
258
0
    }
259
260
0
    rReq.Done();
261
0
}
262
263
void SfxViewFrame::GetState_Impl( SfxItemSet &rSet )
264
0
{
265
0
    SfxObjectShell *pDocSh = GetObjectShell();
266
267
0
    if ( !pDocSh )
268
0
        return;
269
270
0
    const WhichRangesContainer & pRanges = rSet.GetRanges();
271
0
    DBG_ASSERT(!pRanges.empty(), "Set without Range");
272
0
    for ( auto const & pRange : pRanges )
273
0
    {
274
0
        for ( sal_uInt16 nWhich = pRange.first; nWhich <= pRange.second; ++nWhich )
275
0
        {
276
0
            switch(nWhich)
277
0
            {
278
0
            case SID_NEWDOCDIRECT :
279
0
            {
280
0
                if ( !m_pImpl->aFactoryName.isEmpty() )
281
0
                {
282
0
                    rSet.Put( SfxStringItem( nWhich, "private:factory/"+m_pImpl->aFactoryName ) );
283
0
                }
284
0
                break;
285
0
            }
286
287
0
            case SID_NEWWINDOW:
288
0
                rSet.DisableItem(nWhich);
289
0
                break;
290
291
0
            case SID_CLOSEWIN:
292
0
            {
293
                // disable CloseWin, if frame is not a task
294
0
                Reference < XCloseable > xTask( GetFrame().GetFrameInterface(),  UNO_QUERY );
295
0
                if ( !xTask.is() )
296
0
                    rSet.DisableItem(nWhich);
297
0
                break;
298
0
            }
299
300
0
            case SID_SHOWPOPUPS :
301
0
                break;
302
303
0
            case SID_OBJECT:
304
0
                if ( GetViewShell() && GetViewShell()->GetVerbs().hasElements() && !GetObjectShell()->IsInPlaceActive() )
305
0
                {
306
0
                    uno::Any aAny(GetViewShell()->GetVerbs());
307
0
                    rSet.Put( SfxUnoAnyItem( sal_uInt16( SID_OBJECT ), aAny ) );
308
0
                }
309
0
                else
310
0
                    rSet.DisableItem( SID_OBJECT );
311
0
                break;
312
313
0
            default:
314
0
                OSL_FAIL( "invalid message-id" );
315
0
            }
316
0
        }
317
0
    }
318
0
}
319
320
void SfxViewFrame::INetExecute_Impl( SfxRequest &rRequest )
321
0
{
322
0
    sal_uInt16 nSlotId = rRequest.GetSlot();
323
0
    switch( nSlotId )
324
0
    {
325
0
        case SID_BROWSE_FORWARD:
326
0
        case SID_BROWSE_BACKWARD:
327
0
            OSL_FAIL( "SfxViewFrame::INetExecute_Impl: SID_BROWSE_FORWARD/BACKWARD are dead!" );
328
0
            break;
329
0
        case SID_CREATELINK:
330
0
        {
331
/*! (pb) we need new implementation to create a link
332
*/
333
0
            break;
334
0
        }
335
0
        case SID_FOCUSURLBOX:
336
0
        {
337
0
            SfxStateCache *pCache = GetBindings().GetAnyStateCache_Impl( SID_OPENURL );
338
0
            if( pCache )
339
0
            {
340
0
                SfxControllerItem* pCtrl = pCache->GetItemLink();
341
0
                while( pCtrl )
342
0
                {
343
0
                    pCtrl->StateChangedAtToolBoxControl( SID_FOCUSURLBOX, SfxItemState::UNKNOWN, nullptr );
344
0
                    pCtrl = pCtrl->GetItemLink();
345
0
                }
346
0
            }
347
0
        }
348
0
    }
349
350
    // Recording
351
0
    rRequest.Done();
352
0
}
353
354
void SfxViewFrame::INetState_Impl( SfxItemSet &rItemSet )
355
0
{
356
0
    rItemSet.DisableItem( SID_BROWSE_FORWARD );
357
0
    rItemSet.DisableItem( SID_BROWSE_BACKWARD );
358
359
    // Add/SaveToBookmark at BASIC-IDE, QUERY-EDITOR etc. disable
360
0
    SfxObjectShell *pDocSh = GetObjectShell();
361
0
    bool bEmbedded = pDocSh && pDocSh->GetCreateMode() == SfxObjectCreateMode::EMBEDDED;
362
0
    if ( !pDocSh || bEmbedded || !pDocSh->HasName() )
363
0
        rItemSet.DisableItem( SID_CREATELINK );
364
0
}
365
366
void SfxViewFrame::Activate( bool /*bMDI*/ )
367
3.93k
{
368
3.93k
    DBG_ASSERT(GetViewShell(), "No Shell");
369
//(mba): here maybe as in Beanframe NotifyEvent ?!
370
3.93k
}
371
372
void SfxViewFrame::Deactivate( bool /*bMDI*/ )
373
3.93k
{
374
3.93k
    DBG_ASSERT(GetViewShell(), "No Shell");
375
//(mba): here maybe as in Beanframe NotifyEvent ?!
376
3.93k
}
377
378
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */