00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <config.h>
00026
00027 #include "ktoolinvocation.h"
00028
00029 #include <kconfiggroup.h>
00030
00031 #include "klauncher_iface.h"
00032 #include "kcmdlineargs.h"
00033 #include "kconfig.h"
00034 #include "kcodecs.h"
00035 #include "kdebug.h"
00036 #include "kglobal.h"
00037 #include "kshell.h"
00038 #include "kmacroexpander.h"
00039 #include "klocale.h"
00040 #include "kstandarddirs.h"
00041 #include "kmessage.h"
00042 #include "kservice.h"
00043
00044 #include <QtCore/QCoreApplication>
00045 #include <QtCore/QProcess>
00046 #include <QtCore/QHash>
00047 #include <QtCore/QDebug>
00048 #include <QtCore/QBool>
00049 #include <QtCore/QFile>
00050 #include <QtDBus/QtDBus>
00051
00052 static QStringList splitEmailAddressList( const QString & aStr )
00053 {
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063 QStringList list;
00064
00065 if (aStr.isEmpty())
00066 return list;
00067
00068 QString addr;
00069 uint addrstart = 0;
00070 int commentlevel = 0;
00071 bool insidequote = false;
00072
00073 for (int index=0; index<aStr.length(); index++) {
00074
00075
00076 switch (aStr[index].toLatin1()) {
00077 case '"' :
00078 if (commentlevel == 0)
00079 insidequote = !insidequote;
00080 break;
00081 case '(' :
00082 if (!insidequote)
00083 commentlevel++;
00084 break;
00085 case ')' :
00086 if (!insidequote) {
00087 if (commentlevel > 0)
00088 commentlevel--;
00089 else {
00090
00091
00092 return list;
00093 }
00094 }
00095 break;
00096 case '\\' :
00097 index++;
00098 break;
00099 case ',' :
00100 if (!insidequote && (commentlevel == 0)) {
00101 addr = aStr.mid(addrstart, index-addrstart);
00102 if (!addr.isEmpty())
00103 list += addr.simplified();
00104 addrstart = index+1;
00105 }
00106 break;
00107 }
00108 }
00109
00110 if (!insidequote && (commentlevel == 0)) {
00111 addr = aStr.mid(addrstart, aStr.length()-addrstart);
00112 if (!addr.isEmpty())
00113 list += addr.simplified();
00114 }
00115
00116
00117
00118
00119
00120 return list;
00121 }
00122
00123 void KToolInvocation::invokeMailer(const QString &_to, const QString &_cc, const QString &_bcc,
00124 const QString &subject, const QString &body,
00125 const QString & , const QStringList &attachURLs,
00126 const QByteArray& startup_id )
00127 {
00128 if (!isMainThreadActive())
00129 return;
00130
00131 KConfig config("emaildefaults");
00132 KConfigGroup defaultsGrp(&config, "Defaults");
00133
00134 QString group = defaultsGrp.readEntry("Profile","Default");
00135
00136 KConfigGroup profileGrp(&config, QString("PROFILE_%1").arg(group) );
00137 QString command = profileGrp.readPathEntry("EmailClient", QString());
00138
00139 QString to, cc, bcc;
00140 if (command.isEmpty() || command == QLatin1String("kmail")
00141 || command.endsWith("/kmail"))
00142 {
00143 command = QLatin1String("kmail --composer -s %s -c %c -b %b --body %B --attach %A -- %t");
00144 if ( !_to.isEmpty() )
00145 {
00146
00147
00148 to = QString( "=?utf8?b?%1?=" ).arg( _to.toUtf8().toBase64().constData() );
00149 }
00150 if ( !_cc.isEmpty() )
00151 cc = QString( "=?utf8?b?%1?=" ).arg( _cc.toUtf8().toBase64().constData() );
00152 if ( !_bcc.isEmpty() )
00153 bcc = QString( "=?utf8?b?%1?=" ).arg( _bcc.toUtf8().toBase64().constData() );
00154 } else {
00155 to = _to;
00156 cc = _cc;
00157 bcc = _bcc;
00158 if( !command.contains( '%' ))
00159 command += " %u";
00160 }
00161
00162 if (profileGrp.readEntry("TerminalClient", false))
00163 {
00164 KConfigGroup confGroup( KGlobal::config(), "General" );
00165 QString preferredTerminal = confGroup.readPathEntry("TerminalApplication", "konsole");
00166 command = preferredTerminal + " -e " + command;
00167 }
00168
00169 QStringList cmdTokens = KShell::splitArgs(command);
00170 QString cmd = cmdTokens.takeFirst();
00171
00172 KUrl url;
00173
00174 if (!to.isEmpty())
00175 {
00176 QStringList tos = splitEmailAddressList( to );
00177 url.setPath( tos.first() );
00178 tos.erase( tos.begin() );
00179 for (QStringList::ConstIterator it = tos.constBegin(); it != tos.constEnd(); ++it)
00180 url.addQueryItem("to",*it);
00181
00182 }
00183 const QStringList ccs = splitEmailAddressList( cc );
00184 for (QStringList::ConstIterator it = ccs.constBegin(); it != ccs.constEnd(); ++it)
00185 url.addQueryItem("cc",*it);
00186
00187 const QStringList bccs = splitEmailAddressList( bcc );
00188 for (QStringList::ConstIterator it = bccs.constBegin(); it != bccs.constEnd(); ++it)
00189 url.addQueryItem("bcc",*it);
00190
00191 for (QStringList::ConstIterator it = attachURLs.constBegin(); it != attachURLs.constEnd(); ++it)
00192 url.addQueryItem("attach",*it);
00193
00194 if (!subject.isEmpty())
00195 url.addQueryItem("subject",subject);
00196
00197 if (!body.isEmpty())
00198 url.addQueryItem("body",body);
00199
00200
00201
00202 if ( ! (to.isEmpty() && (!url.hasQuery())) )
00203 url.setProtocol("mailto");
00204
00205 QHash<QChar, QString> keyMap;
00206 keyMap.insert('t', to);
00207 keyMap.insert('s', subject);
00208 keyMap.insert('c', cc);
00209 keyMap.insert('b', bcc);
00210 keyMap.insert('B', body);
00211 keyMap.insert('u', url.url());
00212
00213 QString attachlist = attachURLs.join(",");
00214 attachlist.prepend('\'');
00215 attachlist.append('\'');
00216 keyMap.insert('A', attachlist);
00217
00218 for (QStringList::Iterator it = cmdTokens.begin(); it != cmdTokens.end(); )
00219 {
00220 if (*it == "%A")
00221 {
00222 if (it == cmdTokens.begin())
00223 continue;
00224 QStringList::ConstIterator urlit = attachURLs.begin();
00225 QStringList::ConstIterator urlend = attachURLs.end();
00226 if ( urlit != urlend )
00227 {
00228 QStringList::Iterator previt = it;
00229 --previt;
00230 *it = *urlit;
00231 ++it;
00232 while ( ++urlit != urlend )
00233 {
00234 cmdTokens.insert( it, *previt );
00235 cmdTokens.insert( it, *urlit );
00236 }
00237 } else {
00238 --it;
00239 it = cmdTokens.erase( cmdTokens.erase( it ) );
00240 }
00241 } else {
00242 *it = KMacroExpander::expandMacros(*it, keyMap);
00243 ++it;
00244 }
00245 }
00246
00247 QString error;
00248
00249
00250 if (kdeinitExec(cmd, cmdTokens, &error, NULL, startup_id ))
00251 {
00252 KMessage::message(KMessage::Error,
00253 i18n("Could not launch the mail client:\n\n%1", error),
00254 i18n("Could not Launch Mail Client"));
00255 }
00256 }
00257
00258 void KToolInvocation::invokeBrowser( const QString &url, const QByteArray& startup_id )
00259 {
00260 if (!isMainThreadActive())
00261 return;
00262
00263 QStringList args;
00264 args << url;
00265 QString error;
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275 QString exe;
00276
00277 const QString xdg_open = KStandardDirs::findExe("xdg-open");
00278 if (qgetenv("KDE_FULL_SESSION").isEmpty()) {
00279 exe = xdg_open;
00280 }
00281
00282 if (exe.isEmpty()) {
00283
00284 KConfigGroup config(KGlobal::config(), "General");
00285 const QString browserApp = config.readPathEntry("BrowserApplication", QString());
00286 if (!browserApp.isEmpty()) {
00287 exe = browserApp;
00288 if (exe.startsWith('!')) {
00289 exe = exe.mid(1);
00290 QStringList cmdTokens = KShell::splitArgs(exe);
00291 exe = cmdTokens.takeFirst();
00292 args = cmdTokens + args;
00293 } else {
00294
00295 KService::Ptr service = KService::serviceByStorageId(exe);
00296 if (service) {
00297 kDebug() << "Starting service" << service->entryPath();
00298 if (startServiceByDesktopPath(service->entryPath(), args,
00299 &error, 0, 0, startup_id)) {
00300 KMessage::message(KMessage::Error,
00301
00302 i18n("Could not launch the browser:\n\n%1", error),
00303 i18n("Could not Launch Browser"));
00304 }
00305 return;
00306 }
00307 }
00308 } else {
00309 const QString kfmclient = KStandardDirs::findExe("kfmclient");
00310 if (!kfmclient.isEmpty()) {
00311 exe = kfmclient;
00312 args.prepend("openURL");
00313 } else {
00314 exe = xdg_open;
00315 }
00316 }
00317 }
00318
00319 if (exe.isEmpty()) {
00320 exe = "kde-open";
00321 }
00322
00323 kDebug(180) << "Using" << exe << "to open" << url;
00324 if (kdeinitExec(exe, args, &error, NULL, startup_id ))
00325 {
00326 KMessage::message(KMessage::Error,
00327
00328 i18n("Could not launch the browser:\n\n%1", error),
00329 i18n("Could not Launch Browser"));
00330 }
00331 }
00332
00333 void KToolInvocation::invokeTerminal(const QString &command,
00334 const QString &workdir,
00335 const QByteArray &startup_id)
00336 {
00337 if (!isMainThreadActive()) {
00338 return;
00339 }
00340
00341 KConfigGroup confGroup( KGlobal::config(), "General" );
00342 QString exec = confGroup.readPathEntry("TerminalApplication", "konsole");
00343
00344 if (!command.isEmpty()) {
00345 if (exec == "konsole") {
00346 exec += " --noclose";
00347 } else if (exec == "xterm") {
00348 exec += " -hold";
00349 }
00350
00351 exec += " -e " + command;
00352 }
00353
00354 QStringList cmdTokens = KShell::splitArgs(exec);
00355 QString cmd = cmdTokens.takeFirst();
00356
00357 if (exec == "konsole" && !workdir.isEmpty()) {
00358 cmdTokens << "--workdir";
00359 cmdTokens << workdir;
00360
00361
00362 }
00363
00364 QString error;
00365 if (self()->startServiceInternal("kdeinit_exec_with_workdir",
00366 cmd, cmdTokens, &error, 0, NULL, startup_id, false, workdir)) {
00367 KMessage::message(KMessage::Error,
00368 i18n("Could not launch the terminal client:\n\n%1", error),
00369 i18n("Could not Launch Terminal Client"));
00370 }
00371 }