Coverage Report

Created: 2026-10-14 09:33

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/sd/source/ui/dlg/filedlg.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 <config_features.h>
21
22
#include <com/sun/star/media/XPlayer.hpp>
23
#include <com/sun/star/lang/IllegalArgumentException.hpp>
24
#include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp>
25
#include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
26
#include <com/sun/star/ui/dialogs/XFilePicker3.hpp>
27
#include <com/sun/star/ui/dialogs/XFilePickerControlAccess.hpp>
28
#include <com/sun/star/ui/dialogs/FilePickerEvent.hpp>
29
#include <vcl/idle.hxx>
30
#include <osl/diagnose.h>
31
#include <vcl/svapp.hxx>
32
#include <sfx2/filedlghelper.hxx>
33
#include <avmedia/mediawindow.hxx>
34
#include <filedlg.hxx>
35
#include <sdresid.hxx>
36
#include <strings.hrc>
37
38
// -----------      SdFileDialog_Imp        ---------------------------
39
40
class SdFileDialog_Imp : public sfx2::FileDialogHelper
41
{
42
private:
43
    friend class SdOpenSoundFileDialog;
44
45
    css::uno::Reference< css::ui::dialogs::XFilePickerControlAccess >   mxControlAccess;
46
47
    css::uno::Reference< css::media::XPlayer > mxPlayer;
48
    ImplSVEvent * mnPlaySoundEvent;
49
    bool mbLabelPlaying;
50
    Idle maUpdateIdle;
51
52
    DECL_LINK( PlayMusicHdl, void *, void );
53
    DECL_LINK( IsMusicStoppedHdl, Timer *, void );
54
55
public:
56
    explicit SdFileDialog_Imp(weld::Window *pParent);
57
    virtual ~SdFileDialog_Imp() override;
58
59
    // overwritten from FileDialogHelper, to receive user feedback
60
    virtual void ControlStateChanged( const css::ui::dialogs::FilePickerEvent& aEvent ) override;
61
};
62
63
void SdFileDialog_Imp::ControlStateChanged( const css::ui::dialogs::FilePickerEvent& aEvent )
64
0
{
65
0
    SolarMutexGuard aGuard;
66
67
0
    switch( aEvent.ElementId )
68
0
    {
69
0
        case css::ui::dialogs::ExtendedFilePickerElementIds::PUSHBUTTON_PLAY:
70
0
            if( mxControlAccess.is() )
71
0
            {
72
0
                if( mnPlaySoundEvent )
73
0
                    Application::RemoveUserEvent( mnPlaySoundEvent );
74
75
0
                mnPlaySoundEvent = Application::PostUserEvent( LINK( this, SdFileDialog_Imp, PlayMusicHdl ) );
76
0
            }
77
0
            break;
78
0
    }
79
0
}
80
81
IMPL_LINK_NOARG(SdFileDialog_Imp, PlayMusicHdl, void*, void)
82
0
{
83
0
    maUpdateIdle.Stop();
84
0
    mnPlaySoundEvent = nullptr;
85
86
0
    if (mxPlayer.is())
87
0
    {
88
0
        if (mxPlayer->isPlaying())
89
0
            mxPlayer->stop();
90
0
        mxPlayer.clear();
91
0
    }
92
93
0
#if HAVE_FEATURE_AVMEDIA
94
0
    if( mbLabelPlaying )
95
0
    {
96
0
        try
97
0
        {
98
0
            mxControlAccess->setLabel( css::ui::dialogs::ExtendedFilePickerElementIds::PUSHBUTTON_PLAY,
99
0
                                       SdResId( STR_PLAY ) );
100
0
            mbLabelPlaying = false;
101
0
        }
102
0
        catch(const css::lang::IllegalArgumentException&)
103
0
        {
104
#ifdef DBG_UTIL
105
            OSL_FAIL( "Cannot access play button" );
106
#endif
107
0
        }
108
0
    }
109
0
    else
110
0
    {
111
0
        OUString aUrl( GetPath() );
112
0
        if ( !aUrl.isEmpty() )
113
0
        {
114
0
            try
115
0
            {
116
0
                mxPlayer.set( avmedia::MediaWindow::createPlayer( aUrl, u""_ustr ), css::uno::UNO_SET_THROW );
117
0
                mxPlayer->start();
118
0
                maUpdateIdle.Start();
119
0
            }
120
0
            catch (const css::uno::Exception&)
121
0
            {
122
0
                mxPlayer.clear();
123
0
            }
124
125
0
            if (mxPlayer.is())
126
0
            {
127
0
                try
128
0
                {
129
0
                    mxControlAccess->setLabel( css::ui::dialogs::ExtendedFilePickerElementIds::PUSHBUTTON_PLAY,
130
0
                                               SdResId( STR_STOP ) );
131
0
                    mbLabelPlaying = true;
132
0
                }
133
0
                catch (const css::lang::IllegalArgumentException&)
134
0
                {
135
#ifdef DBG_UTIL
136
                    OSL_FAIL( "Cannot access play button" );
137
#endif
138
0
                }
139
0
            }
140
0
        }
141
0
    }
142
0
#endif
143
0
}
144
145
IMPL_LINK_NOARG(SdFileDialog_Imp, IsMusicStoppedHdl, Timer *, void)
146
0
{
147
0
    SolarMutexGuard aGuard;
148
149
0
    if (mxPlayer.is() && mxPlayer->isPlaying() &&
150
0
            mxPlayer->getMediaTime() < mxPlayer->getDuration())
151
0
    {
152
0
        maUpdateIdle.Start();
153
0
        return;
154
0
    }
155
156
0
    if( !mxControlAccess.is() )
157
0
        return;
158
159
0
    try
160
0
    {
161
0
        mxControlAccess->setLabel( css::ui::dialogs::ExtendedFilePickerElementIds::PUSHBUTTON_PLAY,
162
0
                                   SdResId( STR_PLAY ) );
163
0
        mbLabelPlaying = false;
164
0
    }
165
0
    catch (const css::lang::IllegalArgumentException&)
166
0
    {
167
#ifdef DBG_UTIL
168
        OSL_FAIL( "Cannot access play button" );
169
#endif
170
0
    }
171
0
}
172
173
SdFileDialog_Imp::SdFileDialog_Imp(weld::Window* pParent)
174
0
    : FileDialogHelper(css::ui::dialogs::TemplateDescription::FILEOPEN_LINK_PLAY, FileDialogFlags::NONE, pParent)
175
0
    , mnPlaySoundEvent(nullptr)
176
0
    , mbLabelPlaying(false)
177
0
    , maUpdateIdle( "SdFileDialog_Imp maUpdateIdle" )
178
0
{
179
0
    maUpdateIdle.SetInvokeHandler(LINK(this, SdFileDialog_Imp, IsMusicStoppedHdl));
180
181
0
    css::uno::Reference < css::ui::dialogs::XFilePicker3 > xFileDlg = GetFilePicker();
182
183
    // get the control access
184
0
    mxControlAccess.set( xFileDlg, css::uno::UNO_QUERY );
185
186
0
    if( !mxControlAccess.is() )
187
0
        return;
188
189
0
    try
190
0
    {
191
0
        mxControlAccess->setLabel( css::ui::dialogs::ExtendedFilePickerElementIds::PUSHBUTTON_PLAY,
192
0
                                   SdResId( STR_PLAY ) );
193
0
    }
194
0
    catch (const css::lang::IllegalArgumentException&)
195
0
    {
196
#ifdef DBG_UTIL
197
        OSL_FAIL( "Cannot set play button label" );
198
#endif
199
0
    }
200
0
}
201
202
SdFileDialog_Imp::~SdFileDialog_Imp()
203
0
{
204
0
    if( mnPlaySoundEvent )
205
0
        Application::RemoveUserEvent( mnPlaySoundEvent );
206
0
}
207
208
// -----------      SdOpenSoundFileDialog       -----------------------
209
210
// these are simple forwarders
211
SdOpenSoundFileDialog::SdOpenSoundFileDialog(weld::Window *pParent)
212
0
    : mpImpl(new SdFileDialog_Imp(pParent))
213
0
{
214
0
    OUString aDescr = SdResId(STR_ALL_FILES);
215
0
    mpImpl->AddFilter( aDescr, u"*.*"_ustr);
216
0
    mpImpl->SetContext(sfx2::FileDialogHelper::DrawImpressOpenSound);
217
218
    // setup filter
219
0
#if defined UNX
220
0
    aDescr = SdResId(STR_AU_FILE);
221
0
    mpImpl->AddFilter( aDescr, u"*.au;*.snd"_ustr);
222
0
    aDescr = SdResId(STR_VOC_FILE);
223
0
    mpImpl->AddFilter( aDescr, u"*.voc"_ustr);
224
0
    aDescr = SdResId(STR_WAV_FILE);
225
0
    mpImpl->AddFilter( aDescr, u"*.wav"_ustr);
226
0
    aDescr = SdResId(STR_AIFF_FILE);
227
0
    mpImpl->AddFilter( aDescr, u"*.aiff"_ustr);
228
0
    aDescr = SdResId(STR_SVX_FILE);
229
0
    mpImpl->AddFilter( aDescr, u"*.svx"_ustr);
230
#else
231
    aDescr = SdResId(STR_WAV_FILE);
232
    mpImpl->AddFilter( aDescr, "*.wav;*.mp3;*.ogg" );
233
    aDescr = SdResId(STR_MIDI_FILE);
234
    mpImpl->AddFilter( aDescr, "*.mid" );
235
#endif
236
0
}
237
238
SdOpenSoundFileDialog::~SdOpenSoundFileDialog()
239
0
{
240
0
}
241
242
ErrCode SdOpenSoundFileDialog::Execute()
243
0
{
244
0
    return mpImpl->Execute();
245
0
}
246
247
OUString SdOpenSoundFileDialog::GetPath() const
248
0
{
249
0
    return mpImpl->GetPath();
250
0
}
251
252
void SdOpenSoundFileDialog::SetPath( const OUString& rPath )
253
0
{
254
0
    mpImpl->SetDisplayDirectory( rPath );
255
0
}
256
257
// WIP, please don't remove, dear Clang plugins
258
bool SdOpenSoundFileDialog::IsInsertAsLinkSelected() const
259
0
{
260
0
    bool bInsertAsLinkSelected = false;
261
0
    css::uno::Reference<css::ui::dialogs::XFilePicker3> const xFilePicker(mpImpl->GetFilePicker());
262
0
    css::uno::Reference<css::ui::dialogs::XFilePickerControlAccess> const xControlAccess(xFilePicker, css::uno::UNO_QUERY_THROW);
263
0
    xControlAccess->getValue(css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_LINK, 0) >>= bInsertAsLinkSelected;
264
0
    return bInsertAsLinkSelected;
265
0
}
266
267
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */