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>
34 #include "FPServiceInfo.hxx"
38 #include <strings.hrc>
40 using namespace ::com::sun::star
;
41 using namespace ::com::sun::star::ui::dialogs
;
42 using namespace ::com::sun::star::ui::dialogs::TemplateDescription
;
43 using namespace ::com::sun::star::ui::dialogs::ExtendedFilePickerElementIds
;
44 using namespace ::com::sun::star::ui::dialogs::CommonFilePickerElementIds
;
45 using namespace ::com::sun::star::lang
;
46 using namespace ::com::sun::star::beans
;
47 using namespace ::com::sun::star::uno
;
53 uno::Sequence
<OUString
> FilePicker_getSupportedServiceNames()
55 return { "com.sun.star.ui.dialogs.FilePicker", "com.sun.star.ui.dialogs.SystemFilePicker",
56 "com.sun.star.ui.dialogs.Gtk3KDE5FilePicker" };
62 Gtk3KDE5FilePicker::Gtk3KDE5FilePicker(const uno::Reference
<uno::XComponentContext
>&)
63 : Gtk3KDE5FilePicker_Base(_helperMutex
)
65 setMultiSelectionMode(false);
67 // tdf#124598 dummy KWidget use to make gtk3_kde5 VCL plugin link against KIO libraries
69 QUrl aUrl
= KFileWidget::getStartUrl(QUrl(), sDummyStr
);
70 aUrl
.setPath("/dev/null");
73 Gtk3KDE5FilePicker::~Gtk3KDE5FilePicker() = default;
76 Gtk3KDE5FilePicker::addFilePickerListener(const uno::Reference
<XFilePickerListener
>& xListener
)
78 SolarMutexGuard aGuard
;
79 m_xListener
= xListener
;
83 Gtk3KDE5FilePicker::removeFilePickerListener(const uno::Reference
<XFilePickerListener
>&)
85 SolarMutexGuard aGuard
;
89 void SAL_CALL
Gtk3KDE5FilePicker::setTitle(const OUString
& title
)
91 m_ipc
.sendCommand(Commands::SetTitle
, title
);
94 sal_Int16 SAL_CALL
Gtk3KDE5FilePicker::execute()
97 return m_ipc
.execute();
100 void SAL_CALL
Gtk3KDE5FilePicker::setMultiSelectionMode(sal_Bool multiSelect
)
102 m_ipc
.sendCommand(Commands::SetMultiSelectionMode
, bool(multiSelect
));
105 void SAL_CALL
Gtk3KDE5FilePicker::setDefaultName(const OUString
& name
)
107 m_ipc
.sendCommand(Commands::SetDefaultName
, name
);
110 void SAL_CALL
Gtk3KDE5FilePicker::setDisplayDirectory(const OUString
& dir
)
112 m_ipc
.sendCommand(Commands::SetDisplayDirectory
, dir
);
115 OUString SAL_CALL
Gtk3KDE5FilePicker::getDisplayDirectory()
117 auto id
= m_ipc
.sendCommand(Commands::GetDisplayDirectory
);
119 m_ipc
.readResponse(id
, dir
);
123 uno::Sequence
<OUString
> SAL_CALL
Gtk3KDE5FilePicker::getFiles()
125 uno::Sequence
<OUString
> seq
= getSelectedFiles();
126 if (seq
.getLength() > 1)
131 uno::Sequence
<OUString
> SAL_CALL
Gtk3KDE5FilePicker::getSelectedFiles()
133 auto id
= m_ipc
.sendCommand(Commands::GetSelectedFiles
);
134 uno::Sequence
<OUString
> seq
;
135 m_ipc
.readResponse(id
, seq
);
139 void SAL_CALL
Gtk3KDE5FilePicker::appendFilter(const OUString
& title
, const OUString
& filter
)
141 m_ipc
.sendCommand(Commands::AppendFilter
, title
, filter
);
144 void SAL_CALL
Gtk3KDE5FilePicker::setCurrentFilter(const OUString
& title
)
146 m_ipc
.sendCommand(Commands::SetCurrentFilter
, title
);
149 OUString SAL_CALL
Gtk3KDE5FilePicker::getCurrentFilter()
151 auto id
= m_ipc
.sendCommand(Commands::GetCurrentFilter
);
153 m_ipc
.readResponse(id
, filter
);
157 void SAL_CALL
Gtk3KDE5FilePicker::appendFilterGroup(const OUString
& /*rGroupTitle*/,
158 const uno::Sequence
<beans::StringPair
>& filters
)
160 const sal_uInt16 length
= filters
.getLength();
161 for (sal_uInt16 i
= 0; i
< length
; ++i
)
163 beans::StringPair aPair
= filters
[i
];
164 appendFilter(aPair
.First
, aPair
.Second
);
168 void SAL_CALL
Gtk3KDE5FilePicker::setValue(sal_Int16 controlId
, sal_Int16 nControlAction
,
169 const uno::Any
& value
)
171 if (value
.has
<bool>())
173 m_ipc
.sendCommand(Commands::SetValue
, controlId
, nControlAction
, value
.get
<bool>());
177 SAL_INFO("vcl.gtkkde5", "set value of unhandled type " << controlId
);
181 uno::Any SAL_CALL
Gtk3KDE5FilePicker::getValue(sal_Int16 controlId
, sal_Int16 nControlAction
)
183 if (CHECKBOX_AUTOEXTENSION
== controlId
)
184 // We ignore this one and rely on QFileDialog to provide the function.
185 // Always return false, to pretend we do not support this, otherwise
186 // LO core would try to be smart and cut the extension in some places,
187 // interfering with QFileDialog's handling of it. QFileDialog also
188 // saves the value of the setting, so LO core is not needed for that either.
189 return uno::Any(false);
191 auto id
= m_ipc
.sendCommand(Commands::GetValue
, controlId
, nControlAction
);
194 m_ipc
.readResponse(id
, value
);
196 return uno::Any(value
);
199 void SAL_CALL
Gtk3KDE5FilePicker::enableControl(sal_Int16 controlId
, sal_Bool enable
)
201 m_ipc
.sendCommand(Commands::EnableControl
, controlId
, bool(enable
));
204 void SAL_CALL
Gtk3KDE5FilePicker::setLabel(sal_Int16 controlId
, const OUString
& label
)
206 m_ipc
.sendCommand(Commands::SetLabel
, controlId
, label
);
209 OUString SAL_CALL
Gtk3KDE5FilePicker::getLabel(sal_Int16 controlId
)
211 auto id
= m_ipc
.sendCommand(Commands::GetLabel
, controlId
);
213 m_ipc
.readResponse(id
, label
);
217 void Gtk3KDE5FilePicker::addCustomControl(sal_Int16 controlId
)
219 const char* resId
= nullptr;
223 case CHECKBOX_AUTOEXTENSION
:
224 resId
= STR_FPICKER_AUTO_EXTENSION
;
226 case CHECKBOX_PASSWORD
:
227 resId
= STR_FPICKER_PASSWORD
;
229 case CHECKBOX_FILTEROPTIONS
:
230 resId
= STR_FPICKER_FILTER_OPTIONS
;
232 case CHECKBOX_READONLY
:
233 resId
= STR_FPICKER_READONLY
;
236 resId
= STR_FPICKER_INSERT_AS_LINK
;
238 case CHECKBOX_PREVIEW
:
239 resId
= STR_FPICKER_SHOW_PREVIEW
;
241 case CHECKBOX_SELECTION
:
242 resId
= STR_FPICKER_SELECTION
;
244 case CHECKBOX_GPGENCRYPTION
:
245 resId
= STR_FPICKER_GPGENCRYPT
;
247 case PUSHBUTTON_PLAY
:
248 resId
= STR_FPICKER_PLAY
;
250 case LISTBOX_VERSION
:
251 resId
= STR_FPICKER_VERSION
;
253 case LISTBOX_TEMPLATE
:
254 resId
= STR_FPICKER_TEMPLATES
;
256 case LISTBOX_IMAGE_TEMPLATE
:
257 resId
= STR_FPICKER_IMAGE_TEMPLATE
;
259 case LISTBOX_IMAGE_ANCHOR
:
260 resId
= STR_FPICKER_IMAGE_ANCHOR
;
262 case LISTBOX_VERSION_LABEL
:
263 case LISTBOX_TEMPLATE_LABEL
:
264 case LISTBOX_IMAGE_TEMPLATE_LABEL
:
265 case LISTBOX_IMAGE_ANCHOR_LABEL
:
266 case LISTBOX_FILTER_SELECTOR
:
272 case CHECKBOX_AUTOEXTENSION
:
273 case CHECKBOX_PASSWORD
:
274 case CHECKBOX_FILTEROPTIONS
:
275 case CHECKBOX_READONLY
:
277 case CHECKBOX_PREVIEW
:
278 case CHECKBOX_SELECTION
:
279 case CHECKBOX_GPGENCRYPTION
:
281 // the checkbox is created even for CHECKBOX_AUTOEXTENSION to simplify
282 // code, but the checkbox is hidden and ignored
283 bool hidden
= controlId
== CHECKBOX_AUTOEXTENSION
;
285 m_ipc
.sendCommand(Commands::AddCheckBox
, controlId
, hidden
, getResString(resId
));
289 case PUSHBUTTON_PLAY
:
290 case LISTBOX_VERSION
:
291 case LISTBOX_TEMPLATE
:
292 case LISTBOX_IMAGE_TEMPLATE
:
293 case LISTBOX_IMAGE_ANCHOR
:
294 case LISTBOX_VERSION_LABEL
:
295 case LISTBOX_TEMPLATE_LABEL
:
296 case LISTBOX_IMAGE_TEMPLATE_LABEL
:
297 case LISTBOX_IMAGE_ANCHOR_LABEL
:
298 case LISTBOX_FILTER_SELECTOR
:
303 void SAL_CALL
Gtk3KDE5FilePicker::initialize(const uno::Sequence
<uno::Any
>& args
)
305 // parameter checking
307 if (args
.getLength() == 0)
309 throw lang::IllegalArgumentException("no arguments", static_cast<XFilePicker2
*>(this), 1);
314 if ((arg
.getValueType() != cppu::UnoType
<sal_Int16
>::get())
315 && (arg
.getValueType() != cppu::UnoType
<sal_Int8
>::get()))
317 throw lang::IllegalArgumentException("invalid argument type",
318 static_cast<XFilePicker2
*>(this), 1);
321 sal_Int16 templateId
= -1;
324 bool saveDialog
= false;
327 case FILEOPEN_SIMPLE
:
330 case FILESAVE_SIMPLE
:
334 case FILESAVE_AUTOEXTENSION
:
336 addCustomControl(CHECKBOX_AUTOEXTENSION
);
339 case FILESAVE_AUTOEXTENSION_PASSWORD
:
342 addCustomControl(CHECKBOX_PASSWORD
);
343 addCustomControl(CHECKBOX_GPGENCRYPTION
);
346 case FILESAVE_AUTOEXTENSION_PASSWORD_FILTEROPTIONS
:
349 addCustomControl(CHECKBOX_AUTOEXTENSION
);
350 addCustomControl(CHECKBOX_PASSWORD
);
351 addCustomControl(CHECKBOX_GPGENCRYPTION
);
352 addCustomControl(CHECKBOX_FILTEROPTIONS
);
355 case FILESAVE_AUTOEXTENSION_SELECTION
:
357 addCustomControl(CHECKBOX_AUTOEXTENSION
);
358 addCustomControl(CHECKBOX_SELECTION
);
361 case FILESAVE_AUTOEXTENSION_TEMPLATE
:
363 addCustomControl(CHECKBOX_AUTOEXTENSION
);
364 addCustomControl(LISTBOX_TEMPLATE
);
367 case FILEOPEN_LINK_PREVIEW_IMAGE_TEMPLATE
:
368 addCustomControl(CHECKBOX_LINK
);
369 addCustomControl(CHECKBOX_PREVIEW
);
370 addCustomControl(LISTBOX_IMAGE_TEMPLATE
);
373 case FILEOPEN_LINK_PREVIEW_IMAGE_ANCHOR
:
374 addCustomControl(CHECKBOX_LINK
);
375 addCustomControl(CHECKBOX_PREVIEW
);
376 addCustomControl(LISTBOX_IMAGE_ANCHOR
);
380 addCustomControl(PUSHBUTTON_PLAY
);
383 case FILEOPEN_LINK_PLAY
:
384 addCustomControl(CHECKBOX_LINK
);
385 addCustomControl(PUSHBUTTON_PLAY
);
388 case FILEOPEN_READONLY_VERSION
:
389 addCustomControl(CHECKBOX_READONLY
);
390 addCustomControl(LISTBOX_VERSION
);
393 case FILEOPEN_LINK_PREVIEW
:
394 addCustomControl(CHECKBOX_LINK
);
395 addCustomControl(CHECKBOX_PREVIEW
);
398 case FILEOPEN_PREVIEW
:
399 addCustomControl(CHECKBOX_PREVIEW
);
403 SAL_INFO("vcl.gtkkde5", "unknown templates " << templateId
);
407 setTitle(getResString(saveDialog
? STR_FPICKER_SAVE
: STR_FPICKER_OPEN
));
409 m_ipc
.sendCommand(Commands::Initialize
, saveDialog
);
412 void SAL_CALL
Gtk3KDE5FilePicker::cancel()
417 void Gtk3KDE5FilePicker::disposing(const lang::EventObject
& rEvent
)
419 uno::Reference
<XFilePickerListener
> xFilePickerListener(rEvent
.Source
, uno::UNO_QUERY
);
421 if (xFilePickerListener
.is())
423 removeFilePickerListener(xFilePickerListener
);
427 OUString SAL_CALL
Gtk3KDE5FilePicker::getImplementationName() { return FILE_PICKER_IMPL_NAME
; }
429 sal_Bool SAL_CALL
Gtk3KDE5FilePicker::supportsService(const OUString
& ServiceName
)
431 return cppu::supportsService(this, ServiceName
);
434 uno::Sequence
<OUString
> SAL_CALL
Gtk3KDE5FilePicker::getSupportedServiceNames()
436 return FilePicker_getSupportedServiceNames();
439 void Gtk3KDE5FilePicker::filterChanged()
441 FilePickerEvent aEvent
;
442 aEvent
.ElementId
= LISTBOX_FILTER
;
443 SAL_INFO("vcl.gtkkde5", "filter changed");
444 if (m_xListener
.is())
445 m_xListener
->controlStateChanged(aEvent
);
448 void Gtk3KDE5FilePicker::selectionChanged()
450 FilePickerEvent aEvent
;
451 SAL_INFO("vcl.gtkkde5", "file selection changed");
452 if (m_xListener
.is())
453 m_xListener
->fileSelectionChanged(aEvent
);
456 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */