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

Applets

icon.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright 2007 by Aaron Seigo <aseigo@kde.org                     *
00003  *                                                                         *
00004  *   This program is free software; you can redistribute it and/or modify  *
00005  *   it under the terms of the GNU General Public License as published by  *
00006  *   the Free Software Foundation; either version 2 of the License, or     *
00007  *   (at your option) any later version.                                   *
00008  *                                                                         *
00009  *   This program is distributed in the hope that it will be useful,       *
00010  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00011  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00012  *   GNU General Public License for more details.                          *
00013  *                                                                         *
00014  *   You should have received a copy of the GNU General Public License     *
00015  *   along with this program; if not, write to the                         *
00016  *   Free Software Foundation, Inc.,                                       *
00017  *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA .        *
00018  ***************************************************************************/
00019 
00020 #include "icon.h"
00021 
00022 #include <QGraphicsSceneDragDropEvent>
00023 #include <QGraphicsSceneMouseEvent>
00024 #include <QGraphicsItem>
00025 #include <QEvent>
00026 #include <QMimeData>
00027 #include <QGraphicsLinearLayout>
00028 
00029 #include <KGlobalSettings>
00030 #include <KDebug>
00031 #include <KDesktopFile>
00032 #include <KIconLoader>
00033 #include <KLocale>
00034 #include <KMenu>
00035 #include <KPropertiesDialog>
00036 #include <KRun>
00037 #include <KSharedConfig>
00038 #include <KShell>
00039 #include <KUrl>
00040 #include <KWindowSystem>
00041 #include <kio/copyjob.h>
00042 #include <kio/netaccess.h>
00043 
00044 #include <Plasma/Theme>
00045 #include <Plasma/IconWidget>
00046 #include <Plasma/Containment>
00047 #include <Plasma/ToolTipManager>
00048 
00049 IconApplet::IconApplet(QObject *parent, const QVariantList &args)
00050     : Plasma::Applet(parent, args),
00051       m_icon(0),
00052       m_dialog(0)
00053 {
00054     setAcceptDrops(true);
00055     setBackgroundHints(NoBackground);
00056     setHasConfigurationInterface(true);
00057     m_icon = new Plasma::IconWidget(this);
00058 
00059     if (args.count() > 0) {
00060         setUrl(args.value(0).toString());
00061         m_icon->setText(m_text);
00062     }
00063 
00064     resize(m_icon->sizeFromIconSize(IconSize(KIconLoader::Desktop)));
00065     //kDebug() << "sized to:" << geometry();
00066 }
00067 
00068 void IconApplet::init()
00069 {
00070     QGraphicsLinearLayout *layout = new QGraphicsLinearLayout(this);
00071     layout->setContentsMargins(0, 0, 0, 0);
00072     layout->setSpacing(0);
00073 
00074     layout->addItem(m_icon);
00075 
00076     KConfigGroup cg = config();
00077 
00078     if (!m_url.isValid()) {
00079         setUrl(cg.readEntry("Url", m_url));
00080     }
00081     setDisplayLines(2);
00082 
00083     registerAsDragHandle(m_icon);
00084     Plasma::ToolTipManager::self()->registerWidget(m_icon);
00085 
00086     setAspectRatioMode(Plasma::ConstrainedSquare);
00087 
00088     // we do this right away since we may have our config
00089     // read shortly by the containment. usually applets don't need
00090     // this, but desktop icons requires some hacks.
00091     //
00092     // in particular, if we were created with a url passed into via
00093     // the args parameter in the ctor, then there won't be an entry
00094     // in our config, and desktop icons support banks on the fact
00095     // that there will be
00096     cg.writeEntry("Url", m_url);
00097 }
00098 
00099 IconApplet::~IconApplet()
00100 {
00101     delete m_dialog;
00102 }
00103 
00104 void IconApplet::saveState(KConfigGroup &cg) const
00105 {
00106     cg.writeEntry("Url", m_url);
00107 }
00108 
00109 void IconApplet::setUrl(const KUrl& url)
00110 {
00111     m_url = KIO::NetAccess::mostLocalUrl(url, 0);
00112 
00113     m_mimetype = KMimeType::findByUrl(url);
00114 
00115     if (m_url.isLocalFile() && KDesktopFile::isDesktopFile(m_url.toLocalFile())) {
00116         KDesktopFile f(m_url.toLocalFile());
00117         m_text = f.readName();
00118         //corrupted desktop file?
00119         if (m_text.isNull()) {
00120             m_text = m_url.fileName();
00121         }
00122         m_icon->setIcon(f.readIcon());
00123 
00124         m_genericName = f.readGenericName();
00125     } else {
00126         m_text = m_url.fileName();
00127 
00128         if(m_text.isEmpty() && m_url.isLocalFile()) {
00129             //handle special case like the / folder
00130             m_text = m_url.directory();
00131         }else if(m_text.isEmpty()) { 
00132             //if we can't find a name, at least take the protocol name, like trash, remote etc.
00133             m_text = m_url.protocol();
00134         }
00135 
00136         m_icon->setIcon(KMimeType::iconNameForUrl(url));
00137     }
00138 
00139     if (m_icon->icon().isNull()) {
00140         m_icon->setIcon("unknown");
00141     }
00142 
00143     kDebug() << "url was" << url << "and is" << m_url;
00144 }
00145 
00146 void IconApplet::openUrl()
00147 {
00148     if (m_url.isValid()) {
00149         emit releaseVisualFocus();
00150         KRun *run = new KRun(m_url, 0);
00151     }
00152 }
00153 
00154 void IconApplet::constraintsEvent(Plasma::Constraints constraints)
00155 {
00156     setBackgroundHints(NoBackground);
00157 
00158     if (constraints & Plasma::FormFactorConstraint) {
00159         disconnect(m_icon, SIGNAL(activated()), this, SLOT(openUrl()));
00160         disconnect(m_icon, SIGNAL(clicked()), this, SLOT(openUrl()));
00161 
00162         if (formFactor() == Plasma::Planar ||
00163             formFactor() == Plasma::MediaCenter) {
00164             connect(m_icon, SIGNAL(activated()), this, SLOT(openUrl()));
00165             m_icon->setText(m_text);
00166             //FIXME TOOL TIP MANAGER
00167             //m_icon->setToolTip(Plasma::ToolTipData());
00168             m_icon->setDrawBackground(true);
00169         } else {
00170             //in the panel the icon behaves like a button
00171             connect(m_icon, SIGNAL(clicked()), this, SLOT(openUrl()));
00172             m_icon->setText(QString());
00173             Plasma::ToolTipContent data(m_text, m_genericName, m_icon->icon());
00174             Plasma::ToolTipManager::self()->setContent(m_icon, data);
00175             m_icon->setDrawBackground(false);
00176         }
00177     }
00178 }
00179 
00180 void IconApplet::showConfigurationInterface()
00181 {
00182     if (m_dialog == 0) {
00183         m_dialog = new KPropertiesDialog(m_url, 0 /*no parent widget*/);
00184         connect(m_dialog, SIGNAL(applied()), this, SLOT(acceptedPropertiesDialog()));
00185         connect(m_dialog, SIGNAL(propertiesClosed()), this, SLOT(propertiesDialogClosed()));
00186         m_dialog->setWindowTitle(i18n("%1 Icon Settings", m_url.fileName()));
00187         m_dialog->show();
00188     } else {
00189         KWindowSystem::setOnDesktop(m_dialog->winId(), KWindowSystem::currentDesktop());
00190         m_dialog->show();
00191         KWindowSystem::activateWindow(m_dialog->winId());
00192     }
00193 }
00194 
00195 void IconApplet::setDisplayLines(int displayLines)
00196 {
00197     if (m_icon) {
00198         if (m_icon->numDisplayLines() == displayLines) {
00199             return;
00200         }
00201         m_icon->setNumDisplayLines(displayLines);
00202         update();
00203     }
00204 }
00205 
00206 int IconApplet::displayLines()
00207 {
00208     if (m_icon) {
00209         return m_icon->numDisplayLines();
00210     }
00211     return 0;
00212 }
00213 
00214 void IconApplet::acceptedPropertiesDialog()
00215 {
00216     KConfigGroup cg = config();
00217     m_url = m_dialog->kurl();
00218     cg.writeEntry("Url", m_url);
00219     setUrl(m_url);
00220     update();
00221 }
00222 
00223 void IconApplet::propertiesDialogClosed()
00224 {
00225     m_dialog = 0;
00226 }
00227 
00228 void IconApplet::dropEvent(QGraphicsSceneDragDropEvent *event)
00229 {
00230     if (!KUrl::List::canDecode(event->mimeData())) {
00231         return;
00232     }
00233 
00234     KUrl::List urls = KUrl::List::fromMimeData(event->mimeData());
00235 
00236     if (urls.count() > 0) {
00237         event->accept();
00238     } else {
00239         return;
00240     }
00241 
00242 
00243     if (m_url.isEmpty()) {
00244         setUrl(urls.first());
00245         //TODO: why we don't call updateConstraints()?
00246         constraintsEvent(Plasma::FormFactorConstraint);
00247     } else if (m_url.isLocalFile() &&
00248                m_mimetype &&
00249                (m_mimetype->is("application/x-executable") ||
00250                 m_mimetype->is("application/x-shellscript") ||
00251                 KDesktopFile::isDesktopFile(m_url.toLocalFile()))) {
00252 
00253         //Parameters
00254         QString params;
00255         foreach (const KUrl &url, urls) {
00256             if (url.isLocalFile()) {
00257                 params += ' ' + KShell::quoteArg(url.path());
00258             } else {
00259                 params += ' ' + KShell::quoteArg(url.prettyUrl());
00260             }
00261         }
00262 
00263         //Command
00264         QString commandStr;
00265         //Extract the command from the Desktop file
00266         if (KDesktopFile::isDesktopFile(m_url.toLocalFile())) {
00267             KDesktopFile f(m_url.toLocalFile());
00268             KConfigGroup config = f.desktopGroup();
00269             commandStr = config.readPathEntry( "Exec", QString() );
00270 
00271             if (commandStr.isEmpty()) {
00272                 QString path = f.readUrl();
00273                 if (path.isEmpty()) {
00274                     path = f.readPath();
00275                 }
00276 
00277                 if (path.isEmpty()) {
00278                     return;
00279                 }
00280 
00281                 KUrl dest(path);
00282                 KMimeType::Ptr mime = KMimeType::findByUrl(dest);
00283                 if (m_mimetype->is("inode/directory")) {
00284                     dropUrls(urls, dest, event->modifiers());
00285                 }
00286             }
00287         } else {
00288             //Else just exec the local executable
00289             commandStr = KShell::quoteArg(m_url.path());
00290         }
00291 
00292         KRun::runCommand(commandStr + ' ' + params, 0);
00293     } else if (m_mimetype->is("inode/directory")) {
00294         dropUrls(urls, m_url, event->modifiers());
00295     }
00296 }
00297 
00298 QPainterPath IconApplet::shape() const
00299 {
00300     return m_icon->shape();
00301 }
00302 
00303 //dropUrls from DolphinDropController
00304 void IconApplet::dropUrls(const KUrl::List& urls,
00305                           const KUrl& destination,
00306                           Qt::KeyboardModifiers modifier)
00307 {
00308     kDebug() << "Source" << urls;
00309     kDebug() << "Destination:" << destination;
00310 
00311     Qt::DropAction action = Qt::CopyAction;
00312 
00313     const bool shiftPressed   = modifier & Qt::ShiftModifier;
00314     const bool controlPressed = modifier & Qt::ControlModifier;
00315     const bool altPressed = modifier & Qt::AltModifier;
00316     if (shiftPressed && controlPressed) {
00317         // shortcut for 'Link Here' is used
00318         action = Qt::LinkAction;
00319     } else if (shiftPressed) {
00320         // shortcut for 'Move Here' is used
00321         action = Qt::MoveAction;
00322     } else if (controlPressed) {
00323         // shortcut for 'Copy Here' is used
00324         action = Qt::CopyAction;
00325     } else if (altPressed) {
00326         // shortcut for 'Link Here' is used
00327         action = Qt::LinkAction;
00328     } else {
00329         // open a context menu which offers the following actions:
00330         // - Move Here
00331         // - Copy Here
00332         // - Link Here
00333         // - Cancel
00334 
00335         KMenu popup(0);
00336 
00337         QString seq = QKeySequence(Qt::ShiftModifier).toString();
00338         seq.chop(1); // chop superfluous '+'
00339         QAction* moveAction = popup.addAction(KIcon("go-jump"),
00340                                               i18nc("@action:inmenu",
00341                                                     "&Move Here\t<shortcut>%1</shortcut>", seq));
00342 
00343         seq = QKeySequence(Qt::ControlModifier).toString();
00344         seq.chop(1);
00345         QAction* copyAction = popup.addAction(KIcon("edit-copy"),
00346                                               i18nc("@action:inmenu",
00347                                                     "&Copy Here\t<shortcut>%1</shortcut>", seq));
00348 
00349         seq = QKeySequence(Qt::ControlModifier + Qt::ShiftModifier).toString();
00350         seq.chop(1);
00351         QAction* linkAction = popup.addAction(KIcon("insert-link"),
00352                                               i18nc("@action:inmenu",
00353                                                     "&Link Here\t<shortcut>%1</shortcut>", seq));
00354 
00355         popup.addSeparator();
00356         popup.addAction(KIcon("process-stop"), i18nc("@action:inmenu", "Cancel"));
00357 
00358         QAction* activatedAction = popup.exec(QCursor::pos());
00359         if (activatedAction == moveAction) {
00360             action = Qt::MoveAction;
00361         } else if (activatedAction == copyAction) {
00362             action = Qt::CopyAction;
00363         } else if (activatedAction == linkAction) {
00364             action = Qt::LinkAction;
00365         } else {
00366             return;
00367         }
00368     }
00369 
00370     switch (action) {
00371     case Qt::MoveAction:
00372         KIO::move(urls, destination);
00373         break;
00374 
00375     case Qt::CopyAction:
00376         KIO::copy(urls, destination);
00377         break;
00378 
00379     case Qt::LinkAction:
00380         KIO::link(urls, destination);
00381         break;
00382 
00383     default:
00384         break;
00385     }
00386 }
00387 
00388 #include "icon.moc"
00389 

Applets

Skip menu "Applets"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members

API Reference

Skip menu "API Reference"
  • KWin
  •   KWin Libraries
  • Libraries
  •   libkworkspace
  •   libsolidcontrol
  •   libtaskmanager
  • Plasma
  •   Animators
  •   Applets
  •   Engines
  • Solid Modules
Generated for API Reference 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