• Skip to content
  • Skip to link menu
KDE 4.3 API Reference
  • KDE API Reference
  • kdelibs
  • Sitemap
  • Contact Us
 

KDECore

ktoolinvocation_x11.cpp

Go to the documentation of this file.
00001 /* This file is part of the KDE libraries
00002     Copyright (c) 1997,1998 Matthias Kalle Dalheimer <kalle@kde.org>
00003     Copyright (c) 1999 Espen Sand <espen@kde.org>
00004     Copyright (c) 2000-2004 Frerich Raabe <raabe@kde.org>
00005     Copyright (c) 2003,2004 Oswald Buddenhagen <ossi@kde.org>
00006     Copyright (c) 2006 Thiago Macieira <thiago@kde.org>
00007     Copyright (C) 2008 Aaron Seigo <aseigo@kde.org>
00008 
00009     This library is free software; you can redistribute it and/or
00010     modify it under the terms of the GNU Library General Public
00011     License as published by the Free Software Foundation; either
00012     version 2 of the License, or (at your option) any later version.
00013 
00014     This library is distributed in the hope that it will be useful,
00015     but WITHOUT ANY WARRANTY; without even the implied warranty of
00016     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00017     Library General Public License for more details.
00018 
00019     You should have received a copy of the GNU Library General Public License
00020     along with this library; see the file COPYING.LIB.  If not, write to
00021     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00022     Boston, MA 02110-1301, USA.
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     // This is a copy of KPIM::splitEmailAddrList().
00055     // Features:
00056     // - always ignores quoted characters
00057     // - ignores everything (including parentheses and commas)
00058     //   inside quoted strings
00059     // - supports nested comments
00060     // - ignores everything (including double quotes and commas)
00061     //   inside comments
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         // the following conversion to latin1 is o.k. because
00075         // we can safely ignore all non-latin1 characters
00076         switch (aStr[index].toLatin1()) {
00077         case '"' : // start or end of quoted string
00078             if (commentlevel == 0)
00079                 insidequote = !insidequote;
00080             break;
00081         case '(' : // start of comment
00082             if (!insidequote)
00083                 commentlevel++;
00084             break;
00085         case ')' : // end of comment
00086             if (!insidequote) {
00087                 if (commentlevel > 0)
00088                     commentlevel--;
00089                 else {
00090                     //kDebug() << "Error in address splitting: Unmatched ')'"
00091                     //          << endl;
00092                     return list;
00093                 }
00094             }
00095             break;
00096         case '\\' : // quoted character
00097             index++; // ignore the quoted character
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     // append the last address to the list
00110     if (!insidequote && (commentlevel == 0)) {
00111         addr = aStr.mid(addrstart, aStr.length()-addrstart);
00112         if (!addr.isEmpty())
00113             list += addr.simplified();
00114     }
00115     //else
00116     //  kDebug() << "Error in address splitting: "
00117     //            << "Unexpected end of address list"
00118     //            << endl;
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 & /*messageFile TODO*/, 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             // put the whole address lists into RFC2047 encoded blobs; technically
00147             // this isn't correct, but KMail understands it nonetheless
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     //QStringList qry;
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         //qry.append( "to=" + QLatin1String(KUrl::toPercentEncoding( *it ) ));
00182     }
00183     const QStringList ccs = splitEmailAddressList( cc );
00184     for (QStringList::ConstIterator it = ccs.constBegin(); it != ccs.constEnd(); ++it)
00185         url.addQueryItem("cc",*it);
00186     //qry.append( "cc=" + QLatin1String(KUrl::toPercentEncoding( *it ) ));
00187     const QStringList bccs = splitEmailAddressList( bcc );
00188     for (QStringList::ConstIterator it = bccs.constBegin(); it != bccs.constEnd(); ++it)
00189         url.addQueryItem("bcc",*it);
00190     //qry.append( "bcc=" + QLatin1String(KUrl::toPercentEncoding( *it ) ));
00191     for (QStringList::ConstIterator it = attachURLs.constBegin(); it != attachURLs.constEnd(); ++it)
00192         url.addQueryItem("attach",*it);
00193     //qry.append( "attach=" + QLatin1String(KUrl::toPercentEncoding( *it ) ));
00194     if (!subject.isEmpty())
00195         url.addQueryItem("subject",subject);
00196     //qry.append( "subject=" + QLatin1String(KUrl::toPercentEncoding( subject ) ));
00197     if (!body.isEmpty())
00198         url.addQueryItem("body",body);
00199     //qry.append( "body=" + QLatin1String(KUrl::toPercentEncoding( body ) ));
00200     //url.setQuery( qry.join( "&" ) );
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()) // better safe than sorry ...
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     // TODO this should check if cmd has a .desktop file, and use data from it, together
00249     // with sending more ASN data
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     // This method should launch a webbrowser, preferrably without doing a mimetype
00268     // check first, like KRun (i.e. kde-open) would do.
00269 
00270     // In a KDE session, honour BrowserApplication if set, otherwise call kfmclient if present,
00271     // otherwise xdg-open, otherwise kde-open (which does a mimetype check first though).
00272 
00273     // Outside KDE, call xdg-open if present, otherwise fallback to the above logic.
00274 
00275     QString exe; // the binary we are going to launch.
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         // We're in a KDE session (or there's no xdg-open installed)
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); // Literal command
00290                 QStringList cmdTokens = KShell::splitArgs(exe);
00291                 exe = cmdTokens.takeFirst();
00292                 args = cmdTokens + args;
00293             } else {
00294                 // desktop file ID
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                                           // TODO: i18n("Could not launch %1:\n\n%2", exe, error),
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"; // it's from kdebase-runtime, it has to be there.
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                           // TODO: i18n("Could not launch %1:\n\n%2", exe, error),
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         // For other terminals like xterm, we'll simply change the working
00361         // directory before launching them, see below.
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 }

KDECore

Skip menu "KDECore"
  • Main Page
  • Modules
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • Kate
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.6.1
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal