00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "plasma/private/packages_p.h"
00021
00022 #include <math.h>
00023 #include <float.h>
00024
00025 #include <QFileInfo>
00026
00027 #include <kconfiggroup.h>
00028 #include <kdesktopfile.h>
00029 #include <klocale.h>
00030 #include <kmessagebox.h>
00031
00032 #include <knewstuff2/engine.h>
00033
00034 #include "plasma/private/wallpaper_p.h"
00035
00036 namespace Plasma
00037 {
00038
00039 PlasmoidPackage::PlasmoidPackage(QObject *parent)
00040 : Plasma::PackageStructure(parent, QString("Plasmoid"))
00041 {
00042 addDirectoryDefinition("images", "images/", i18n("Images"));
00043 QStringList mimetypes;
00044 mimetypes << "image/svg+xml" << "image/png" << "image/jpeg";
00045 setMimetypes("images", mimetypes);
00046
00047 addDirectoryDefinition("config", "config/", i18n("Configuration Definitions"));
00048 mimetypes.clear();
00049 mimetypes << "text/xml";
00050 setMimetypes("config", mimetypes);
00051 setMimetypes("configui", mimetypes);
00052
00053 addDirectoryDefinition("ui", "ui", i18n("User Interface"));
00054 setMimetypes("ui", mimetypes);
00055
00056 addDirectoryDefinition("scripts", "code", i18n("Executable Scripts"));
00057 mimetypes.clear();
00058 mimetypes << "text/plain";
00059 setMimetypes("scripts", mimetypes);
00060
00061 addDirectoryDefinition("translations", "locale", i18n("Translations"));
00062
00063 addFileDefinition("mainconfigui", "ui/config.ui", i18n("Main Config UI File"));
00064 addFileDefinition("mainconfigxml", "config/main.xml", i18n("Configuration XML file"));
00065 addFileDefinition("mainscript", "code/main", i18n("Main Script File"));
00066 setRequired("mainscript", true);
00067 }
00068
00069 void PlasmoidPackage::pathChanged()
00070 {
00071 KDesktopFile config(path() + "/metadata.desktop");
00072 KConfigGroup cg = config.desktopGroup();
00073 QString mainScript = cg.readEntry("X-Plasma-MainScript", QString());
00074 if (!mainScript.isEmpty()) {
00075 addFileDefinition("mainscript", mainScript, i18n("Main Script File"));
00076 setRequired("mainscript", true);
00077 }
00078 }
00079
00080 void PlasmoidPackage::createNewWidgetBrowser(QWidget *parent)
00081 {
00082 KNS::Engine *engine = new KNS::Engine(parent);
00083 if (engine->init("plasmoids.knsrc")) {
00084 engine->downloadDialog(this, SLOT(widgetBrowserFinished()));
00085 }
00086 }
00087
00088 void PlasmoidPackage::widgetBrowserFinished()
00089 {
00090 emit newWidgetBrowserFinished();
00091 }
00092
00093 ThemePackage::ThemePackage(QObject *parent)
00094 : Plasma::PackageStructure(parent, QString("Plasma Theme"))
00095 {
00096 addDirectoryDefinition("dialogs", "dialogs/", i18n("Images for dialogs"));
00097 addFileDefinition("dialogs/background", "dialogs/background.svg",
00098 i18n("Generic dialog background"));
00099 addFileDefinition("dialogs/shutdowndialog", "dialogs/shutdowndialog.svg",
00100 i18n("Theme for the logout dialog"));
00101
00102 addDirectoryDefinition("wallpapers", "wallpapers/", i18n("Wallpaper packages"));
00103
00104 addDirectoryDefinition("widgets", "widgets/", i18n("Images for widgets"));
00105 addFileDefinition("widgets/background", "widgets/background.svg",
00106 i18n("Background image for widgets"));
00107 addFileDefinition("widgets/clock", "widgets/clock.svg",
00108 i18n("Analog clock face"));
00109 addFileDefinition("widgets/panel-background", "widgets/panel-background.svg",
00110 i18n("Background image for panels"));
00111 addFileDefinition("widgets/plot-background", "widgets/plot-background.svg",
00112 i18n("Background for graphing widgets"));
00113 addFileDefinition("widgets/tooltip", "widgets/tooltip.svg",
00114 i18n("Background image for tooltips"));
00115
00116 addDirectoryDefinition("opaque/dialogs", "opaque/dialogs/", i18n("Opaque images for dialogs"));
00117 addFileDefinition("opaque/dialogs/background", "opaque/dialogs/background.svg",
00118 i18n("Opaque generic dialog background"));
00119 addFileDefinition("opaque/dialogs/shutdowndialog", "opaque/dialogs/shutdowndialog.svg",
00120 i18n("Opaque theme for the logout dialog"));
00121
00122 addDirectoryDefinition("opaque/widgets", "opaque/widgets/", i18n("Opaque images for widgets"));
00123 addFileDefinition("opaque/widgets/panel-background", "opaque/widgets/panel-background.svg",
00124 i18n("Opaque background image for panels"));
00125 addFileDefinition("opaque/widgets/tooltip", "opaque/widgets/tooltip.svg",
00126 i18n("Opaque background image for tooltips"));
00127
00128 addDirectoryDefinition("locolor/dialogs", "locolor/dialogs/",
00129 i18n("Low color images for dialogs"));
00130 addFileDefinition("locolor/dialogs/background", "locolor/dialogs/background.svg",
00131 i18n("Low color generic dialog background"));
00132 addFileDefinition("locolor/dialogs/shutdowndialog", "locolor/dialogs/shutdowndialog.svg",
00133 i18n("Low color theme for the logout dialog"));
00134
00135 addDirectoryDefinition("locolor/widgets", "locolor/widgets/", i18n("Images for widgets"));
00136 addFileDefinition("locolor/widgets/background", "locolor/widgets/background.svg",
00137 i18n("Low color background image for widgets"));
00138 addFileDefinition("locolor/widgets/clock", "locolor/widgets/clock.svg",
00139 i18n("Low color analog clock face"));
00140 addFileDefinition("locolor/widgets/panel-background", "locolor/widgets/panel-background.svg",
00141 i18n("Low color background image for panels"));
00142 addFileDefinition("locolor/widgets/plot-background", "locolor/widgets/plot-background.svg",
00143 i18n("Low color background for graphing widgets"));
00144 addFileDefinition("locolor/widgets/tooltip", "locolor/widgets/tooltip.svg",
00145 i18n("Low color background image for tooltips"));
00146
00147 addFileDefinition("colors", "colors", i18n("KColorScheme configuration file"));
00148
00149 QStringList mimetypes;
00150 mimetypes << "image/svg+xml";
00151 setDefaultMimetypes(mimetypes);
00152 }
00153
00154 WallpaperPackage::WallpaperPackage(Wallpaper *paper, QObject *parent)
00155 : PackageStructure(parent, "Background"),
00156 m_paper(paper),
00157 m_fullPackage(true)
00158 {
00159 QStringList mimetypes;
00160 mimetypes << "image/svg" << "image/png" << "image/jpeg" << "image/jpg";
00161 setDefaultMimetypes(mimetypes);
00162
00163 addDirectoryDefinition("images", "images/", i18n("Images"));
00164 setRequired("images", true);
00165 addFileDefinition("screenshot", "screenshot.png", i18n("Screenshot"));
00166 setAllowExternalPaths(true);
00167
00168 if (m_paper) {
00169 connect(paper, SIGNAL(renderHintsChanged()), this, SLOT(renderHintsChanged()));
00170 connect(m_paper, SIGNAL(destroyed(QObject*)), this, SLOT(paperDestroyed()));
00171 }
00172 }
00173
00174 void WallpaperPackage::renderHintsChanged()
00175 {
00176 if (m_fullPackage) {
00177 findBestPaper();
00178 }
00179 }
00180
00181 void WallpaperPackage::pathChanged()
00182 {
00183 static bool guard = false;
00184
00185 if (guard) {
00186 return;
00187 }
00188
00189 guard = true;
00190
00191 QFileInfo info(path());
00192
00193 m_fullPackage = info.isDir();
00194 if (m_fullPackage) {
00195 setContentsPrefix("contents/");
00196 findBestPaper();
00197 } else {
00198
00199 addFileDefinition("preferred", info.fileName(), i18n("Recommended wallpaper file"));
00200 setContentsPrefix(QString());
00201
00202 setPath(info.path());
00203 }
00204
00205 guard = false;
00206 }
00207
00208 QSize WallpaperPackage::resSize(const QString &str) const
00209 {
00210 int index = str.indexOf('x');
00211 if (index != -1) {
00212 return QSize(str.left(index).toInt(),
00213 str.mid(index + 1).toInt());
00214 } else {
00215 return QSize();
00216 }
00217 }
00218
00219 void WallpaperPackage::findBestPaper()
00220 {
00221 QStringList images = entryList("images");
00222 if (images.empty()) {
00223 return;
00224 }
00225
00226
00227
00228
00229 float best = FLT_MAX;
00230 const QSize size = m_paper ? m_paper->d->targetSize.toSize() : QSize(100000, 100000);
00231 const Wallpaper::ResizeMethod method = m_paper ? m_paper->d->lastResizeMethod
00232 : Wallpaper::ScaledResize;
00233
00234 QString bestImage;
00235 foreach (const QString &entry, images) {
00236 QSize candidate = resSize(QFileInfo(entry).baseName());
00237 if (candidate == QSize()) {
00238 continue;
00239 }
00240
00241 double dist = distance(candidate, size, method);
00242
00243 if (bestImage.isEmpty() || dist < best) {
00244 bestImage = entry;
00245 best = dist;
00246
00247 if (dist == 0) {
00248 break;
00249 }
00250 }
00251 }
00252
00253
00254 addFileDefinition("preferred", path("images") + bestImage, i18n("Recommended wallpaper file"));
00255 }
00256
00257 float WallpaperPackage::distance(const QSize& size, const QSize& desired,
00258 Plasma::Wallpaper::ResizeMethod method) const
00259 {
00260
00261 float delta = size.width() * size.height() -
00262 desired.width() * desired.height();
00263
00264 delta /= ((desired.width() * desired.height())+(size.width() * size.height()))/2;
00265
00266
00267 switch (method) {
00268 case Plasma::Wallpaper::ScaledResize: {
00269
00270
00271 float deltaRatio = 1.0;
00272 if (size.height() > 0 && desired.height() > 0) {
00273 deltaRatio = float(size.width()) / float(size.height()) -
00274 float(desired.width()) / float(desired.height());
00275 }
00276 return fabs(deltaRatio) * 3.0 + (delta >= 0.0 ? delta : -delta + 5.0);
00277 }
00278 case Plasma::Wallpaper::ScaledAndCroppedResize:
00279
00280 return delta >= 0.0 ? delta : -delta + 2.0;
00281 default:
00282
00283 return fabs(delta);
00284 }
00285 }
00286
00287 void WallpaperPackage::paperDestroyed()
00288 {
00289 m_paper = 0;
00290 }
00291
00292 }
00293
00294 #include "packages_p.moc"
00295