File indexing completed on 2023-12-10 04:56:57
0001 /* 0002 * Copyright (C) 2012 Dan Vrátil <dvratil@redhat.com> 0003 * 0004 * This library is free software; you can redistribute it and/or 0005 * modify it under the terms of the GNU Lesser General Public 0006 * License as published by the Free Software Foundation; either 0007 * version 2.1 of the License, or (at your option) any later version. 0008 * 0009 * This library is distributed in the hope that it will be useful, 0010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0012 * Lesser General Public License for more details. 0013 * 0014 * You should have received a copy of the GNU Lesser General Public 0015 * License along with this library; if not, write to the Free Software 0016 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 0017 */ 0018 0019 #include "actions.h" 0020 0021 #include <TelepathyQt/Account> 0022 #include <TelepathyQt/ChannelRequestHints> 0023 #include <TelepathyQt/Contact> 0024 #include <TelepathyQt/PendingChannelRequest> 0025 #include <TelepathyQt/PendingFailure> 0026 #include <TelepathyQt/ReferencedHandles> 0027 0028 #include <QMimeType> 0029 #include <KToolInvocation> 0030 #include "ktp-debug.h" 0031 #include <KLocalizedString> 0032 #include <KNotification> 0033 #include <KAboutData> 0034 0035 #define PREFERRED_TEXT_CHAT_HANDLER QLatin1String("org.freedesktop.Telepathy.Client.KTp.TextUi") 0036 #define PREFERRED_FILE_TRANSFER_HANDLER QLatin1String("org.freedesktop.Telepathy.Client.KTp.FileTransfer") 0037 #define PREFERRED_AUDIO_VIDEO_HANDLER QLatin1String("org.freedesktop.Telepathy.Client.KTp.CallUi") 0038 #define PREFERRED_RFB_HANDLER QLatin1String("org.freedesktop.Telepathy.Client.krfb_rfb_handler") 0039 0040 using namespace KTp; 0041 0042 Tp::PendingChannelRequest* Actions::startChat(const Tp::AccountPtr &account, 0043 const QString &contactIdentifier, 0044 bool delegateToPreferredHandler) 0045 { 0046 if (account.isNull() || contactIdentifier.isEmpty()) { 0047 qCWarning(KTP_COMMONINTERNALS) << "Parameters invalid"; 0048 } 0049 0050 qCDebug(KTP_COMMONINTERNALS) << "Requesting text channel for contact id: " << contactIdentifier; 0051 0052 Tp::ChannelRequestHints hints; 0053 if (delegateToPreferredHandler) { 0054 hints.setHint(QLatin1String("org.freedesktop.Telepathy.ChannelRequest"), 0055 QLatin1String("DelegateToPreferredHandler"), 0056 QVariant(true)); 0057 } 0058 0059 return account->ensureTextChat(contactIdentifier, 0060 QDateTime::currentDateTime(), 0061 PREFERRED_TEXT_CHAT_HANDLER, 0062 hints); 0063 } 0064 0065 Tp::PendingChannelRequest* Actions::startChat(const Tp::AccountPtr &account, 0066 const Tp::ContactPtr &contact, 0067 bool delegateToPreferredHandler) 0068 { 0069 if (account.isNull() || contact.isNull()) { 0070 qCWarning(KTP_COMMONINTERNALS) << "Parameters invalid"; 0071 } 0072 0073 qCDebug(KTP_COMMONINTERNALS) << "Requesting text channel for" << contact->id(); 0074 0075 Tp::ChannelRequestHints hints; 0076 if (delegateToPreferredHandler) { 0077 hints.setHint(QLatin1String("org.freedesktop.Telepathy.ChannelRequest"), 0078 QLatin1String("DelegateToPreferredHandler"), 0079 QVariant(true)); 0080 } 0081 0082 return account->ensureTextChat(contact, 0083 QDateTime::currentDateTime(), 0084 PREFERRED_TEXT_CHAT_HANDLER, 0085 hints); 0086 } 0087 0088 Tp::PendingChannelRequest* Actions::startGroupChat(const Tp::AccountPtr &account, 0089 const QString &roomName) 0090 { 0091 if (account.isNull() || roomName.isEmpty()) { 0092 qCWarning(KTP_COMMONINTERNALS) << "Parameters invalid"; 0093 } 0094 0095 qCDebug(KTP_COMMONINTERNALS) << "Requesting text chat room " << roomName; 0096 0097 Tp::ChannelRequestHints hints; 0098 hints.setHint(QLatin1String("org.kde.telepathy"), QLatin1String("forceRaiseWindow"), QVariant(true)); 0099 0100 return account->ensureTextChatroom(roomName, 0101 QDateTime::currentDateTime(), 0102 PREFERRED_TEXT_CHAT_HANDLER, 0103 hints); 0104 } 0105 0106 Tp::PendingChannelRequest* Actions::startAudioCall(const Tp::AccountPtr &account, 0107 const Tp::ContactPtr &contact) 0108 { 0109 if (account.isNull() || contact.isNull()) { 0110 qCWarning(KTP_COMMONINTERNALS) << "Parameters invalid"; 0111 } 0112 0113 qCDebug(KTP_COMMONINTERNALS) << "Requesting audio channel for" << contact->id(); 0114 0115 return account->ensureAudioCall(contact, 0116 QLatin1String("audio"), 0117 QDateTime::currentDateTime(), 0118 PREFERRED_AUDIO_VIDEO_HANDLER); 0119 } 0120 0121 Tp::PendingChannelRequest* Actions::startAudioVideoCall(const Tp::AccountPtr &account, 0122 const Tp::ContactPtr &contact) 0123 { 0124 if (account.isNull() || contact.isNull()) { 0125 qCWarning(KTP_COMMONINTERNALS) << "Parameters invalid"; 0126 } 0127 0128 qCDebug(KTP_COMMONINTERNALS) << "Requesting audio-video channel for" << contact->id(); 0129 0130 return account->ensureAudioVideoCall(contact, 0131 QLatin1String("audio"), 0132 QLatin1String("video"), 0133 QDateTime::currentDateTime(), 0134 PREFERRED_AUDIO_VIDEO_HANDLER); 0135 } 0136 0137 Tp::PendingChannelRequest* Actions::startDesktopSharing(const Tp::AccountPtr &account, 0138 const Tp::ContactPtr &contact) 0139 { 0140 if (account.isNull() || contact.isNull()) { 0141 qCWarning(KTP_COMMONINTERNALS) << "Parameters invalid"; 0142 } 0143 0144 qCDebug(KTP_COMMONINTERNALS) << "Requesting stream tube for" << contact->id(); 0145 0146 return account->createStreamTube(contact, 0147 QLatin1String("rfb"), 0148 QDateTime::currentDateTime(), 0149 PREFERRED_RFB_HANDLER); 0150 } 0151 0152 Tp::PendingChannelRequest* Actions::startFileTransfer(const Tp::AccountPtr &account, 0153 const Tp::ContactPtr &contact, 0154 const QString &filePath) 0155 { 0156 if (account.isNull() || contact.isNull()) { 0157 qCWarning(KTP_COMMONINTERNALS) << "Parameters invalid"; 0158 } 0159 0160 qCDebug(KTP_COMMONINTERNALS) << "Requesting file transfer of" << filePath << "to" << contact->id(); 0161 0162 QFileInfo fileInfo(filePath); 0163 0164 Tp::FileTransferChannelCreationProperties fileTransferProperties; 0165 0166 if (account->serviceName() == QLatin1String("google-talk") && 0167 (fileInfo.suffix() == QLatin1String("exe") || fileInfo.suffix() == QLatin1String("ini"))) { 0168 0169 qCDebug(KTP_COMMONINTERNALS) << "Google Talk forbids transfering files with suffix \"ini\" or \"exe\". Renaming."; 0170 0171 QString fileName = fileInfo.fileName().append(QLatin1String("_")); 0172 0173 QMimeDatabase db; 0174 fileTransferProperties = Tp::FileTransferChannelCreationProperties(fileName, 0175 db.mimeTypeForFile(filePath).name(), 0176 fileInfo.size()); 0177 0178 fileTransferProperties.setUri(QUrl::fromLocalFile(filePath).toString()); 0179 fileTransferProperties.setLastModificationTime(fileInfo.lastModified()); 0180 0181 KNotification *notification = new KNotification (QLatin1String("googletalkExtensionsError")); 0182 notification->setText(i18n("Transferring files with .exe or .ini extension is not allowed by Google Talk. It was sent with filename <i>%1</i>", fileName)); 0183 notification->setTitle(i18n("Transferred file renamed")); 0184 0185 notification->setComponentName(QStringLiteral("ktelepathy")); 0186 notification->sendEvent(); 0187 0188 } else { 0189 QMimeDatabase db; 0190 fileTransferProperties = Tp::FileTransferChannelCreationProperties( 0191 filePath, db.mimeTypeForFile(filePath, QMimeDatabase::MatchContent).name()); 0192 } 0193 0194 return account->createFileTransfer(contact, 0195 fileTransferProperties, 0196 QDateTime::currentDateTime(), 0197 PREFERRED_FILE_TRANSFER_HANDLER); 0198 } 0199 0200 Tp::PendingOperation* Actions::startFileTransfer(const Tp::AccountPtr &account, 0201 const Tp::ContactPtr &contact, 0202 const QUrl &url) 0203 { 0204 if (account.isNull() || contact.isNull() || url.isEmpty()) { 0205 qCWarning(KTP_COMMONINTERNALS) << "Parameters invalid"; 0206 } 0207 0208 qCDebug(KTP_COMMONINTERNALS) << "Requesting file transfer of" << url.toLocalFile() << "to" << contact->id(); 0209 0210 Tp::PendingOperation *ret = nullptr; 0211 if (url.isLocalFile()) { 0212 ret = startFileTransfer(account, contact, url.toLocalFile()); 0213 } else { 0214 ret = new Tp::PendingFailure(QLatin1String("Failed file transfer"), QString(QLatin1String("You are only supposed to send local files, not %1")).arg(url.toString()), account); 0215 } 0216 return ret; 0217 } 0218 0219 void Actions::openLogViewer(const Tp::AccountPtr &account, 0220 const Tp::ContactPtr &contact) 0221 { 0222 if (account.isNull() || contact.isNull()) { 0223 qCWarning(KTP_COMMONINTERNALS) << "Parameters invalid"; 0224 return; 0225 } 0226 0227 openLogViewer(account, contact->id()); 0228 } 0229 0230 void Actions::openLogViewer(const QUrl &uri) 0231 { 0232 qCDebug(KTP_COMMONINTERNALS) << "Opening logviewer for" << uri; 0233 0234 QStringList arguments; 0235 arguments << QLatin1String("--") << uri.toString(); 0236 0237 KToolInvocation::kdeinitExec(QLatin1String("ktp-log-viewer"), arguments); 0238 } 0239 0240 void Actions::openLogViewer(const Tp::AccountPtr& account, const QString& targetId) 0241 { 0242 if (account.isNull() || targetId.isEmpty()) { 0243 qCWarning(KTP_COMMONINTERNALS) << " Parameters invalid"; 0244 return; 0245 } 0246 0247 qCDebug(KTP_COMMONINTERNALS) << "Opening logviewer for" << targetId; 0248 0249 QStringList arguments; 0250 arguments << QLatin1String("--") << account->uniqueIdentifier() << targetId; 0251 0252 /* Use "--" so that KCmdLineArgs does not parse UIDs starting with "-" as arguments */ 0253 KToolInvocation::kdeinitExec(QLatin1String("ktp-log-viewer"), arguments); 0254 } 0255 0256 0257 const QVariantMap createHintsForCollabRequest(const Actions::DocumentList& documents, bool needOpenEditor) 0258 { 0259 QVariantMap hints; 0260 hints.insert(QLatin1String("initialDocumentsSize"), documents.size()); 0261 for ( int i = 0; i < documents.size(); i++ ) { 0262 const QString key(QLatin1String("initialDocument") + QString::number(i)); 0263 hints.insert(key, documents.at(i).fileName()); 0264 if ( needOpenEditor ) { 0265 hints.insert(key + QLatin1String("_source"), documents.at(i).url()); 0266 } 0267 } 0268 if ( needOpenEditor ) { 0269 hints.insert(QLatin1String("needToOpenDocument"), QVariant(true)); 0270 } 0271 return hints; 0272 } 0273 0274 Tp::PendingChannelRequest* createCollabRequest(const Tp::AccountPtr account, 0275 const Actions::DocumentList documents, 0276 QVariantMap requestBase, 0277 bool needOpenEditor) 0278 { 0279 QVariantMap hints = createHintsForCollabRequest(documents, needOpenEditor); 0280 0281 requestBase.insert(TP_QT_IFACE_CHANNEL + QLatin1String(".ChannelType"), 0282 TP_QT_IFACE_CHANNEL_TYPE_STREAM_TUBE); 0283 requestBase.insert(TP_QT_IFACE_CHANNEL_TYPE_STREAM_TUBE + QLatin1String(".Service"), 0284 QLatin1String("infinote")); 0285 0286 Tp::PendingChannelRequest* channelRequest; 0287 channelRequest = account->ensureChannel(requestBase, 0288 QDateTime::currentDateTime(), 0289 QLatin1String("org.freedesktop.Telepathy.Client.KTp.infinoteServer"), 0290 hints); 0291 0292 return channelRequest; 0293 } 0294 0295 Tp::PendingChannelRequest* Actions::startCollaborativeEditing(const Tp::AccountPtr& account, 0296 const Tp::ContactPtr& contact, 0297 const DocumentList& documents, 0298 bool needOpenEditor) 0299 { 0300 QVariantMap request; 0301 request.insert(TP_QT_IFACE_CHANNEL + QLatin1String(".TargetHandleType"), 0302 (uint) Tp::HandleTypeContact); 0303 request.insert(TP_QT_IFACE_CHANNEL + QLatin1String(".TargetHandle"), 0304 contact->handle().at(0)); 0305 return createCollabRequest(account, documents, request, needOpenEditor); 0306 } 0307 0308 Tp::PendingChannelRequest* Actions::startCollaborativeEditing(const Tp::AccountPtr& account, 0309 const QString& chatroom, 0310 const DocumentList& documents, 0311 bool needOpenEditor) 0312 { 0313 QVariantMap request; 0314 request.insert(TP_QT_IFACE_CHANNEL + QLatin1String(".TargetHandleType"), 0315 (uint) Tp::HandleTypeRoom); 0316 request.insert(TP_QT_IFACE_CHANNEL + QLatin1String(".TargetID"), 0317 chatroom); 0318 return createCollabRequest(account, documents, request, needOpenEditor); 0319 }