00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
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.h>
00045 #include <plasma/widgets/icon.h>
00046 #include <plasma/containment.h>
00047
00048 IconApplet::IconApplet(QObject *parent, const QVariantList &args)
00049 : Plasma::Applet(parent, args),
00050 m_dialog(0),
00051 m_mimetype(0)
00052 {
00053 setAcceptDrops(true);
00054 setBackgroundHints(NoBackground);
00055 setHasConfigurationInterface(true);
00056 m_icon = new Plasma::Icon(this);
00057
00058 if (args.count() > 0) {
00059 setUrl(args.value(0).toString());
00060 m_icon->setText(m_text);
00061 }
00062
00063 resize(m_icon->sizeFromIconSize(IconSize(KIconLoader::Desktop)));
00064
00065 }
00066
00067 void IconApplet::init()
00068 {
00069 QGraphicsLinearLayout *layout = new QGraphicsLinearLayout(this);
00070 layout->setContentsMargins(0, 0, 0, 0);
00071 layout->setSpacing(0);
00072
00073 layout->addItem(m_icon);
00074
00075 KConfigGroup cg = config();
00076
00077 if (!m_url.isValid()) {
00078 setUrl(cg.readEntry("Url", m_url));
00079 }
00080 setDisplayLines(2);
00081
00082 registerAsDragHandle(m_icon);
00083
00084 setAspectRatioMode(Plasma::ConstrainedSquare);
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094 cg.writeEntry("Url", m_url);
00095 }
00096
00097 IconApplet::~IconApplet()
00098 {
00099 delete m_dialog;
00100 }
00101
00102 void IconApplet::saveState(KConfigGroup &cg) const
00103 {
00104 cg.writeEntry("Url", m_url);
00105 }
00106
00107 void IconApplet::setUrl(const KUrl& url)
00108 {
00109 m_url = KIO::NetAccess::mostLocalUrl(url, 0);
00110
00111 m_mimetype = KMimeType::findByUrl(url);
00112
00113 if (m_url.isLocalFile() && KDesktopFile::isDesktopFile(m_url.toLocalFile())) {
00114 KDesktopFile f(m_url.toLocalFile());
00115 m_text = f.readName();
00116
00117 if (m_text.isNull()) {
00118 m_text = m_url.fileName();
00119 }
00120 m_icon->setIcon(f.readIcon());
00121
00122 m_genericName = f.readGenericName();
00123 } else {
00124 m_text = m_url.fileName();
00125 m_icon->setIcon(KMimeType::iconNameForUrl(url));
00126 }
00127
00128 if (m_icon->icon().isNull()) {
00129 m_icon->setIcon("unknown");
00130 }
00131 }
00132
00133 void IconApplet::openUrl()
00134 {
00135 if (m_url.isValid()) {
00136 emit releaseVisualFocus();
00137 KRun::runUrl(m_url, m_mimetype->name(), 0);
00138 }
00139 }
00140
00141 void IconApplet::constraintsEvent(Plasma::Constraints constraints)
00142 {
00143 setBackgroundHints(NoBackground);
00144
00145 if (constraints & Plasma::FormFactorConstraint) {
00146 disconnect(m_icon, SIGNAL(activated()), this, SLOT(openUrl()));
00147 disconnect(m_icon, SIGNAL(clicked()), this, SLOT(openUrl()));
00148
00149 if (formFactor() == Plasma::Planar ||
00150 formFactor() == Plasma::MediaCenter) {
00151 connect(m_icon, SIGNAL(activated()), this, SLOT(openUrl()));
00152 m_icon->setText(m_text);
00153
00154
00155 m_icon->setDrawBackground(true);
00156 } else {
00157
00158 connect(m_icon, SIGNAL(clicked()), this, SLOT(openUrl()));
00159 m_icon->setText(QString());
00160
00161
00162
00163
00164
00165
00166 m_icon->setDrawBackground(false);
00167 }
00168 }
00169 }
00170
00171 void IconApplet::showConfigurationInterface()
00172 {
00173 if (m_dialog == 0) {
00174 m_dialog = new KPropertiesDialog(m_url, 0 );
00175 connect(m_dialog, SIGNAL(applied()), this, SLOT(acceptedPropertiesDialog()));
00176 connect(m_dialog, SIGNAL(propertiesClosed()), this, SLOT(propertiesDialogClosed()));
00177 m_dialog->show();
00178 } else {
00179 KWindowSystem::setOnDesktop(m_dialog->winId(), KWindowSystem::currentDesktop());
00180 m_dialog->show();
00181 KWindowSystem::activateWindow(m_dialog->winId());
00182 }
00183 }
00184
00185 void IconApplet::setDisplayLines(int displayLines)
00186 {
00187 if (m_icon) {
00188 if (m_icon->numDisplayLines() == displayLines) {
00189 return;
00190 }
00191 m_icon->setNumDisplayLines(displayLines);
00192 update();
00193 }
00194 }
00195
00196 int IconApplet::displayLines()
00197 {
00198 if (m_icon) {
00199 return m_icon->numDisplayLines();
00200 }
00201 return 0;
00202 }
00203
00204 void IconApplet::acceptedPropertiesDialog()
00205 {
00206 KConfigGroup cg = config();
00207 m_url = m_dialog->kurl();
00208 cg.writeEntry("Url", m_url);
00209 setUrl(m_url);
00210 update();
00211 }
00212
00213 void IconApplet::propertiesDialogClosed()
00214 {
00215 m_dialog = 0;
00216 }
00217
00218 void IconApplet::dropEvent(QGraphicsSceneDragDropEvent *event)
00219 {
00220 if (!KUrl::List::canDecode(event->mimeData())) {
00221 return;
00222 }
00223
00224 KUrl::List urls = KUrl::List::fromMimeData(event->mimeData());
00225
00226 if (urls.count() > 0) {
00227 event->accept();
00228 } else {
00229 return;
00230 }
00231
00232
00233 if (m_url.isEmpty()) {
00234 setUrl(urls.first());
00235
00236 constraintsEvent(Plasma::FormFactorConstraint);
00237 } else if (m_url.isLocalFile() &&
00238 (m_mimetype &&
00239 m_mimetype->is("application/x-executable") ||
00240 m_mimetype->is("application/x-shellscript") ||
00241 KDesktopFile::isDesktopFile(m_url.toLocalFile()))) {
00242
00243
00244 QString params;
00245 foreach (const KUrl &url, urls) {
00246 if (url.isLocalFile()) {
00247 params += ' ' + KShell::quoteArg(url.path());
00248 } else {
00249 params += ' ' + KShell::quoteArg(url.prettyUrl());
00250 }
00251 }
00252
00253
00254 QString commandStr;
00255
00256 if (KDesktopFile::isDesktopFile(m_url.toLocalFile())) {
00257 KDesktopFile f(m_url.toLocalFile());
00258 KConfigGroup config = f.desktopGroup();
00259 commandStr = config.readPathEntry( "Exec", QString() );
00260
00261 if (commandStr.isEmpty()) {
00262 QString path = f.readUrl();
00263 if (path.isEmpty()) {
00264 path = f.readPath();
00265 }
00266
00267 if (path.isEmpty()) {
00268 return;
00269 }
00270
00271 KUrl dest(path);
00272 KMimeType::Ptr mime = KMimeType::findByUrl(dest);
00273 if (m_mimetype->is("inode/directory")) {
00274 dropUrls(urls, dest, event->modifiers());
00275 }
00276 }
00277 } else {
00278
00279 commandStr = KShell::quoteArg(m_url.path());
00280 }
00281
00282 KRun::runCommand(commandStr + ' ' + params, 0);
00283 } else if (m_mimetype->is("inode/directory")) {
00284 dropUrls(urls, m_url, event->modifiers());
00285 }
00286 }
00287
00288 QPainterPath IconApplet::shape() const
00289 {
00290 return m_icon->shape();
00291 }
00292
00293
00294 void IconApplet::dropUrls(const KUrl::List& urls,
00295 const KUrl& destination,
00296 Qt::KeyboardModifiers modifier)
00297 {
00298 kDebug() << "Source" << urls;
00299 kDebug() << "Destination:" << destination;
00300
00301 Qt::DropAction action = Qt::CopyAction;
00302
00303 const bool shiftPressed = modifier & Qt::ShiftModifier;
00304 const bool controlPressed = modifier & Qt::ControlModifier;
00305 const bool altPressed = modifier & Qt::AltModifier;
00306 if (shiftPressed && controlPressed) {
00307
00308 action = Qt::LinkAction;
00309 } else if (shiftPressed) {
00310
00311 action = Qt::MoveAction;
00312 } else if (controlPressed) {
00313
00314 action = Qt::CopyAction;
00315 } else if (altPressed) {
00316
00317 action = Qt::LinkAction;
00318 } else {
00319
00320
00321
00322
00323
00324
00325 KMenu popup(0);
00326
00327 QString seq = QKeySequence(Qt::ShiftModifier).toString();
00328 seq.chop(1);
00329 QAction* moveAction = popup.addAction(KIcon("go-jump"),
00330 i18nc("@action:inmenu",
00331 "&Move Here\t<shortcut>%1</shortcut>", seq));
00332
00333 seq = QKeySequence(Qt::ControlModifier).toString();
00334 seq.chop(1);
00335 QAction* copyAction = popup.addAction(KIcon("edit-copy"),
00336 i18nc("@action:inmenu",
00337 "&Copy Here\t<shortcut>%1</shortcut>", seq));
00338
00339 seq = QKeySequence(Qt::ControlModifier + Qt::ShiftModifier).toString();
00340 seq.chop(1);
00341 QAction* linkAction = popup.addAction(KIcon("insert-link"),
00342 i18nc("@action:inmenu",
00343 "&Link Here\t<shortcut>%1</shortcut>", seq));
00344
00345 popup.addSeparator();
00346 popup.addAction(KIcon("process-stop"), i18nc("@action:inmenu", "Cancel"));
00347
00348 QAction* activatedAction = popup.exec(QCursor::pos());
00349 if (activatedAction == moveAction) {
00350 action = Qt::MoveAction;
00351 } else if (activatedAction == copyAction) {
00352 action = Qt::CopyAction;
00353 } else if (activatedAction == linkAction) {
00354 action = Qt::LinkAction;
00355 } else {
00356 return;
00357 }
00358 }
00359
00360 switch (action) {
00361 case Qt::MoveAction:
00362 KIO::move(urls, destination);
00363 break;
00364
00365 case Qt::CopyAction:
00366 KIO::copy(urls, destination);
00367 break;
00368
00369 case Qt::LinkAction:
00370 KIO::link(urls, destination);
00371 break;
00372
00373 default:
00374 break;
00375 }
00376 }
00377
00378 #include "icon.moc"
00379