1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
21 #include <KFileWidget>
23 #include "gtk3_kde5_filepicker.hxx"
25 #include <com/sun/star/lang/IllegalArgumentException.hpp>
26 #include <cppuhelper/supportsservice.hxx>
27 #include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
28 #include <com/sun/star/ui/dialogs/CommonFilePickerElementIds.hpp>
29 #include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp>
31 #include <sal/log.hxx>
32 #include <vcl/svapp.hxx>
33 #include "FPServiceInfo.hxx"
37 #include <fpicker/strings.hrc>
39 using namespace ::com::sun::star
;
40 using namespace ::com::sun::star::ui::dialogs
;
41 using namespace ::com::sun::star::ui::dialogs::TemplateDescription
;
42 using namespace ::com::sun::star::ui::dialogs::ExtendedFilePickerElementIds
;
43 using namespace ::com::sun::star::ui::dialogs::CommonFilePickerElementIds
;
44 using namespace ::com::sun::star::lang
;
45 using namespace ::com::sun::star::beans
;
46 using namespace ::com::sun::star::uno
;
52 uno::Sequence
<OUString
> FilePicker_getSupportedServiceNames()
54 return { "com.sun.star.ui.dialogs.FilePicker", "com.sun.star.ui.dialogs.SystemFilePicker",
55 "com.sun.star.ui.dialogs.Gtk3KDE5FilePicker" };
61 Gtk3KDE5FilePicker::Gtk3KDE5FilePicker(const uno::Reference
<uno::XComponentContext
>&)
62 : Gtk3KDE5FilePicker_Base(_helperMutex
)
64 setMultiSelectionMode(false);
66 // tdf#124598 dummy KWidget use to make gtk3_kde5 VCL plugin link against KIO libraries
68 QUrl aUrl
= KFileWidget::getStartUrl(QUrl(), sDummyStr
);
69 aUrl
.setPath("/dev/null");
72 Gtk3KDE5FilePicker::~Gtk3KDE5FilePicker() = default;
75 Gtk3KDE5FilePicker::addFilePickerListener(const uno::Reference
<XFilePickerListener
>& xListener
)
77 SolarMutexGuard aGuard
;
78 m_xListener
= xListener
;
82 Gtk3KDE5FilePicker::removeFilePickerListener(const uno::Reference
<XFilePickerListener
>&)
84 SolarMutexGuard aGuard
;
88 void SAL_CALL
Gtk3KDE5FilePicker::setTitle(const OUString
& title
)
90 m_ipc
.sendCommand(Commands::SetTitle
, title
);
93 sal_Int16 SAL_CALL
Gtk3KDE5FilePicker::execute()
96 return m_ipc
.execute();
99 void SAL_CALL
Gtk3KDE5FilePicker::setMultiSelectionMode(sal_Bool multiSelect
)
101 m_ipc
.sendCommand(Commands::SetMultiSelectionMode
, bool(multiSelect
));
104 void SAL_CALL
Gtk3KDE5FilePicker::setDefaultName(const OUString
& name
)
106 m_ipc
.sendCommand(Commands::SetDefaultName
, name
);
109 void SAL_CALL
Gtk3KDE5FilePicker::setDisplayDirectory(const OUString
& dir
)
111 m_ipc
.sendCommand(Commands::SetDisplayDirectory
, dir
);
114 OUString SAL_CALL
Gtk3KDE5FilePicker::getDisplayDirectory()
116 auto id
= m_ipc
.sendCommand(Commands::GetDisplayDirectory
);
118 m_ipc
.readResponse(id
, dir
);
122 uno::Sequence
<OUString
> SAL_CALL
Gtk3KDE5FilePicker::getFiles()
124 uno::Sequence
<OUString
> seq
= getSelectedFiles();
125 if (seq
.getLength() > 1)
130 uno::Sequence
<OUString
> SAL_CALL
Gtk3KDE5FilePicker::getSelectedFiles()
132 auto id
= m_ipc
.sendCommand(Commands::GetSelectedFiles
);
133 uno::Sequence
<OUString
> seq
;
134 m_ipc
.readResponse(id
, seq
);
138 void SAL_CALL
Gtk3KDE5FilePicker::appendFilter(const OUString
& title
, const OUString
& filter
)
140 m_ipc
.sendCommand(Commands::AppendFilter
, title
, filter
);
143 void SAL_CALL
Gtk3KDE5FilePicker::setCurrentFilter(const OUString
& title
)
145 m_ipc
.sendCommand(Commands::SetCurrentFilter
, title
);
148 OUString SAL_CALL
Gtk3KDE5FilePicker::getCurrentFilter()
150 auto id
= m_ipc
.sendCommand(Commands::GetCurrentFilter
);
152 m_ipc
.readResponse(id
, filter
);
156 void SAL_CALL
Gtk3KDE5FilePicker::appendFilterGroup(const OUString
& /*rGroupTitle*/,
157 const uno::Sequence
<beans::StringPair
>& filters
)
159 const sal_uInt16 length
= filters
.getLength();
160 for (sal_uInt16 i
= 0; i
< length
; ++i
)
162 beans::StringPair aPair
= filters
[i
];
163 appendFilter(aPair
.First
, aPair
.Second
);
167 void SAL_CALL
Gtk3KDE5FilePicker::setValue(sal_Int16 controlId
, sal_Int16 nControlAction
,
168 const uno::Any
& value
)
170 if (value
.has
<bool>())
172 m_ipc
.sendCommand(Commands::SetValue
, controlId
, nControlAction
, value
.get
<bool>());
176 SAL_INFO("vcl.gtkkde5", "set value of unhandled type " << controlId
);
180 uno::Any SAL_CALL
Gtk3KDE5FilePicker::getValue(sal_Int16 controlId
, sal_Int16 nControlAction
)
182 if (CHECKBOX_AUTOEXTENSION
== controlId
)
183 // We ignore this one and rely on QFileDialog to provide the function.
184 // Always return false, to pretend we do not support this, otherwise
185 // LO core would try to be smart and cut the extension in some places,
186 // interfering with QFileDialog's handling of it. QFileDialog also
187 // saves the value of the setting, so LO core is not needed for that either.
188 return uno::Any(false);
190 auto id
= m_ipc
.sendCommand(Commands::GetValue
, controlId
, nControlAction
);
193 m_ipc
.readResponse(id
, value
);
195 return uno::Any(value
);
198 void SAL_CALL
Gtk3KDE5FilePicker::enableControl(sal_Int16 controlId
, sal_Bool enable
)
200 m_ipc
.sendCommand(Commands::EnableControl
, controlId
, bool(enable
));
203 void SAL_CALL
Gtk3KDE5FilePicker::setLabel(sal_Int16 controlId
, const OUString
& label
)
205 m_ipc
.sendCommand(Commands::SetLabel
, controlId
, label
);
208 OUString SAL_CALL
Gtk3KDE5FilePicker::getLabel(sal_Int16 controlId
)
210 auto id
= m_ipc
.sendCommand(Commands::GetLabel
, controlId
);
212 m_ipc
.readResponse(id
, label
);
216 void Gtk3KDE5FilePicker::addCustomControl(sal_Int16 controlId
)
222 case CHECKBOX_AUTOEXTENSION
:
223 resId
= STR_SVT_FILEPICKER_AUTO_EXTENSION
;
225 case CHECKBOX_PASSWORD
:
226 resId
= STR_SVT_FILEPICKER_PASSWORD
;
228 case CHECKBOX_FILTEROPTIONS
:
229 resId
= STR_SVT_FILEPICKER_FILTER_OPTIONS
;
231 case CHECKBOX_READONLY
:
232 resId
= STR_SVT_FILEPICKER_READONLY
;
235 resId
= STR_SVT_FILEPICKER_INSERT_AS_LINK
;
237 case CHECKBOX_PREVIEW
:
238 resId
= STR_SVT_FILEPICKER_SHOW_PREVIEW
;
240 case CHECKBOX_SELECTION
:
241 resId
= STR_SVT_FILEPICKER_SELECTION
;
243 case CHECKBOX_GPGENCRYPTION
:
244 resId
= STR_SVT_FILEPICKER_GPGENCRYPT
;
246 case PUSHBUTTON_PLAY
:
247 resId
= STR_SVT_FILEPICKER_PLAY
;
249 case LISTBOX_VERSION
:
250 resId
= STR_SVT_FILEPICKER_VERSION
;
252 case LISTBOX_TEMPLATE
:
253 resId
= STR_SVT_FILEPICKER_TEMPLATES
;
255 case LISTBOX_IMAGE_TEMPLATE
:
256 resId
= STR_SVT_FILEPICKER_IMAGE_TEMPLATE
;
258 case LISTBOX_IMAGE_ANCHOR
:
259 resId
= STR_SVT_FILEPICKER_IMAGE_ANCHOR
;
261 case LISTBOX_VERSION_LABEL
:
262 case LISTBOX_TEMPLATE_LABEL
:
263 case LISTBOX_IMAGE_TEMPLATE_LABEL
:
264 case LISTBOX_IMAGE_ANCHOR_LABEL
:
265 case LISTBOX_FILTER_SELECTOR
:
271 case CHECKBOX_AUTOEXTENSION
:
272 case CHECKBOX_PASSWORD
:
273 case CHECKBOX_FILTEROPTIONS
:
274 case CHECKBOX_READONLY
:
276 case CHECKBOX_PREVIEW
:
277 case CHECKBOX_SELECTION
:
278 case CHECKBOX_GPGENCRYPTION
:
280 // the checkbox is created even for CHECKBOX_AUTOEXTENSION to simplify
281 // code, but the checkbox is hidden and ignored
282 bool hidden
= controlId
== CHECKBOX_AUTOEXTENSION
;
284 m_ipc
.sendCommand(Commands::AddCheckBox
, controlId
, hidden
, getResString(resId
));
288 case PUSHBUTTON_PLAY
:
289 case LISTBOX_VERSION
:
290 case LISTBOX_TEMPLATE
:
291 case LISTBOX_IMAGE_TEMPLATE
:
292 case LISTBOX_IMAGE_ANCHOR
:
293 case LISTBOX_VERSION_LABEL
:
294 case LISTBOX_TEMPLATE_LABEL
:
295 case LISTBOX_IMAGE_TEMPLATE_LABEL
:
296 case LISTBOX_IMAGE_ANCHOR_LABEL
:
297 case LISTBOX_FILTER_SELECTOR
:
302 void SAL_CALL
Gtk3KDE5FilePicker::initialize(const uno::Sequence
<uno::Any
>& args
)
304 // parameter checking
306 if (args
.getLength() == 0)
308 throw lang::IllegalArgumentException("no arguments", static_cast<XFilePicker2
*>(this), 1);
313 if ((arg
.getValueType() != cppu::UnoType
<sal_Int16
>::get())
314 && (arg
.getValueType() != cppu::UnoType
<sal_Int8
>::get()))
316 throw lang::IllegalArgumentException("invalid argument type",
317 static_cast<XFilePicker2
*>(this), 1);
320 sal_Int16 templateId
= -1;
323 bool saveDialog
= false;
326 case FILEOPEN_SIMPLE
:
329 case FILESAVE_SIMPLE
:
333 case FILESAVE_AUTOEXTENSION
:
335 addCustomControl(CHECKBOX_AUTOEXTENSION
);
338 case FILESAVE_AUTOEXTENSION_PASSWORD
:
341 addCustomControl(CHECKBOX_PASSWORD
);
342 addCustomControl(CHECKBOX_GPGENCRYPTION
);
345 case FILESAVE_AUTOEXTENSION_PASSWORD_FILTEROPTIONS
:
348 addCustomControl(CHECKBOX_AUTOEXTENSION
);
349 addCustomControl(CHECKBOX_PASSWORD
);
350 addCustomControl(CHECKBOX_GPGENCRYPTION
);
351 addCustomControl(CHECKBOX_FILTEROPTIONS
);
354 case FILESAVE_AUTOEXTENSION_SELECTION
:
356 addCustomControl(CHECKBOX_AUTOEXTENSION
);
357 addCustomControl(CHECKBOX_SELECTION
);
360 case FILESAVE_AUTOEXTENSION_TEMPLATE
:
362 addCustomControl(CHECKBOX_AUTOEXTENSION
);
363 addCustomControl(LISTBOX_TEMPLATE
);
366 case FILEOPEN_LINK_PREVIEW_IMAGE_TEMPLATE
:
367 addCustomControl(CHECKBOX_LINK
);
368 addCustomControl(CHECKBOX_PREVIEW
);
369 addCustomControl(LISTBOX_IMAGE_TEMPLATE
);
372 case FILEOPEN_LINK_PREVIEW_IMAGE_ANCHOR
:
373 addCustomControl(CHECKBOX_LINK
);
374 addCustomControl(CHECKBOX_PREVIEW
);
375 addCustomControl(LISTBOX_IMAGE_ANCHOR
);
379 addCustomControl(PUSHBUTTON_PLAY
);
382 case FILEOPEN_LINK_PLAY
:
383 addCustomControl(CHECKBOX_LINK
);
384 addCustomControl(PUSHBUTTON_PLAY
);
387 case FILEOPEN_READONLY_VERSION
:
388 addCustomControl(CHECKBOX_READONLY
);
389 addCustomControl(LISTBOX_VERSION
);
392 case FILEOPEN_LINK_PREVIEW
:
393 addCustomControl(CHECKBOX_LINK
);
394 addCustomControl(CHECKBOX_PREVIEW
);
397 case FILEOPEN_PREVIEW
:
398 addCustomControl(CHECKBOX_PREVIEW
);
402 SAL_INFO("vcl.gtkkde5", "unknown templates " << templateId
);
406 setTitle(getResString(saveDialog
? STR_FILEDLG_SAVE
: STR_FILEDLG_OPEN
));
408 m_ipc
.sendCommand(Commands::Initialize
, saveDialog
);
411 void SAL_CALL
Gtk3KDE5FilePicker::cancel()
416 void Gtk3KDE5FilePicker::disposing(const lang::EventObject
& rEvent
)
418 uno::Reference
<XFilePickerListener
> xFilePickerListener(rEvent
.Source
, uno::UNO_QUERY
);
420 if (xFilePickerListener
.is())
422 removeFilePickerListener(xFilePickerListener
);
426 OUString SAL_CALL
Gtk3KDE5FilePicker::getImplementationName() { return FILE_PICKER_IMPL_NAME
; }
428 sal_Bool SAL_CALL
Gtk3KDE5FilePicker::supportsService(const OUString
& ServiceName
)
430 return cppu::supportsService(this, ServiceName
);
433 uno::Sequence
<OUString
> SAL_CALL
Gtk3KDE5FilePicker::getSupportedServiceNames()
435 return FilePicker_getSupportedServiceNames();
438 void Gtk3KDE5FilePicker::filterChanged()
440 FilePickerEvent aEvent
;
441 aEvent
.ElementId
= LISTBOX_FILTER
;
442 SAL_INFO("vcl.gtkkde5", "filter changed");
443 if (m_xListener
.is())
444 m_xListener
->controlStateChanged(aEvent
);
447 void Gtk3KDE5FilePicker::selectionChanged()
449 FilePickerEvent aEvent
;
450 SAL_INFO("vcl.gtkkde5", "file selection changed");
451 if (m_xListener
.is())
452 m_xListener
->fileSelectionChanged(aEvent
);
455 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */