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 .
20 #include "kde5_filepicker_ipc.hxx"
23 #include <QApplication>
28 #include "kde5_filepicker.hxx"
30 void readIpcArg(std::istream
& stream
, QString
& string
)
32 const auto buffer
= readIpcStringArg(stream
);
33 string
= QString::fromUtf8(buffer
.data(), buffer
.size());
36 void sendIpcArg(std::ostream
& stream
, const QString
& string
)
38 const auto utf8
= string
.toUtf8();
39 sendIpcStringArg(stream
, utf8
.size(), utf8
.data());
42 static void sendIpcArg(std::ostream
& stream
, const QStringList
& list
)
44 stream
<< static_cast<uint32_t>(list
.size()) << ' ';
45 for (const auto& entry
: list
)
47 sendIpcArg(stream
, entry
);
51 static void readCommandArgs(Commands command
, QList
<QVariant
>& args
)
55 case Commands::SetTitle
:
58 readIpcArgs(std::cin
, title
);
62 case Commands::SetWinId
:
64 sal_uIntPtr winId
= 0;
65 readIpcArgs(std::cin
, winId
);
66 QVariant aWinIdVariant
;
67 aWinIdVariant
.setValue(winId
);
68 args
.append(aWinIdVariant
);
71 case Commands::SetMultiSelectionMode
:
73 bool multiSelection
= false;
74 readIpcArgs(std::cin
, multiSelection
);
75 args
.append(multiSelection
);
78 case Commands::SetDefaultName
:
81 readIpcArgs(std::cin
, name
);
85 case Commands::SetDisplayDirectory
:
88 readIpcArgs(std::cin
, dir
);
92 case Commands::AppendFilter
:
94 QString title
, filter
;
95 readIpcArgs(std::cin
, title
, filter
);
100 case Commands::SetCurrentFilter
:
103 readIpcArgs(std::cin
, title
);
107 case Commands::SetValue
:
109 sal_Int16 controlId
= 0;
110 sal_Int16 nControlAction
= 0;
112 readIpcArgs(std::cin
, controlId
, nControlAction
, value
);
113 args
.append(controlId
);
114 args
.append(nControlAction
);
118 case Commands::GetValue
:
120 sal_Int16 controlId
= 0;
121 sal_Int16 nControlAction
= 0;
122 readIpcArgs(std::cin
, controlId
, nControlAction
);
123 args
.append(controlId
);
124 args
.append(nControlAction
);
127 case Commands::EnableControl
:
129 sal_Int16 controlId
= 0;
130 bool enabled
= false;
131 readIpcArgs(std::cin
, controlId
, enabled
);
132 args
.append(controlId
);
133 args
.append(enabled
);
136 case Commands::SetLabel
:
138 sal_Int16 controlId
= 0;
140 readIpcArgs(std::cin
, controlId
, label
);
141 args
.append(controlId
);
145 case Commands::GetLabel
:
147 sal_Int16 controlId
= 0;
148 readIpcArgs(std::cin
, controlId
);
149 args
.append(controlId
);
152 case Commands::AddCheckBox
:
154 sal_Int16 controlId
= 0;
157 readIpcArgs(std::cin
, controlId
, hidden
, label
);
158 args
.append(controlId
);
163 case Commands::Initialize
:
165 bool saveDialog
= false;
166 readIpcArgs(std::cin
, saveDialog
);
167 args
.append(saveDialog
);
172 // no extra parameters/arguments
178 static void readCommands(FilePickerIpc
* ipc
)
180 while (!std::cin
.eof())
182 uint64_t messageId
= 0;
184 readIpcArgs(std::cin
, messageId
, command
);
186 // retrieve additional command-specific arguments
187 QList
<QVariant
> args
;
188 readCommandArgs(command
, args
);
190 emit ipc
->commandReceived(messageId
, command
, args
);
192 // stop processing once 'Quit' command has been sent
193 if (command
== Commands::Quit
)
200 FilePickerIpc::FilePickerIpc(KDE5FilePicker
* filePicker
, QObject
* parent
)
202 , m_filePicker(filePicker
)
204 // required to be able to pass those via signal/slot
205 qRegisterMetaType
<uint64_t>("uint64_t");
206 qRegisterMetaType
<Commands
>("Commands");
208 connect(this, &FilePickerIpc::commandReceived
, this, &FilePickerIpc::handleCommand
);
210 // read IPC commands and their args in a separate thread, so this does not block everything else;
211 // 'commandReceived' signal is emitted every time a command and its args have been read;
212 // thread will run until the filepicker process is terminated
213 m_ipcReaderThread
= std::make_unique
<std::thread
>(readCommands
, this);
216 FilePickerIpc::~FilePickerIpc()
218 // join thread that reads commands
219 m_ipcReaderThread
->join();
222 bool FilePickerIpc::handleCommand(uint64_t messageId
, Commands command
, QList
<QVariant
> args
)
226 case Commands::SetTitle
:
228 QString title
= args
.takeFirst().toString();
229 m_filePicker
->setTitle(title
);
232 case Commands::SetWinId
:
234 sal_uIntPtr winId
= args
.takeFirst().value
<sal_uIntPtr
>();
235 m_filePicker
->setWinId(winId
);
238 case Commands::Execute
:
240 sendIpcArgs(std::cout
, messageId
, m_filePicker
->execute());
243 case Commands::SetMultiSelectionMode
:
245 bool multiSelection
= args
.takeFirst().toBool();
246 m_filePicker
->setMultiSelectionMode(multiSelection
);
249 case Commands::SetDefaultName
:
251 QString name
= args
.takeFirst().toString();
252 m_filePicker
->setDefaultName(name
);
255 case Commands::SetDisplayDirectory
:
257 QString dir
= args
.takeFirst().toString();
258 m_filePicker
->setDisplayDirectory(dir
);
261 case Commands::GetDisplayDirectory
:
263 sendIpcArgs(std::cout
, messageId
, m_filePicker
->getDisplayDirectory());
266 case Commands::GetSelectedFiles
:
269 for (auto const& url_
: m_filePicker
->getSelectedFiles())
272 if (url
.scheme() == QLatin1String("webdav")
273 || url
.scheme() == QLatin1String("webdavs"))
275 // translate webdav and webdavs URLs into a format supported by LO
276 url
.setScheme(QLatin1String("vnd.sun.star.") + url
.scheme());
278 else if (url
.scheme() == QLatin1String("smb"))
280 // clear the user name - the GIO backend does not support this apparently
281 // when no username is available, it will ask for the password
284 files
<< url
.toString();
286 sendIpcArgs(std::cout
, messageId
, files
);
289 case Commands::AppendFilter
:
291 QString title
= args
.takeFirst().toString();
292 QString filter
= args
.takeFirst().toString();
293 m_filePicker
->appendFilter(title
, filter
);
296 case Commands::SetCurrentFilter
:
298 QString title
= args
.takeFirst().toString();
299 m_filePicker
->setCurrentFilter(title
);
302 case Commands::GetCurrentFilter
:
304 sendIpcArgs(std::cout
, messageId
, m_filePicker
->getCurrentFilter());
307 case Commands::SetValue
:
309 sal_Int16 controlId
= args
.takeFirst().value
<sal_Int16
>();
310 sal_Int16 nControlAction
= args
.takeFirst().value
<sal_Int16
>();
311 bool value
= args
.takeFirst().toBool();
312 m_filePicker
->setValue(controlId
, nControlAction
, value
);
315 case Commands::GetValue
:
317 sal_Int16 controlId
= args
.takeFirst().value
<sal_Int16
>();
318 sal_Int16 nControlAction
= args
.takeFirst().value
<sal_Int16
>();
319 sendIpcArgs(std::cout
, messageId
, m_filePicker
->getValue(controlId
, nControlAction
));
322 case Commands::EnableControl
:
324 sal_Int16 controlId
= args
.takeFirst().value
<sal_Int16
>();
325 bool enabled
= args
.takeFirst().toBool();
326 m_filePicker
->enableControl(controlId
, enabled
);
329 case Commands::SetLabel
:
331 sal_Int16 controlId
= args
.takeFirst().value
<sal_Int16
>();
332 QString label
= args
.takeFirst().toString();
333 m_filePicker
->setLabel(controlId
, label
);
336 case Commands::GetLabel
:
338 sal_Int16 controlId
= args
.takeFirst().value
<sal_Int16
>();
339 sendIpcArgs(std::cout
, messageId
, m_filePicker
->getLabel(controlId
));
342 case Commands::AddCheckBox
:
344 sal_Int16 controlId
= args
.takeFirst().value
<sal_Int16
>();
345 bool hidden
= args
.takeFirst().toBool();
346 QString label
= args
.takeFirst().toString();
347 m_filePicker
->addCheckBox(controlId
, label
, hidden
);
350 case Commands::Initialize
:
352 bool saveDialog
= args
.takeFirst().toBool();
353 m_filePicker
->initialize(saveDialog
);
356 case Commands::EnablePickFolderMode
:
358 m_filePicker
->enableFolderMode();
363 QCoreApplication::quit();
367 qWarning() << "unhandled command " << static_cast<uint16_t>(command
);
368 QCoreApplication::exit(1);
372 #include <kde5_filepicker_ipc.moc>
374 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */