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

Applets

notifierdialog.cpp

Go to the documentation of this file.
00001 /*
00002     Copyright 2008 by Alexis Ménard <darktears31@gmail.com>
00003 
00004     This library is free software; you can redistribute it and/or
00005     modify it under the terms of the GNU Library General Public
00006     License as published by the Free Software Foundation; either
00007     version 2 of the License, or (at your option) any later version.
00008 
00009     This library 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 GNU
00012     Library General Public License for more details.
00013 
00014     You should have received a copy of the GNU Library General Public License
00015     along with this library; see the file COPYING.LIB.  If not, write to
00016     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00017     Boston, MA 02110-1301, USA.
00018 */
00019 
00020 #include "notifierdialog.h"
00021 
00022 //Qt
00023 #include <QStandardItemModel>
00024 #include <QModelIndex>
00025 #include <QLabel>
00026 #include <QVBoxLayout>
00027 #include <QtDBus/QDBusInterface>
00028 #include <QtDBus/QDBusReply>
00029 #include <QHeaderView>
00030 #include <QTimer>
00031 #include <QMetaEnum>
00032 
00033 //KDE
00034 #include <KDebug>
00035 #include <KColorScheme>
00036 #include <KIcon>
00037 #include <KIconLoader>
00038 #include <KGlobalSettings>
00039 #include <KMessageBox>
00040 
00041 //plasma
00042 #include <Plasma/Dialog>
00043 #include <Plasma/Delegate>
00044 #include <Plasma/Theme>
00045 
00046 //solid
00047 #include <solid/device.h>
00048 #include <solid/opticaldisc.h>
00049 #include <solid/storageaccess.h>
00050 #include <solid/opticaldrive.h>
00051 #include <solid/deviceinterface.h>
00052 
00053 //own
00054 #include "notifierview.h"
00055 #include "devicenotifier.h"
00056 
00057 using namespace Notifier;
00058 using namespace Plasma;
00059 
00060 NotifierDialog::NotifierDialog(DeviceNotifier * notifier,QObject *parent)
00061     : QObject(parent),
00062       m_hotplugModel(0),
00063       m_widget(0),
00064       m_notifierView(0),
00065       m_label(0),
00066       m_notifier(notifier),
00067       m_rootItem(0)
00068 {
00069     m_hotplugModel = new QStandardItemModel(this);
00070     buildDialog();
00071     //make the invisible root for tree device
00072     m_rootItem = m_hotplugModel->invisibleRootItem();
00073 }
00074 
00075 NotifierDialog::~NotifierDialog()
00076 {
00077 
00078 }
00079 
00080 QWidget * NotifierDialog::dialog()
00081 {
00082     return m_widget;
00083 }
00084 
00085 void NotifierDialog::hide()
00086 {
00087     m_widget->hide();
00088 }
00089 
00090 void NotifierDialog::show()
00091 {
00092     m_widget->show();
00093 }
00094 
00095 QStandardItem* NotifierDialog::searchOrCreateDeviceCategory(const QString &categoryName)
00096 {
00097     int rowCount = m_hotplugModel->rowCount();
00098     if(rowCount > 0)
00099     {
00100         int i = 0;
00101         while (i<rowCount)
00102         {
00103             QModelIndex index = m_hotplugModel->index(i, 0);
00104             QString itemUdi = m_hotplugModel->data(index, SolidUdiRole).toString();
00105             QStandardItem *currentItem = m_hotplugModel->itemFromIndex(index);
00106             if(currentItem)
00107             {
00108                 QString currentItemName = currentItem->text();
00109                 if (currentItemName == categoryName)
00110                 {
00111                     //the category is find... we have to return the pointer on this category
00112                     return m_hotplugModel->itemFromIndex(index);
00113                 }
00114             }
00115             i++;
00116         }
00117     }
00118     //insert a new category for device if not find and return the pointer
00119     QStandardItem *newCategory = new QStandardItem(QString(categoryName));
00120     m_hotplugModel->setData(newCategory->index(),categoryName,Qt::DisplayRole);
00121     m_rootItem->insertRow(0,newCategory);
00122     m_hotplugModel->setItem(0, 1, NULL);
00123     m_hotplugModel->setHeaderData(0, Qt::Horizontal,QString(""),Qt::EditRole);
00124     m_hotplugModel->setHeaderData(1, Qt::Horizontal,QString(""),Qt::EditRole);
00125     return newCategory;
00126 }
00127 
00128 void NotifierDialog::insertDevice(const QString &name)
00129 {
00130     QStandardItem *item = new QStandardItem();
00131     item->setData(name, SolidUdiRole);
00132     item->setData(Plasma::Delegate::MainColumn, ScopeRole);
00133     item->setData(false, SubTitleMandatoryRole);
00134 
00135     QStandardItem *actionItem = new QStandardItem();
00136     actionItem->setData(name, SolidUdiRole);
00137     actionItem->setData(Plasma::Delegate::SecondaryActionColumn, ScopeRole);
00138 
00139     //search or create the category for inserted device
00140     QString udi = item->data(SolidUdiRole).toString();
00141     if(!udi.isNull()) {
00142         Solid::Device device(udi);
00143         QString categoryOfInsertedDevice = getCategoryNameOfDevice(device);
00144         QStandardItem *currentCategory = searchOrCreateDeviceCategory(categoryOfInsertedDevice);
00145         if(currentCategory)
00146         {
00147             currentCategory->insertRow(0,item);
00148             currentCategory->setChild(0, 1, actionItem);
00149         }
00150         else
00151         {
00152             delete item;
00153             delete actionItem;
00154         }
00155     }
00156     else
00157     {
00158         delete item;
00159         delete actionItem;
00160     }
00161 
00162     m_notifierView->calculateRects();
00163 }
00164 
00165 void NotifierDialog::setUnMount(bool unmount, const QString &name) 
00166 {
00167     QModelIndex index = indexForUdi(name);
00168     if (!index.isValid()) {
00169         return;
00170     }
00171     QStandardItem *currentItem = m_hotplugModel->itemFromIndex(index);
00172     QStandardItem *childAction = currentItem->parent()->child(currentItem->row(), 1);
00173     QVariant icon;
00174     if (unmount) {
00175         icon = KIcon("media-eject");
00176     }
00177     else {
00178         icon = KIcon();
00179     }
00180     m_hotplugModel->setData(childAction->index(),icon,Qt::DecorationRole);
00181 }
00182 
00183 void NotifierDialog::setDeviceData(const QString &name, QVariant data, int role)
00184 {
00185     QModelIndex index = indexForUdi(name);
00186     if (!index.isValid()) {
00187         return;
00188     }
00189     if (role == Qt::DecorationRole) {
00190         QStandardItem *device = m_hotplugModel->itemFromIndex(index);
00191         QStandardItem *category = device->parent();
00192         QModelIndex parentIndex = category->index();
00193         if (!parentIndex.data(Qt::DecorationRole).isValid()) {
00194            m_hotplugModel->setData(parentIndex,data,role);
00195         }
00196     }
00197     m_hotplugModel->setData(index,data,role);
00198 }
00199 
00200 QVariant NotifierDialog::getDeviceData(const QString &name, int role)
00201 {
00202     QModelIndex index = indexForUdi(name);
00203     if (!index.isValid()) {
00204         return QVariant();
00205     }
00206     else {
00207         return index.data(role);
00208     }
00209 }
00210 
00211 void NotifierDialog::removeDevice(const QString &name)
00212 {
00213     QModelIndex index = indexForUdi(name);
00214     if (!index.isValid()) {
00215         return;
00216     }
00217 
00218     QStandardItem *device = m_hotplugModel->itemFromIndex(index);
00219     QStandardItem *category = device->parent();
00220 
00221     //removing device
00222     category->removeRow(device->row());
00223 
00224     //remove category if there's no devices into it
00225     if (!category->hasChildren()) {
00226         m_rootItem->removeRow(category->row());
00227     }
00228 
00229     m_notifierView->calculateRects();
00230 }
00231 
00232 void NotifierDialog::removeDevice(int index)
00233 {
00234     m_hotplugModel->removeRow(index);
00235     m_notifierView->calculateRects();
00236 }
00237 
00238 int NotifierDialog::countDevices()
00239 {
00240     return m_hotplugModel->rowCount();
00241 }
00242 
00243 QString NotifierDialog::getDeviceUdi(int index)
00244 {
00245     QModelIndex modelIndex = m_hotplugModel->index(index, 0);
00246     return m_hotplugModel->data(modelIndex, SolidUdiRole).toString();
00247 }
00248 
00249 void NotifierDialog::buildDialog()
00250 {
00251     m_widget = new QWidget();
00252 
00253     QVBoxLayout *l_layout = new QVBoxLayout(m_widget);
00254     l_layout->setSpacing(0);
00255     l_layout->setMargin(0);
00256     
00257     m_label = new QLabel(m_widget);
00258     updateColors();
00259     
00260     QLabel *icon = new QLabel(m_widget);
00261     icon->setPixmap(KIcon("emblem-mounted").pixmap(KIconLoader::SizeMedium, KIconLoader::SizeMedium));
00262 
00263     QHBoxLayout *l_layout2 = new QHBoxLayout(m_widget);
00264     l_layout2->setSpacing(0);
00265     l_layout2->setMargin(0);
00266 
00267     l_layout2->addWidget(icon);
00268     l_layout2->addWidget(m_label);
00269 
00270     l_layout2->setAlignment(Qt::AlignCenter);
00271 
00272 
00273     m_notifierView = new NotifierView(m_widget);
00274     m_notifierView->setModel(m_hotplugModel);
00275     m_notifierView->setMinimumSize(150,300);
00276     m_notifierView->setFocusPolicy(Qt::NoFocus);
00277     
00278     Plasma::Delegate *delegate = new Delegate(this);
00279     //map the roles of m_hotplugModel into the standard Plasma::Delegate roles
00280     delegate->setRoleMapping(Plasma::Delegate::SubTitleRole, ActionRole);
00281     delegate->setRoleMapping(Plasma::Delegate::ColumnTypeRole, ScopeRole);
00282     delegate->setRoleMapping(Plasma::Delegate::SubTitleMandatoryRole, SubTitleMandatoryRole);
00283     m_notifierView->setItemDelegate(delegate);
00284 
00285     l_layout->addLayout(l_layout2);
00286     l_layout->addWidget(m_notifierView);
00287     m_widget->setLayout(l_layout);
00288 
00289     connect(m_notifierView, SIGNAL(clicked(const QModelIndex&)),this,SLOT(slotOnItemClicked(const QModelIndex&)));
00290 
00291     connect(Plasma::Theme::defaultTheme(), SIGNAL(themeChanged()), this, SLOT(updateColors()));    // allows updating of colors automatically
00292 }
00293 
00294 void NotifierDialog::storageTeardownDone(Solid::ErrorType error, QVariant errorData)
00295 {
00296     if (error && errorData.isValid()) {
00297         KMessageBox::error(0, i18n("Cannot unmount the device.\nOne or more files on this device are open within an application."), QString());
00298     }
00299     else {
00300         m_notifier->changeNotifierIcon("dialog-ok");
00301         m_notifier->update();
00302         QTimer::singleShot(5000, this, SLOT(resetNotifierIcon()));
00303     }
00304 
00305     //show the message only one time
00306     disconnect(sender(), SIGNAL(teardownDone(Solid::ErrorType, QVariant, const QString &)),
00307                this, SLOT(storageTeardownDone(Solid::ErrorType, QVariant)));
00308 }
00309 
00310 void NotifierDialog::storageEjectDone(Solid::ErrorType error, QVariant errorData)
00311 {
00312     if (error && errorData.isValid()) {
00313         KMessageBox::error(0, i18n("Cannot eject the disc.\nOne or more files on this disc are open within an application."), QString());
00314     } else {
00315         m_notifier->changeNotifierIcon("dialog-ok");
00316         m_notifier->update();
00317         QTimer::singleShot(2000, this, SLOT(resetNotifierIcon()));
00318     }
00319     //show the message only one time
00320     disconnect(sender(), SIGNAL(ejectDone(Solid::ErrorType, QVariant, const QString &)),
00321                this, SLOT(storageEjectDone(Solid::ErrorType, QVariant)));
00322 }
00323 
00324 QModelIndex NotifierDialog::indexForUdi(const QString &udi) const
00325 {
00326     int rowCount = m_hotplugModel->rowCount();
00327     for (int i=0; i < rowCount; ++i) {
00328         QModelIndex index = m_hotplugModel->index(i, 0);
00329         QStandardItem *currentItem = m_hotplugModel->itemFromIndex(index);
00330         for (int j=0; j < currentItem->rowCount(); ++j) {
00331           QStandardItem *childItem = currentItem->child(j, 0);
00332           QString itemUdi = m_hotplugModel->data(childItem->index(), SolidUdiRole).toString();
00333           if (itemUdi == udi) {
00334               return childItem->index();
00335           }
00336         }
00337     }
00338     //Is it possible to go here?no...
00339     kDebug() << "We should not be here!";
00340     return QModelIndex();
00341 }
00342 
00343 void NotifierDialog::slotOnItemClicked(const QModelIndex &index)
00344 {
00345     QString udi = QString(m_hotplugModel->data(index, SolidUdiRole).toString());
00346 
00347     //unmount (probably in the future different action types for different device types)
00348     if (index.data(ScopeRole).toInt() == Plasma::Delegate::SecondaryActionColumn) {
00349         Solid::Device device(udi);
00350 
00351         if (device.is<Solid::OpticalDisc>()) {
00352             Solid::OpticalDrive *drive = device.parent().as<Solid::OpticalDrive>();
00353             connect(drive, SIGNAL(ejectDone(Solid::ErrorType, QVariant, const QString &)),
00354                     this, SLOT(storageEjectDone(Solid::ErrorType, QVariant)));
00355             drive->eject();
00356         } else if (device.is<Solid::StorageVolume>()) {
00357             Solid::StorageAccess *access = device.as<Solid::StorageAccess>();
00358              if (access && access->isAccessible()) {
00359                 connect(access, SIGNAL(teardownDone(Solid::ErrorType, QVariant, const QString &)),this, SLOT(storageTeardownDone(Solid::ErrorType, QVariant)));
00360                 access->teardown();
00361              }
00362         }
00363     //open  (index.data(ScopeRole).toInt() == OpenAction)
00364     } else {
00365         QStringList desktopFiles = m_hotplugModel->data(index, PredicateFilesRole).toStringList();
00366 
00367         kDebug() << "DeviceNotifier:: call Solid Ui Server with params :" << udi \
00368                 << "," << desktopFiles;
00369         QDBusInterface soliduiserver("org.kde.kded", "/modules/soliduiserver", "org.kde.SolidUiServer");
00370         QDBusReply<void> reply = soliduiserver.call("showActionsDialog", udi, desktopFiles);
00371     }
00372     emit itemSelected();
00373 }
00374 
00375 QString NotifierDialog::getCategoryNameOfDevice(const Solid::Device& device)
00376 {
00377     int index = Solid::DeviceInterface::staticMetaObject.indexOfEnumerator("Type");
00378     QMetaEnum typeEnum = Solid::DeviceInterface::staticMetaObject.enumerator(index);
00379     for (int i = typeEnum.keyCount() - 1 ; i > 0; i--)
00380     {
00381         Solid::DeviceInterface::Type type = (Solid::DeviceInterface::Type)typeEnum.value(i);
00382         const Solid::DeviceInterface *interface = device.asDeviceInterface(type);
00383         if (interface)
00384         {
00385             return Solid::DeviceInterface::typeToString(type);
00386         }
00387     }
00388     return 0;
00389 }
00390 
00391 void NotifierDialog::resetNotifierIcon()
00392 {
00393     m_notifier->changeNotifierIcon();
00394     m_notifier->update();
00395 }
00396 
00397 void NotifierDialog::updateColors()
00398 {
00399     KColorScheme colorTheme = KColorScheme(QPalette::Active, KColorScheme::View,Plasma::Theme::defaultTheme()->colorScheme());
00400     m_label->setText(i18n("<font color=\"%1\">Devices recently plugged in:</font>",colorTheme.foreground(KColorScheme::NormalText).color().name()));
00401 
00402     QPalette p = m_widget->palette();
00403     p.setColor(QPalette::Window, Plasma::Theme::defaultTheme()->color(Plasma::Theme::BackgroundColor));
00404     m_widget->setPalette(p);
00405 }
00406 
00407 #include "notifierdialog.moc"

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