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

Plasma

backgrounddialog.cpp

Go to the documentation of this file.
00001 /*
00002   Copyright (c) 2007 Paolo Capriotti <p.capriotti@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 
00010 #define USE_BACKGROUND_PACKAGES
00011 
00012 #include "backgrounddialog.h"
00013 #include <memory>
00014 #include <QAbstractItemView>
00015 #include <QAbstractListModel>
00016 #include <QComboBox>
00017 #include <QDir>
00018 #include <QFileInfo>
00019 #include <QGroupBox>
00020 #include <QLabel>
00021 #include <QList>
00022 #include <QListWidget>
00023 #include <QPainter>
00024 #include <QStackedWidget>
00025 #include <QTimeEdit>
00026 #include <QToolButton>
00027 #include <QVBoxLayout>
00028 #include <QCheckBox>
00029 #include <KColorButton>
00030 #include <KColorScheme>
00031 #include <KDebug>
00032 #include <KDesktopFile>
00033 #include <KDirSelectDialog>
00034 #include <KDirWatch>
00035 #include <KFileDialog>
00036 #include <KGlobalSettings>
00037 #include <KImageFilePreview>
00038 #include <KLocalizedString>
00039 #include <KPushButton>
00040 #include <KSeparator>
00041 #include <KStandardDirs>
00042 #include <knewstuff2/engine.h>
00043 #include <ThreadWeaver/Weaver>
00044 #include <KAboutData>
00045 
00046 #ifdef USE_BACKGROUND_PACKAGES
00047 
00048 #include <plasma/packagemetadata.h>
00049 #include <plasma/panelsvg.h>
00050 #include <plasma/package.h>
00051 #include <plasma/theme.h>
00052 
00053 #endif
00054 
00055 class ThemeInfo
00056 {
00057 public:
00058     QString package;
00059     Plasma::PanelSvg *svg;
00060 };
00061 
00062 class ThemeModel : public QAbstractListModel
00063 {
00064 public:
00065     enum { PackageNameRole = Qt::UserRole,
00066            SvgRole = Qt::UserRole + 1
00067          };
00068 
00069     ThemeModel(QObject *parent = 0);
00070     virtual ~ThemeModel();
00071 
00072     virtual int rowCount(const QModelIndex &parent = QModelIndex()) const;
00073     virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
00074     int indexOf(const QString &path) const;
00075     void reload();
00076 private:
00077     QMap<QString, ThemeInfo> m_themes;
00078 };
00079 
00080 ThemeModel::ThemeModel( QObject *parent )
00081 : QAbstractListModel( parent )
00082 {
00083     reload();
00084 }
00085 
00086 ThemeModel::~ThemeModel()
00087 {
00088 }
00089 
00090 void ThemeModel::reload()
00091 {
00092     reset();
00093     //TODO: the svg objects don't get deleted until the dialog goes away!
00094     m_themes.clear();
00095 
00096     // get all desktop themes
00097     KStandardDirs dirs;
00098     QStringList themes = dirs.findAllResources("data", "desktoptheme/*/metadata.desktop", KStandardDirs::NoDuplicates);
00099     foreach (const QString &theme, themes) {
00100         kDebug() << theme;
00101         int themeSepIndex = theme.lastIndexOf("/", -1);
00102         QString themeRoot = theme.left(themeSepIndex);
00103         int themeNameSepIndex = themeRoot.lastIndexOf("/", -1);
00104         QString packageName = themeRoot.right(themeRoot.length() - themeNameSepIndex - 1);
00105 
00106         KDesktopFile df(theme);
00107         QString name = df.readName();
00108         if (name.isEmpty()) {
00109             name = packageName;
00110         }
00111 
00112         Plasma::PanelSvg *svg = new Plasma::PanelSvg(this);
00113         svg->setImagePath(themeRoot + "/widgets/background.svg");
00114         svg->setEnabledBorders(Plasma::PanelSvg::AllBorders);
00115         ThemeInfo info;
00116         info.package = packageName;
00117         info.svg = svg;
00118         m_themes[name] = info;
00119     }
00120 
00121     beginInsertRows(QModelIndex(), 0, m_themes.size());
00122     endInsertRows();
00123 }
00124 
00125 int ThemeModel::rowCount(const QModelIndex &) const
00126 {
00127     return m_themes.size();
00128 }
00129 
00130 QVariant ThemeModel::data(const QModelIndex &index, int role) const
00131 {
00132     if (!index.isValid()) {
00133         return QVariant();
00134     }
00135 
00136     if (index.row() >= m_themes.size()) {
00137         return QVariant();
00138     }
00139 
00140     QMap<QString, ThemeInfo>::const_iterator it = m_themes.constBegin();
00141     for (int i = 0; i < index.row(); ++i) {
00142         ++it;
00143     }
00144 
00145     switch (role) {
00146         case Qt::DisplayRole:
00147             return it.key();
00148         case PackageNameRole:
00149             return (*it).package;
00150         case SvgRole:
00151             return qVariantFromValue((void*)(*it).svg);
00152         default:
00153             return QVariant();
00154     }
00155 }
00156 
00157 int ThemeModel::indexOf(const QString &name) const
00158 {
00159     QMapIterator<QString, ThemeInfo> it(m_themes);
00160     int i = -1;
00161     while (it.hasNext()) {
00162         ++i;
00163         if (it.next().value().package == name) {
00164             return i;
00165         }
00166     }
00167 
00168     return -1;
00169 }
00170 
00171 
00172 
00173 class ThemeDelegate : public QAbstractItemDelegate
00174 {
00175 public:
00176     ThemeDelegate( QObject * parent = 0 );
00177 
00178     virtual void paint(QPainter *painter, 
00179                        const QStyleOptionViewItem &option,
00180                        const QModelIndex &index) const;
00181     virtual QSize sizeHint(const QStyleOptionViewItem &option,
00182                            const QModelIndex &index) const;
00183 private:
00184     static const int MARGIN = 5;
00185 };
00186 
00187 ThemeDelegate::ThemeDelegate( QObject * parent )
00188 : QAbstractItemDelegate( parent )
00189 {
00190     kDebug();
00191 }
00192 
00193 void ThemeDelegate::paint(QPainter *painter,
00194                                const QStyleOptionViewItem &option,
00195                                const QModelIndex &index) const
00196 {
00197     QString title = index.model()->data(index, Qt::DisplayRole).toString();
00198     QString package = index.model()->data(index, ThemeModel::PackageNameRole).toString();
00199 
00200     // highlight selected item
00201     painter->save();
00202     if (option.state & QStyle::State_Selected) {
00203         painter->setBrush(option.palette.color(QPalette::Highlight));
00204     } else {
00205         painter->setBrush(Qt::gray);
00206     }
00207     painter->drawRect(option.rect);
00208     painter->restore();
00209 
00210     // draw image
00211     Plasma::PanelSvg *svg = static_cast<Plasma::PanelSvg *>(index.model()->data(index, ThemeModel::SvgRole).value<void *>());
00212     svg->resizePanel(QSize(option.rect.width()-(2*MARGIN), 100-(2*MARGIN)));
00213     QRect imgRect = QRect(option.rect.topLeft(), QSize( option.rect.width()-(2*MARGIN), 100-(2*MARGIN) )).
00214         translated(MARGIN, MARGIN);
00215     svg->paintPanel( painter, imgRect, QPoint(option.rect.left() + MARGIN, option.rect.top() + MARGIN) );
00216 
00217     // draw text
00218     painter->save();
00219     QFont font = painter->font();
00220     font.setWeight(QFont::Bold);
00221     QString colorFile = KStandardDirs::locate("data", "desktoptheme/" + package + "/colors");
00222     if (!colorFile.isEmpty()) {
00223         KSharedConfigPtr colors = KSharedConfig::openConfig(colorFile);
00224         KColorScheme colorScheme(QPalette::Active, KColorScheme::Window, colors);
00225         painter->setPen(colorScheme.foreground(KColorScheme::NormalText).color());
00226     }
00227     painter->setFont(font);
00228     painter->drawText(option.rect, Qt::AlignCenter | Qt::TextWordWrap, title);
00229     painter->restore();
00230 }
00231 
00232 QSize ThemeDelegate::sizeHint(const QStyleOptionViewItem &, const QModelIndex &) const
00233 {
00234     return QSize(200, 100);
00235 }
00236 
00237 
00238 class BackgroundContainer
00239 {
00240 public:
00241     virtual ~BackgroundContainer();
00242     virtual bool contains(const QString &path) const = 0;
00243 };
00244 
00245 QList<Background *> 
00246 findAllBackgrounds(const BackgroundContainer *container, 
00247                    const QString &path, 
00248                    float ratio)
00249 {
00250     QList<Background *> res;
00251 
00252 #ifdef USE_BACKGROUND_PACKAGES
00253 
00254     // get all packages in this directory
00255     QStringList packages = Plasma::Package::listInstalled(path);
00256     foreach (const QString &packagePath, packages)
00257     {
00258         kDebug() << packagePath;
00259         std::auto_ptr<Background> pkg(
00260             new BackgroundPackage(path+packagePath, ratio));
00261 //             kDebug() << "Package is valid?" << pkg->isValid();
00262 //             kDebug() << "Path passed to the constructor" << path+packagePath;
00263         if (pkg->isValid() && 
00264             (!container || !container->contains(pkg->path()))) {
00265             res.append(pkg.release());
00266         }
00267     }
00268 //     kDebug() << packages << res;
00269 
00270 #endif
00271 
00272     // search normal wallpapers
00273     QDir dir(path);
00274     QStringList filters;
00275     filters << "*.png" << "*.jpeg" << "*.jpg" << "*.svg" << "*.svgz";
00276     dir.setNameFilters(filters);
00277     dir.setFilter(QDir::Files | QDir::Hidden);
00278     QFileInfoList files = dir.entryInfoList();
00279     foreach (const QFileInfo &wp, files)
00280     {
00281         if (!container || !container->contains(wp.filePath())) {
00282             res.append(new BackgroundFile(wp.filePath(), ratio));
00283         }
00284     }
00285 
00286     return res;
00287 }
00288 
00289 BackgroundContainer::~BackgroundContainer()
00290 {
00291 }
00292 
00293 class BackgroundListModel : public QAbstractListModel
00294                           , public BackgroundContainer
00295 {
00296 public:
00297     BackgroundListModel(float ratio, QObject *listener);
00298     virtual ~BackgroundListModel();
00299     
00300     virtual int rowCount(const QModelIndex &parent = QModelIndex()) const;
00301     virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
00302     Background* package(int index) const;
00303     
00304     void reload();
00305     void reload(const QStringList &selected);
00306     void addBackground(const QString &path);
00307     int indexOf(const QString &path) const;
00308     void removeBackground(const QString &path);
00309     virtual bool contains(const QString &bg) const;
00310 private:
00311     QObject *m_listener;
00312     QList<Background*> m_packages;
00313     float m_ratio;
00314     KDirWatch m_dirwatch;
00315 };
00316 
00317 class BackgroundDelegate : public QAbstractItemDelegate
00318 {
00319 public:
00320     enum {
00321         AuthorRole = Qt::UserRole,
00322         ScreenshotRole
00323     };
00324 
00325     BackgroundDelegate(QObject *listener,
00326                        float ratio, QObject *parent = 0);
00327     
00328     virtual void paint(QPainter *painter, 
00329                        const QStyleOptionViewItem &option, 
00330                        const QModelIndex &index) const;
00331     virtual QSize sizeHint(const QStyleOptionViewItem &option, 
00332                            const QModelIndex &index) const;
00333 private:
00334     static const int MARGIN = 5;
00335     QObject *m_listener;
00336     float m_ratio;
00337 };
00338 
00339 BackgroundListModel::BackgroundListModel(float ratio, QObject *listener)
00340 : m_listener(listener)
00341 , m_ratio(ratio)
00342 {
00343     connect(&m_dirwatch, SIGNAL(deleted(QString)), listener, SLOT(removeBackground(QString)));
00344 }
00345 
00346 void BackgroundListModel::removeBackground(const QString &path)
00347 {
00348     int index;
00349     while ((index = indexOf(path)) != -1) {
00350         beginRemoveRows(QModelIndex(), index, index);
00351         m_packages.removeAt(index);
00352         endRemoveRows();
00353     }
00354 }
00355 
00356 void BackgroundListModel::reload() 
00357 {
00358     reload(QStringList());
00359 }
00360 
00361 void BackgroundListModel::reload(const QStringList& selected)
00362 {
00363     QStringList dirs = KGlobal::dirs()->findDirs("wallpaper", "");
00364     QList<Background *> tmp;
00365     foreach (const QString &file, selected) {
00366         if (!contains(file) && QFile::exists(file)) {
00367             tmp << new BackgroundFile(file, m_ratio);
00368         }
00369     }
00370     foreach (const QString &dir, dirs) {
00371         tmp += findAllBackgrounds(this, dir, m_ratio);
00372     }
00373     
00374     // add new files to dirwatch
00375     foreach (Background *b, tmp) {
00376         if (!m_dirwatch.contains(b->path())) {
00377             m_dirwatch.addFile(b->path());
00378         }
00379     }
00380     
00381     if (!tmp.isEmpty()) {
00382         beginInsertRows(QModelIndex(), 0, tmp.size() - 1);
00383         m_packages = tmp + m_packages;
00384         endInsertRows();
00385     }
00386 }
00387 
00388 void BackgroundListModel::addBackground(const QString& path) {
00389     if (!contains(path)) {
00390         if (!m_dirwatch.contains(path)) {
00391             m_dirwatch.addFile(path);
00392         }
00393         beginInsertRows(QModelIndex(), 0, 0);
00394         m_packages.prepend(new BackgroundFile(path, m_ratio));
00395         endInsertRows();
00396     }
00397 }
00398 
00399 int BackgroundListModel::indexOf(const QString &path) const
00400 {
00401     for (int i = 0; i < m_packages.size(); i++) {
00402         if (path.startsWith(m_packages[i]->path())) {
00403             return i;
00404         }
00405     }
00406     return -1;
00407 }
00408 
00409 bool BackgroundListModel::contains(const QString &path) const
00410 {
00411     return indexOf(path) != -1;
00412 }
00413 
00414 BackgroundListModel::~BackgroundListModel()
00415 {
00416     foreach (Background* pkg, m_packages) {
00417         delete pkg;
00418     }
00419 }
00420 
00421 int BackgroundListModel::rowCount(const QModelIndex &) const
00422 {
00423     return m_packages.size();
00424 }
00425 
00426 QVariant BackgroundListModel::data(const QModelIndex &index, int role) const
00427 {
00428     if (!index.isValid()) {
00429         return QVariant();
00430     }
00431 
00432     if (index.row() >= m_packages.size()) {
00433         return QVariant();
00434     }
00435 
00436     Background *b = package(index.row());
00437     if (!b) {
00438         return QVariant();
00439     }
00440 
00441     switch (role) {
00442     case Qt::DisplayRole:
00443         return b->title();
00444     case BackgroundDelegate::ScreenshotRole: {
00445         QPixmap pix = b->screenshot();
00446         if (pix.isNull() && !b->screenshotGenerationStarted()) {
00447             connect(b, SIGNAL(screenshotDone(QPersistentModelIndex)),
00448                     m_listener, SLOT(updateScreenshot(QPersistentModelIndex)),
00449                     Qt::QueuedConnection);
00450             b->generateScreenshot(index);
00451         }
00452         return pix;
00453     }
00454     case BackgroundDelegate::AuthorRole:
00455         return b->author();
00456     default:
00457         return QVariant();
00458     }
00459 }
00460 
00461 Background* BackgroundListModel::package(int index) const
00462 {
00463     return m_packages.at(index);
00464 }
00465 
00466 BackgroundDelegate::BackgroundDelegate(QObject *listener,
00467                                        float ratio, QObject *parent)
00468 : QAbstractItemDelegate(parent)
00469 , m_listener(listener)
00470 , m_ratio(ratio)
00471 {
00472 }
00473 
00474 void BackgroundDelegate::paint(QPainter *painter, 
00475                                const QStyleOptionViewItem &option, 
00476                                const QModelIndex &index) const
00477 {
00478     QString title = index.model()->data(index, Qt::DisplayRole).toString();
00479     QString author = index.model()->data(index, AuthorRole).toString();
00480     QPixmap pix = index.model()->data(index, ScreenshotRole).value<QPixmap>();
00481         
00482     // draw selection outline
00483     if (option.state & QStyle::State_Selected) {
00484         QPen oldPen = painter->pen();
00485         painter->setPen(option.palette.color(QPalette::Highlight));
00486         painter->drawRect(option.rect.adjusted(2, 2, -2, -2));
00487         painter->setPen(oldPen);
00488     }
00489     
00490     // draw pixmap
00491     int maxheight = Background::SCREENSHOT_HEIGHT;
00492     int maxwidth = int(maxheight * m_ratio);
00493     if (!pix.isNull()) {
00494         QSize sz = pix.size();
00495         int x = MARGIN + (maxwidth - pix.width()) / 2;
00496         int y = MARGIN + (maxheight - pix.height()) / 2;
00497         QRect imgRect = QRect(option.rect.topLeft(), pix.size()).translated(x, y);
00498         painter->drawPixmap(imgRect, pix);
00499     }
00500     
00501     // draw text
00502     painter->save();
00503     QFont font = painter->font();
00504     font.setWeight(QFont::Bold);
00505     painter->setFont(font);
00506     int x = option.rect.left() + MARGIN * 5 + maxwidth;
00507     
00508     QRect textRect(x,
00509                    option.rect.top() + MARGIN,
00510                    option.rect.width() - x - MARGIN * 2,
00511                    maxheight);
00512     QString text = title;
00513     QString authorCaption;
00514     if (!author.isEmpty()) {
00515         authorCaption = i18nc("Caption to wallpaper preview, %1 author name",
00516                               "by %1", author);
00517         text += '\n' + authorCaption;
00518     }
00519     QRect boundingRect = painter->boundingRect(
00520         textRect, Qt::AlignVCenter | Qt::TextWordWrap, text);
00521     painter->drawText(boundingRect, Qt::TextWordWrap, title);
00522     if (!author.isEmpty()) {
00523         QRect titleRect = painter->boundingRect(boundingRect, Qt::TextWordWrap, title);
00524         QRect authorRect(titleRect.bottomLeft(), textRect.size());
00525         painter->setFont(KGlobalSettings::smallestReadableFont());
00526         painter->drawText(authorRect, Qt::TextWordWrap, authorCaption);
00527     }
00528 
00529     painter->restore();
00530 }
00531 
00532 QSize BackgroundDelegate::sizeHint(const QStyleOptionViewItem &, 
00533                                    const QModelIndex &) const
00534 {
00535     return QSize(100, Background::SCREENSHOT_HEIGHT + MARGIN * 2);
00536 }
00537 
00538 
00539 BackgroundDialog::BackgroundDialog(const QSize &res, 
00540                                    const KConfigGroup &config,
00541                                    const KConfigGroup &globalConfig,
00542                                    QWidget *parent)
00543 : KDialog(parent)
00544 , m_res(res)
00545 , m_ratio((float) res.width() / res.height())
00546 , m_currentSlide(-1)
00547 , m_preview_renderer(QSize(128, 101), (float) 128 / res.width())
00548 {
00549     setWindowIcon(KIcon("preferences-desktop-wallpaper"));
00550     setCaption(i18n("Desktop Settings"));
00551     setButtons(Ok | Cancel | Apply);
00552 
00553     QWidget * main = new QWidget(this);
00554     setupUi(main);
00555 
00556     // static, slideshow or none?
00557     connect(m_mode, SIGNAL(currentIndexChanged(int)),
00558             this, SLOT(changeBackgroundMode(int)));
00559 
00560     // static picture
00561     m_model = new BackgroundListModel(m_ratio, this);
00562     m_view->setModel(m_model);
00563     m_view->setItemDelegate(new BackgroundDelegate(m_view->view(), m_ratio, this));
00564     m_view->view()->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
00565     connect(m_view, SIGNAL(currentIndexChanged(int)),
00566             this, SLOT(update()));
00567     m_pictureUrlButton->setIcon(KIcon("document-open"));
00568     connect(m_pictureUrlButton, SIGNAL(clicked()), this, SLOT(showFileDialog()));
00569 
00570     // resize method
00571     m_resizeMethod->addItem(i18n("Scaled & Cropped"),
00572                             Background::ScaleCrop);
00573     m_resizeMethod->addItem(i18n("Scaled"), 
00574                             Background::Scale);
00575     m_resizeMethod->addItem(i18n("Centered"), 
00576                             Background::Center);
00577     m_resizeMethod->addItem(i18n("Tiled"),
00578                             Background::Tiled);
00579     m_resizeMethod->addItem(i18n("Center Tiled"),
00580                             Background::CenterTiled);
00581     connect(m_resizeMethod, SIGNAL(currentIndexChanged(int)),
00582             this, SLOT(update()));
00583 
00584     // color
00585     m_color->setColor(palette().color(QPalette::Window));
00586     connect(m_color, SIGNAL(changed(QColor)), this, SLOT(update()));
00587 
00588     // slideshow
00589     m_addDir->setIcon(KIcon("list-add"));
00590     connect(m_addDir, SIGNAL(clicked()), this, SLOT(slotAddDir()));
00591     m_removeDir->setIcon(KIcon("list-remove"));
00592     connect(m_removeDir, SIGNAL(clicked()), this, SLOT(slotRemoveDir()));
00593     connect(m_dirlist, SIGNAL(currentRowChanged(int)), this, SLOT(updateSlideshow()));
00594 
00595     m_slideshowDelay->setMinimumTime(QTime(0, 0, 30));
00596 
00597     // preview
00598     QString monitorPath = KStandardDirs::locate("data",  "kcontrol/pics/monitor.png");
00599 
00600     // Size of monitor image: 200x186
00601     // Geometry of "display" part of monitor image: (23,14)-[151x115]
00602     qreal previewRatio = 128.0 / (101.0 * m_ratio);
00603     QSize monitorSize(200, int(186 * previewRatio));
00604     QRect previewRect(23, int(14 * previewRatio), 151, int(115 * previewRatio));
00605     m_preview_renderer.setSize(previewRect.size());
00606     
00607     m_monitor->setPixmap(QPixmap(monitorPath).scaled(monitorSize));
00608     m_monitor->setWhatsThis(i18n(
00609         "This picture of a monitor contains a preview of "
00610         "what the current settings will look like on your desktop."));
00611     m_preview = new QLabel(m_monitor);
00612     m_preview->setScaledContents(true);
00613     m_preview->setGeometry(previewRect);
00614 
00615     connect(m_newStuff, SIGNAL(clicked()), this, SLOT(getNewWallpaper()));
00616     connect(m_newThemeButton, SIGNAL(clicked()), this, SLOT(getNewThemes()));
00617 
00618     qRegisterMetaType<QImage>("QImage");
00619     connect(&m_preview_timer, SIGNAL(timeout()), this, SLOT(updateSlideshowPreview()));
00620     connect(&m_preview_renderer, SIGNAL(done(int, const QImage &)), 
00621             this, SLOT(previewRenderingDone(int, const QImage &)));
00622     connect(this, SIGNAL(finished(int)), this, SLOT(cleanup()));
00623 
00624     m_themeModel = new ThemeModel(this);
00625     m_theme->setModel(m_themeModel);
00626     m_theme->setItemDelegate(new ThemeDelegate(m_theme->view()));
00627     m_theme->view()->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
00628 
00629     setMainWidget(main);
00630     m_emailLine->setTextInteractionFlags(Qt::TextSelectableByMouse);
00631 
00632     reloadConfig(config, globalConfig);
00633     adjustSize();
00634 }
00635 
00636 void BackgroundDialog::reloadConfig(const KConfigGroup &config, const KConfigGroup &globalConfig)
00637 {
00638     Q_UNUSED(globalConfig)
00639 
00640     // initialize
00641     int mode = config.readEntry("backgroundmode", int(kStaticBackground));
00642     m_mode->setCurrentIndex(mode);
00643     int delay = config.readEntry("slideTimer", 60);
00644     QTime time(0, 0, 0);
00645     time = time.addSecs(delay);
00646     m_slideshowDelay->setTime(time);
00647 
00648     // we go from index -> data -> config file entry (data) -> index. oi vey.
00649     int resizeMethod = m_resizeMethod->itemData(m_resizeMethod->currentIndex()).toInt();
00650     resizeMethod = config.readEntry("wallpaperposition", resizeMethod);
00651     resizeMethod = m_resizeMethod->findData(resizeMethod);
00652     m_resizeMethod->setCurrentIndex(resizeMethod);
00653 
00654     m_dirlist->clear();
00655     QStringList dirs = config.readEntry("slidepaths", QStringList());
00656     if (dirs.isEmpty()) {
00657         dirs << KStandardDirs::installPath("wallpaper");
00658     }
00659     foreach (const QString &dir, dirs) {
00660         m_dirlist->addItem(dir);
00661     }
00662     m_selected = config.readEntry("selected", QStringList());
00663     m_model->reload(m_selected);
00664     QString defaultPath = Plasma::Theme::defaultTheme()->wallpaperPath();
00665     QString currentPath = config.readEntry("wallpaper", defaultPath);
00666 
00667     kDebug() << "Default would be" << defaultPath << "but we're loading" << currentPath << "instead";
00668 
00669     int index = m_model->indexOf(currentPath);
00670     if (index != -1) {
00671         m_view->setCurrentIndex(index);
00672     }
00673 
00674     m_color->setColor(config.readEntry("wallpapercolor", m_color->color()));
00675     m_theme->setCurrentIndex(m_themeModel->indexOf(Plasma::Theme::defaultTheme()->themeName()));
00676 
00677     if (mode == kSlideshowBackground) {
00678         updateSlideshow();
00679     } else {
00680         update();
00681     }
00682 }
00683 
00684 void BackgroundDialog::saveConfig(KConfigGroup config, KConfigGroup globalConfig)
00685 {
00686     Q_UNUSED(globalConfig)
00687     int mode = m_mode->currentIndex();
00688     config.writeEntry("backgroundmode", mode);
00689     if (mode == kStaticBackground) {
00690         config.writeEntry("wallpaper", m_img);
00691         config.writeEntry("wallpapercolor", m_color->color());
00692         config.writeEntry("wallpaperposition", 
00693             m_resizeMethod->itemData(m_resizeMethod->currentIndex()).toInt());
00694         config.writeEntry("selected", m_selected);
00695     } else if (mode == kNoBackground) {
00696         config.writeEntry("wallpaper", QString());
00697         config.writeEntry("wallpapercolor", m_color->color());
00698     } else {
00699         QStringList dirs;
00700         for (int i = 0; i < m_dirlist->count(); i++) {
00701             dirs << m_dirlist->item(i)->text();
00702         }
00703         config.writeEntry("slidepaths", dirs);
00704         int seconds = QTime(0, 0, 0).secsTo(m_slideshowDelay->time());
00705         config.writeEntry("slideTimer", seconds);
00706     }
00707 
00708     QString newTheme = m_theme->itemData(m_theme->currentIndex(), ThemeModel::PackageNameRole).toString();
00709     Plasma::Theme::defaultTheme()->setThemeName(newTheme);
00710 }
00711 
00712 void BackgroundDialog::getNewWallpaper()
00713 {
00714     KNS::Engine engine(0);
00715     if (engine.init("wallpaper.knsrc")) {
00716         KNS::Entry::List entries = engine.downloadDialogModal(this);
00717 
00718         if (entries.size() > 0) {
00719             m_model->reload();
00720         }
00721     }
00722 }
00723 
00724 void BackgroundDialog::getNewThemes()
00725 {
00726     KNS::Engine engine(0);
00727     if (engine.init("plasma-themes.knsrc")) {
00728         KNS::Entry::List entries = engine.downloadDialogModal(this);
00729 
00730         if (entries.size() > 0) {
00731             m_themeModel->reload();
00732             m_theme->setCurrentIndex(m_themeModel->indexOf(Plasma::Theme::defaultTheme()->themeName()));
00733         }
00734     }
00735 }
00736 
00737 void BackgroundDialog::showFileDialog()
00738 {
00739     m_dialog = new KFileDialog(KUrl(), "*.png *.jpeg *.jpg *.svg *.svgz", this);
00740     KImageFilePreview *previewWidget = new KImageFilePreview(m_dialog);
00741     m_dialog->setPreviewWidget(previewWidget);
00742     m_dialog->setOperationMode(KFileDialog::Opening);
00743     m_dialog->setCaption(i18n("Select Wallpaper Image File"));
00744     m_dialog->setModal(false);
00745     m_dialog->show();
00746     m_dialog->raise();
00747     m_dialog->activateWindow();
00748 
00749     connect(m_dialog, SIGNAL(okClicked()), this, SLOT(browse()));
00750 }
00751 
00752 void BackgroundDialog::browse()
00753 {
00754     QString wallpaper = m_dialog->selectedFile();
00755     disconnect(m_dialog, SIGNAL(okClicked()), this, SLOT(browse()));
00756 
00757     m_dialog->deleteLater();
00758 
00759     if (wallpaper.isEmpty()) {
00760         return;
00761     }
00762 
00763     // add background to the model
00764     m_model->addBackground(wallpaper);
00765 
00766     // select it
00767     int index = m_model->indexOf(wallpaper);
00768     if (index != -1) {
00769         m_view->setCurrentIndex(index);
00770     }
00771 
00772     // save it
00773     m_selected << wallpaper;
00774 }
00775 
00776 bool BackgroundDialog::setMetadata(QLabel *label,
00777                                    const QString &text)
00778 {
00779     if (text.isEmpty()) {
00780         label->hide();
00781         return false;
00782     }
00783     else {
00784         label->show();
00785         label->setText(text);
00786         return true;
00787     }
00788 }
00789 
00790 void BackgroundDialog::update()
00791 {
00792     if (m_mode->currentIndex() == kNoBackground) {
00793         m_img.clear();
00794         setPreview(m_img, Background::Scale);
00795         return;
00796     }
00797     int index = m_view->currentIndex();
00798     if (index == -1) {
00799         return;
00800     }
00801     Background *b = m_model->package(index);
00802     if (!b) {
00803         return;
00804     }
00805 
00806     // Prepare more user-friendly forms of some pieces of data.
00807     // - license by config is more a of a key value,
00808     //   try to get the proper name if one of known licenses.
00809     QString license = b->license();
00810     KAboutLicense knownLicense = KAboutLicense::byKeyword(license);
00811     if (knownLicense.key() != KAboutData::License_Custom) {
00812         license = knownLicense.name(KAboutData::ShortName);
00813     }
00814     // - last ditch attempt to localize author's name, if not such by config
00815     //   (translators can "hook" names from outside if resolute enough).
00816     QString author = i18nc("Wallpaper info, author name", "%1", b->author());
00817 
00818     // FIXME the second parameter is not used, get rid of it.
00819     bool someMetadata = setMetadata(m_authorLine, author);
00820     someMetadata = setMetadata(m_licenseLine, license) || someMetadata;
00821     someMetadata = setMetadata(m_emailLine, b->email()) || someMetadata;
00822     //m_authorLabel->setVisible(someMetadata);
00823     //m_emailLabel->setVisible(someMetadata);
00824     //m_licenseLabel->setVisible(someMetadata);
00825 //     m_metadataSeparator->setVisible(someMetadata);
00826 
00827     
00828     Background::ResizeMethod method = (Background::ResizeMethod)
00829         m_resizeMethod->itemData(m_resizeMethod->currentIndex()).value<int>();
00830     
00831     m_img = b->findBackground(m_res, method);
00832     setPreview(m_img, method);
00833 }
00834 
00835 void BackgroundDialog::setPreview(const QString& img, Background::ResizeMethod method)
00836 {
00837     m_preview_token = m_preview_renderer.render(img, m_color->color(), method, Qt::FastTransformation);
00838 }
00839 
00840 void BackgroundDialog::slotAddDir()
00841 {
00842     KUrl empty;
00843     KDirSelectDialog dialog(empty, true, this);
00844     if (dialog.exec()) {
00845         m_dirlist->addItem(dialog.url().path());
00846         updateSlideshow();
00847     }
00848 }
00849 
00850 void BackgroundDialog::slotRemoveDir()
00851 {
00852     int row = m_dirlist->currentRow();
00853     if (row != -1) {
00854         m_dirlist->takeItem(row);
00855         updateSlideshow();
00856     }
00857 }
00858 
00859 void BackgroundDialog::updateSlideshow()
00860 {
00861     int row = m_dirlist->currentRow();
00862     m_removeDir->setEnabled(row != -1);
00863     
00864     // populate background list
00865     m_slideshowBackgrounds.clear();
00866     for (int i = 0; i < m_dirlist->count(); i++) {
00867         QString dir = m_dirlist->item(i)->text();
00868         m_slideshowBackgrounds += findAllBackgrounds(0, dir, m_ratio);
00869     }
00870     
00871     // start preview
00872     if (m_slideshowBackgrounds.isEmpty()) {
00873         m_preview->setPixmap(QPixmap());
00874         m_preview_timer.stop();
00875     }
00876     else {
00877         m_currentSlide = -1;
00878         if (!m_preview_timer.isActive()) {
00879             m_preview_timer.start(3000);
00880         }
00881     }
00882 }
00883 
00884 void BackgroundDialog::updateSlideshowPreview()
00885 {
00886     if (!m_slideshowBackgrounds.isEmpty()) {
00887         // increment current slide index
00888         m_currentSlide++;
00889         m_currentSlide = m_currentSlide % m_slideshowBackgrounds.count();
00890 
00891         Background *slide = m_slideshowBackgrounds[m_currentSlide];
00892         Q_ASSERT(slide);
00893         
00894         const Background::ResizeMethod method = Background::Scale;
00895         m_img = slide->findBackground(m_res, method);
00896         setPreview(m_img, method);
00897     }
00898     else {
00899         m_preview->setPixmap(QPixmap());
00900     }
00901 }
00902 
00903 void BackgroundDialog::changeBackgroundMode(int mode)
00904 {
00905     switch (mode)
00906     {
00907     case kStaticBackground:
00908         m_preview_timer.stop();
00909         stackedWidget->setCurrentIndex(0);
00910         enableButtons(true);
00911         update();
00912         break;
00913     case kNoBackground:
00914         m_preview_timer.stop();
00915         stackedWidget->setCurrentIndex(0);
00916         enableButtons(false);
00917         update();
00918         break;
00919     case kSlideshowBackground:
00920         stackedWidget->setCurrentIndex(1);
00921         updateSlideshow();
00922         enableButtons(true);
00923         break;
00924     }
00925 }
00926 
00927 void BackgroundDialog::enableButtons(bool enabled)
00928 {
00929     m_view->setEnabled(enabled);
00930     m_resizeMethod->setEnabled(enabled);
00931     m_pictureUrlButton->setEnabled(enabled);
00932 }
00933 
00934 bool BackgroundDialog::contains(const QString &path) const
00935 {
00936     foreach (Background *bg, m_slideshowBackgrounds)
00937     {
00938         if (bg->path() == path) {
00939             return true;
00940         }
00941     }
00942     return false;
00943 }
00944 
00945 void BackgroundDialog::previewRenderingDone(int token, const QImage &image)
00946 {
00947     // display preview only if it is the latest rendered file
00948     if (token == m_preview_token) {
00949         m_preview->setPixmap(QPixmap::fromImage(image));
00950     }
00951 }
00952 
00953 void BackgroundDialog::updateScreenshot(QPersistentModelIndex index)
00954 {
00955     m_view->view()->update(index);
00956 }
00957 
00958 void BackgroundDialog::cleanup()
00959 {
00960     m_preview_timer.stop();
00961 }
00962 
00963 void BackgroundDialog::removeBackground(const QString &path)
00964 {
00965     m_model->removeBackground(path);
00966 }

Plasma

Skip menu "Plasma"
  • 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
  •   libplasma
  •   libsolidcontrol
  •   libtaskmanager
  • Plasma
  •   Animators
  •   Applets
  •   Engines
  • Solid Modules
Generated for API Reference by doxygen 1.5.4
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