00001
00002
00003
00004
00005
00006
00007
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
00094 m_themes.clear();
00095
00096
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
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
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
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
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
00262
00263 if (pkg->isValid() &&
00264 (!container || !container->contains(pkg->path()))) {
00265 res.append(pkg.release());
00266 }
00267 }
00268
00269
00270 #endif
00271
00272
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
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
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
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
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
00557 connect(m_mode, SIGNAL(currentIndexChanged(int)),
00558 this, SLOT(changeBackgroundMode(int)));
00559
00560
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
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
00585 m_color->setColor(palette().color(QPalette::Window));
00586 connect(m_color, SIGNAL(changed(QColor)), this, SLOT(update()));
00587
00588
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
00598 QString monitorPath = KStandardDirs::locate("data", "kcontrol/pics/monitor.png");
00599
00600
00601
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
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
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
00764 m_model->addBackground(wallpaper);
00765
00766
00767 int index = m_model->indexOf(wallpaper);
00768 if (index != -1) {
00769 m_view->setCurrentIndex(index);
00770 }
00771
00772
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
00807
00808
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
00815
00816 QString author = i18nc("Wallpaper info, author name", "%1", b->author());
00817
00818
00819 bool someMetadata = setMetadata(m_authorLine, author);
00820 someMetadata = setMetadata(m_licenseLine, license) || someMetadata;
00821 someMetadata = setMetadata(m_emailLine, b->email()) || someMetadata;
00822
00823
00824
00825
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
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
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
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
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 }