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

Applets

trash.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright 2007 by Marco Martin <notmart@gmail.com>                    *
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 "trash.h"
00021 
00022 //QT
00023 #include <QGraphicsSceneDragDropEvent>
00024 #include <QApplication>
00025 #include <QGraphicsLinearLayout>
00026 
00027 //KDE
00028 #include <KGlobalSettings>
00029 #include <KCModuleProxy>
00030 #include <KConfigDialog>
00031 #include <KDebug>
00032 #include <KLocale>
00033 #include <KIconLoader>
00034 #include <KMimeType>
00035 #include <KRun>
00036 #include <KSharedConfig>
00037 #include <KMessageBox>
00038 #include <KUrl>
00039 #include <KProcess>
00040 #include <KStandardDirs>
00041 
00042 #include <kfileplacesmodel.h>
00043 #include <KIO/CopyJob>
00044 #include <KIO/JobUiDelegate>
00045 
00046 //Plasma
00047 #include <Plasma/IconWidget>
00048 #include <Plasma/Containment>
00049 #include <Plasma/ToolTipManager>
00050 
00051 //Solid
00052 #include <solid/devicenotifier.h>
00053 #include <solid/device.h>
00054 #include <solid/deviceinterface.h>
00055 #include <solid/predicate.h>
00056 #include <solid/storageaccess.h>
00057 #include <solid/opticaldrive.h>
00058 #include <solid/opticaldisc.h>
00059 
00060 
00061 Trash::Trash(QObject *parent, const QVariantList &args)
00062     : Plasma::Applet(parent, args),
00063       m_icon(0),
00064       m_dirLister(0),
00065       emptyTrash(0),
00066       m_count(0),
00067       m_showText(false),
00068       m_places(0),
00069       m_proxy(0),
00070       m_emptyProcess(0)
00071 {
00072     setHasConfigurationInterface(true);
00073     setAspectRatioMode(Plasma::ConstrainedSquare);
00074 
00075     m_icon = new Plasma::IconWidget(KIcon("user-trash"),QString(),this);
00076     m_icon->setNumDisplayLines(2);
00077     m_icon->setDrawBackground(true);
00078 
00079     resize(m_icon->sizeFromIconSize(IconSize(KIconLoader::Desktop)));
00080     createMenu();
00081 }
00082 
00083 Trash::~Trash()
00084 {
00085 }
00086 
00087 void Trash::init()
00088 {
00089     registerAsDragHandle(m_icon);
00090 
00091     QGraphicsLinearLayout *layout = new QGraphicsLinearLayout(this);
00092     layout->setContentsMargins(0, 0, 0, 0);
00093     layout->setSpacing(0);
00094     layout->addItem(m_icon);
00095 
00096     setAcceptDrops(true);
00097 
00098     m_dirLister = new KDirLister();
00099     connect( m_dirLister, SIGNAL( clear() ),
00100              this, SLOT( slotClear() ) );
00101     connect( m_dirLister, SIGNAL( completed() ),
00102              this, SLOT( slotCompleted() ) );
00103     connect( m_dirLister, SIGNAL( deleteItem( const KFileItem & ) ),
00104              this, SLOT( slotDeleteItem( const KFileItem & ) ) );
00105 
00106     m_dirLister->openUrl(KUrl("trash:/"));
00107 
00108     connect(m_icon, SIGNAL(activated()), this, SLOT(slotOpen()));
00109 }
00110 
00111 void Trash::createConfigurationInterface(KConfigDialog *parent)
00112 {
00113     m_proxy = new KCModuleProxy("kcmtrash");
00114 
00115     parent->addPage(m_proxy, i18n("Trash"), icon());
00116     connect(parent, SIGNAL(okClicked()), this, SLOT(slotApplyConfig()));
00117 
00118     m_proxy->load();
00119 }
00120 
00121 void Trash::createMenu()
00122 {
00123     QAction* open = new QAction(SmallIcon("document-open"),i18n("&Open"), this);
00124     actions.append(open);
00125     connect(open, SIGNAL(triggered(bool)), this , SLOT(slotOpen()));
00126 
00127     emptyTrash = new QAction(SmallIcon("trash-empty"),i18n("&Empty Trashcan"), this);
00128     actions.append(emptyTrash);
00129     connect(emptyTrash, SIGNAL(triggered(bool)), this , SLOT(slotEmpty()));
00130 
00131     m_menu.addTitle(i18n("Trash"));
00132     m_menu.addAction(open);
00133     m_menu.addAction(emptyTrash);
00134 
00135     //add the menu as an action icon
00136     QAction* menu = new QAction(SmallIcon("arrow-up-double"),i18n("&Menu"), this);
00137     connect(menu, SIGNAL(triggered(bool)), this , SLOT(popup()));
00138     m_icon->addIconAction(menu);
00139 
00140     connect(&m_menu, SIGNAL(aboutToHide()), m_icon, SLOT(setUnpressed()));
00141 }
00142 
00143 void Trash::popup()
00144 {
00145     if (m_menu.isVisible()) {
00146         m_menu.hide();
00147         return;
00148     }
00149     m_menu.popup(popupPosition(m_menu.sizeHint()));
00150     m_icon->setPressed();
00151 }
00152 
00153 void Trash::constraintsEvent(Plasma::Constraints constraints)
00154 {
00155     setBackgroundHints(NoBackground);
00156 
00157     if (constraints & Plasma::FormFactorConstraint) {
00158         disconnect(m_icon, SIGNAL(activated()), this, SLOT(slotOpen()));
00159         disconnect(m_icon, SIGNAL(clicked()), this, SLOT(slotOpen()));
00160 
00161         if (formFactor() == Plasma::Planar ||
00162             formFactor() == Plasma::MediaCenter) {
00163 
00164             connect(m_icon, SIGNAL(activated()), this, SLOT(slotOpen()));
00165 
00166             m_icon->setText(i18n("Trash"));
00167             m_icon->setInfoText(i18np("One item", "%1 items", m_count));
00168             m_showText = true;
00169             m_icon->setDrawBackground(true);
00170             //Adding an arbitrary width to make room for a larger count of items
00171             setMinimumSize(m_icon->sizeFromIconSize(IconSize(KIconLoader::Desktop))+=QSizeF(20,0));
00172         } else {
00173             //in a panel the icon always behaves like a button
00174             connect(m_icon, SIGNAL(clicked()), this, SLOT(slotOpen()));
00175 
00176             m_icon->setText(0);
00177             m_icon->setInfoText(0);
00178             m_showText = false;
00179             m_icon->setDrawBackground(false);
00180 
00181             setMinimumSize(m_icon->sizeFromIconSize(IconSize(KIconLoader::Small)));
00182         }
00183         updateIcon();
00184     }
00185 }
00186 
00187 void Trash::slotOpen()
00188 {
00189     emit releaseVisualFocus();
00190     KRun::runUrl(KUrl("trash:/"), "inode/directory", 0);
00191 }
00192 
00193 void Trash::slotEmpty()
00194 {
00195     if (m_emptyProcess) {
00196         //FIXME 4.3: Instead, tell the user the trash is still being empties and just return
00197         delete m_emptyProcess;
00198         m_emptyProcess = 0;
00199     }
00200 
00201     emit releaseVisualFocus();
00202     const QString text(i18nc("@info", "Do you really want to empty the trash? All items will be deleted."));
00203     //FIXME: should use KMessageBox::createKMessageBox so that it doesn't block the whole app!
00204     const bool del = KMessageBox::warningContinueCancel(&m_menu,
00205                                                         text,
00206                                                         QString(),
00207                                                         KGuiItem(i18nc("@action:button", "Empty Trash"),
00208                                                                   KIcon("user-trash"))
00209                                                         ) == KMessageBox::Continue;
00210 
00211     if (del) {
00212          // We can't use KonqOperations here. To avoid duplicating its code (small, though),
00213         // we can simply call ktrash.
00214         //KonqOperations::emptyTrash(&m_menu);
00215         m_emptyProcess = new KProcess(this);
00216         connect(m_emptyProcess, SIGNAL(finished(int,QProcess::ExitStatus)),
00217                 this, SLOT(emptyFinished(int,QProcess::ExitStatus)));
00218         (*m_emptyProcess) << KStandardDirs::findExe("ktrash") << "--empty";
00219         m_emptyProcess->start();
00220     }
00221 }
00222 
00223 void Trash::emptyFinished(int exitCode, QProcess::ExitStatus exitStatus)
00224 {
00225     Q_UNUSED(exitCode)
00226     Q_UNUSED(exitStatus)
00227     //TODO: check the exit status and let the user know if it fails
00228     delete m_emptyProcess;
00229     m_emptyProcess = 0;
00230 }
00231 
00232 void Trash::updateIcon()
00233 {
00234     Plasma::ToolTipContent data;
00235     data.setMainText(i18n("Trash"));
00236 
00237     if (m_count > 0) {
00238         m_icon->setIcon(KIcon("user-trash-full"));
00239 
00240         data.setSubText(i18np("One item", "%1 items", m_count));
00241         if (m_showText) {
00242             m_icon->setInfoText(i18np("One item", "%1 items", m_count));
00243         }
00244     } else {
00245         m_icon->setIcon(KIcon("user-trash"));
00246 
00247         data.setSubText(i18nc("The trash is empty. This is not an action, but a state", "Empty"));
00248         if (m_showText) {
00249             m_icon->setInfoText(i18nc("The trash is empty. This is not an action, but a state", "Empty"));
00250         }
00251     }
00252 
00253     m_icon->update();
00254 
00255     data.setImage(m_icon->icon().pixmap(IconSize(KIconLoader::Desktop)));
00256 
00257     if (!m_showText) {
00258         Plasma::ToolTipManager::self()->setContent(this, data);
00259     } else {
00260         Plasma::ToolTipManager::self()->clearContent(this);
00261     }
00262 
00263     emptyTrash->setEnabled(m_count > 0);
00264 }
00265 
00266 void Trash::slotClear()
00267 {
00268     m_count = 0;
00269     updateIcon();
00270 }
00271 
00272 void Trash::slotCompleted()
00273 {
00274     m_count = m_dirLister->items(KDirLister::AllItems).count();
00275     updateIcon();
00276 }
00277 
00278 void Trash::slotDeleteItem(const KFileItem &)
00279 {
00280     m_count--;
00281     updateIcon();
00282 }
00283 
00284 void Trash::slotApplyConfig()
00285 {
00286     m_proxy->save();
00287 }
00288 
00289 QList<QAction*> Trash::contextualActions()
00290 {
00291     return actions;
00292 }
00293 
00294 void Trash::dropEvent(QGraphicsSceneDragDropEvent *event)
00295 {
00296     if (KUrl::List::canDecode(event->mimeData())) {
00297         const KUrl::List urls = KUrl::List::fromMimeData(event->mimeData());
00298         if (urls.count() > 0) {
00299             event->accept();
00300 
00301             //some special operation was done instead of simply deleting a file
00302             bool specialOperation = false;
00303 
00304             if (!m_places) {
00305                 m_places = new KFilePlacesModel(this);
00306             }
00307 
00308             foreach (const KUrl& url, urls) {
00309                 const Solid::Predicate predicate(Solid::DeviceInterface::StorageAccess, "filePath", url.path());
00310 
00311                 //query for mounted devices
00312                 const QList<Solid::Device> devList = Solid::Device::listFromQuery(predicate, QString());
00313 
00314 
00315                 //seek for an item in the places (e.g. Dolphin sidebar)
00316                 const QModelIndex index = m_places->closestItem(url);
00317 
00318                 if (devList.count() > 0) {
00319                     //Assuming a mountpoint has a single device
00320                     Solid::Device device = devList.first();
00321 
00322                     if (device.is<Solid::OpticalDisc>()) {
00323                         device.parent().as<Solid::OpticalDrive>()->eject();
00324                     } else {
00325                         device.as<Solid::StorageAccess>()->teardown();
00326                     }
00327 
00328                     specialOperation = true;
00329                 //hide if there is exactly that item in the places model
00330                 } else if (m_places->bookmarkForIndex(index).url() == url) {
00331                     m_places->removePlace(index);
00332                     specialOperation = true;
00333                 }
00334             }
00335 
00336              //finally, try to trash a file
00337             if (!specialOperation) {
00338                 KIO::Job* job = KIO::trash(urls);
00339                 job->ui()->setWindow(0);
00340                 job->ui()->setAutoErrorHandlingEnabled(true);
00341             }
00342         }
00343     }
00344 }
00345 
00346 #include "trash.moc"
00347 

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