• Skip to content
  • Skip to link menu
KDE 4.2 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 
00043 #include <QtCore/QCoreApplication>
00044 #include <QtCore/QProcess>
00045 #include <QtCore/QHash>
00046 #include <QtCore/QDebug>
00047 #include <QtCore/QBool>
00048 #include <QtCore/QFile>
00049 #include <QtDBus/QtDBus>
00050 
00051 static QStringList splitEmailAddressList( const QString & aStr )
00052 {
00053     // This is a copy of KPIM::splitEmailAddrList().
00054     // Features:
00055     // - always ignores quoted characters
00056     // - ignores everything (including parentheses and commas)
00057     //   inside quoted strings
00058     // - supports nested comments
00059     // - ignores everything (including double quotes and commas)
00060     //   inside comments
00061 
00062     QStringList list;
00063 
00064     if (aStr.isEmpty())
00065         return list;
00066 
00067     QString addr;
00068     uint addrstart = 0;
00069     int commentlevel = 0;
00070     bool insidequote = false;
00071 
00072     for (int index=0; index<aStr.length(); index++) {
00073         // the following conversion to latin1 is o.k. because
00074         // we can safely ignore all non-latin1 characters
00075         switch (aStr[index].toLatin1()) {
00076         case '"' : // start or end of quoted string
00077             if (commentlevel == 0)
00078                 insidequote = !insidequote;
00079             break;
00080         case '(' : // start of comment
00081             if (!insidequote)
00082                 commentlevel++;
00083             break;
00084         case ')' : // end of comment
00085             if (!insidequote) {
00086                 if (commentlevel > 0)
00087                     commentlevel--;
00088                 else {
00089                     //kDebug() << "Error in address splitting: Unmatched ')'"
00090                     //          << endl;
00091                     return list;
00092                 }
00093             }
00094             break;
00095         case '\\' : // quoted character
00096             index++; // ignore the quoted character
00097             break;
00098         case ',' :
00099             if (!insidequote && (commentlevel == 0)) {
00100                 addr = aStr.mid(addrstart, index-addrstart);
00101                 if (!addr.isEmpty())
00102                     list += addr.simplified();
00103                 addrstart = index+1;
00104             }
00105             break;
00106         }
00107     }
00108     // append the last address to the list
00109     if (!insidequote && (commentlevel == 0)) {
00110         addr = aStr.mid(addrstart, aStr.length()-addrstart);
00111         if (!addr.isEmpty())
00112             list += addr.simplified();
00113     }
00114     //else
00115     //  kDebug() << "Error in address splitting: "
00116     //            << "Unexpected end of address list"
00117     //            << endl;
00118 
00119     return list;
00120 }
00121 
00122 void KToolInvocation::invokeMailer(const QString &_to, const QString &_cc, const QString &_bcc,
00123                                    const QString &subject, const QString &body,
00124                                    const QString & /*messageFile TODO*/, const QStringList &attachURLs,
00125                                    const QByteArray& startup_id )
00126 {
00127     if (!isMainThreadActive())
00128         return;
00129 
00130     KConfig config("emaildefaults");
00131     KConfigGroup defaultsGrp(&config, "Defaults");
00132 
00133     QString group = defaultsGrp.readEntry("Profile","Default");
00134 
00135     KConfigGroup profileGrp(&config, QString("PROFILE_%1").arg(group) );
00136     QString command = profileGrp.readPathEntry("EmailClient", QString());
00137 
00138     QString to, cc, bcc;
00139     if (command.isEmpty() || command == QLatin1String("kmail")
00140         || command.endsWith("/kmail"))
00141     {
00142         command = QLatin1String("kmail --composer -s %s -c %c -b %b --body %B --attach %A -- %t");
00143         if ( !_to.isEmpty() )
00144         {
00145             // put the whole address lists into RFC2047 encoded blobs; technically
00146             // this isn't correct, but KMail understands it nonetheless
00147             to = QString( "=?utf8?b?%1?=" ).arg( _to.toUtf8().toBase64().constData() );
00148         }
00149         if ( !_cc.isEmpty() )
00150             cc = QString( "=?utf8?b?%1?=" ).arg( _cc.toUtf8().toBase64().constData() );
00151         if ( !_bcc.isEmpty() )
00152             bcc = QString( "=?utf8?b?%1?=" ).arg( _bcc.toUtf8().toBase64().constData() );
00153     } else {
00154         to = _to;
00155         cc = _cc;
00156         bcc = _bcc;
00157         if( !command.contains( '%' ))
00158             command += " %u";
00159     }
00160 
00161     if (profileGrp.readEntry("TerminalClient", false))
00162     {
00163         KConfigGroup confGroup( KGlobal::config(), "General" );
00164         QString preferredTerminal = confGroup.readPathEntry("TerminalApplication", "konsole");
00165         command = preferredTerminal + " -e " + command;
00166     }
00167 
00168     QStringList cmdTokens = KShell::splitArgs(command);
00169     QString cmd = cmdTokens.takeFirst();
00170 
00171     KUrl url;
00172     //QStringList qry;
00173     if (!to.isEmpty())
00174     {
00175         QStringList tos = splitEmailAddressList( to );
00176         url.setPath( tos.first() );
00177         tos.erase( tos.begin() );
00178         for (QStringList::ConstIterator it = tos.constBegin(); it != tos.constEnd(); ++it)
00179             url.addQueryItem("to",*it);
00180         //qry.append( "to=" + QLatin1String(KUrl::toPercentEncoding( *it ) ));
00181     }
00182     const QStringList ccs = splitEmailAddressList( cc );
00183     for (QStringList::ConstIterator it = ccs.constBegin(); it != ccs.constEnd(); ++it)
00184         url.addQueryItem("cc",*it);
00185     //qry.append( "cc=" + QLatin1String(KUrl::toPercentEncoding( *it ) ));
00186     const QStringList bccs = splitEmailAddressList( bcc );
00187     for (QStringList::ConstIterator it = bccs.constBegin(); it != bccs.constEnd(); ++it)
00188         url.addQueryItem("bcc",*it);
00189     //qry.append( "bcc=" + QLatin1String(KUrl::toPercentEncoding( *it ) ));
00190     for (QStringList::ConstIterator it = attachURLs.constBegin(); it != attachURLs.constEnd(); ++it)
00191         url.addQueryItem("attach",*it);
00192     //qry.append( "attach=" + QLatin1String(KUrl::toPercentEncoding( *it ) ));
00193     if (!subject.isEmpty())
00194         url.addQueryItem("subject",subject);
00195     //qry.append( "subject=" + QLatin1String(KUrl::toPercentEncoding( subject ) ));
00196     if (!body.isEmpty())
00197         url.addQueryItem("body",body);
00198     //qry.append( "body=" + QLatin1String(KUrl::toPercentEncoding( body ) ));
00199     //url.setQuery( qry.join( "&" ) );
00200 
00201     if ( ! (to.isEmpty() && (!url.hasQuery())) )
00202         url.setProtocol("mailto");
00203 
00204     QHash<QChar, QString> keyMap;
00205     keyMap.insert('t', to);
00206     keyMap.insert('s', subject);
00207     keyMap.insert('c', cc);
00208     keyMap.insert('b', bcc);
00209     keyMap.insert('B', body);
00210     keyMap.insert('u', url.url());
00211 
00212     QString attachlist = attachURLs.join(",");
00213     attachlist.prepend('\'');
00214     attachlist.append('\'');
00215     keyMap.insert('A', attachlist);
00216 
00217     for (QStringList::Iterator it = cmdTokens.begin(); it != cmdTokens.end(); )
00218     {
00219         if (*it == "%A")
00220         {
00221             if (it == cmdTokens.begin()) // better safe than sorry ...
00222                 continue;
00223             QStringList::ConstIterator urlit = attachURLs.begin();
00224             QStringList::ConstIterator urlend = attachURLs.end();
00225             if ( urlit != urlend )
00226             {
00227                 QStringList::Iterator previt = it;
00228                 --previt;
00229                 *it = *urlit;
00230                 ++it;
00231                 while ( ++urlit != urlend )
00232                 {
00233                     cmdTokens.insert( it, *previt );
00234                     cmdTokens.insert( it, *urlit );
00235                 }
00236             } else {
00237                 --it;
00238                 it = cmdTokens.erase( cmdTokens.erase( it ) );
00239             }
00240         } else {
00241             *it = KMacroExpander::expandMacros(*it, keyMap);
00242             ++it;
00243         }
00244     }
00245 
00246     QString error;
00247     // TODO this should check if cmd has a .desktop file, and use data from it, together
00248     // with sending more ASN data
00249     if (kdeinitExec(cmd, cmdTokens, &error, NULL, startup_id ))
00250     {
00251       KMessage::message(KMessage::Error,
00252                       i18n("Could not launch the mail client:\n\n%1", error),
00253                       i18n("Could not Launch Mail Client"));
00254     }
00255 }
00256 
00257 void KToolInvocation::invokeBrowser( const QString &url, const QByteArray& startup_id )
00258 {
00259     if (!isMainThreadActive())
00260         return;
00261 
00262     QStringList args;
00263     args << url;
00264 
00265     // This method should launch a webbrowser, preferrably without doing a mimetype
00266     // check first, like KRun (i.e. kde-open) would do.
00267 
00268     // In a KDE session, call kfmclient (which honors BrowserApplication) if present,
00269     // otherwise xdg-open, otherwise kde-open (which does a mimetype check first though).
00270 
00271     // Outside KDE, call xdg-open if present, otherwise fallback to the above logic.
00272 
00273     QString exe; // the binary we are going to launch.
00274 
00275     const QString xdg_open = KStandardDirs::findExe("xdg-open");
00276     if (qgetenv("KDE_FULL_SESSION").isEmpty()) {
00277         exe = xdg_open;
00278     }
00279 
00280     if (exe.isEmpty()) {
00281         const QString kfmclient = KStandardDirs::findExe("kfmclient");
00282         if (!kfmclient.isEmpty()) {
00283             exe = kfmclient;
00284             args.prepend("openURL");
00285         } else
00286             exe = xdg_open;
00287     }
00288 
00289     if (exe.isEmpty()) {
00290         exe = "kde-open"; // it's from kdebase-runtime, it has to be there.
00291     }
00292 
00293     kDebug() << "Using" << exe << "to open" << url;
00294     QString error;
00295     if (kdeinitExec(exe, args, &error, NULL, startup_id ))
00296     {
00297         KMessage::message(KMessage::Error,
00298                           // TODO: i18n("Could not launch %1:\n\n%2", exe, error),
00299                           i18n("Could not launch the browser:\n\n%1", error),
00300                           i18n("Could not Launch Browser"));
00301     }
00302 }
00303 
00304 void KToolInvocation::invokeTerminal(const QString &command,
00305                                      const QString &workdir,
00306                                      const QByteArray &startup_id)
00307 {
00308     if (!isMainThreadActive()) {
00309         return;
00310     }
00311 
00312     KConfigGroup confGroup( KGlobal::config(), "General" );
00313     QString exec = confGroup.readPathEntry("TerminalApplication", "konsole");
00314 
00315     if (!command.isEmpty()) {
00316         if (exec == "konsole") {
00317             exec += " --noclose";
00318         } else if (exec == "xterm") {
00319             exec += " -hold";
00320         }
00321 
00322         exec += " -e " + command;
00323     }
00324 
00325     QStringList cmdTokens = KShell::splitArgs(exec);
00326     QString cmd = cmdTokens.takeFirst();
00327 
00328     if (exec == "konsole" && !workdir.isEmpty()) {
00329         cmdTokens << "--workdir";
00330         cmdTokens << workdir;
00331         // For other terminals like xterm, we'll simply change the working
00332         // directory before launching them, see below.
00333     }
00334 
00335     QString error;
00336     if (self()->startServiceInternal("kdeinit_exec_with_workdir",
00337                                     cmd, cmdTokens, &error, 0, NULL, startup_id, false, workdir)) {
00338       KMessage::message(KMessage::Error,
00339                       i18n("Could not launch the terminal client:\n\n%1", error),
00340                       i18n("Could not Launch Terminal Client"));
00341     }
00342 }

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
  • Kross
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.5.7
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