Version 6.4.0.0.beta1, tag libreoffice-6.4.0.0.beta1
[LibreOffice.git] / vcl / unx / gtk3_kde5 / gtk3_kde5_filepicker.cxx
blobeec532d4091a6ad652f5802aacdfd8a80c5bc53c
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 .
20 #include <QUrl>
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"
36 #undef Region
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;
49 // helper functions
51 namespace
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" };
60 // 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
68 QString sDummyStr;
69 QUrl aUrl = KFileWidget::getStartUrl(QUrl(), sDummyStr);
70 aUrl.setPath("/dev/null");
73 Gtk3KDE5FilePicker::~Gtk3KDE5FilePicker() = default;
75 void SAL_CALL
76 Gtk3KDE5FilePicker::addFilePickerListener(const uno::Reference<XFilePickerListener>& xListener)
78 SolarMutexGuard aGuard;
79 m_xListener = xListener;
82 void SAL_CALL
83 Gtk3KDE5FilePicker::removeFilePickerListener(const uno::Reference<XFilePickerListener>&)
85 SolarMutexGuard aGuard;
86 m_xListener.clear();
89 void SAL_CALL Gtk3KDE5FilePicker::setTitle(const OUString& title)
91 m_ipc.sendCommand(Commands::SetTitle, title);
94 sal_Int16 SAL_CALL Gtk3KDE5FilePicker::execute()
96 SolarMutexGuard g;
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);
118 OUString dir;
119 m_ipc.readResponse(id, dir);
120 return dir;
123 uno::Sequence<OUString> SAL_CALL Gtk3KDE5FilePicker::getFiles()
125 uno::Sequence<OUString> seq = getSelectedFiles();
126 if (seq.getLength() > 1)
127 seq.realloc(1);
128 return seq;
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);
136 return 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);
152 OUString filter;
153 m_ipc.readResponse(id, filter);
154 return 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>());
175 else
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);
193 bool value = false;
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);
212 OUString label;
213 m_ipc.readResponse(id, label);
214 return label;
217 void Gtk3KDE5FilePicker::addCustomControl(sal_Int16 controlId)
219 const char* resId = nullptr;
221 switch (controlId)
223 case CHECKBOX_AUTOEXTENSION:
224 resId = STR_FPICKER_AUTO_EXTENSION;
225 break;
226 case CHECKBOX_PASSWORD:
227 resId = STR_FPICKER_PASSWORD;
228 break;
229 case CHECKBOX_FILTEROPTIONS:
230 resId = STR_FPICKER_FILTER_OPTIONS;
231 break;
232 case CHECKBOX_READONLY:
233 resId = STR_FPICKER_READONLY;
234 break;
235 case CHECKBOX_LINK:
236 resId = STR_FPICKER_INSERT_AS_LINK;
237 break;
238 case CHECKBOX_PREVIEW:
239 resId = STR_FPICKER_SHOW_PREVIEW;
240 break;
241 case CHECKBOX_SELECTION:
242 resId = STR_FPICKER_SELECTION;
243 break;
244 case CHECKBOX_GPGENCRYPTION:
245 resId = STR_FPICKER_GPGENCRYPT;
246 break;
247 case PUSHBUTTON_PLAY:
248 resId = STR_FPICKER_PLAY;
249 break;
250 case LISTBOX_VERSION:
251 resId = STR_FPICKER_VERSION;
252 break;
253 case LISTBOX_TEMPLATE:
254 resId = STR_FPICKER_TEMPLATES;
255 break;
256 case LISTBOX_IMAGE_TEMPLATE:
257 resId = STR_FPICKER_IMAGE_TEMPLATE;
258 break;
259 case LISTBOX_IMAGE_ANCHOR:
260 resId = STR_FPICKER_IMAGE_ANCHOR;
261 break;
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:
267 break;
270 switch (controlId)
272 case CHECKBOX_AUTOEXTENSION:
273 case CHECKBOX_PASSWORD:
274 case CHECKBOX_FILTEROPTIONS:
275 case CHECKBOX_READONLY:
276 case CHECKBOX_LINK:
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));
287 break;
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:
299 break;
303 void SAL_CALL Gtk3KDE5FilePicker::initialize(const uno::Sequence<uno::Any>& args)
305 // parameter checking
306 uno::Any arg;
307 if (args.getLength() == 0)
309 throw lang::IllegalArgumentException("no arguments", static_cast<XFilePicker2*>(this), 1);
312 arg = args[0];
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;
322 arg >>= templateId;
324 bool saveDialog = false;
325 switch (templateId)
327 case FILEOPEN_SIMPLE:
328 break;
330 case FILESAVE_SIMPLE:
331 saveDialog = true;
332 break;
334 case FILESAVE_AUTOEXTENSION:
335 saveDialog = true;
336 addCustomControl(CHECKBOX_AUTOEXTENSION);
337 break;
339 case FILESAVE_AUTOEXTENSION_PASSWORD:
341 saveDialog = true;
342 addCustomControl(CHECKBOX_PASSWORD);
343 addCustomControl(CHECKBOX_GPGENCRYPTION);
344 break;
346 case FILESAVE_AUTOEXTENSION_PASSWORD_FILTEROPTIONS:
348 saveDialog = true;
349 addCustomControl(CHECKBOX_AUTOEXTENSION);
350 addCustomControl(CHECKBOX_PASSWORD);
351 addCustomControl(CHECKBOX_GPGENCRYPTION);
352 addCustomControl(CHECKBOX_FILTEROPTIONS);
353 break;
355 case FILESAVE_AUTOEXTENSION_SELECTION:
356 saveDialog = true;
357 addCustomControl(CHECKBOX_AUTOEXTENSION);
358 addCustomControl(CHECKBOX_SELECTION);
359 break;
361 case FILESAVE_AUTOEXTENSION_TEMPLATE:
362 saveDialog = true;
363 addCustomControl(CHECKBOX_AUTOEXTENSION);
364 addCustomControl(LISTBOX_TEMPLATE);
365 break;
367 case FILEOPEN_LINK_PREVIEW_IMAGE_TEMPLATE:
368 addCustomControl(CHECKBOX_LINK);
369 addCustomControl(CHECKBOX_PREVIEW);
370 addCustomControl(LISTBOX_IMAGE_TEMPLATE);
371 break;
373 case FILEOPEN_LINK_PREVIEW_IMAGE_ANCHOR:
374 addCustomControl(CHECKBOX_LINK);
375 addCustomControl(CHECKBOX_PREVIEW);
376 addCustomControl(LISTBOX_IMAGE_ANCHOR);
377 break;
379 case FILEOPEN_PLAY:
380 addCustomControl(PUSHBUTTON_PLAY);
381 break;
383 case FILEOPEN_LINK_PLAY:
384 addCustomControl(CHECKBOX_LINK);
385 addCustomControl(PUSHBUTTON_PLAY);
386 break;
388 case FILEOPEN_READONLY_VERSION:
389 addCustomControl(CHECKBOX_READONLY);
390 addCustomControl(LISTBOX_VERSION);
391 break;
393 case FILEOPEN_LINK_PREVIEW:
394 addCustomControl(CHECKBOX_LINK);
395 addCustomControl(CHECKBOX_PREVIEW);
396 break;
398 case FILEOPEN_PREVIEW:
399 addCustomControl(CHECKBOX_PREVIEW);
400 break;
402 default:
403 SAL_INFO("vcl.gtkkde5", "unknown templates " << templateId);
404 return;
407 setTitle(getResString(saveDialog ? STR_FPICKER_SAVE : STR_FPICKER_OPEN));
409 m_ipc.sendCommand(Commands::Initialize, saveDialog);
412 void SAL_CALL Gtk3KDE5FilePicker::cancel()
414 // TODO
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: */