38 auto startMessage = QDBusMessage::createMethodCall(portalService, portalPath,
39 fileTransferInterface,
"StartTransfer"_L1);
40 const QVariantMap options{ {
"writable"_L1,
true }, {
"autostop"_L1,
true } };
41 startMessage.setArguments({ options });
42 const QDBusReply<QString> key = QDBusConnection::sessionBus().call(startMessage);
44 qCWarning(lcQpaPortalFileTransfer) <<
"failed to start transfer" << key.error();
47 QList<QDBusUnixFileDescriptor> fds;
48 for (
const auto &url : urls) {
49 if (
int fd = open(QFile::encodeName(url.toLocalFile()),
O_PATH | O_CLOEXEC); fd > 0)
50 fds.emplaceBack().giveFileDescriptor(fd);
52 qCInfo(lcQpaPortalFileTransfer) <<
"failed to open" << url;
54 auto nextChunk = [&fds](
auto lastEnd) {
55 constexpr qsizetype chunkSize = 16;
56 const auto remaining = fds.cend() - lastEnd;
57 return std::pair{lastEnd, std::next(lastEnd, std::min(remaining, chunkSize))};
59 for (
auto chunk = nextChunk(fds.cbegin()); chunk.first != fds.cend(); chunk = nextChunk(chunk.second)) {
60 auto addFilesMessage = QDBusMessage::createMethodCall(portalService, portalPath, fileTransferInterface,
"AddFiles"_L1);
61 addFilesMessage.setArguments({key.value(), QVariant::fromValue(QList<QDBusUnixFileDescriptor>{chunk.first, chunk.second}), QVariantMap{}});
62 const QDBusReply<
void> addFilesResult = QDBusConnection::sessionBus().call(addFilesMessage, QDBus::Block, portalWaitTimeMs);
63 if (!addFilesResult.isValid()) {
64 qCWarning(lcQpaPortalFileTransfer) <<
"failed to add files" << addFilesResult.error();
73 qCDebug(lcQpaPortalFileTransfer) <<
"retrieving files for" << key;
74 auto message = QDBusMessage::createMethodCall(portalService, portalPath, fileTransferInterface,
"RetrieveFiles"_L1);
75 message.setArguments({key, QVariantMap()});
76 const QDBusReply<QStringList> reply = QDBusConnection::sessionBus().call(message, QDBus::Block, portalWaitTimeMs);
77 if (!reply.isValid()) {
78 qCDebug(lcQpaPortalFileTransfer) <<
"error retrieving files" << reply.error();
81 const QStringList paths = reply.value();