Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Evergreen:11.1:Test
kdebase4-wallpapers
plasma.diff
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File plasma.diff of Package kdebase4-wallpapers
Patch-rediff: rediff-plasma.sh --- dataengines/weather/plasma-dataengine-weather.desktop +++ dataengines/weather/plasma-dataengine-weather.desktop @@ -29,7 +29,7 @@ Name[ml]=കാലാവസ്ഥയെക്കുറിച്ചുള്ള ഡാറ്റ നല്കുന്ന എഞ്ചിന് Name[mr]=हवामान माहिती इंजिन Name[nb]=Værdata-motor -Name[nds]=Weder-Hanteerkarn +Name[nds]=Weder-Datenkarn Name[ne]=मौसम डेटा इन्जिन Name[nl]=Weer (gegevensengine) Name[nn]=Vêrdatamotor @@ -41,8 +41,8 @@ Name[ru]=Поисковая машина погоды Name[se]=Dálkedáhtamohtor Name[sl]=Pogon s podatki o vremenu -Name[sr]=мотор метеоролошких услова -Name[sr@latin]=motor meteoroloških uslova +Name[sr]=датомотор метеоролошких услова +Name[sr@latin]=datomotor meteoroloških uslova Name[sv]=Datagränssnitt för väder Name[th]=กลไกข้อมูลพยากรณ์อากาศ Name[tr]=Hava Durumu Veri Motoru --- dataengines/hotplug/plasma-dataengine-hotplug.desktop +++ dataengines/hotplug/plasma-dataengine-hotplug.desktop @@ -25,7 +25,7 @@ Name[ml]=ഹോട്ട്പ്ലഗ് ഈവന്റ് ഡേറ്റാ എഞ്ചിന് Name[mr]=हॉटप्लग घटना माहिती इंजिन Name[nb]=Motor for hendelsesdata -Name[nds]=Tokoppel-Hanteerkarn +Name[nds]=Tokoppel-Datenkarn Name[ne]=हटप्लग घटना डेटा इन्जिन Name[nl]=Hotplug-gebeurtenis (gegevensengine) Name[nn]=Datamotor for Hotplug-hendingar @@ -37,8 +37,8 @@ Name[ru]=Поставщик данных «Подключаемые устройства» Name[se]=Hotplug-dáhpáhusaid dáhtamohtor Name[sl]=Pogon s podatki o priklapljanju -Name[sr]=мотор врућег укључивања -Name[sr@latin]=motor vrućeg uključivanja +Name[sr]=датомотор врућег укључивања +Name[sr@latin]=datomotor vrućeg uključivanja Name[sv]=Datagränssnitt för inkopplingshändelse Name[th]=กลไกข้อมูลเหตุการณ์อุปกรณ์แบบ Hot Plug Name[tr]=Hotplug Olay Verisi Motoru --- dataengines/dict/plasma-dataengine-dict.desktop +++ dataengines/dict/plasma-dataengine-dict.desktop @@ -30,7 +30,7 @@ Name[ml]=നിഘണ്ടു ഡേറ്റാ എഞ്ചിന് Name[mr]=शब्दकोष माहिती इंजिन Name[nb]=Ordboksdata-motor -Name[nds]=Wöörbook-Hanteerkarn +Name[nds]=Wöörbook-Datenkarn Name[ne]=शब्दकोश डेटा इन्जिन Name[nl]=Woordenboek (gegevensengine) Name[nn]=Ordboksdatamotor @@ -42,8 +42,8 @@ Name[ru]=Поставщик данных «Словарь» Name[se]=Sátnegirjedáhtamohtor Name[sl]=Podatkovni pogon za slovarje -Name[sr]=мотор речника -Name[sr@latin]=motor rečnika +Name[sr]=датомотор речника +Name[sr@latin]=datomotor rečnika Name[sv]=Datagränssnitt för ordlista Name[tg]=Барномаҳои луғат Name[th]=กลไกข้อมูลพจนานุกรม --- dataengines/filebrowser/plasma-dataengine-filebrowser.desktop +++ dataengines/filebrowser/plasma-dataengine-filebrowser.desktop @@ -29,7 +29,7 @@ Name[nds]=Kiekerkarn för Dateien un Ornern Name[ne]=फाइल र डाइरेकटरी ब्राउजर इन्जिन Name[nl]=Engine voor het bladeren door mappen en bestanden -Name[nn]=Motor for fil- og mappelesing +Name[nn]=Datamotor for fil- og mappelesar Name[pa]=ਫਾਇਲ ਅਤੇ ਡਾਇਰੈਕਟਰੀ ਬਰਾਊਜ਼ਰ ਇੰਜਣ Name[pl]=Przeglądarka plików i katalogów Name[pt]=Motor de Navegação em Ficheiros e Pastas @@ -79,7 +79,7 @@ Comment[nds]=Infos över Dateien un Ornern för Lüttprogrammen Comment[ne]=प्लाज्मोइडका लागि फाइलहरू र डाइरेक्टरीहरूको बारेमा जानकारी Comment[nl]=Informatie over bestanden en mappen voor Plasmoids -Comment[nn]=Informasjon om filer og mapper for Plasmoidar +Comment[nn]=Informasjon om filer og mapper for plasmoidar Comment[pa]=ਪਲਾਜਮੋਡੀਸ ਲਈ ਫਾਇਲਾਂ ਅਤੇ ਡਾਇਰੈਕਟਰੀਆਂ ਵਾਸਤੇ ਜਾਣਕਾਰੀ Comment[pl]=Informacje o plikach i katalogach dla plazmoidów Comment[pt]=Informação sobre os ficheiros e pastas nos Plasmóides --- dataengines/tasks/plasma-dataengine-tasks.desktop +++ dataengines/tasks/plasma-dataengine-tasks.desktop @@ -26,7 +26,7 @@ Name[ml]=ടാസ്ക് മാനേജ്മെന്റ് ഡേറ്റാ എഞ്ചിന് Name[mr]=कार्य व्यवस्थापन माहिती इंजिन Name[nb]=Motor for oppgavedata -Name[nds]=Opgavenpleeg-Hanteerkarn +Name[nds]=Opgavenpleeg-Datenkarn Name[ne]=कार्य व्यवस्थापन डेटा इन्जिन Name[nl]=Taakbeheer (gegevensengine) Name[nn]=Datamotor for oppgåvestyring @@ -38,8 +38,8 @@ Name[ru]=Поставщик данных управления заданиями Name[se]=Bargogieđahallama dáhtamohtor Name[sl]=Pogon s podatki o upravljanju z opravili -Name[sr]=мотор управљања задацима -Name[sr@latin]=motor upravljanja zadacima +Name[sr]=датомотор управљања задацима +Name[sr@latin]=datomotor upravljanja zadacima Name[sv]=Datagränssnitt för aktivitetshantering Name[th]=กลไกข้อมูลจัดการงาน Name[tr]=Görev Yönetimi Veri Motoru --- dataengines/nowplaying/plasma-dataengine-nowplaying.desktop +++ dataengines/nowplaying/plasma-dataengine-nowplaying.desktop @@ -61,7 +61,7 @@ Comment[hu]=Kiírja az éppen lejátszott zene jellemzőit Comment[is]=Telur upp hvaða tónlist er verið að spila Comment[it]=Mostra la musica attualmente in riproduzione -Comment[ja]=今聴いている音楽を表示します +Comment[ja]=今聴いているものを表示します Comment[kk]=Қазір орындалып жатқан әуендер тізімі Comment[km]=រាយតន្ដ្រីដែលកពុងចាក់ Comment[ko]=현재 재생 중인 음악 표시하기 --- dataengines/places/plasma-dataengine-places.desktop +++ dataengines/places/plasma-dataengine-places.desktop @@ -27,7 +27,7 @@ Name[ml]=സ്ഥാനങ്ങളെക്കുറിച്ചുള്ള ഡാറ്റ നല്കുന്ന എഞ്ചിന് Name[mr]=माहिती इंजिन स्थित करतो Name[nb]=Steder-datamotor -Name[nds]=Steden-Hanteerkarn +Name[nds]=Steden-Datenkarn Name[ne]=स्थान डेटा इन्जिन Name[nl]=Locaties (gegevensengine) Name[nn]=Datamotor for stader @@ -39,8 +39,8 @@ Name[ru]=Поставщик данных «Точки входа» Name[se]=Báikedáhtamohtor Name[sl]=Pogon s podatki o mestih -Name[sr]=мотор местâ -Name[sr@latin]=motor mestâ +Name[sr]=датомотор местâ +Name[sr@latin]=datomotor mestâ Name[sv]=Datagränssnitt för platser Name[th]=กลไกข้อมูลที่หลัก ๆ Name[tr]=Konumlar Veri Motoru --- dataengines/mouse/plasma-dataengine-mouse.desktop +++ dataengines/mouse/plasma-dataengine-mouse.desktop @@ -28,7 +28,7 @@ Name[ml]=മൌസ് ഡേറ്റാ എഞ്ചിന് Name[mr]=माउस माहिती इंजिन Name[nb]=Musedata-motor -Name[nds]=Muus-Hanteerkarn +Name[nds]=Muus-Datenkarn Name[ne]=माउस डेटा इन्जिन Name[nl]=Muis (gegevensengine) Name[nn]=Datamotor for mus @@ -40,8 +40,8 @@ Name[ru]=Поставщик данных мыши Name[se]=Sáhpándáhtamohtor Name[sl]=Pogon s podatki o miški -Name[sr]=мотор стања миша -Name[sr@latin]=motor stanja miša +Name[sr]=датомотор стања миша +Name[sr@latin]=datomotor stanja miša Name[sv]=Datagränssnitt för mus Name[th]=กลไกข้อมูลเมาส์ Name[tr]=Fare Veri Motoru @@ -91,7 +91,7 @@ Comment[ro]=Date despre maus pentru plasmoizi Comment[ru]=Данные об указателе мыши для плазмоидов Comment[se]=Sáhpándáhtat plasmoidaide -Comment[sl]=Podatki o miški za Plazmoide +Comment[sl]=Podatki o miški za gradnike Comment[sr]=Подаци о мишу за плазмоиде Comment[sr@latin]=Podaci o mišu za plazmoide Comment[sv]=Musdata för Plasmoider --- dataengines/powermanagement/powermanagementengine.cpp +++ dataengines/powermanagement/powermanagementengine.cpp @@ -1,7 +1,8 @@ /* - * Copyright (C) 2007 Aaron Seigo <aseigo@kde.org> - * Copyright (C) 2007 Sebastian Kuegler <sebas@kde.org> - * CopyRight (C) 2007 Maor Vanmak <mvanmak1@gmail.com> + * Copyright 2007 Aaron Seigo <aseigo@kde.org> + * Copyright 2007-2008 Sebastian Kuegler <sebas@kde.org> + * CopyRight 2007 Maor Vanmak <mvanmak1@gmail.com> + * Copyright 2008 Dario Freddi <drf54321@gmail.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License version 2 as @@ -31,15 +32,18 @@ #include <KLocale> #include "plasma/datacontainer.h" +#include <QtDBus/QDBusInterface> +#include <QtDBus/QDBusReply> PowermanagementEngine::PowermanagementEngine(QObject* parent, const QVariantList& args) : Plasma::DataEngine(parent, args) , m_acadapter(0) , m_sources(0) + , m_dbus(QDBusConnection::sessionBus()) { Q_UNUSED(args) - m_sources << I18N_NOOP("Battery") << I18N_NOOP("AC Adapter") << I18N_NOOP("Sleepstates"); + m_sources << "Battery" << "AC Adapter" << "Sleepstates" << "PowerDevil"; // This following call can be removed, but if we do, the // data is not shown in the plasmaengineexplorer. @@ -55,20 +59,44 @@ this, SLOT(deviceRemoved(QString))); connect(Solid::DeviceNotifier::instance(), SIGNAL(deviceAdded(QString)), this, SLOT(deviceAdded(QString))); + + QStringList modules; + QDBusInterface kdedInterface("org.kde.kded", "/kded", "org.kde.kded"); + QDBusReply<QStringList> reply = kdedInterface.call("loadedModules"); + + if (!reply.isValid()) { + return; + } + + modules = reply.value(); + + if (modules.contains("powerdevil")) { + + if (!m_dbus.connect("org.kde.kded", "/modules/powerdevil", "org.kde.PowerDevil", + "profileChanged", this, + SLOT(profilesChanged(const QString&, const QStringList&)))) { + kDebug() << "error!"; + } + + QDBusMessage msg = QDBusMessage::createMethodCall("org.kde.kded", "/modules/powerdevil", + "org.kde.PowerDevil", "streamData"); + m_dbus.call(msg); + + } } -QStringList PowermanagementEngine::sources() const +QStringList PowermanagementEngine::sources() const { return m_sources + m_batterySources.values(); } bool PowermanagementEngine::sourceRequestEvent(const QString &name) { - if (name == I18N_NOOP("Battery")) { + if (name == "Battery") { QList<Solid::Device> list_battery = Solid::Device::listFromType(Solid::DeviceInterface::Battery, QString()); if (list_battery.count() == 0) { - setData(I18N_NOOP("Battery"), I18N_NOOP("has Battery"), false); + setData("Battery", "has Battery", false); return true; } @@ -79,31 +107,33 @@ const Solid::Battery* battery = device_battery.as<Solid::Battery>(); if(battery != 0) { - QString source = QString(I18N_NOOP("Battery%1")).arg(index++); + if(battery->type() == Solid::Battery::PrimaryBattery) { + QString source = QString("Battery%1").arg(index++); - battery_sources<<source; + battery_sources<<source; - m_batterySources[device_battery.udi()] = source; + m_batterySources[device_battery.udi()] = source; - connect(battery, SIGNAL(chargeStateChanged(int, const QString &)), this, - SLOT(updateBatteryChargeState(int, const QString &))); - connect(battery, SIGNAL(chargePercentChanged(int, const QString &)), this, - SLOT(updateBatteryChargePercent(int, const QString &))); - connect(battery, SIGNAL(plugStateChanged(bool, const QString &)), this, - SLOT(updateBatteryPlugState(bool, const QString &))); + connect(battery, SIGNAL(chargeStateChanged(int, const QString &)), this, + SLOT(updateBatteryChargeState(int, const QString &))); + connect(battery, SIGNAL(chargePercentChanged(int, const QString &)), this, + SLOT(updateBatteryChargePercent(int, const QString &))); + connect(battery, SIGNAL(plugStateChanged(bool, const QString &)), this, + SLOT(updateBatteryPlugState(bool, const QString &))); - // Set initial values - updateBatteryChargeState(battery->chargeState(), device_battery.udi()); - updateBatteryChargePercent(battery->chargePercent(), device_battery.udi()); - updateBatteryPlugState(battery->isPlugged(), device_battery.udi()); + // Set initial values + updateBatteryChargeState(battery->chargeState(), device_battery.udi()); + updateBatteryChargePercent(battery->chargePercent(), device_battery.udi()); + updateBatteryPlugState(battery->isPlugged(), device_battery.udi()); + } } } if (battery_sources.count() > 0) { - setData(I18N_NOOP("Battery"), I18N_NOOP("has Battery"), true); - setData(I18N_NOOP("Battery"), I18N_NOOP("sources"), battery_sources); + setData("Battery", "has Battery", true); + setData("Battery", "sources", battery_sources); } - } else if (name == I18N_NOOP("AC Adapter")) { + } else if (name == "AC Adapter") { // AC Adapter handling QList<Solid::Device> list_ac = Solid::Device::listFromType(Solid::DeviceInterface::AcAdapter, QString()); @@ -113,24 +143,28 @@ connect(m_acadapter, SIGNAL(plugStateChanged(bool, const QString &)), this, SLOT(updateAcPlugState(bool))); } - } else if (name == I18N_NOOP("Sleepstates")) { + } else if (name == "Sleepstates") { QSet<Solid::PowerManagement::SleepState> sleepstates = Solid::PowerManagement::supportedSleepStates(); // We first set all possible sleepstates to false, then enable the ones that are available - setData(I18N_NOOP("Sleepstates"), I18N_NOOP("Standby"), false); - setData(I18N_NOOP("Sleepstates"), I18N_NOOP("Suspend"), false); - setData(I18N_NOOP("Sleepstates"), I18N_NOOP("Hibernate"), false); + setData("Sleepstates", "Standby", false); + setData("Sleepstates", "Suspend", false); + setData("Sleepstates", "Hibernate", false); - foreach (Solid::PowerManagement::SleepState sleepstate, sleepstates) { + foreach (const Solid::PowerManagement::SleepState &sleepstate, sleepstates) { if (sleepstate == Solid::PowerManagement::StandbyState) { - setData(I18N_NOOP("Sleepstates"), I18N_NOOP("Supports standby"), true); + setData("Sleepstates", "Supports standby", true); } else if (sleepstate == Solid::PowerManagement::SuspendState) { - setData(I18N_NOOP("Sleepstates"), I18N_NOOP("Supports suspend"), true); + setData("Sleepstates", "Supports suspend", true); } else if (sleepstate == Solid::PowerManagement::HibernateState) { - setData(I18N_NOOP("Sleepstates"), I18N_NOOP("Supports hibernate"), true); + setData("Sleepstates", "Supports hibernate", true); } kDebug() << "Sleepstate \"" << sleepstate << "\" supported."; } + } else if (name == "PowerDevil") { + QDBusMessage msg = QDBusMessage::createMethodCall("org.kde.kded", "/modules/powerdevil", + "org.kde.PowerDevil", "streamData"); + m_dbus.call(msg); } else { kDebug() << "Data for '" << name << "' not found"; } @@ -141,36 +175,36 @@ { QString state; if (newState == Solid::Battery::NoCharge) { - state = I18N_NOOP("NoCharge"); + state = "NoCharge"; } else if (newState == Solid::Battery::Charging) { - state = I18N_NOOP("Charging"); + state = "Charging"; } else if (newState == Solid::Battery::Discharging) { - state = I18N_NOOP("Discharging"); + state = "Discharging"; } else { - state = I18N_NOOP("Could not determine battery status. Something is fishy here. :o"); + state = "Could not determine battery status. Something is fishy here. :o"; } const QString& source = m_batterySources[udi]; - setData(source, I18N_NOOP("State"), state); + setData(source, "State", state); scheduleSourcesUpdated(); } void PowermanagementEngine::updateBatteryPlugState(bool newState, const QString& udi) { const QString& source = m_batterySources[udi]; - setData(source, I18N_NOOP("Plugged in"), newState); + setData(source, "Plugged in", newState); scheduleSourcesUpdated(); } void PowermanagementEngine::updateBatteryChargePercent(int newValue, const QString& udi) { const QString& source = m_batterySources[udi]; - setData(source, I18N_NOOP("Percent"), newValue); + setData(source, "Percent", newValue); scheduleSourcesUpdated(); } void PowermanagementEngine::updateAcPlugState(bool newState) { - setData(I18N_NOOP("AC Adapter"), I18N_NOOP("Plugged in"), newState); + setData("AC Adapter", "Plugged in", newState); scheduleSourcesUpdated(); } @@ -221,4 +255,11 @@ } } +void PowermanagementEngine::profilesChanged( const QString ¤t, const QStringList &profiles ) +{ + setData("PowerDevil", "currentProfile", current); + setData("PowerDevil", "availableProfiles", profiles); + scheduleSourcesUpdated(); +} + #include "powermanagementengine.moc" --- dataengines/powermanagement/powermanagementengine.h +++ dataengines/powermanagement/powermanagementengine.h @@ -1,6 +1,7 @@ /* - * Copyright (C) 2007 Aaron Seigo <aseigo@kde.org> - * Copyright (C) 2007 Sebastian Kuegler <sebas@kde.org> + * Copyright 2007 Aaron Seigo <aseigo@kde.org> + * Copyright 2007-2008 Sebastian Kuegler <sebas@kde.org> + * Copyright 2008 Dario Freddi <drf54321@gmail.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License version 2 as @@ -25,11 +26,12 @@ #include <solid/battery.h> #include <solid/acadapter.h> +#include <QtDBus/QDBusConnection> #include <QHash> /** * This class provides runtime information about the battery and AC status - * for use in a simple battery monitor Plasma applets. + * for use in power management Plasma applets. */ class PowermanagementEngine : public Plasma::DataEngine { @@ -51,13 +53,15 @@ void updateAcPlugState(bool newState); void deviceRemoved(const QString& udi); void deviceAdded(const QString& udi); + void profilesChanged(const QString ¤t, const QStringList &profiles); private: Solid::AcAdapter* m_acadapter; QStringList m_sources; - + QDBusConnection m_dbus; + QHash<QString, QString> m_batterySources; - + }; K_EXPORT_PLASMA_DATAENGINE(powermanagement, PowermanagementEngine) --- dataengines/powermanagement/plasma-dataengine-powermanagement.desktop +++ dataengines/powermanagement/plasma-dataengine-powermanagement.desktop @@ -28,7 +28,7 @@ Name[ml]=വൈദ്യുതി നടത്തിപ്പിനുള്ള ഡാറ്റ നല്കുന്ന എഞ്ചിന് Name[mr]=पॉवर व्यवस्थापन माहिती इंजिन Name[nb]=Motor for strømstyringsdata -Name[nds]=Stroomkuntrull-Hanteerkarn +Name[nds]=Stroomkuntrull-Datenkarn Name[ne]=पावर व्यवस्थापन डेटा इन्जिन Name[nl]=Energiebeheer (gegevensengine) Name[nn]=Datamotor for straumstyring @@ -40,8 +40,8 @@ Name[ru]=Поставщик данных управления питанием Name[se]=El-rávdnjegieđahallama dáhtamohtor Name[sl]=Pogon s podatki o upravljanju z energijo -Name[sr]=мотор управљања енергијом -Name[sr@latin]=motor upravljanja energijom +Name[sr]=датомотор управљања енергијом +Name[sr@latin]=datomotor upravljanja energijom Name[sv]=Datagränssnitt för strömsparfunktion Name[th]=กลไกข้อมูลระบบจัดการพลังงาน Name[tr]=Güç Yönetimi Veri Motoru --- dataengines/soliddevice/plasma-dataengine-soliddevice.desktop +++ dataengines/soliddevice/plasma-dataengine-soliddevice.desktop @@ -26,7 +26,7 @@ Name[lv]=Solid ierīču datu dzinējs Name[ml]=സോളിഡ് നല്കുന്ന ഉപകരണങ്ങളെക്കുറിച്ചുള്ള ഡാറ്റ നല്കുന്ന എഞ്ചിന് Name[nb]=Datamotor for SolidDevice -Name[nds]=SolidDevice-Hanteerkarn +Name[nds]=SolidDevice-Datenkarn Name[ne]=ठोस यन्त्र डेटा इन्जिन Name[nl]=SolidDevice (gegevensengine) Name[nn]=Datamotor for SolidDevice @@ -38,8 +38,8 @@ Name[ru]=Поставщик данных данных SolidDevice Name[se]=SolidDevice-dáhtamohtor Name[sl]=Pogon s podatki od SolidDevice -Name[sr]=мотор Солида -Name[sr@latin]=motor Solida +Name[sr]=датомотор Солида +Name[sr@latin]=datomotor Solida Name[sv]=Datagränssnitt för Solid-enhet Name[th]=กลไกข้อมูลอุปกรณ์ Solid Name[tr]=Solid Aygıt Veri Motoru --- dataengines/time/plasma-dataengine-time.desktop +++ dataengines/time/plasma-dataengine-time.desktop @@ -32,7 +32,7 @@ Name[ml]=സമയത്തിന്റെ ഡാറ്റ നല്കുന്ന എഞ്ചിന് Name[mr]=वेळ माहिती इंजन Name[nb]=Tidsdata-motor -Name[nds]=Tiet-Hanteerkarn +Name[nds]=Tiet-Datenkarn Name[ne]=समय डेटा इन्जिन Name[nl]=Tijd (gegevensengine) Name[nn]=Tidsdatamotor @@ -44,8 +44,8 @@ Name[ru]=Поставщик данных времени Name[se]=Áigedáhtamohtor Name[sl]=Pogon s podatki o času -Name[sr]=мотор датума и времена -Name[sr@latin]=motor datuma i vremena +Name[sr]=датомотор датума и времена +Name[sr@latin]=datomotor datuma i vremena Name[sv]=Datagränssnitt för tid Name[th]=กลไกข้อมูลเวลา Name[tr]=Saat Veri Motoru --- desktoptheme/widgets/scrollbar.svg +++ desktoptheme/widgets/scrollbar.svg @@ -0,0 +1,1185 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="48" + height="98" + id="svg3642" + sodipodi:version="0.32" + inkscape:version="0.46" + sodipodi:docbase="/home/diau/failed Graphics attempts/plasma background/41/widgets" + sodipodi:docname="scrollbar.svgz" + inkscape:output_extension="org.inkscape.output.svgz.inkscape" + version="1.0"> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="5.6568543" + inkscape:cx="-1.7081019" + inkscape:cy="40.242351" + inkscape:current-layer="layer1" + showgrid="true" + inkscape:grid-bbox="true" + inkscape:document-units="px" + inkscape:window-width="1680" + inkscape:window-height="987" + inkscape:window-x="0" + inkscape:window-y="0" + width="48px" + height="48px" + showguides="true" + inkscape:guide-bbox="true" + objecttolerance="9" + gridtolerance="13"> + <inkscape:grid + visible="true" + enabled="true" + id="grid2555" + type="xygrid" /> + </sodipodi:namedview> + <defs + id="defs3644"> + <inkscape:perspective + id="perspective3927" + inkscape:persp3d-origin="300 : 400 : 1" + inkscape:vp_z="700 : 600 : 1" + inkscape:vp_y="0 : 1000 : 0" + inkscape:vp_x="-50 : 600 : 1" + sodipodi:type="inkscape:persp3d" /> + <inkscape:perspective + id="perspective173" + inkscape:persp3d-origin="300 : 400 : 1" + inkscape:vp_z="700 : 600 : 1" + inkscape:vp_y="0 : 1000 : 0" + inkscape:vp_x="-50 : 600 : 1" + sodipodi:type="inkscape:persp3d" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient38324" + id="radialGradient6667" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(4.6875e-2,0,0,0.1886979,139.0625,1096.4758)" + cx="1940" + cy="667.86218" + fx="1940" + fy="667.86218" + r="640" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient7141" + id="linearGradient6665" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(4.6875e-2,0,0,0.9714286,200,478.85713)" + x1="460.29968" + y1="800" + x2="460.29968" + y2="764.96027" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient38324" + id="radialGradient6523" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(4.6875e-2,0,0,0.1886979,139.0625,1096.4758)" + cx="1940" + cy="667.86218" + fx="1510.0791" + fy="668.79901" + r="640" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient7141" + id="linearGradient6521" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(4.6875e-2,0,0,0.9714286,200,478.85713)" + x1="460.29968" + y1="800" + x2="460.29968" + y2="764.96027" /> + <linearGradient + id="linearGradient38324" + inkscape:collect="always"> + <stop + offset="0" + style="stop-color:#ffffff;stop-opacity:1;" + id="stop38326" /> + <stop + offset="1" + style="stop-color:#ffffff;stop-opacity:0;" + id="stop38328" /> + </linearGradient> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient38324" + id="radialGradient6410" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(4.6875e-2,0,0,0.1886979,139.0625,1096.4758)" + cx="1940" + cy="667.86218" + fx="1940" + fy="667.86218" + r="640" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient7141" + id="linearGradient6416" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(4.6875e-2,0,0,0.9714286,200,478.85713)" + x1="460.29968" + y1="800" + x2="460.29968" + y2="764.96027" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient3215" + id="radialGradient7781" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(-0.1740976,0,0,-0.3189789,588.2195,1700.637)" + cx="2132.25" + cy="136.14069" + fx="2132.25" + fy="136.14069" + r="91.609398" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient3215" + id="radialGradient7779" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(0.1740976,0,0,-0.3189789,28.999302,1700.6721)" + cx="2132.25" + cy="136.14069" + fx="2132.25" + fy="136.14069" + r="91.609398" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient3215" + id="radialGradient7777" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(1,0,0,-0.3189789,-1732.0312,1700.6602)" + cx="2040.6406" + cy="136.14062" + fx="2040.6406" + fy="136.14062" + r="91.609398" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient7141" + id="linearGradient7775" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(0.9966917,0,0,1,245.38566,1570.7243)" + x1="50.10762" + y1="89.277901" + x2="50.10762" + y2="9.2778997" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient3215" + id="radialGradient7793" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(1,0,0,3.1799296e-2,1e-7,1538.8854)" + cx="214.86403" + cy="1562.4542" + fx="214.36403" + fy="1529.1011" + r="91.609375" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient3215" + id="radialGradient7791" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(-0.1681654,3.4136193e-3,4.2099459e-2,1.1902826e-2,569.84457,1578.8558)" + cx="2132.25" + cy="136.14069" + fx="2132.25" + fy="136.14069" + r="91.609398" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient7141" + id="linearGradient7789" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(1,0,0,7.5757576e-2,244.89238,1586.6911)" + x1="50.10762" + y1="89.277901" + x2="50.10762" + y2="9.2778997" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient3215" + id="radialGradient7773" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(-0.1740976,0,0,-0.3189789,588.2195,1639.637)" + cx="2132.25" + cy="136.14069" + fx="2132.25" + fy="136.14069" + r="91.609398" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient3215" + id="radialGradient7771" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(1,0,0,0.4197507,1e-7,878.68648)" + cx="215" + cy="1608.8442" + fx="214.5" + fy="1575.4911" + r="91.609375" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient3215" + id="radialGradient7769" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(0.1740976,0,0,-0.3189789,28.999303,1639.6721)" + cx="2132.25" + cy="136.14069" + fx="2132.25" + fy="136.14069" + r="91.609398" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient3215" + id="radialGradient7767" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(1,0,0,-0.3189789,-1732.0313,1639.6602)" + cx="2040.6406" + cy="136.14062" + fx="2040.6406" + fy="136.14062" + r="91.609398" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient3215" + id="radialGradient7765" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(-0.1681654,4.5059775e-2,4.2099459e-2,0.1571173,569.84457,1406.2968)" + cx="2132.25" + cy="136.14069" + fx="2132.25" + fy="136.14069" + r="91.609398" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient7141" + id="linearGradient7763" + gradientUnits="userSpaceOnUse" + gradientTransform="translate(244.89238,1509.7221)" + x1="50.10762" + y1="89.277901" + x2="50.10762" + y2="9.2778997" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient3215" + id="radialGradient7787" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(-1,0,0,3.1799296e-2,453,1538.8854)" + cx="214.61086" + cy="1563.174" + fx="214.11086" + fy="1529.8208" + r="91.609375" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient3215" + id="radialGradient7785" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(0.1681654,3.4136193e-3,-4.2099459e-2,1.1902826e-2,-116.84457,1578.8558)" + cx="2132.25" + cy="136.14069" + fx="2132.25" + fy="136.14069" + r="91.609398" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient7141" + id="linearGradient7783" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(-1,0,0,7.5757576e-2,208.10762,1586.6911)" + x1="50.10762" + y1="89.277901" + x2="50.10762" + y2="9.2778997" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient3215" + id="radialGradient7761" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(0.1740976,0,0,-0.3189789,-135.2195,1639.637)" + cx="2132.25" + cy="136.14069" + fx="2132.25" + fy="136.14069" + r="91.609398" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient3215" + id="radialGradient7759" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(-1,0,0,0.4197507,453,878.68648)" + cx="215" + cy="1608.8442" + fx="214.5" + fy="1575.4911" + r="91.609375" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient3215" + id="radialGradient7757" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(-0.1740976,0,0,-0.3189789,424.0007,1639.6721)" + cx="2132.25" + cy="136.14069" + fx="2132.25" + fy="136.14069" + r="91.609398" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient3215" + id="radialGradient7755" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(-1,0,0,-0.3189789,2185.0313,1639.6602)" + cx="2040.6406" + cy="136.14062" + fx="2040.6406" + fy="136.14062" + r="91.609398" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient3215" + id="radialGradient7753" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(0.1681654,4.5059775e-2,-4.2099459e-2,0.1571173,-116.84457,1406.2968)" + cx="2132.25" + cy="136.14069" + fx="2132.25" + fy="136.14069" + r="91.609398" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient7141" + id="linearGradient7751" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(-1,0,0,1,208.10762,1509.7221)" + x1="50.10762" + y1="89.277901" + x2="50.10762" + y2="9.2778997" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient7141" + id="linearGradient7649" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(-0.7142857,0,0,7.5757576e-2,-1.92313,11.688002)" + x1="50.10762" + y1="89.277901" + x2="50.10762" + y2="9.2778997" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient3215" + id="radialGradient7901" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(4.9624586e-3,4.5059775e-2,-1.2423295e-3,0.1571173,213.79434,1467.2968)" + cx="2132.25" + cy="136.14069" + fx="2132.25" + fy="136.14069" + r="91.609398" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient3215" + id="radialGradient7899" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(-2.9509392e-2,0,0,-0.4197507,230.6101,2223.3112)" + cx="215" + cy="1608.8442" + fx="214.5" + fy="1575.4911" + r="91.609375" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient3215" + id="radialGradient7897" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(2.9509392e-2,0,0,0.4197507,212.3733,939.68651)" + cx="215" + cy="1608.8442" + fx="214.5" + fy="1575.4911" + r="91.609375" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient3215" + id="radialGradient7895" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(-4.9624586e-3,4.5059775e-2,1.2423295e-3,0.1571173,229.18906,1467.2968)" + cx="2132.25" + cy="136.14069" + fx="2132.25" + fy="136.14069" + r="91.609398" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient3215" + id="radialGradient7893" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(2.9509392e-2,0,0,0.3189789,161.26211,1541.3405)" + cx="2040.6406" + cy="136.14062" + fx="2040.6406" + fy="136.14062" + r="91.609398" /> + <linearGradient + id="linearGradient7141"> + <stop + offset="0" + style="stop-color:#222222;stop-opacity:1;" + id="stop7143" /> + <stop + offset="0.23586744" + style="stop-color:#0c0c0c;stop-opacity:1;" + id="stop7149" /> + <stop + offset="1" + style="stop-color:#000000;stop-opacity:1" + id="stop7145" /> + </linearGradient> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient7141" + id="linearGradient7891" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(2.9509392e-2,0,0,1,224.61652,1570.7221)" + x1="50.10762" + y1="89.277901" + x2="50.10762" + y2="9.2778997" /> + <linearGradient + id="linearGradient3215"> + <stop + offset="0" + style="stop-color:#ffffff;stop-opacity:1;" + id="stop3217" /> + <stop + offset="0.5" + style="stop-color:#ffffff;stop-opacity:0.28158844;" + id="stop3221" /> + <stop + offset="1" + style="stop-color:#ffffff;stop-opacity:0;" + id="stop3219" /> + </linearGradient> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient3215" + id="radialGradient7889" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(-2.9509392e-2,0,0,0.4197507,230.58705,939.68651)" + cx="215" + cy="1608.8442" + fx="214.5" + fy="1575.4911" + r="91.609375" /> + <linearGradient + y2="764.96027" + x2="460.29968" + y1="800" + x1="460.29968" + gradientTransform="matrix(4.6875e-2,0,0,0.9714286,200,478.85713)" + gradientUnits="userSpaceOnUse" + id="linearGradient4303" + xlink:href="#linearGradient7141" + inkscape:collect="always" /> + <radialGradient + r="640" + fy="668.79901" + fx="1510.0791" + cy="667.86218" + cx="1940" + gradientTransform="matrix(4.6875e-2,0,0,0.1886979,139.0625,1096.4758)" + gradientUnits="userSpaceOnUse" + id="radialGradient4305" + xlink:href="#linearGradient38324" + inkscape:collect="always" /> + <linearGradient + y2="764.96027" + x2="460.29968" + y1="800" + x1="460.29968" + gradientTransform="matrix(4.6875e-2,0,0,0.9714286,200,478.85713)" + gradientUnits="userSpaceOnUse" + id="linearGradient4335" + xlink:href="#linearGradient7141" + inkscape:collect="always" /> + <radialGradient + r="640" + fy="668.79901" + fx="1510.0791" + cy="667.86218" + cx="1940" + gradientTransform="matrix(4.6875e-2,0,0,0.1886979,139.0625,1096.4758)" + gradientUnits="userSpaceOnUse" + id="radialGradient4337" + xlink:href="#linearGradient38324" + inkscape:collect="always" /> + <linearGradient + y2="764.96027" + x2="460.29968" + y1="800" + x1="460.29968" + gradientTransform="matrix(4.6875e-2,0,0,0.9714286,200,478.85713)" + gradientUnits="userSpaceOnUse" + id="linearGradient4367" + xlink:href="#linearGradient7141" + inkscape:collect="always" /> + <radialGradient + r="640" + fy="667.86218" + fx="1940" + cy="667.86218" + cx="1940" + gradientTransform="matrix(4.6875e-2,0,0,0.1886979,139.0625,1096.4758)" + gradientUnits="userSpaceOnUse" + id="radialGradient4369" + xlink:href="#linearGradient38324" + inkscape:collect="always" /> + <linearGradient + y2="764.96027" + x2="460.29968" + y1="800" + x1="460.29968" + gradientTransform="matrix(4.6875e-2,0,0,0.9714286,200,478.85713)" + gradientUnits="userSpaceOnUse" + id="linearGradient4385" + xlink:href="#linearGradient7141" + inkscape:collect="always" /> + <radialGradient + r="640" + fy="667.86218" + fx="1940" + cy="667.86218" + cx="1940" + gradientTransform="matrix(4.6875e-2,0,0,0.1886979,139.0625,1096.4758)" + gradientUnits="userSpaceOnUse" + id="radialGradient4387" + xlink:href="#linearGradient38324" + inkscape:collect="always" /> + <linearGradient + y2="764.96027" + x2="460.29968" + y1="800" + x1="460.29968" + gradientTransform="matrix(4.6875e-2,0,0,0.9714286,200,478.85713)" + gradientUnits="userSpaceOnUse" + id="linearGradient4395" + xlink:href="#linearGradient7141" + inkscape:collect="always" /> + <radialGradient + r="640" + fy="667.86218" + fx="1940" + cy="667.86218" + cx="1940" + gradientTransform="matrix(4.6875e-2,0,0,0.1886979,139.0625,1096.4758)" + gradientUnits="userSpaceOnUse" + id="radialGradient4397" + xlink:href="#linearGradient38324" + inkscape:collect="always" /> + <linearGradient + y2="764.96027" + x2="460.29968" + y1="800" + x1="460.29968" + gradientTransform="matrix(4.6875e-2,0,0,0.9714286,200,478.85713)" + gradientUnits="userSpaceOnUse" + id="linearGradient2337" + xlink:href="#linearGradient7141" + inkscape:collect="always" /> + <radialGradient + r="640" + fy="667.86218" + fx="1940" + cy="667.86218" + cx="1940" + gradientTransform="matrix(4.6875e-2,0,0,0.1886979,139.0625,1096.4758)" + gradientUnits="userSpaceOnUse" + id="radialGradient2339" + xlink:href="#linearGradient38324" + inkscape:collect="always" /> + <inkscape:perspective + sodipodi:type="inkscape:persp3d" + inkscape:vp_x="-50 : 600 : 1" + inkscape:vp_y="0 : 1000 : 0" + inkscape:vp_z="700 : 600 : 1" + inkscape:persp3d-origin="300 : 400 : 1" + id="perspective3529" /> + <radialGradient + r="91.609375" + fy="1529.8208" + fx="214.11086" + cy="1563.174" + cx="214.61086" + gradientTransform="matrix(-1,0,0,3.1799296e-2,302,21.8832)" + gradientUnits="userSpaceOnUse" + id="radialGradient3581" + xlink:href="#linearGradient3215" + inkscape:collect="always" /> + <radialGradient + r="91.609375" + fy="1529.1011" + fx="214.36403" + cy="1562.4542" + cx="214.86403" + gradientTransform="matrix(1,0,0,3.1799296e-2,-153,21.8832)" + gradientUnits="userSpaceOnUse" + id="radialGradient3614" + xlink:href="#linearGradient3215" + inkscape:collect="always" /> + <inkscape:perspective + sodipodi:type="inkscape:persp3d" + inkscape:vp_x="-50 : 600 : 1" + inkscape:vp_y="0 : 1000 : 0" + inkscape:vp_z="700 : 600 : 1" + inkscape:persp3d-origin="300 : 400 : 1" + id="perspective3634" /> + <inkscape:perspective + sodipodi:type="inkscape:persp3d" + inkscape:vp_x="-50 : 600 : 1" + inkscape:vp_y="0 : 1000 : 0" + inkscape:vp_z="700 : 600 : 1" + inkscape:persp3d-origin="300 : 400 : 1" + id="perspective3647" /> + <inkscape:perspective + sodipodi:type="inkscape:persp3d" + inkscape:vp_x="-50 : 600 : 1" + inkscape:vp_y="0 : 1000 : 0" + inkscape:vp_z="700 : 600 : 1" + inkscape:persp3d-origin="300 : 400 : 1" + id="perspective3660" /> + <inkscape:perspective + sodipodi:type="inkscape:persp3d" + inkscape:vp_x="-50 : 600 : 1" + inkscape:vp_y="0 : 1000 : 0" + inkscape:vp_z="700 : 600 : 1" + inkscape:persp3d-origin="300 : 400 : 1" + id="perspective3673" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient7141" + id="linearGradient2439" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(0.9966917,0,0,1,245.38566,1570.7243)" + x1="50.10762" + y1="89.277901" + x2="50.10762" + y2="9.2778997" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient3215" + id="radialGradient2441" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(1,0,0,-0.3189789,-1732.0312,1700.6602)" + cx="2040.6406" + cy="136.14062" + fx="2040.6406" + fy="136.14062" + r="91.609398" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient3215" + id="radialGradient2443" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(0.1740976,0,0,-0.3189789,28.999302,1700.6721)" + cx="2132.25" + cy="136.14069" + fx="2132.25" + fy="136.14069" + r="91.609398" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient3215" + id="radialGradient2445" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(-0.1740976,0,0,-0.3189789,588.2195,1700.637)" + cx="2132.25" + cy="136.14069" + fx="2132.25" + fy="136.14069" + r="91.609398" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient3215" + id="radialGradient2453" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(1,0,0,-0.3182575,-1731.4668,1700.5705)" + cx="2040.6406" + cy="136.14062" + fx="2040.6406" + fy="136.14062" + r="91.609398" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient3215" + id="radialGradient2455" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(0.1740976,0,0,-0.3185758,29.563694,1700.622)" + cx="2132.25" + cy="136.14069" + fx="2132.25" + fy="136.14069" + r="91.609398" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient3215" + id="radialGradient2457" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(-0.1740976,0,0,-0.3185899,588.78391,1700.5887)" + cx="2132.25" + cy="136.14069" + fx="2132.25" + fy="136.14069" + r="91.609398" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient7141" + id="linearGradient2459" + gradientUnits="userSpaceOnUse" + gradientTransform="translate(245.45478,1570.7243)" + x1="50.10762" + y1="89.277901" + x2="50.10762" + y2="9.2778997" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient7141" + id="linearGradient2570" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(2.9411745e-2,0,0,0.9996163,18.614494,-5.274403)" + x1="50.10762" + y1="89.277901" + x2="50.10762" + y2="9.2778997" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient3215" + id="radialGradient2590" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(-0.1740976,0,0,-0.3189204,214.0007,65.662628)" + cx="2132.25" + cy="136.14069" + fx="2132.25" + fy="136.14069" + r="91.609398" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient3215" + id="radialGradient2593" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(-1,0,0,-0.3189204,1975.0313,65.65073)" + cx="2040.6406" + cy="136.14062" + fx="2040.6406" + fy="136.14062" + r="91.609398" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient7141" + id="linearGradient2599" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(-1,0,0,0.9998167,-1.89238,-64.261352)" + x1="50.10762" + y1="89.277901" + x2="50.10762" + y2="9.2778997" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient7141" + id="linearGradient2609" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(-1,0,0,7.5757576e-2,-1.89238,11.690183)" + x1="50.10762" + y1="89.277901" + x2="50.10762" + y2="9.2778997" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient3215" + id="radialGradient2626" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(0.1740976,0,0,-0.3189204,-183.0007,65.662628)" + cx="2132.25" + cy="136.14069" + fx="2132.25" + fy="136.14069" + r="91.609398" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient3215" + id="radialGradient2629" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(1,0,0,-0.3189204,-1944.0313,65.65073)" + cx="2040.6406" + cy="136.14062" + fx="2040.6406" + fy="136.14062" + r="91.609398" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient7141" + id="linearGradient2635" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(1,0,0,0.9998167,32.89238,-64.261352)" + x1="50.10762" + y1="89.277901" + x2="50.10762" + y2="9.2778997" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient7141" + id="linearGradient2645" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(1,0,0,7.5724258e-2,32.89238,11.690759)" + x1="50.10762" + y1="89.277901" + x2="50.10762" + y2="9.2778997" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient7141" + id="linearGradient2672" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(2.941176e-2,0,0,1,13.614423,-64.278817)" + x1="50.10762" + y1="89.277901" + x2="50.10762" + y2="9.2778997" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient3215" + id="radialGradient2691" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(1,0,0,0.3189789,-1944.0312,-34.662617)" + cx="2040.6406" + cy="136.14062" + fx="2040.6406" + fy="136.14062" + r="91.609398" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient7141" + id="linearGradient2694" + gradientUnits="userSpaceOnUse" + gradientTransform="translate(32.89238,-5.281017)" + x1="50.10762" + y1="89.277901" + x2="50.10762" + y2="9.2778997" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient3215" + id="radialGradient2697" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(-1,0,0,0.4197507,405.21875,-636.31661)" + cx="215" + cy="1608.8442" + fx="214.5" + fy="1575.4911" + r="91.609375" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient3215" + id="radialGradient2716" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(-1,0,0,0.3189789,1975.0312,-34.662617)" + cx="2040.6406" + cy="136.14062" + fx="2040.6406" + fy="136.14062" + r="91.609398" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient7141" + id="linearGradient2719" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(-1,0,0,1,-1.89238,-5.281017)" + x1="50.10762" + y1="89.277901" + x2="50.10762" + y2="9.2778997" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient3215" + id="radialGradient2722" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(1,0,0,0.4197507,-374.21875,-636.31661)" + cx="215" + cy="1608.8442" + fx="214.5" + fy="1575.4911" + r="91.609375" /> + </defs> + <metadata + id="metadata3647"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + </cc:Work> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + </cc:Work> + </rdf:RDF> + </metadata> + <g + inkscape:groupmode="layer" + inkscape:label="Layer 1" + id="layer1"> + <rect + style="opacity:0.5;fill:#7b7b7b;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.25;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="rect3570" + width="54" + height="100" + x="-1" + y="-2" /> + <path + style="opacity:0.45;fill:url(#linearGradient2672);fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1" + d="M 12.999941,18.999083 L 12.999941,25.999083 L 17.983397,25.999083 C 17.98886,25.999083 17.994596,25.982883 17.999941,25.967883 L 17.999941,18.999083 L 12.999941,18.999083 z" + id="background-bottom" /> + <path + style="opacity:0.45;fill:url(#linearGradient2645);fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1" + d="M 5,12.999083 L 5,17.996884 L 12,17.996884 L 12,12.999083 L 5,12.999083 z" + id="background-left" /> + <path + style="opacity:0.45;fill:url(#linearGradient2635);fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1" + d="M 5,19.001283 L 5,19.438703 C 5,23.068637 7.93185,26 11.5625,26 L 12,26 L 12,19.001283 L 5,19.001283 z" + id="background-bottomleft" /> + <path + style="opacity:0.45;fill:url(#linearGradient2694);fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1" + d="M 11.5625,4.996883 C 7.64428,4.996883 5,7.751983 5,11.559383 L 5,11.996883 L 12,11.996883 L 12,4.996883 L 11.5625,4.996883 z" + id="background-topleft" + sodipodi:nodetypes="cccccc" /> + <path + id="background-right" + d="M 26,12.999083 L 26,17.999083 L 19,17.999083 L 19,12.999083 L 26,12.999083 z" + style="opacity:0.45;fill:url(#linearGradient2609);fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1" /> + <path + id="background-bottomright" + d="M 26,19.001283 L 26,19.438703 C 26,23.068637 23.06815,26 19.4375,26 L 19,26 L 19,19.001283 L 26,19.001283 z" + style="opacity:0.45;fill:url(#linearGradient2599);fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1" /> + <path + id="background-topright" + d="M 19.4375,4.996883 C 23.17916,4.996883 26,7.574983 26,11.559383 L 26,11.996883 L 19,11.996883 L 19,4.996883 L 19.4375,4.996883 z" + style="opacity:0.45;fill:url(#linearGradient2719);fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1" + sodipodi:nodetypes="cccccc" /> + <path + id="background-center" + d="M 18,12.996902 L 18,17.996902 L 13,17.996902 L 13,12.996902 L 18,12.996902 z" + style="opacity:0.45;fill:url(#linearGradient7649);fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1" /> + <path + sodipodi:nodetypes="ccccc" + id="background-top" + d="M 13.000004,4.996854 L 13.000004,11.996867 L 18.000004,11.996867 L 18.000004,4.996854 L 13.000004,4.996854 z" + style="opacity:0.45;fill:url(#linearGradient2570);fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1" /> + <rect + y="1" + x="1" + height="4.375" + width="5" + id="hint-stretch-borders" + style="opacity:0.875;fill:#008000;fill-opacity:1;stroke:none;stroke-width:0;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + <path + id="slider-bottom" + d="M 32.999941,39.999083 L 32.999941,46.999083 L 37.983397,46.999083 C 37.98886,46.999083 37.994596,46.982883 37.999941,46.967883 L 37.999941,39.999083 L 32.999941,39.999083 z" + style="opacity:0.45;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998000000000;stroke-opacity:1" /> + <path + id="slider-left" + d="M 25,33.999083 L 25,38.996884 L 32,38.996884 L 32,33.999083 L 25,33.999083 z" + style="opacity:0.45;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998000000000;stroke-opacity:1" /> + <path + id="slider-bottomleft" + d="M 25,40.001283 L 25,40.438703 C 25,44.068637 27.93185,47 31.5625,47 L 32,47 L 32,40.001283 L 25,40.001283 z" + style="opacity:0.45;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998000000000;stroke-opacity:1" /> + <path + sodipodi:nodetypes="cccccc" + id="slider-topleft" + d="M 31.5625,25.996883 C 27.64428,25.996883 25,28.751983 25,32.559383 L 25,32.996883 L 32,32.996883 L 32,25.996883 L 31.5625,25.996883 z" + style="opacity:0.45;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998000000000;stroke-opacity:1" /> + <path + style="opacity:0.45;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998000000000;stroke-opacity:1" + d="M 46,33.999083 L 46,38.999083 L 39,38.999083 L 39,33.999083 L 46,33.999083 z" + id="slider-right" /> + <path + style="opacity:0.45;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998000000000;stroke-opacity:1" + d="M 46,40.001283 L 46,40.438703 C 46,44.068637 43.06815,47 39.4375,47 L 39,47 L 39,40.001283 L 46,40.001283 z" + id="slider-bottomright" /> + <path + sodipodi:nodetypes="cccccc" + style="opacity:0.45;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998000000000;stroke-opacity:1" + d="M 39.4375,25.996883 C 43.17916,25.996883 46,28.574983 46,32.559383 L 46,32.996883 L 39,32.996883 L 39,25.996883 L 39.4375,25.996883 z" + id="slider-topright" /> + <path + style="opacity:0.45;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998000000000;stroke-opacity:1" + d="M 38,33.996902 L 38,38.996902 L 33,38.996902 L 33,33.996902 L 38,33.996902 z" + id="slider-center" /> + <path + style="opacity:0.45;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998000000000;stroke-opacity:1" + d="M 33.000004,25.996854 L 33.000004,32.996867 L 38.000004,32.996867 L 38.000004,25.996854 L 33.000004,25.996854 z" + id="slider-top" + sodipodi:nodetypes="ccccc" /> + <path + style="opacity:0.45;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.89285706999999981;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1" + d="M 2.9913867,39.001421 C 2.6002611,39.036262 2.2597586,39.252656 2.0978297,39.569287 C 1.9359008,39.885918 1.9770745,40.254823 2.2058792,40.53738 L 7.1093501,46.597053 C 7.3165618,46.850138 7.6485414,47 8.0019722,47 C 8.3554029,47 8.6873826,46.850138 8.8945943,46.597053 L 13.798066,40.53738 C 14.036107,40.239549 14.065991,39.849128 13.875506,39.525668 C 13.685021,39.202208 13.30608,38.999902 12.893542,39.001421 L 3.110403,39.001421 C 3.0707598,38.999526 3.0310298,38.999526 2.9913867,39.001421 z" + id="arrow-down" + sodipodi:nodetypes="csccsccsccc" /> + <path + sodipodi:nodetypes="csccsccsccc" + id="arrow-up" + d="M 2.9913867,36.998579 C 2.6002611,36.963738 2.2597586,36.747344 2.0978297,36.430713 C 1.9359008,36.114082 1.9770745,35.745177 2.2058792,35.46262 L 7.1093501,29.402947 C 7.3165618,29.149862 7.6485414,29 8.0019722,29 C 8.3554029,29 8.6873826,29.149862 8.8945943,29.402947 L 13.798066,35.46262 C 14.036107,35.760451 14.065991,36.150872 13.875506,36.474332 C 13.685021,36.797792 13.30608,37.000098 12.893542,36.998579 L 3.110403,36.998579 C 3.0707598,37.000474 3.0310298,37.000474 2.9913867,36.998579 z" + style="opacity:0.45;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.89285706999999981;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1" /> + <path + sodipodi:nodetypes="csccsccsccc" + id="arrow-left" + d="M 22.998579,36.991387 C 22.963738,36.600261 22.747344,36.259759 22.430713,36.09783 C 22.114082,35.935901 21.745177,35.977074 21.46262,36.205879 L 15.402947,41.10935 C 15.149862,41.316562 15,41.648541 15,42.001972 C 15,42.355403 15.149862,42.687383 15.402947,42.894594 L 21.46262,47.798066 C 21.760451,48.036107 22.150872,48.065991 22.474332,47.875506 C 22.797792,47.685021 23.000098,47.30608 22.998579,46.893542 L 22.998579,37.110403 C 23.000474,37.07076 23.000474,37.03103 22.998579,36.991387 z" + style="opacity:0.45;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.89285707;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1" /> + <path + style="opacity:0.45;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.89285707;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1" + d="M 15.001421,26.991387 C 15.036262,26.600261 15.252656,26.259759 15.569287,26.09783 C 15.885918,25.935901 16.254823,25.977074 16.53738,26.205879 L 22.597053,31.10935 C 22.850138,31.316562 23,31.648541 23,32.001972 C 23,32.355403 22.850138,32.687383 22.597053,32.894594 L 16.53738,37.798066 C 16.239549,38.036107 15.849128,38.065991 15.525668,37.875506 C 15.202208,37.685021 14.999902,37.30608 15.001421,36.893542 L 15.001421,27.110403 C 14.999526,27.07076 14.999526,27.03103 15.001421,26.991387 z" + id="arrow-right" + sodipodi:nodetypes="csccsccsccc" /> + <path + style="opacity:0.6;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1" + d="M 32.999941,64.0312 L 32.999941,71.0312 L 37.983397,71.0312 C 37.98886,71.0312 37.994596,71.015 37.999941,71 L 37.999941,64.0312 L 32.999941,64.0312 z" + id="mouseover-slider-bottom" /> + <path + style="opacity:0.6;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1" + d="M 25,58.0312 L 25,63.029001 L 32,63.029001 L 32,58.0312 L 25,58.0312 z" + id="mouseover-slider-left" /> + <path + style="opacity:0.6;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1" + d="M 25,64.0334 L 25,64.47082 C 25,68.100754 27.93185,71.032117 31.5625,71.032117 L 32,71.032117 L 32,64.0334 L 25,64.0334 z" + id="mouseover-slider-bottomleft" /> + <path + style="opacity:0.6;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1" + d="M 31.5625,50.029 C 27.64428,50.029 25,52.7841 25,56.5915 L 25,57.029 L 32,57.029 L 32,50.029 L 31.5625,50.029 z" + id="mouseover-slider-topleft" + sodipodi:nodetypes="cccccc" /> + <path + id="mouseover-slider-right" + d="M 46,58.0312 L 46,63.0312 L 39,63.0312 L 39,58.0312 L 46,58.0312 z" + style="opacity:0.6;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1" /> + <path + id="mouseover-slider-bottomright" + d="M 46,64.0334 L 46,64.47082 C 46,68.100754 43.06815,71.032117 39.4375,71.032117 L 39,71.032117 L 39,64.0334 L 46,64.0334 z" + style="opacity:0.6;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1" /> + <path + id="mouseover-slider-topright" + d="M 39.4375,50.029 C 43.17916,50.029 46,52.6071 46,56.5915 L 46,57.029 L 39,57.029 L 39,50.029 L 39.4375,50.029 z" + style="opacity:0.6;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1" + sodipodi:nodetypes="cccccc" /> + <path + id="mouseover-slider-center" + d="M 38,58.029019 L 38,63.029019 L 33,63.029019 L 33,58.029019 L 38,58.029019 z" + style="opacity:0.6;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1" /> + <path + sodipodi:nodetypes="ccccc" + id="mouseover-slider-top" + d="M 33.000004,57.028984 L 33.000004,50.028971 L 38.000004,50.028971 L 38.000004,57.028984 L 33.000004,57.028984 z" + style="opacity:0.6;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1" /> + <path + sodipodi:nodetypes="csccsccsccc" + id="mouseover-arrow-down" + d="M 2.9913867,63.033538 C 2.6002611,63.068379 2.2597586,63.284773 2.0978297,63.601404 C 1.9359008,63.918035 1.9770745,64.28694 2.2058792,64.569497 L 7.1093501,70.62917 C 7.3165618,70.882255 7.6485414,71.032117 8.0019722,71.032117 C 8.3554029,71.032117 8.6873826,70.882255 8.8945943,70.62917 L 13.798066,64.569497 C 14.036107,64.271666 14.065991,63.881245 13.875506,63.557785 C 13.685021,63.234325 13.30608,63.032019 12.893542,63.033538 L 3.110403,63.033538 C 3.0707598,63.031643 3.0310298,63.031643 2.9913867,63.033538 z" + style="opacity:0.6;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.89285707;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1" /> + <path + style="opacity:0.6;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.89285707;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1" + d="M 2.9913867,61.030696 C 2.6002611,60.995855 2.2597586,60.779461 2.0978297,60.46283 C 1.9359008,60.146199 1.9770745,59.777294 2.2058792,59.494737 L 7.1093501,53.435064 C 7.3165618,53.181979 7.6485414,53.032117 8.0019722,53.032117 C 8.3554029,53.032117 8.6873826,53.181979 8.8945943,53.435064 L 13.798066,59.494737 C 14.036107,59.792568 14.065991,60.182989 13.875506,60.506449 C 13.685021,60.829909 13.30608,61.032215 12.893542,61.030696 L 3.110403,61.030696 C 3.0707598,61.032591 3.0310298,61.032591 2.9913867,61.030696 z" + id="mouseover-arrow-up" + sodipodi:nodetypes="csccsccsccc" /> + <path + style="opacity:0.6;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.89285707;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1" + d="M 22.998579,61.023504 C 22.963738,60.632378 22.747344,60.291876 22.430713,60.129947 C 22.114082,59.968018 21.745177,60.009191 21.46262,60.237996 L 15.402947,65.141467 C 15.149862,65.348679 15,65.680658 15,66.034089 C 15,66.38752 15.149862,66.7195 15.402947,66.926711 L 21.46262,71.830183 C 21.760451,72.068224 22.150872,72.098108 22.474332,71.907623 C 22.797792,71.717138 23.000098,71.338197 22.998579,70.925659 L 22.998579,61.14252 C 23.000474,61.102877 23.000474,61.063147 22.998579,61.023504 z" + id="mouseover-arrow-left" + sodipodi:nodetypes="csccsccsccc" /> + <path + sodipodi:nodetypes="csccsccsccc" + id="mouseover-arrow-right" + d="M 15.001421,51.023504 C 15.036262,50.632378 15.252656,50.291876 15.569287,50.129947 C 15.885918,49.968018 16.254823,50.009191 16.53738,50.237996 L 22.597053,55.141467 C 22.850138,55.348679 23,55.680658 23,56.034089 C 23,56.38752 22.850138,56.7195 22.597053,56.926711 L 16.53738,61.830183 C 16.239549,62.068224 15.849128,62.098108 15.525668,61.907623 C 15.202208,61.717138 14.999902,61.338197 15.001421,60.925659 L 15.001421,51.14252 C 14.999526,51.102877 14.999526,51.063147 15.001421,51.023504 z" + style="opacity:0.6;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.89285707;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1" /> + <path + id="sunken-slider-bottom" + d="M 32.999941,89.105541 L 32.999941,96.105541 L 37.983397,96.105541 C 37.98886,96.105541 37.994596,96.089341 37.999941,96.074341 L 37.999941,89.105541 L 32.999941,89.105541 z" + style="opacity:0.8;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1" /> + <path + id="sunken-slider-left" + d="M 25,83.105541 L 25,88.103342 L 32,88.103342 L 32,83.105541 L 25,83.105541 z" + style="opacity:0.8;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1" /> + <path + id="sunken-slider-bottomleft" + d="M 25,89.107741 L 25,89.545161 C 25,93.175095 27.93185,96.106458 31.5625,96.106458 L 32,96.106458 L 32,89.107741 L 25,89.107741 z" + style="opacity:0.8;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1" /> + <path + sodipodi:nodetypes="cccccc" + id="sunken-slider-topleft" + d="M 31.5625,75.103341 C 27.64428,75.103341 25,77.858441 25,81.665841 L 25,82.103341 L 32,82.103341 L 32,75.103341 L 31.5625,75.103341 z" + style="opacity:0.8;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1" /> + <path + style="opacity:0.8;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1" + d="M 46,83.105541 L 46,88.105541 L 39,88.105541 L 39,83.105541 L 46,83.105541 z" + id="sunken-slider-right" /> + <path + style="opacity:0.8;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1" + d="M 46,89.107741 L 46,89.545161 C 46,93.175095 43.06815,96.106458 39.4375,96.106458 L 39,96.106458 L 39,89.107741 L 46,89.107741 z" + id="sunken-slider-bottomright" /> + <path + sodipodi:nodetypes="cccccc" + style="opacity:0.8;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1" + d="M 39.4375,75.103341 C 43.17916,75.103341 46,77.681441 46,81.665841 L 46,82.103341 L 39,82.103341 L 39,75.103341 L 39.4375,75.103341 z" + id="sunken-slider-topright" /> + <path + style="opacity:0.8;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1" + d="M 38,83.10336 L 38,88.10336 L 33,88.10336 L 33,83.10336 L 38,83.10336 z" + id="sunken-slider-center" /> + <path + style="opacity:0.8;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1" + d="M 33.000004,75.103312 L 33.000004,82.103325 L 38.000004,82.103325 L 38.000004,75.103312 L 33.000004,75.103312 z" + id="sunken-slider-top" + sodipodi:nodetypes="ccccc" /> + <path + style="opacity:0.8;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.89285707;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1" + d="M 2.9913867,88.107879 C 2.6002611,88.14272 2.2597586,88.359114 2.0978297,88.675745 C 1.9359008,88.992376 1.9770745,89.361281 2.2058792,89.643838 L 7.1093501,95.703511 C 7.3165618,95.956596 7.6485414,96.106458 8.0019722,96.106458 C 8.3554029,96.106458 8.6873826,95.956596 8.8945943,95.703511 L 13.798066,89.643838 C 14.036107,89.346007 14.065991,88.955586 13.875506,88.632126 C 13.685021,88.308666 13.30608,88.10636 12.893542,88.107879 L 3.110403,88.107879 C 3.0707598,88.105984 3.0310298,88.105984 2.9913867,88.107879 z" + id="sunken-arrow-down" + sodipodi:nodetypes="csccsccsccc" /> + <path + sodipodi:nodetypes="csccsccsccc" + id="sunken-arrow-up" + d="M 2.9913867,86.105037 C 2.6002611,86.070196 2.2597586,85.853802 2.0978297,85.537171 C 1.9359008,85.22054 1.9770745,84.851635 2.2058792,84.569078 L 7.1093501,78.509405 C 7.3165618,78.25632 7.6485414,78.106458 8.0019722,78.106458 C 8.3554029,78.106458 8.6873826,78.25632 8.8945943,78.509405 L 13.798066,84.569078 C 14.036107,84.866909 14.065991,85.25733 13.875506,85.58079 C 13.685021,85.90425 13.30608,86.106556 12.893542,86.105037 L 3.110403,86.105037 C 3.0707598,86.106932 3.0310298,86.106932 2.9913867,86.105037 z" + style="opacity:0.8;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.89285707;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1" /> + <path + sodipodi:nodetypes="csccsccsccc" + id="sunken-arrow-left" + d="M 22.998579,86.097845 C 22.963738,85.706719 22.747344,85.366217 22.430713,85.204288 C 22.114082,85.042359 21.745177,85.083532 21.46262,85.312337 L 15.402947,90.215808 C 15.149862,90.42302 15,90.754999 15,91.10843 C 15,91.461861 15.149862,91.793841 15.402947,92.001052 L 21.46262,96.904524 C 21.760451,97.142565 22.150872,97.172449 22.474332,96.981964 C 22.797792,96.791479 23.000098,96.412538 22.998579,96 L 22.998579,86.216861 C 23.000474,86.177218 23.000474,86.137488 22.998579,86.097845 z" + style="opacity:0.8;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.89285707;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1" /> + <path + style="opacity:0.8;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.89285707;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1" + d="M 15.001421,76.097845 C 15.036262,75.706719 15.252656,75.366217 15.569287,75.204288 C 15.885918,75.042359 16.254823,75.083532 16.53738,75.312337 L 22.597053,80.215808 C 22.850138,80.42302 23,80.754999 23,81.10843 C 23,81.461861 22.850138,81.793841 22.597053,82.001052 L 16.53738,86.904524 C 16.239549,87.142565 15.849128,87.172449 15.525668,86.981964 C 15.202208,86.791479 14.999902,86.412538 15.001421,86 L 15.001421,76.216861 C 14.999526,76.177218 14.999526,76.137488 15.001421,76.097845 z" + id="sunken-arrow-right" + sodipodi:nodetypes="csccsccsccc" /> + </g> +</svg> --- desktoptheme/widgets/monitor.svg +++ desktoptheme/widgets/monitor.svg @@ -0,0 +1,1954 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + id="svg2" + sodipodi:version="0.32" + inkscape:version="0.46" + width="200" + height="200" + version="1.0" + sodipodi:docbase="/home/david" + sodipodi:docname="monitor.svgz" + inkscape:output_extension="org.inkscape.output.svgz.inkscape" + inkscape:export-filename="computer.png" + inkscape:export-xdpi="33.75" + inkscape:export-ydpi="33.75"> + <sodipodi:namedview + inkscape:window-height="710" + inkscape:window-width="1110" + inkscape:pageshadow="2" + inkscape:pageopacity="0.0" + guidetolerance="10.0" + gridtolerance="10.0" + objecttolerance="10.0" + borderopacity="1.0" + bordercolor="#666666" + pagecolor="#ffffff" + id="namedview3861" + showguides="true" + inkscape:guide-bbox="true" + width="128px" + height="128px" + showgrid="true" + inkscape:zoom="2.8284271" + inkscape:cx="102.44857" + inkscape:cy="165.98078" + inkscape:window-x="129" + inkscape:window-y="83" + inkscape:current-layer="svg2" + inkscape:grid-points="true"> + <inkscape:grid + enabled="true" + visible="true" + empspacing="2" + empopacity="0.4" + opacity="0.2" + empcolor="#0000ff" + color="#0000ff" + spacingy="2px" + spacingx="2px" + originy="0px" + originx="0px" + type="xygrid" + id="GridFromPre046Settings" /> + </sodipodi:namedview> + <metadata + id="metadata7"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + </cc:Work> + </rdf:RDF> + </metadata> + <defs + id="defs5"> + <radialGradient + r="91.609398" + fy="136.14069" + fx="2132.25" + cy="136.14069" + cx="2132.25" + gradientTransform="matrix(4.9460378e-3,4.5042486e-2,-1.2382186e-3,0.157057,66.828125,-50.659102)" + gradientUnits="userSpaceOnUse" + id="radialGradient3536" + xlink:href="#linearGradient3215" + inkscape:collect="always" /> + <radialGradient + r="91.609375" + fy="1575.4911" + fx="214.5" + cy="1608.8442" + cx="215" + gradientTransform="matrix(-2.9411745e-2,0,0,-0.4195896,83.588241,705.06522)" + gradientUnits="userSpaceOnUse" + id="radialGradient3539" + xlink:href="#linearGradient3215" + inkscape:collect="always" /> + <radialGradient + r="91.609375" + fy="1575.4911" + fx="214.5" + cy="1608.8442" + cx="215" + gradientTransform="matrix(2.9411745e-2,0,0,0.4195896,65.411787,-578.06695)" + gradientUnits="userSpaceOnUse" + id="radialGradient3542" + xlink:href="#linearGradient3215" + inkscape:collect="always" /> + <radialGradient + r="91.609398" + fy="136.14069" + fx="2132.25" + cy="136.14069" + cx="2132.25" + gradientTransform="matrix(-4.9460378e-3,4.5042486e-2,1.2382186e-3,0.157057,82.171903,-50.659102)" + gradientUnits="userSpaceOnUse" + id="radialGradient3545" + xlink:href="#linearGradient3215" + inkscape:collect="always" /> + <radialGradient + r="91.609398" + fy="136.14062" + fx="2040.6406" + cy="136.14062" + cx="2040.6406" + gradientTransform="matrix(2.9411745e-2,0,0,0.3188565,14.469724,23.356188)" + gradientUnits="userSpaceOnUse" + id="radialGradient3548" + xlink:href="#linearGradient3215" + inkscape:collect="always" /> + <linearGradient + y2="9.2778997" + x2="50.10762" + y1="89.277901" + x1="50.10762" + gradientTransform="matrix(2.9411745e-2,0,0,0.9996163,77.614494,52.726514)" + gradientUnits="userSpaceOnUse" + id="linearGradient3551" + xlink:href="#linearGradient7141" + inkscape:collect="always" /> + <radialGradient + r="91.609375" + fy="1575.4911" + fx="214.5" + cy="1608.8442" + cx="215" + gradientTransform="matrix(-2.9411745e-2,0,0,0.4195896,83.565267,-578.06695)" + gradientUnits="userSpaceOnUse" + id="radialGradient3554" + xlink:href="#linearGradient3215" + inkscape:collect="always" /> + <linearGradient + id="linearGradient3427" + inkscape:collect="always"> + <stop + id="stop3429" + offset="0" + style="stop-color:#ffffff;stop-opacity:1;" /> + <stop + id="stop3431" + offset="1" + style="stop-color:#ffffff;stop-opacity:0;" /> + </linearGradient> + <linearGradient + id="linearGradient3303" + inkscape:collect="always"> + <stop + id="stop3305" + offset="0" + style="stop-color:#ffffff;stop-opacity:1;" /> + <stop + id="stop3307" + offset="1" + style="stop-color:#ffffff;stop-opacity:0;" /> + </linearGradient> + <linearGradient + id="linearGradient7751" + inkscape:collect="always"> + <stop + id="stop7753" + offset="0" + style="stop-color:#ffffff;stop-opacity:1;" /> + <stop + id="stop7755" + offset="1" + style="stop-color:#ffffff;stop-opacity:0;" /> + </linearGradient> + <linearGradient + id="linearGradient3273" + inkscape:collect="always"> + <stop + id="stop3275" + offset="0" + style="stop-color:#ffffff;stop-opacity:1;" /> + <stop + id="stop3277" + offset="1" + style="stop-color:#ffffff;stop-opacity:0;" /> + </linearGradient> + <linearGradient + id="linearGradient3410" + inkscape:collect="always"> + <stop + id="stop3412" + offset="0" + style="stop-color:#000000;stop-opacity:1;" /> + <stop + id="stop3414" + offset="1" + style="stop-color:#000000;stop-opacity:0;" /> + </linearGradient> + <linearGradient + id="linearGradient3259"> + <stop + id="stop3261" + offset="0" + style="stop-color:#1f1f1f;stop-opacity:1;" /> + <stop + id="stop3263" + offset="1" + style="stop-color:#424242;stop-opacity:1;" /> + </linearGradient> + <linearGradient + id="linearGradient3385"> + <stop + id="stop3387" + offset="0" + style="stop-color:#d6d6d6;stop-opacity:1;" /> + <stop + id="stop3389" + offset="1" + style="stop-color:#ffffff;stop-opacity:1;" /> + </linearGradient> + <linearGradient + id="linearGradient3393"> + <stop + id="stop3395" + offset="0" + style="stop-color:#efefef;stop-opacity:1" /> + <stop + id="stop3397" + offset="1" + style="stop-color:#b8b8b8;stop-opacity:1" /> + </linearGradient> + <linearGradient + id="linearGradient3288" + inkscape:collect="always"> + <stop + id="stop3290" + offset="0" + style="stop-color:#ffffff;stop-opacity:1;" /> + <stop + id="stop3292" + offset="1" + style="stop-color:#ffffff;stop-opacity:0;" /> + </linearGradient> + <linearGradient + id="linearGradient7706" + inkscape:collect="always"> + <stop + id="stop7708" + offset="0" + style="stop-color:#ffffff;stop-opacity:1;" /> + <stop + id="stop7710" + offset="1" + style="stop-color:#ffffff;stop-opacity:0;" /> + </linearGradient> + <linearGradient + id="linearGradient7141"> + <stop + id="stop7143" + style="stop-color:#222222;stop-opacity:1;" + offset="0" /> + <stop + id="stop7149" + style="stop-color:#0c0c0c;stop-opacity:1;" + offset="0.23586744" /> + <stop + id="stop7145" + style="stop-color:#000000;stop-opacity:1" + offset="1" /> + </linearGradient> + <linearGradient + id="linearGradient3215"> + <stop + id="stop3217" + style="stop-color:#ffffff;stop-opacity:1;" + offset="0" /> + <stop + id="stop3221" + style="stop-color:#ffffff;stop-opacity:0.28158844;" + offset="0.5" /> + <stop + id="stop3219" + style="stop-color:#ffffff;stop-opacity:0;" + offset="1" /> + </linearGradient> + <inkscape:perspective + id="perspective384" + inkscape:persp3d-origin="64 : 42.666667 : 1" + inkscape:vp_z="128 : 64 : 1" + inkscape:vp_y="0 : 1000 : 0" + inkscape:vp_x="0 : 64 : 1" + sodipodi:type="inkscape:persp3d" /> + <linearGradient + id="linearGradient7290"> + <stop + style="stop-color:#dddddd;stop-opacity:1;" + offset="0" + id="stop7292" /> + <stop + style="stop-color:#a7a7a7;stop-opacity:1;" + offset="1" + id="stop7294" /> + </linearGradient> + <linearGradient + id="linearGradient7150"> + <stop + id="stop7152" + offset="0" + style="stop-color:#ffffff;stop-opacity:0;" /> + <stop + id="stop7154" + offset="1" + style="stop-color:#ffffff;stop-opacity:1;" /> + </linearGradient> + <linearGradient + id="linearGradient7136" + inkscape:collect="always"> + <stop + id="stop7138" + offset="0" + style="stop-color:#ffffff;stop-opacity:1;" /> + <stop + id="stop7140" + offset="1" + style="stop-color:#ffffff;stop-opacity:0;" /> + </linearGradient> + <linearGradient + id="linearGradient4029"> + <stop + id="stop4031" + offset="0" + style="stop-color:#818584;stop-opacity:1;" /> + <stop + style="stop-color:#000000;stop-opacity:1;" + offset="0.5" + id="stop4033" /> + <stop + id="stop4035" + offset="1" + style="stop-color:#818584;stop-opacity:1;" /> + </linearGradient> + <linearGradient + id="linearGradient3722"> + <stop + id="stop3724" + offset="0" + style="stop-color:#ececec;stop-opacity:1;" /> + <stop + id="stop3726" + offset="1" + style="stop-color:#404040;stop-opacity:1;" /> + </linearGradient> + <linearGradient + id="linearGradient3611"> + <stop + style="stop-color:#818584;stop-opacity:1;" + offset="0" + id="stop3613" /> + <stop + id="stop3615" + offset="0.5" + style="stop-color:#ffffff;stop-opacity:1;" /> + <stop + style="stop-color:#818584;stop-opacity:1;" + offset="1" + id="stop3617" /> + </linearGradient> + <linearGradient + id="linearGradient3483"> + <stop + style="stop-color:#ba0000;stop-opacity:1;" + offset="0" + id="stop3485" /> + <stop + style="stop-color:#ba0000;stop-opacity:0;" + offset="1" + id="stop3487" /> + </linearGradient> + <linearGradient + id="linearGradient3176"> + <stop + id="stop3178" + offset="0" + style="stop-color:#000000;stop-opacity:1;" /> + <stop + id="stop3180" + offset="1" + style="stop-color:#afb0b0;stop-opacity:0;" /> + </linearGradient> + <linearGradient + id="linearGradient3166"> + <stop + id="stop3168" + offset="0" + style="stop-color:#ffffff;stop-opacity:1;" /> + <stop + style="stop-color:#ffffff;stop-opacity:0.82206404;" + offset="0.5990991" + id="stop3518" /> + <stop + id="stop3170" + offset="1" + style="stop-color:#ffffff;stop-opacity:0;" /> + </linearGradient> + <linearGradient + id="linearGradient3149"> + <stop + id="stop3151" + offset="0" + style="stop-color:#ffffff;stop-opacity:1;" /> + <stop + style="stop-color:#ffffff;stop-opacity:0;" + offset="0.34797296" + id="stop3157" /> + <stop + id="stop4061" + offset="0.65930116" + style="stop-color:#ffffff;stop-opacity:0;" /> + <stop + id="stop3153" + offset="1" + style="stop-color:#ffffff;stop-opacity:1;" /> + </linearGradient> + <linearGradient + id="linearGradient3954"> + <stop + id="stop3956" + offset="0" + style="stop-color:#b3b3b3;stop-opacity:1;" /> + <stop + style="stop-color:#ffffff;stop-opacity:1;" + offset="0.52879584" + id="stop3962" /> + <stop + id="stop3958" + offset="1" + style="stop-color:#c5c5c5;stop-opacity:1;" /> + </linearGradient> + <linearGradient + id="linearGradient3065"> + <stop + style="stop-color:#ffffff;stop-opacity:1;" + offset="0" + id="stop3067" /> + <stop + id="stop3073" + offset="1" + style="stop-color:#000000;stop-opacity:1;" /> + <stop + style="stop-color:#000000;stop-opacity:1;" + offset="1" + id="stop3069" /> + </linearGradient> + <linearGradient + id="linearGradient3088"> + <stop + style="stop-color:#000000;stop-opacity:1;" + offset="0" + id="stop3090" /> + <stop + id="stop3098" + offset="0.73626375" + style="stop-color:#000000;stop-opacity:0.49803922;" /> + <stop + style="stop-color:#000000;stop-opacity:0;" + offset="1" + id="stop3092" /> + </linearGradient> + <radialGradient + r="25.9375" + fy="-0.23275588" + fx="162.46797" + cy="-0.23275588" + cx="162.46797" + gradientTransform="matrix(0.7001186,0,0,2.7816652,48.721132,1.3717999)" + gradientUnits="userSpaceOnUse" + id="radialGradient7164" + xlink:href="#linearGradient7150" + inkscape:collect="always" /> + <mask + id="mask7160" + maskUnits="userSpaceOnUse"> + <path + style="opacity:1;fill:url(#radialGradient7164);fill-opacity:1;stroke:none;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1" + d="M 137.37423,-51.650649 C 136.90963,-51.650649 136.53048,-51.183286 136.53048,-50.619399 L 136.53048,-0.18189907 C 141.47984,0.40821793 146.5415,0.72435094 151.68673,0.72435094 C 164.60291,0.72435094 176.96094,-1.191205 188.40548,-4.713149 L 188.40548,-50.619399 C 188.40548,-51.183286 188.02634,-51.650649 187.56173,-51.650649 L 137.37423,-51.650649 z" + id="path7162" /> + </mask> + <linearGradient + y2="118.57565" + x2="47.238132" + y1="74.379738" + x1="88.188385" + gradientTransform="matrix(0.7018405,0,0,0.7018405,-31.780515,17.907276)" + gradientUnits="userSpaceOnUse" + id="linearGradient5524" + xlink:href="#linearGradient3722" + inkscape:collect="always" /> + <linearGradient + y2="15.908398" + x2="72.281242" + y1="58" + x1="70.316795" + gradientTransform="translate(102.53048,-57.275649)" + gradientUnits="userSpaceOnUse" + id="linearGradient5542" + xlink:href="#linearGradient7136" + inkscape:collect="always" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient4050" + id="linearGradient4056" + x1="69" + y1="35.035378" + x2="69" + y2="0.60519463" + gradientUnits="userSpaceOnUse" /> + <clipPath + clipPathUnits="userSpaceOnUse" + id="clipPath4024"> + <rect + style="fill:#e20071;fill-opacity:1" + y="7.9999967" + x="8" + id="rect4026" + height="88" + width="112" + ry="0" /> + </clipPath> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient5645" + id="linearGradient3002" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(1.214876,0,0,-1.2057416,-356.23137,-16.727269)" + x1="314.05814" + y1="11.862287" + x2="314.05814" + y2="-113.61256" /> + <linearGradient + id="linearGradient5645"> + <stop + id="stop5647" + offset="0" + style="stop-color:#000000;stop-opacity:1;" /> + <stop + id="stop5649" + offset="1" + style="stop-color:#000000;stop-opacity:0;" /> + </linearGradient> + <linearGradient + id="linearGradient4854"> + <stop + id="stop4857" + offset="0" + style="stop-color:#ffffff;stop-opacity:1;" /> + <stop + style="stop-color:#ffffff;stop-opacity:1;" + offset="0.5" + id="stop4010" /> + <stop + id="stop4859" + offset="1" + style="stop-color:#ffffff;stop-opacity:0" /> + </linearGradient> + <linearGradient + id="linearGradient4838"> + <stop + style="stop-color:#9a9a9a;stop-opacity:1;" + offset="0" + id="stop4840" /> + <stop + id="stop4846" + offset="0.26439792" + style="stop-color:#d0d0d0;stop-opacity:1;" /> + <stop + id="stop4842" + offset="0.52879584" + style="stop-color:#e4e4e4;stop-opacity:1;" /> + <stop + style="stop-color:#e2e2e2;stop-opacity:1;" + offset="0.76439792" + id="stop4848" /> + <stop + style="stop-color:#acacac;stop-opacity:1;" + offset="1" + id="stop4844" /> + </linearGradient> + <linearGradient + y2="165.22659" + x2="196.125" + y1="165.22659" + x1="49.875" + gradientUnits="userSpaceOnUse" + id="linearGradient4804"> + <stop + id="stop4806" + style="stop-color:#6b6b6b;stop-opacity:1;" + offset="0" /> + <stop + id="stop4808" + style="stop-color:#d6d9df;stop-opacity:1;" + offset="0.1716" /> + <stop + id="stop4810" + style="stop-color:#737373;stop-opacity:1;" + offset="0.30770001" /> + <stop + id="stop4812" + style="stop-color:#e1e4e7;stop-opacity:1;" + offset="0.5" /> + <stop + id="stop4814" + style="stop-color:#818181;stop-opacity:1;" + offset="0.74559999" /> + <stop + id="stop4816" + style="stop-color:#868d93;stop-opacity:1;" + offset="0.77539998" /> + <stop + id="stop4818" + style="stop-color:#9b9da3;stop-opacity:1;" + offset="0.83310002" /> + <stop + id="stop4820" + style="stop-color:#8e9198;stop-opacity:1;" + offset="0.89039999" /> + <stop + id="stop4822" + style="stop-color:#8f949a;stop-opacity:1;" + offset="0.9465" /> + <stop + id="stop4824" + style="stop-color:#adb0b5;stop-opacity:1;" + offset="1" /> + </linearGradient> + <linearGradient + id="linearGradient3258"> + <stop + id="stop3260" + offset="0" + style="stop-color:#ececec;stop-opacity:1;" /> + <stop + id="stop3262" + offset="1" + style="stop-color:#404040;stop-opacity:1;" /> + </linearGradient> + <linearGradient + id="linearGradient3250"> + <stop + style="stop-color:#818584;stop-opacity:1;" + offset="0" + id="stop3252" /> + <stop + id="stop3254" + offset="0.5" + style="stop-color:#ffffff;stop-opacity:1;" /> + <stop + style="stop-color:#818584;stop-opacity:1;" + offset="1" + id="stop3256" /> + </linearGradient> + <linearGradient + id="linearGradient3242"> + <stop + id="stop3244" + offset="0" + style="stop-color:#b3b3b3;stop-opacity:1;" /> + <stop + style="stop-color:#ffffff;stop-opacity:1;" + offset="0.52879584" + id="stop3246" /> + <stop + id="stop3248" + offset="1" + style="stop-color:#909090;stop-opacity:1;" /> + </linearGradient> + <linearGradient + id="XMLID_18_" + gradientUnits="userSpaceOnUse" + x1="26" + y1="69" + x2="220" + y2="69"> + <stop + offset="0" + style="stop-color:#3383E6" + id="stop3354" /> + <stop + offset="1" + style="stop-color:#6ECAF7" + id="stop3364" /> + </linearGradient> + <linearGradient + id="linearGradient6160"> + <stop + style="stop-color:#000000;stop-opacity:1;" + offset="0" + id="stop6162" /> + <stop + style="stop-color:#000000;stop-opacity:0;" + offset="1" + id="stop6164" /> + </linearGradient> + <linearGradient + id="linearGradient3623"> + <stop + style="stop-color:#666666;stop-opacity:1;" + offset="0" + id="stop3625" /> + <stop + style="stop-color:#ffffff;stop-opacity:0;" + offset="1" + id="stop3627" /> + </linearGradient> + <linearGradient + id="linearGradient4050"> + <stop + style="stop-color:#000000;stop-opacity:1;" + offset="0" + id="stop4052" /> + <stop + style="stop-color:#000000;stop-opacity:0;" + offset="1" + id="stop4054" /> + </linearGradient> + <linearGradient + y2="0.60519463" + x2="69" + y1="35.035378" + x1="69" + gradientUnits="userSpaceOnUse" + id="linearGradient2810" + xlink:href="#linearGradient4050" + inkscape:collect="always" /> + <linearGradient + y2="-145.81259" + x2="69.935677" + y1="43.267174" + x1="69.935677" + gradientTransform="matrix(1.5974545,0,0,1.5316348,3.7629107,-1.2222354)" + gradientUnits="userSpaceOnUse" + id="linearGradient4270" + xlink:href="#linearGradient5645" + inkscape:collect="always" /> + <linearGradient + y2="110" + x2="166.95312" + y1="14" + x1="126.03124" + gradientTransform="matrix(0.9709466,0,0,0.9270577,-11.464306,-146.50147)" + gradientUnits="userSpaceOnUse" + id="linearGradient4276" + xlink:href="#XMLID_18_" + inkscape:collect="always" /> + <inkscape:perspective + sodipodi:type="inkscape:persp3d" + inkscape:vp_x="0 : 526.18109 : 1" + inkscape:vp_y="0 : 1000 : 0" + inkscape:vp_z="744.09448 : 526.18109 : 1" + inkscape:persp3d-origin="372.04724 : 350.78739 : 1" + id="perspective3855" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient7706" + id="linearGradient4573" + gradientUnits="userSpaceOnUse" + gradientTransform="translate(208,0)" + x1="-637" + y1="29.069431" + x2="-637" + y2="-163" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient3288" + id="linearGradient4575" + gradientUnits="userSpaceOnUse" + gradientTransform="translate(-385,-62)" + x1="-154.25182" + y1="-423.82953" + x2="-65.956993" + y2="-94.308769" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient3393" + id="radialGradient4577" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(1.5639745,-4.2049211e-8,3.0891185e-8,1.1489639,-524.0541,-13.332462)" + cx="-122.25" + cy="-192.92754" + fx="-122.25" + fy="-192.92754" + r="94" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient3385" + id="linearGradient4579" + gradientUnits="userSpaceOnUse" + gradientTransform="translate(-592.99999,-61.999226)" + x1="-100" + y1="-106.62158" + x2="-100" + y2="-228.88507" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient3259" + id="linearGradient4581" + gradientUnits="userSpaceOnUse" + gradientTransform="translate(-592.99999,-61.999226)" + x1="-80" + y1="-67.985718" + x2="-80" + y2="-208.05618" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient3410" + id="linearGradient4583" + gradientUnits="userSpaceOnUse" + gradientTransform="translate(-786.99999,-61.999226)" + x1="90.5" + y1="-193.5" + x2="90.5" + y2="-11.834614" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient3273" + id="radialGradient4585" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(2.1538834,-1.1992624e-8,3.4454488e-8,2.4746178,-454.53398,151.70365)" + cx="-120" + cy="-150.6152" + fx="-120.37437" + fy="-166.52031" + r="78" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient3273" + id="radialGradient4587" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(1.2820885,-7.5752261e-8,2.0757046e-7,3.5130793,-559.14935,265.72246)" + cx="-120" + cy="-109.7959" + fx="-120" + fy="-109.7959" + r="78" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient3393" + id="radialGradient4589" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(1.5639745,-4.2049211e-8,3.0891185e-8,1.1489639,-524.0541,-13.333233)" + cx="-122.25" + cy="-192.92754" + fx="-122.25" + fy="-192.92754" + r="94" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient3385" + id="linearGradient4591" + gradientUnits="userSpaceOnUse" + gradientTransform="translate(-592.99999,-61.999997)" + x1="-100" + y1="-106.62158" + x2="-100" + y2="-228.88507" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient3259" + id="linearGradient4593" + gradientUnits="userSpaceOnUse" + gradientTransform="translate(-592.99999,-61.999997)" + x1="-80" + y1="-67.985718" + x2="-80" + y2="-208.05618" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient3410" + id="linearGradient4595" + gradientUnits="userSpaceOnUse" + gradientTransform="translate(-786.99999,-61.999997)" + x1="90.5" + y1="-193.5" + x2="90.5" + y2="-11.834614" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient3273" + id="radialGradient4597" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(2.1538834,-1.1992624e-8,3.4454488e-8,2.4746178,-454.53398,151.70288)" + cx="-120" + cy="-150.6152" + fx="-120.37437" + fy="-166.52031" + r="78" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient3273" + id="radialGradient4599" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(1.2820885,-7.5752261e-8,2.0757046e-7,3.5130793,-559.14935,265.72169)" + cx="-120" + cy="-109.7959" + fx="-120" + fy="-109.7959" + r="78" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient7751" + id="linearGradient4601" + gradientUnits="userSpaceOnUse" + x1="-616.84747" + y1="-73.742973" + x2="-616.84747" + y2="-194.07599" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient3393" + id="radialGradient4603" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(1.5639745,-4.2049211e-8,3.0891185e-8,1.1489639,-524.0541,-13.333234)" + cx="-122.25" + cy="-192.92754" + fx="-122.25" + fy="-192.92754" + r="94" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient3385" + id="linearGradient4605" + gradientUnits="userSpaceOnUse" + gradientTransform="translate(-592.99999,-61.999998)" + x1="-100" + y1="-106.62158" + x2="-100" + y2="-228.88507" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient3259" + id="linearGradient4607" + gradientUnits="userSpaceOnUse" + gradientTransform="translate(-592.99999,-61.999998)" + x1="-80" + y1="-67.985718" + x2="-80" + y2="-208.05618" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient3303" + id="linearGradient4609" + gradientUnits="userSpaceOnUse" + gradientTransform="translate(-592.99999,42.700002)" + x1="-127.61703" + y1="-310.29703" + x2="-127.61703" + y2="-275.16071" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient3410" + id="linearGradient4611" + gradientUnits="userSpaceOnUse" + gradientTransform="translate(-786.99999,-61.999998)" + x1="90.5" + y1="-193.5" + x2="90.5" + y2="-11.834614" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient3427" + id="linearGradient4613" + gradientUnits="userSpaceOnUse" + gradientTransform="translate(-592.99999,-61.999998)" + x1="-11.793251" + y1="-0.17180708" + x2="-11.793251" + y2="-124.49196" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient3273" + id="radialGradient4615" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(2.1538834,-1.1992624e-8,3.4454488e-8,2.4746178,-454.53398,151.70288)" + cx="-120" + cy="-150.6152" + fx="-120.37437" + fy="-166.52031" + r="78" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient3273" + id="radialGradient4617" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(1.2820885,-7.5752261e-8,2.0757046e-7,3.5130793,-559.14935,265.72169)" + cx="-120" + cy="-109.7959" + fx="-120" + fy="-109.7959" + r="78" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient3393" + id="radialGradient4619" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(1.5639745,-4.2049211e-8,3.0891185e-8,1.1489639,-524.0541,-13.33323)" + cx="-122.25" + cy="-192.92754" + fx="-122.25" + fy="-192.92754" + r="94" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient3385" + id="linearGradient4621" + gradientUnits="userSpaceOnUse" + gradientTransform="translate(-592.99999,-61.999994)" + x1="-100" + y1="-106.62158" + x2="-100" + y2="-228.88507" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient3259" + id="linearGradient4623" + gradientUnits="userSpaceOnUse" + gradientTransform="translate(-592.99999,-61.999994)" + x1="-80" + y1="-67.985718" + x2="-80" + y2="-208.05618" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient3410" + id="linearGradient4625" + gradientUnits="userSpaceOnUse" + gradientTransform="translate(-786.99999,-61.999994)" + x1="90.5" + y1="-193.5" + x2="90.5" + y2="-11.834614" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient3273" + id="radialGradient4627" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(2.1538834,-1.1992624e-8,3.4454488e-8,2.4746178,-454.53398,151.70288)" + cx="-120" + cy="-150.6152" + fx="-120.37437" + fy="-166.52031" + r="78" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient3273" + id="radialGradient4629" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(1.2820885,-7.5752261e-8,2.0757046e-7,3.5130793,-559.14935,265.72169)" + cx="-120" + cy="-109.7959" + fx="-120" + fy="-109.7959" + r="78" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient3393" + id="radialGradient4631" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(1.5639745,-4.2049211e-8,3.0891185e-8,1.1489639,-524.0541,-13.333233)" + cx="-122.25" + cy="-192.92754" + fx="-122.25" + fy="-192.92754" + r="94" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient3385" + id="linearGradient4633" + gradientUnits="userSpaceOnUse" + gradientTransform="translate(-592.99999,-61.999997)" + x1="-100" + y1="-106.62158" + x2="-100" + y2="-228.88507" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient3259" + id="linearGradient4635" + gradientUnits="userSpaceOnUse" + gradientTransform="translate(-592.99999,-61.999997)" + x1="-80" + y1="-67.985718" + x2="-80" + y2="-208.05618" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient3303" + id="linearGradient4637" + gradientUnits="userSpaceOnUse" + gradientTransform="translate(-592.99999,42.700003)" + x1="-127.61703" + y1="-310.29703" + x2="-127.61703" + y2="-275.16071" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient3410" + id="linearGradient4639" + gradientUnits="userSpaceOnUse" + gradientTransform="translate(-786.99999,-61.999997)" + x1="90.5" + y1="-193.5" + x2="90.5" + y2="-11.834614" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient3427" + id="linearGradient4641" + gradientUnits="userSpaceOnUse" + gradientTransform="translate(-592.99999,-61.999997)" + x1="-11.793251" + y1="-0.17180708" + x2="-11.793251" + y2="-124.49196" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient3273" + id="radialGradient4643" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(2.1538834,-1.1992624e-8,3.4454488e-8,2.4746178,-454.53398,151.70288)" + cx="-120" + cy="-150.6152" + fx="-120.37437" + fy="-166.52031" + r="78" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient3273" + id="radialGradient4645" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(1.2820885,-7.5752261e-8,2.0757046e-7,3.5130793,-559.14935,265.72169)" + cx="-120" + cy="-109.7959" + fx="-120" + fy="-109.7959" + r="78" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient3393" + id="radialGradient4647" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(1.5639745,-4.2049211e-8,3.0891185e-8,1.1489639,-524.0541,-13.333233)" + cx="-122.25" + cy="-192.92754" + fx="-122.25" + fy="-192.92754" + r="94" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient3385" + id="linearGradient4649" + gradientUnits="userSpaceOnUse" + gradientTransform="translate(-592.99999,-61.999997)" + x1="-100" + y1="-106.62158" + x2="-100" + y2="-228.88507" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient3259" + id="linearGradient4651" + gradientUnits="userSpaceOnUse" + gradientTransform="translate(-592.99999,-61.999997)" + x1="-80" + y1="-67.985718" + x2="-80" + y2="-208.05618" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient3410" + id="linearGradient4653" + gradientUnits="userSpaceOnUse" + gradientTransform="translate(-786.99999,-61.999997)" + x1="90.5" + y1="-193.5" + x2="90.5" + y2="-11.834614" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient3273" + id="radialGradient4655" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(2.1538834,-1.1992624e-8,3.4454488e-8,2.4746178,-454.53398,151.70288)" + cx="-120" + cy="-150.6152" + fx="-120.37437" + fy="-166.52031" + r="78" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient3273" + id="radialGradient4657" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(1.2820885,-7.5752261e-8,2.0757046e-7,3.5130793,-559.14935,265.72169)" + cx="-120" + cy="-109.7959" + fx="-120" + fy="-109.7959" + r="78" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient3393" + id="radialGradient4659" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(1.5639745,-4.2071879e-8,3.0891185e-8,1.1495833,-524.0541,-13.212119)" + cx="-122.25" + cy="-192.92754" + fx="-122.25" + fy="-192.92754" + r="94" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient3385" + id="linearGradient4661" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(1,0,0,1.0005391,-592.99999,-61.905118)" + x1="-100" + y1="-106.62158" + x2="-100" + y2="-228.88507" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient3259" + id="linearGradient4663" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(1,0,0,1.0005391,-592.99999,-61.967652)" + x1="-80" + y1="-67.985718" + x2="-80" + y2="-208.05618" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient3410" + id="linearGradient4665" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(1,0,0,1.0005391,-786.99999,-61.905118)" + x1="90.5" + y1="-193.5" + x2="90.5" + y2="-11.834614" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient3427" + id="linearGradient4667" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(1,0,0,1.0005391,-592.99999,-61.905118)" + x1="-11.793251" + y1="-0.17180708" + x2="-11.793251" + y2="-124.49196" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient3273" + id="radialGradient4669" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(2.1538834,-1.1999089e-8,3.4454488e-8,2.4759518,-454.53398,151.91296)" + cx="-120" + cy="-150.6152" + fx="-120.37437" + fy="-166.52031" + r="78" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient3273" + id="radialGradient4671" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(1.2820885,-7.5793098e-8,2.0757046e-7,3.5149731,-559.14935,265.99324)" + cx="-120" + cy="-109.7959" + fx="-120" + fy="-109.7959" + r="78" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient3393" + id="radialGradient4673" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(1.5639745,-4.2049211e-8,3.0891185e-8,1.1489639,-524.0541,-13.33323)" + cx="-122.25" + cy="-192.92754" + fx="-122.25" + fy="-192.92754" + r="94" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient3385" + id="linearGradient4675" + gradientUnits="userSpaceOnUse" + gradientTransform="translate(-592.99999,-61.999994)" + x1="-100" + y1="-106.62158" + x2="-100" + y2="-228.88507" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient3259" + id="linearGradient4677" + gradientUnits="userSpaceOnUse" + gradientTransform="translate(-592.99999,-61.999994)" + x1="-80" + y1="-67.985718" + x2="-80" + y2="-208.05618" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient3303" + id="linearGradient4679" + gradientUnits="userSpaceOnUse" + gradientTransform="translate(-592.99999,42.700006)" + x1="-127.61703" + y1="-310.29703" + x2="-127.61703" + y2="-275.16071" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient3410" + id="linearGradient4681" + gradientUnits="userSpaceOnUse" + gradientTransform="translate(-786.99999,-61.999994)" + x1="90.5" + y1="-193.5" + x2="90.5" + y2="-11.834614" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient3427" + id="linearGradient4683" + gradientUnits="userSpaceOnUse" + gradientTransform="translate(-592.99999,-61.999994)" + x1="-11.793251" + y1="-0.17180708" + x2="-11.793251" + y2="-124.49196" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient3273" + id="radialGradient4685" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(2.1538834,-1.1992624e-8,3.4454488e-8,2.4746178,-454.53398,151.70288)" + cx="-120" + cy="-150.6152" + fx="-120.37437" + fy="-166.52031" + r="78" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient3273" + id="radialGradient4687" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(1.2820885,-7.5752261e-8,2.0757046e-7,3.5130793,-559.14935,265.72169)" + cx="-120" + cy="-109.7959" + fx="-120" + fy="-109.7959" + r="78" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient3273" + id="radialGradient4691" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(1.2820885,-7.5752261e-8,2.0757046e-7,3.5130793,255.85065,522.72169)" + cx="-120" + cy="-109.7959" + fx="-120" + fy="-109.7959" + r="78" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient3273" + id="radialGradient4694" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(2.1538834,-1.1992624e-8,3.4454488e-8,2.4746178,360.46602,408.70288)" + cx="-120" + cy="-150.6152" + fx="-120.37437" + fy="-166.52031" + r="78" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient3427" + id="linearGradient4697" + gradientUnits="userSpaceOnUse" + gradientTransform="translate(222.00001,195)" + x1="-11.793251" + y1="-0.17180708" + x2="-11.793251" + y2="-124.49196" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient3410" + id="linearGradient4700" + gradientUnits="userSpaceOnUse" + gradientTransform="translate(28.00001,195)" + x1="90.5" + y1="-193.5" + x2="90.5" + y2="-11.834614" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient3303" + id="linearGradient4703" + gradientUnits="userSpaceOnUse" + gradientTransform="translate(222.00001,299.7)" + x1="-127.61703" + y1="-310.29703" + x2="-127.61703" + y2="-275.16071" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient3259" + id="linearGradient4706" + gradientUnits="userSpaceOnUse" + gradientTransform="translate(222.00001,195)" + x1="-80" + y1="-67.985718" + x2="-80" + y2="-208.05618" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient3385" + id="linearGradient4709" + gradientUnits="userSpaceOnUse" + gradientTransform="translate(222.00001,195)" + x1="-100" + y1="-106.62158" + x2="-100" + y2="-228.88507" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient3393" + id="radialGradient4712" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(1.5639745,-4.2049211e-8,3.0891185e-8,1.1489639,290.9459,243.66677)" + cx="-122.25" + cy="-192.92754" + fx="-122.25" + fy="-192.92754" + r="94" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient3215" + id="radialGradient5515" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(-2.9411745e-2,0,0,0.4195896,83.565267,-578.06695)" + cx="215" + cy="1608.8442" + fx="214.5" + fy="1575.4911" + r="91.609375" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient7141" + id="linearGradient5517" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(2.9411745e-2,0,0,0.9996163,77.614494,52.726514)" + x1="50.10762" + y1="89.277901" + x2="50.10762" + y2="9.2778997" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient3215" + id="radialGradient5519" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(2.9411745e-2,0,0,0.3188565,14.469724,23.356188)" + cx="2040.6406" + cy="136.14062" + fx="2040.6406" + fy="136.14062" + r="91.609398" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient3215" + id="radialGradient5521" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(-4.9460378e-3,4.5042486e-2,1.2382186e-3,0.157057,82.171903,-50.659102)" + cx="2132.25" + cy="136.14069" + fx="2132.25" + fy="136.14069" + r="91.609398" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient3215" + id="radialGradient5523" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(2.9411745e-2,0,0,0.4195896,65.411787,-578.06695)" + cx="215" + cy="1608.8442" + fx="214.5" + fy="1575.4911" + r="91.609375" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient3215" + id="radialGradient5525" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(-2.9411745e-2,0,0,-0.4195896,83.588241,705.06522)" + cx="215" + cy="1608.8442" + fx="214.5" + fy="1575.4911" + r="91.609375" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient3215" + id="radialGradient5527" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(4.9460378e-3,4.5042486e-2,-1.2382186e-3,0.157057,66.828125,-50.659102)" + cx="2132.25" + cy="136.14069" + fx="2132.25" + fy="136.14069" + r="91.609398" /> + </defs> + <image + xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAHIAAABACAYAAADGbyPbAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz +AAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAABKISURB +VHic7ZxtbBzVesf/Z1733eu3OA4bEhOTgBJIuCl5Eam40kWhfEgRVBekUoJQkAAJtSG0SFe8KOFT +BZUiSFQq+ICiVkKCEFGBKqUBEUpVhxuF2sktDk5M4hvH146NHcdee3d2XvphfGafPT6zuyHxZiPx +SEczszs758z5zf85zzlzzjLP81AvxhhjABgAFYAGwASQALB0y5Ytr/X09DxUy/KsXr164tixY38D +4DSASQA5AAUADgDXq6PK0250ASoYryiPMZaPxWI1zdwwjAIpQ11bvYME/Ip0Pc/LR6PRmmas67oz +l3/dw7wZQAKA53meVWtFaprGQda93SwgmWEYZq0VqWmaBr/Nrnu7WUCqpmnGa61IVVU1AApuApg3 +A0gFADNNM1brIFHXdQ6y7q3eQXIlqJFIJKoota1TwzBU/KLIn21M2AKAouu66TdZtTNd11X4fVpa +prqEWo8gRWPwFWn64wW1M0VRqCLrEiC3egUpKkCJRCJGrRXJGBMVGXw1l+qma1KvILkFQ3bRaNTQ +db3W+auKoiiu60rVyBhj9TJMV88gqSrVaDSqm6ZZk4wJG7Zs2bL0uXPn6t691jNIYM6tAlBjsVhN +QIoCa2lpSZ07d04MeOrO6h0k4FecnkqlogvdRnKInucF+x0dHbceP37cQJ13Q+oRJBOSvmzZssam +pqaY4zgLmjGH5zgOXNcFACxfvnwFgAj8oIeWr66sbkCSd5EACXIA6I899tiv4vE4C+t+yOINqq5q +zfM8uK6LQqEA/tAsWrToFhRB0hGJX6LWMkaVqABQNU2LZzKZ2xKJBBhjKNeXlEHjyuLbSr+1bRuK +osCyLDDG0NTU1AogBYC7V+pi6wbmDQUpSIwCVOArwDBNs2HNmjVrkskkFEUBY6xqlVGIYW6ZKtdx +HCiKAsdxYNs2GGNob29vXbt2bUdPT08/AB3+DAEFc+9J6T3cyK5IzUCG+MV5Hf+5pMFXQMOjjz66 +vqOj45ZCoQBVVfm1AMxXoOzY8zzYtg3XdUuCGHo+P6dQKMC27SAPRVGgKIr6/PPP//a5557rATAN +wMZ8FXq0XEIZagKXLUQ+FaDRfbrlAHUAUQBNGzZsWHfw4MF3ADRxNdJLh5WdAuNqtG07+JwGNTwV +CgXkcjnkcjnMzMzAsiwoioJoNIp4PJ5799133/noo48+A3ARPtA8fKjOXALI1BRaHEn5rnulXxeQ +EnCVoAHFtoa7UX0uJXVdb37ttdf+8sUXX/z7fD5v5PP5wK3KLEyZHFqhUEChUAhUSeEVCgXk83lY +loVcLhfsc9dqGAbi8Tiam5udw4cPf7Rnz55/BTAE4DKAWQAWfHfrojgthO9DshX3rwvYawIpaePE +bRg0mkwApq7ryebm5sb33nvvmQ0bNjyUTqfTk5OTQbulKIo0EqVBjOg6AQRqtCwr2OdJBMjBOo4D +z/PAGIOqqtB1HZFIBM3NzbAsa7y3t/ebvXv3fvjjjz9ehD+7LovSGXYOfLW6cwkoDzco9M+FetUg +y8Cj7Zw4rZFvDfhuM5bJZBpeeumlLWvXrl2/ePHiVel0+pZUKpV0XVeZmZnB7OxsUPG8cnlbR10i +T7ZtB/0/sR3kbR/9LVcm/5wab4s1TQNjDJqmBUBTqRRSqRQikYg9Ozs7ns1mh8bGxvr7+/tPHTx4 +8MTJkydHUAQ7i1K4PFHVSqFeLdCqQRKAYfAU+K5RQ3FOagRAPJPJpHfu3Hnf2rVrNyxZsuSOhoaG +xbquJ23bZlwNoipyuVwJABEOj1553090p/wc13VhWVbwMFD3yn8rBkL02PM8qKoKwzAQjUaRTCYR +iUQQiUQQi8UQi8UQjUYRi8VgGIbnOM7U1NTUyOjo6Nn+/v6eTz/99PdffPHFHwHMwAebg6/WAkrb +WA9ysFVBrQiyAkDatkUBJA3DaNi1a9e9GzZs2JjJZFan0+lb4/F4Yy6XU2ZnZ5HNZoOKpSaCop3z +mZmZQDW0gsPgUsgAgodB7FPyPMRyUJCMMZimiWg0CkVRoKpq4HK5Wvnnuq4HAVIsFgtg5/P5KxMT +E4MjIyN9fX19PYcOHfp9V1fXRQBT8AMnDtdBqVJLpmKWAxoKsgxA3rbpKM4Eb9q/f/9v77///r9q +aWlZZtu2Nj09HUCjTz25vjRfmfosy8L09LS0PaT9Sn5M21OgdMiNnkevIV6XKjEejwfulv6e58X3 +xc8ABJA1TQvARqNRTE1NjfX29n799ttv/9vRo0f74Le1s/CjYZlKy7pcKUgBogjQgO8yG+66665l +r7/++tPr1q17MBqNNnJ4NNSnxo+r6QfS33uehytXrsxTMSnvPCDU+IMkAhMHF2SDDel0GoZhSB8Y +bnQuEQUqKydXcyQSQSKRgKIo9tmzZ7/77LPPPty7d+9/ARhHsXvD29eKQJlwIzKADL76DABxAE3b +t2//1fbt259etWrVZtu2jWw2i0KhEDq+WanSyvUH+Xm8fydTEa0kmcIA+RBdpQdL0zQ0NjYGChfd +t2j8O3GSWNi5gB9YxWIxmKaJsbGxga6urs9279790aVLl/4E4ApKA6aSAInCZORmZKMs3IXGALS8 +8sorDz788MM7li5deqdlWWxmZiYIGnhF0Mq5msCrXOUAgGVZmJqakgKRQaVGf1NpQIHeSyQSQSqV +KgEdMnoz72Go9BuxPIqiIBKJIBqNYnZ2drq7u/vwrl273hkYGLiA4gIi2qUpgcnmMpJB5JFnevny +5bft37//d+vXr/+N4zgsl8sF7lOsEAqwHEzx5sQKEM22bUxOTs47r5Jblbn4sPPEe0gkEohEIoEi +RTjida/24RWNu13TNKHrOiYmJkY/+OCDf3rrrbf+A8Al+JGvBSEg8jzPE18d8T5goMKdO3c+9Oyz +z/6uoaGhlY6QyCpgIc3zPExOTlZ8i8FNFsDQ76qI1pFIJGCa5nW/x0rumTEGXdcxN0fJO3HixJGn +n376jbGxsfPwI10eEAUwxbaQBzQJAG27d+/+62eeeeYfVFXVaJ+OW1jUKFo5VcrUK2tPXdfF9PR0 +8BYjTIEypfMyV1M2fqwoChKJBOiEr0puUrxONS5Vdi6Nfg3DgKIo6O/v/8Pjjz++c3BwkEe4FKZL +VcjdaQzA4jfffPOZJ5988m8ZYwp9K1ApQBErRFZ4WTdEFqSIx9lstmT4TLxxMS8xCr6a8rqui1Qq +BT69pNzvK7WL1UCl59CtoihB/3RgYKDviSeeeOHMmTPfw4fJ3azLVcjgQ4wAaH3hhRceefXVV/+R +Mcb4uGTYkytr6GWFFAsY1gcr19bNzs6WdEGqVcfVGi9vMpmcd29hY7uy951h7X41YGUwGWPo7u4+ +tnXr1r8DMADfzdoAHO5K+fBaorW1deW+ffveSiQSCT6yUq5PWM54461pWuDzdV0PjlVVhaqqwaC4 +DCpNXI21aJcVRYFpmkG5eBl5mXnSNK0kifcChAdHYl3JjN6voihoa2vLGIYx/s0335yGH8k6QDGw +UeEPsd3y/vvvv7Zt27bHAAQD1mGVJ3vi+M3SG7pexqPlagOeazE+EnMtC4eo1+KDEmJ3rVyXi+7z +9pIxhrGxsfE1a9Y8AqAPvioLfCEnH7Fp6Ozs/DMKiAcaYTBFcDTzWqlnIe16PTRU0Z5XfCcqXp/X +twwmr8t0Ot3061//evXRo0cvwO+SOBykAkCPRqONS5YsydALcXfBYYrtnCyjhYJXCyVyo9HuQhh/ ++OkMBplRt86F4XketmzZsu7o0aNfw49tChSk6jiOwRhTxKiSXyzMaqW6Sp3/6221aot5/XKo4kgU +fx/KyzSnaP7WSQHAOEgGAJZl5QcHBy93dna2iAPB9Gm4USa+GVnovGrpAXhgqKpqcJ+KogQvt4HS +tvbUqVPDKL7iYnQWnQtg5sSJE70dHR1/zp/8sE70jQJaS/XXEqSYN3/fCZQ2WY7jYHBwcOrIkSP/ +B39QAEBxOqQHP4yd2rdv378/8MADGxsaGgxZ1CmO5NQSaK0rttaKBFASNAKl70e5Gj/55JOv8/n8 +JRQHBErm1KgAlMnJSXdqaiq6cePGO1RVZTJFin2kWiWeXy1MfFgX8p5oQCMbI+ZKdF0XR44c6Xvj +jTfec133PPzXXBaEAQE+VOedOnVqZHh4WN28efNKXddLohzZ0FitolYxz4VOC3kPfEu7b7IRIKrE +zz///IedO3fudxznNICfQN5V0qXVHKQLwD59+vTwhQsXsGnTppWGYShiBmLBRJdAC/JLKtYXByb2 +vcMA8q7JoUOHTr/88sv/7HleL4BR+AMBFubeUYp/dsCTA8A6c+bM8Pnz5+01a9asSCQSughQLCSH +SsdRxfNudIXWGhytj3IjXhQenbY5MzPjffjhhz179uz5F/gjOSOYPxXEoa+u+HR9Po0xBqAJQCaZ +TN65Y8eObY888sjdLS0tOnUFsmBILCBQ7DrIJmKJD8PNaLIXAuL4sWhiHVAVWpaFr7766sKBAwf+ +s6en53/gD5JzJfJJWoW55HCXyqd1iDCjAJIAWgG0t7W1rd6xY8dfbNu2bWUqlVJlA8Q/B6yoWG43 +KvwPMxGI7C2OOExJLcyj0Qfctm10dXWNHDhw4Ouurq7/hr/W5BL8JQp84rOFolu1IXkfSWEaKM6Y +i8FfI9gMoH3FihXrnnrqqd9s2bJlWUtLi8aBXg3UsCE+0b3IZiOIbvp6WFi5qaJE18ihyZoOscyy +cvP75JOov/vuu7GPP/742yNHjnwFH+AoiksSuAr5WhM6IcsV20YKkwI15xIH2gRgUTKZ7HjwwQc3 +3nfffSvvvffeRclkUhGh0ooJe5plLojvi20PvXmarsXogLbsoRTLQmGI5ZJ5F7qlD6lt2/j+++8n +jx079uPhw4f/t7+//w/w28Ax+Aqcga9A7ka5CksgAvDo5CsRJlUnT1yhEfjTQVIA0gCa29raVmzd +unX95s2bO++5557mSCTCxHd5FKb4HXVR4jYMsvhgiCYLOsqdIwYrsiBGBCZr+2kMIH5u2zb6+/tn +vv3223Nffvllz8mTJ0/NgZuYg0fbQK4+6kbpjPRgNl25WXQiUArVwPzAKAmgEUBjR0fHHZs2bVq9 +cuXKJZ2dna2dnZ1x0zRLwPEhKKqAaqCKcMu9kBYBV4qcxTUfMkgyryCLNvnntm1jaGjI6uvr++nM +mTPD3d3dZ48fP96Nouom4SuPz5DjAOn6EBnAkimR5ea1UnXy+TwUquh+aXuamAObANDQ3t6+fP36 +9SvvvPPOW1asWLFo1apVqVQqxUSXxkf5RaC07yULLq6mU18NxDCV0SRbHeZ5HvL5PPr7+7Nz4P7U +3d39Y29v7xn4HfjpOcVNwW/38igux+PgKDxxFRcFOH9eKzUBKA2EZGsbZXCpaoMVWXNQYwCSiURi +yd133925dOnSlkwm07R48eKG9vb25NKlS6PJZJKJ0ynEKRaydqya+T8yRYoq5GoSl+1xt8i/y+Vy +GBoayl+8eDE7PDw8OTQ0dHlgYGD0hx9++OPQ0NB5FIOUaRQVx9VGXSVv7yrBExf3BBClICUwRYVS +lYpgRcgctNjGRoVtBEA8Eok03X777bfedtttizKZTHNra2sqmUxGUqmUmU6njebmZiORSCimaZZA +raRSCg8oXTYnLq/jfbhcLuf99NNP9sTEhHXlypX85OTk7OXLl7ODg4Pj586dGzt79uzF8fHxYRTb +NB6UzJJEI0zRRZZLIrzQpQJlQQowywGlSYVcuTQS5i6aQqbumUPlauZtsQ4gyhiLNzc3N7a1tTW1 +trYmW1paEslkMmaapqbrumaapmYYhqZpmmKapqZpmmIYhsoYY7ZtO5ZluYVCwbEsy7Ysy7Esyy4U +CnY+n7ez2Wx+fHw8Ozo6OjU6OjoxMjIyVigUsii2XRwKV1WeJNod4CpzJdBcyT7disqbt8pZBrEs +yCqBytxvOcAiaPEcDfODLLqMjy+k1YVzaBnEcvEkVhBQ/BMHWtm2JImLUkVI5aCIx/QzD+HKqwog +t5+zYhkgswoQDpXCDQMtfs6HDJnkWHYNERgw/9+pRKMVJCYRNq90WYXL3F+lz8XrhKWgnJUABjd6 +tSMjEqDiNkyxYfvVqCnsmOZJyyHui+aV2cqUEQZa3JcpK2xfzJOWo2qAwc1eyxBXlVDpfqUkexMj +JvF6srzFfWpemX1ZBVebyqks7PolZbhaeNSu2x8msfmdtrBKrgSkGmg/B6BoMqBhKgmDK34WdhyW +3zXBo7Yg/3wFlAVL96/XVtyX5Rt2o+UUKm7LueRKvy9+sQCVvmAg52UkG2YJB1HNfjXHlUy8+XLH +1ezLjhcEnGj/D+qqkk1i4uhuAAAAAElFTkSuQmCC +" + width="114" + height="64" + id="base" + x="46" + y="136" /> + <g + id="Livello_1" + transform="matrix(0.5,0,0,0.5,189,14.867)" /> + <g + id="g3312" + transform="matrix(0.875,0,0,0.8703703,318.74998,21.953671)" /> + <rect + style="opacity:0.875;fill:#008000;fill-opacity:1;stroke:none;stroke-width:0;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="hint-stretch-borders" + width="5" + height="4.375" + x="0" + y="0" /> + <rect + y="19" + x="25.999969" + height="116" + width="152" + id="center" + style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.30000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + <g + transform="translate(815,257)" + id="topleft"> + <path + style="fill:url(#radialGradient4673);fill-opacity:1;stroke:none;stroke-width:0.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M -799,-249 C -803.43882,-249 -807,-245.43881 -807,-241 L -807,-238 L -789,-238 L -789,-249 L -799,-249 z" + id="rect3383" /> + <path + style="fill:url(#linearGradient4675);fill-opacity:1;stroke:none;stroke-width:0.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M -799.0625,-248 C -802.91371,-248 -806,-244.91371 -806,-241.0625 L -806,-238 L -789,-238 L -789,-248 L -799.0625,-248 z" + id="rect3311" /> + <path + style="fill:url(#linearGradient4677);fill-opacity:1;stroke:none;stroke-width:0.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M -798.96875,-245 C -801.20404,-245 -803,-243.20404 -803,-240.96875 L -803,-238 L -789,-238 L -789,-245 L -798.96875,-245 z" + id="rect3271" /> + <path + style="fill:url(#linearGradient4679);fill-opacity:1;stroke:none;stroke-width:0.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M -798.96875,-244.96875 C -801.20403,-244.96875 -803,-243.17279 -803,-240.9375 L -803,-238 C -802.96755,-240.22473 -801.1836,-242.96875 -798.96875,-242.96875 L -789,-242.96875 L -789,-244.96875 L -798.96875,-244.96875 z" + id="rect3298" /> + <path + style="fill:url(#linearGradient4681);fill-opacity:1;stroke:none;stroke-width:0.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M -798.96875,-245 C -801.20403,-245 -803,-243.20404 -803,-240.96875 L -803,-238 L -802,-238 L -802,-241 C -801.99999,-242.66397 -800.66398,-244 -799,-244 L -789,-244 L -789,-245 L -798.96875,-245 z" + id="rect3401" /> + <path + style="fill:url(#linearGradient4683);fill-opacity:1;stroke:none;stroke-width:1.29999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M -798.96875,-245 C -801.20403,-245 -803,-243.20404 -803,-240.96875 L -803,-238 L -789,-238 L -789,-245 L -798.96875,-245 z" + id="path3420" /> + <path + style="opacity:0.70720712;fill:url(#radialGradient4685);fill-opacity:1;stroke:none;stroke-width:0.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M -789,-240 C -790.10256,-239.98303 -790.98303,-239.10256 -791,-238 L -789,-238 L -789,-240 z" + id="rect3281" /> + <path + style="opacity:0.70720712;fill:url(#radialGradient4687);fill-opacity:1;stroke:none;stroke-width:0.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M -789,-240 C -790.10256,-239.98303 -790.98303,-239.10256 -791,-238 L -789,-238 L -789,-240 z" + id="rect5414" /> + <path + style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M -789,-239 C -789.557,-239 -790,-238.557 -790,-238 L -789,-238 L -789,-239 z" + id="rect3267" /> + </g> + <g + transform="translate(815,257)" + id="left"> + <path + style="fill:url(#radialGradient4659);fill-opacity:1;stroke:none;stroke-width:0.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M -807,-238 L -807,-122 L -789,-122 L -789,-238 L -807,-238 z" + id="rect5818" /> + <path + style="fill:url(#linearGradient4661);fill-opacity:1;stroke:none;stroke-width:0.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M -806,-238 L -806,-122 L -789,-122 L -789,-238 L -806,-238 z" + id="rect5820" /> + <path + style="fill:url(#linearGradient4663);fill-opacity:1;stroke:none;stroke-width:0.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M -803,-238 L -803,-122 L -789,-122 L -789,-238 L -803,-238 z" + id="rect5822" /> + <path + style="fill:url(#linearGradient4665);fill-opacity:1;stroke:none;stroke-width:0.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M -803,-238 L -803,-122 L -802,-122 L -802,-238 L -803,-238 z" + id="path5826" /> + <path + style="fill:url(#linearGradient4667);fill-opacity:1;stroke:none;stroke-width:1.29999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M -803,-238 L -803,-173.74663 C -798.42875,-173.13725 -793.73899,-172.59019 -789,-172.08949 L -789,-238 L -803,-238 z" + id="path5828" /> + <path + style="opacity:0.70720712;fill:url(#radialGradient4669);fill-opacity:1;stroke:none;stroke-width:0.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M -791,-238 C -791.00017,-237.98925 -791,-237.97953 -791,-237.96873 L -791,-122 L -789,-122 L -789,-238 L -791,-238 z" + id="rect5830" /> + <path + style="opacity:0.70720712;fill:url(#radialGradient4671);fill-opacity:1;stroke:none;stroke-width:0.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M -791,-238 C -791.00017,-237.98925 -791,-237.97953 -791,-237.96873 L -791,-122 L -789,-122 L -789,-238 L -791,-238 z" + id="rect5832" /> + <path + style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M -790,-238 L -790,-122 L -789,-122 L -789,-238 L -790,-238 z" + id="rect5834" /> + </g> + <g + transform="translate(815,257)" + id="bottomleft"> + <path + style="fill:url(#radialGradient4647);fill-opacity:1;stroke:none;stroke-width:0.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M -807,-122 L -807,-119 C -807,-114.56118 -803.43884,-111 -799,-111 L -789,-111 L -789,-122 L -807,-122 z" + id="rect5938" /> + <path + style="fill:url(#linearGradient4649);fill-opacity:1;stroke:none;stroke-width:0.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M -806,-122 L -806,-118.9375 C -806,-115.08629 -802.91373,-112 -799.0625,-112 L -789,-112 L -789,-122 L -806,-122 z" + id="rect5940" /> + <path + style="fill:url(#linearGradient4651);fill-opacity:1;stroke:none;stroke-width:0.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M -803,-122 L -803,-119.03125 C -803,-116.79596 -801.20407,-115 -798.96875,-115 L -789,-115 L -789,-122 L -803,-122 z" + id="rect5942" /> + <path + style="fill:url(#linearGradient4653);fill-opacity:1;stroke:none;stroke-width:0.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M -803,-122 L -803,-119.03125 C -802.99999,-116.79595 -801.20404,-115 -798.96875,-115 L -789,-115 L -789,-116 L -799,-116 C -800.66397,-116 -802,-117.33601 -802,-119 L -802,-122 L -803,-122 z" + id="path5946" /> + <path + style="opacity:0.70720712;fill:url(#radialGradient4655);fill-opacity:1;stroke:none;stroke-width:0.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M -791,-122 C -790.98303,-120.89744 -790.10257,-120.01697 -789,-120 L -789,-122 L -791,-122 z" + id="rect5950" /> + <path + style="opacity:0.70720712;fill:url(#radialGradient4657);fill-opacity:1;stroke:none;stroke-width:0.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M -791,-122 C -790.98303,-120.89744 -790.10257,-120.01697 -789,-120 L -789,-122 L -791,-122 z" + id="rect5952" /> + <path + style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M -790,-122 C -790,-121.443 -789.55702,-121 -789,-121 L -789,-122 L -790,-122 z" + id="rect5954" /> + </g> + <g + id="top"> + <path + style="fill:url(#radialGradient4712);fill-opacity:1;stroke:none;stroke-width:0.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M 26,8 L 26,19 L 178,19 L 178,8 L 26,8 z" + id="rect6094" /> + <path + style="fill:url(#linearGradient4709);fill-opacity:1;stroke:none;stroke-width:0.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M 26,9 L 26,19 L 178,19 L 178,9 L 26,9 z" + id="rect6096" /> + <path + style="fill:url(#linearGradient4706);fill-opacity:1;stroke:none;stroke-width:0.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M 26,12 L 26,19 L 178,19 L 178,12 L 26,12 z" + id="rect6098" /> + <path + style="fill:url(#linearGradient4703);fill-opacity:1;stroke:none;stroke-width:0.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M 26,12.03125 L 26,14.03125 L 178,14.03125 L 178,12.03125 L 26,12.03125 z" + id="path6100" /> + <path + style="fill:url(#linearGradient4700);fill-opacity:1;stroke:none;stroke-width:0.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M 26,12 L 26,13 L 178,13 L 178,12 L 26,12 z" + id="path6102" /> + <path + style="fill:url(#linearGradient4697);fill-opacity:1;stroke:none;stroke-width:1.29999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M 26,12 L 26,19 L 178,19 L 178,12 L 26,12 z" + id="path6104" /> + <path + style="opacity:0.70720712;fill:url(#radialGradient4694);fill-opacity:1;stroke:none;stroke-width:0.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M 26,17 L 26,19 L 178,19 L 178,17 C 177.98926,16.99983 177.97954,17 177.96875,17 L 26.03125,17 C 26.02046,17 26.01074,16.99983 26,17 z" + id="rect6106" /> + <path + style="opacity:0.70720712;fill:url(#radialGradient4691);fill-opacity:1;stroke:none;stroke-width:0.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M 26,17 L 26,19 L 178,19 L 178,17 C 177.98926,16.99983 177.97954,17 177.96875,17 L 26.03125,17 C 26.02046,17 26.01074,16.99983 26,17 z" + id="rect6108" /> + <path + style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M 26,18 L 26,19 L 178,19 L 178,18 L 26,18 z" + id="rect6110" /> + </g> + <g + transform="translate(815,257)" + id="bottom"> + <path + style="fill:url(#radialGradient4619);fill-opacity:1;stroke:none;stroke-width:0.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M -789,-122 L -789,-111 L -637,-111 L -637,-122 L -789,-122 z" + id="rect6215" /> + <path + style="fill:url(#linearGradient4621);fill-opacity:1;stroke:none;stroke-width:0.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M -789,-122 L -789,-112 L -637,-112 L -637,-122 L -789,-122 z" + id="rect6217" /> + <path + style="fill:url(#linearGradient4623);fill-opacity:1;stroke:none;stroke-width:0.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M -789,-122 L -789,-115 L -637,-115 L -637,-122 L -789,-122 z" + id="rect6219" /> + <path + style="fill:url(#linearGradient4625);fill-opacity:1;stroke:none;stroke-width:0.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M -789,-116 L -789,-115 L -637,-115 L -637,-116 L -789,-116 z" + id="path6223" /> + <path + style="opacity:0.70720712;fill:url(#radialGradient4627);fill-opacity:1;stroke:none;stroke-width:0.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M -789,-122 L -789,-120 C -788.98926,-119.99983 -788.97954,-120 -788.96875,-120 L -637.03125,-120 C -637.02046,-120 -637.01074,-119.99983 -637,-120 L -637,-122 L -789,-122 z" + id="rect6227" /> + <path + style="opacity:0.70720712;fill:url(#radialGradient4629);fill-opacity:1;stroke:none;stroke-width:0.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M -789,-122 L -789,-120 C -788.98926,-119.99983 -788.97954,-120 -788.96875,-120 L -637.03125,-120 C -637.02046,-120 -637.01074,-119.99983 -637,-120 L -637,-122 L -789,-122 z" + id="rect6229" /> + <path + style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M -789,-122 L -789,-121 L -637,-121 L -637,-122 L -789,-122 z" + id="rect6231" /> + </g> + <g + transform="translate(815,257)" + id="topright"> + <path + style="fill:url(#radialGradient4603);fill-opacity:1;stroke:none;stroke-width:0.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M -637,-249 L -637,-238 L -619,-238 L -619,-241 C -619,-245.43882 -622.56119,-249 -627,-249 L -637,-249 z" + id="rect6708" /> + <path + style="fill:url(#linearGradient4605);fill-opacity:1;stroke:none;stroke-width:0.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M -637,-248 L -637,-238 L -620,-238 L -620,-241.0625 C -620,-244.91371 -623.0863,-248 -626.9375,-248 L -637,-248 z" + id="rect6710" /> + <path + style="fill:url(#linearGradient4607);fill-opacity:1;stroke:none;stroke-width:0.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M -637,-245 L -637,-238 L -623,-238 L -623,-240.96875 C -623,-243.20404 -624.79596,-245 -627.03125,-245 L -637,-245 z" + id="rect6712" /> + <path + style="fill:url(#linearGradient4609);fill-opacity:1;stroke:none;stroke-width:0.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M -637,-244.96875 L -637,-242.96875 L -627.03125,-242.96875 C -624.81639,-242.96875 -623.03244,-240.22473 -623,-238 L -623,-240.9375 C -622.99999,-243.17279 -624.79596,-244.96875 -627.03125,-244.96875 L -637,-244.96875 z" + id="path6714" /> + <path + style="fill:url(#linearGradient4611);fill-opacity:1;stroke:none;stroke-width:0.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M -637,-245 L -637,-244 L -627,-244 C -625.33602,-244 -624,-242.66398 -624,-241 L -624,-238 L -623,-238 L -623,-240.96875 C -622.99999,-243.20404 -624.79596,-245 -627.03125,-245 L -637,-245 z" + id="path6716" /> + <path + style="fill:url(#linearGradient4613);fill-opacity:1;stroke:none;stroke-width:1.29999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M -637,-245 L -637,-238 L -623,-238 L -623,-240.96875 C -622.99999,-243.20404 -624.79596,-245 -627.03125,-245 L -637,-245 z" + id="path6718" /> + <path + style="opacity:0.70720712;fill:url(#radialGradient4615);fill-opacity:1;stroke:none;stroke-width:0.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M -637,-240 L -637,-238 L -635,-238 C -635.01697,-239.10256 -635.89743,-239.98303 -637,-240 z" + id="rect6720" /> + <path + style="opacity:0.70720712;fill:url(#radialGradient4617);fill-opacity:1;stroke:none;stroke-width:0.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M -637,-240 L -637,-238 L -635,-238 C -635.01697,-239.10256 -635.89743,-239.98303 -637,-240 z" + id="rect6722" /> + <path + style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M -637,-239 L -637,-238 L -636,-238 C -636,-238.557 -636.44298,-239 -637,-239 z" + id="rect6724" /> + </g> + <g + transform="translate(815,257)" + id="right"> + <path + style="fill:url(#radialGradient4589);fill-opacity:1;stroke:none;stroke-width:0.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M -637,-238 L -637,-122 L -619,-122 L -619,-238 L -637,-238 z" + id="rect6907" /> + <path + style="fill:url(#linearGradient4591);fill-opacity:1;stroke:none;stroke-width:0.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M -637,-238 L -637,-122 L -620,-122 L -620,-238 L -637,-238 z" + id="rect6909" /> + <path + style="fill:url(#linearGradient4593);fill-opacity:1;stroke:none;stroke-width:0.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M -637,-238 L -637,-122 L -623,-122 L -623,-238 L -637,-238 z" + id="rect6911" /> + <path + style="fill:url(#linearGradient4595);fill-opacity:1;stroke:none;stroke-width:0.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M -624,-238 L -624,-122 L -623,-122 L -623,-238 L -624,-238 z" + id="path6915" /> + <path + style="opacity:0.70720712;fill:url(#radialGradient4597);fill-opacity:1;stroke:none;stroke-width:0.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M -637,-238 L -637,-122 L -635,-122 C -634.99983,-122.01074 -635,-122.02046 -635,-122.03125 L -635,-237.96875 C -635,-237.97954 -634.99983,-237.98926 -635,-238 L -637,-238 z" + id="rect6919" /> + <path + style="opacity:0.70720712;fill:url(#radialGradient4599);fill-opacity:1;stroke:none;stroke-width:0.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M -637,-238 L -637,-122 L -635,-122 C -634.99983,-122.01074 -635,-122.02046 -635,-122.03125 L -635,-237.96875 C -635,-237.97954 -634.99983,-237.98926 -635,-238 L -637,-238 z" + id="rect6921" /> + <path + style="opacity:1;fill:url(#linearGradient4601);fill-opacity:1;stroke:none;stroke-width:0.30000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M -637,-238 L -637,-175.59375 C -632.22086,-176.35687 -627.54532,-177.18419 -623,-178.0625 L -623,-238 L -637,-238 z" + id="rect6903" /> + <path + style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M -637,-238 L -637,-122 L -636,-122 L -636,-238 L -637,-238 z" + id="rect6923" /> + </g> + <g + transform="translate(815,257)" + id="bottomright"> + <path + style="fill:url(#radialGradient4577);fill-opacity:1;stroke:none;stroke-width:0.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M -637,-121.99923 L -637,-110.99923 L -627,-110.99923 C -622.56118,-110.99923 -619,-114.56041 -619,-118.99923 L -619,-121.99923 L -637,-121.99923 z" + id="rect7118" /> + <path + style="fill:url(#linearGradient4579);fill-opacity:1;stroke:none;stroke-width:0.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M -637,-121.99923 L -637,-111.99923 L -626.9375,-111.99923 C -623.08629,-111.99923 -620,-115.08552 -620,-118.93673 L -620,-121.99923 L -637,-121.99923 z" + id="rect7120" /> + <path + style="fill:url(#linearGradient4581);fill-opacity:1;stroke:none;stroke-width:0.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M -637,-121.99923 L -637,-114.99923 L -627.03125,-114.99923 C -624.79596,-114.99923 -623,-116.79518 -623,-119.03048 L -623,-121.99923 L -637,-121.99923 z" + id="rect7122" /> + <path + style="fill:url(#linearGradient4583);fill-opacity:1;stroke:none;stroke-width:0.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M -624,-121.99923 L -624,-118.99923 C -623.99999,-117.33524 -625.33602,-115.99923 -627,-115.99923 L -637,-115.99923 L -637,-114.99923 L -627.03125,-114.99923 C -624.79595,-114.99923 -623,-116.79518 -623,-119.03048 L -623,-121.99923 L -624,-121.99923 z" + id="path7126" /> + <path + style="opacity:0.70720712;fill:url(#radialGradient4585);fill-opacity:1;stroke:none;stroke-width:0.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M -637,-121.99923 L -637,-119.99923 C -635.89744,-120.0162 -635.01697,-120.89667 -635,-121.99923 L -637,-121.99923 z" + id="rect7130" /> + <path + style="opacity:0.70720712;fill:url(#radialGradient4587);fill-opacity:1;stroke:none;stroke-width:0.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M -637,-121.99923 L -637,-119.99923 C -635.89744,-120.0162 -635.01697,-120.89667 -635,-121.99923 L -637,-121.99923 z" + id="rect7132" /> + <path + style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M -637,-121.99923 L -637,-120.99923 C -636.443,-120.99923 -636,-121.44223 -636,-121.99923 L -637,-121.99923 z" + id="rect7134" /> + </g> + <g + transform="translate(607,257)" + id="glass"> + <rect + y="-238" + x="-581" + height="116" + width="152" + id="rect7704" + style="opacity:1;fill:url(#linearGradient4573);fill-opacity:1;stroke:none;stroke-width:0.30000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + <path + sodipodi:nodetypes="cccc" + id="path5718" + d="M -581,-238 L -429,-238 L -581,-122 L -581,-238 z" + style="fill:url(#linearGradient4575);fill-opacity:1;stroke:none;stroke-width:0.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1" /> + </g> +</svg> --- desktoptheme/widgets/containment-controls.svg +++ desktoptheme/widgets/containment-controls.svg @@ -2,7 +2,7 @@ <!-- Created with Inkscape (http://www.inkscape.org/) --> <svg xmlns:dc="http://purl.org/dc/elements/1.1/" - xmlns:cc="http://web.resource.org/cc/" + xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" @@ -13,11 +13,11 @@ height="128" id="svg2" sodipodi:version="0.32" - inkscape:version="0.45.1" + inkscape:version="0.46" version="1.0" sodipodi:docbase="/opt/svn/kdebase/workspace/plasma/desktoptheme/widgets" - sodipodi:docname="containment-controls.svg" - inkscape:output_extension="org.inkscape.output.svg.inkscape" + sodipodi:docname="containment-controls.svgz" + inkscape:output_extension="org.inkscape.output.svgz.inkscape" inkscape:export-filename="arrow-up.png" inkscape:export-xdpi="11.25" inkscape:export-ydpi="11.25"> @@ -35,2547 +35,562 @@ id="stop3582" /> </linearGradient> <linearGradient - id="linearGradient8162"> - <stop - id="stop8164" - offset="0" - style="stop-color:#c5c5c5;stop-opacity:1;" /> - <stop - id="stop8166" - offset="1" - style="stop-color:#ffffff;stop-opacity:0;" /> - </linearGradient> - <linearGradient - id="linearGradient8156"> - <stop - id="stop8158" - offset="0" - style="stop-color:#dcdcdc;stop-opacity:1;" /> - <stop - id="stop8160" - offset="1" - style="stop-color:#ffffff;stop-opacity:0;" /> - </linearGradient> - <linearGradient - id="linearGradient8150"> - <stop - id="stop8152" - offset="0" - style="stop-color:#e3e3e3;stop-opacity:1;" /> - <stop - id="stop8154" - offset="1" - style="stop-color:#8f8f8f;stop-opacity:1;" /> - </linearGradient> - <linearGradient - id="linearGradient8144"> - <stop - id="stop8146" - offset="0" - style="stop-color:#cfcfcf;stop-opacity:1;" /> - <stop - id="stop8148" - offset="1" - style="stop-color:#ffffff;stop-opacity:1;" /> - </linearGradient> - <linearGradient - id="linearGradient8138"> - <stop - style="stop-color:#f0f0f0;stop-opacity:1;" - offset="0" - id="stop8140" /> - <stop - style="stop-color:#ffffff;stop-opacity:0;" - offset="1" - id="stop8142" /> - </linearGradient> - <linearGradient - id="linearGradient8132"> - <stop - id="stop8134" - offset="0" - style="stop-color:#787878;stop-opacity:1;" /> - <stop - id="stop8136" - offset="1" - style="stop-color:#ffffff;stop-opacity:0;" /> - </linearGradient> - <linearGradient - id="linearGradient8126"> - <stop - style="stop-color:#ffffff;stop-opacity:1;" - offset="0" - id="stop8128" /> - <stop - style="stop-color:#e1e1e1;stop-opacity:1;" - offset="1" - id="stop8130" /> - </linearGradient> - <linearGradient - id="linearGradient7151"> - <stop - id="stop7153" - offset="0" - style="stop-color:#a8c1ff;stop-opacity:1;" /> - <stop - id="stop7155" - offset="1" - style="stop-color:#b8ddff;stop-opacity:0;" /> - </linearGradient> - <linearGradient - id="linearGradient7145"> - <stop - id="stop7147" - offset="0" - style="stop-color:#c2e2ff;stop-opacity:1;" /> - <stop - id="stop7149" - offset="1" - style="stop-color:#80bbff;stop-opacity:0;" /> - </linearGradient> - <linearGradient - id="linearGradient7139"> - <stop - style="stop-color:#80c2ff;stop-opacity:1;" - offset="0" - id="stop7141" /> - <stop - style="stop-color:#80bbff;stop-opacity:0;" - offset="1" - id="stop7143" /> - </linearGradient> - <linearGradient - id="linearGradient7133"> - <stop - id="stop7135" - offset="0" - style="stop-color:#03002a;stop-opacity:1;" /> - <stop - id="stop7137" - offset="1" - style="stop-color:#00002a;stop-opacity:0;" /> - </linearGradient> - <linearGradient - inkscape:collect="always" - id="linearGradient3710"> - <stop - style="stop-color:#ffffff;stop-opacity:1;" - offset="0" - id="stop3712" /> - <stop - style="stop-color:#ffffff;stop-opacity:0;" - offset="1" - id="stop3714" /> - </linearGradient> - <linearGradient - id="linearGradient3689" + id="linearGradient3272" inkscape:collect="always"> <stop - id="stop3691" + id="stop3274" offset="0" - style="stop-color:#f0ff80;stop-opacity:1" /> + style="stop-color:white;stop-opacity:1;" /> <stop - id="stop3693" + id="stop3276" offset="1" - style="stop-color:#f0ff80;stop-opacity:0" /> + style="stop-color:white;stop-opacity:0;" /> </linearGradient> - <linearGradient + <radialGradient inkscape:collect="always" - id="linearGradient3669"> - <stop - style="stop-color:#ffffff;stop-opacity:1;" - offset="0" - id="stop3671" /> - <stop - style="stop-color:#ffffff;stop-opacity:0;" - offset="1" - id="stop3673" /> - </linearGradient> - <linearGradient + xlink:href="#linearGradient3272" + id="radialGradient3608" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(1.8125,0,0,2.2075201,-143.20779,-217.90313)" + cx="88" + cy="93.5" + fx="88" + fy="93.5" + r="8" /> + <radialGradient inkscape:collect="always" - id="linearGradient3511"> - <stop - style="stop-color:#002a0d;stop-opacity:1;" - offset="0" - id="stop3513" /> - <stop - style="stop-color:#002a0d;stop-opacity:0;" - offset="1" - id="stop3515" /> - </linearGradient> - <linearGradient - id="linearGradient3503" - inkscape:collect="always"> - <stop - id="stop3505" - offset="0" - style="stop-color:#005f1e;stop-opacity:1" /> - <stop - id="stop3507" - offset="1" - style="stop-color:#43943c;stop-opacity:1" /> - </linearGradient> - <linearGradient - id="linearGradient3400"> - <stop - style="stop-color:#e5ff00;stop-opacity:1;" - offset="0" - id="stop3402" /> - <stop - style="stop-color:#e5ff00;stop-opacity:0;" - offset="1" - id="stop3404" /> - </linearGradient> - <linearGradient - id="linearGradient3361"> - <stop - style="stop-color:#edffbf;stop-opacity:1;" - offset="0" - id="stop3363" /> - <stop - style="stop-color:#edffbf;stop-opacity:0;" - offset="1" - id="stop3365" /> - </linearGradient> - <linearGradient - inkscape:collect="always" - id="linearGradient3348"> - <stop - style="stop-color:#cbff10;stop-opacity:1" - offset="0" - id="stop3350" /> - <stop - style="stop-color:#004d00;stop-opacity:1" - offset="1" - id="stop3352" /> - </linearGradient> - <linearGradient - inkscape:collect="always" - id="linearGradient3294"> - <stop - style="stop-color:#37a42c;stop-opacity:1;" - offset="0" - id="stop3296" /> - <stop - style="stop-color:#bff500;stop-opacity:1" - offset="1" - id="stop3298" /> - </linearGradient> - <filter - inkscape:collect="always" - id="filter3396"> - <feGaussianBlur - inkscape:collect="always" - stdDeviation="0.495" - id="feGaussianBlur3398" /> - </filter> - <filter - inkscape:collect="always" - id="filter3533"> - <feGaussianBlur - inkscape:collect="always" - stdDeviation="1.0600355" - id="feGaussianBlur3535" /> - </filter> - <filter - inkscape:collect="always" - x="-0.12239107" - width="1.2447821" - y="-0.078971461" - height="1.1579429" - id="filter3681"> - <feGaussianBlur - inkscape:collect="always" - stdDeviation="0.321914" - id="feGaussianBlur3683" /> - </filter> - <filter - inkscape:collect="always" - x="-0.45196507" - width="1.9039301" - y="-0.29913295" - height="1.5982659" - id="filter3722"> - <feGaussianBlur - inkscape:collect="always" - stdDeviation="1.3476562" - id="feGaussianBlur3724" /> - </filter> - <linearGradient - inkscape:collect="always" - xlink:href="#XMLID_7_" - id="linearGradient2360" + xlink:href="#linearGradient3272" + id="radialGradient3646" gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.1772548,0,0,1.0772187,1.8462753,-4.9416701)" - x1="71.626404" - y1="123.73875" - x2="46.225941" - y2="28.942928" /> + gradientTransform="matrix(1.8125,0,0,2.2075201,-134,-173.90313)" + cx="88" + cy="93.5" + fx="88" + fy="93.5" + r="8" /> <radialGradient inkscape:collect="always" - xlink:href="#linearGradient3669" - id="radialGradient2362" + xlink:href="#linearGradient3272" + id="radialGradient3652" gradientUnits="userSpaceOnUse" - gradientTransform="matrix(0.9650814,0.2619502,-0.9201984,3.3902106,33.309062,-57.693239)" - cx="71.775223" - cy="16.0865" - fx="71.775223" - fy="16.0865" - r="3.15625" /> + gradientTransform="matrix(1,0,0,2.2075201,0,-112.90313)" + cx="88" + cy="93.5" + fx="88" + fy="93.5" + r="8" /> <linearGradient inkscape:collect="always" - xlink:href="#linearGradient7133" - id="linearGradient2364" + xlink:href="#linearGradient3578" + id="linearGradient3658" gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.1772548,0,0,1.0772187,6.5552946,-4.9416701)" - x1="96.373123" - y1="120.42788" - x2="96.373123" - y2="46.089832" /> + gradientTransform="matrix(1,0,0,0.875,96,9.9999934)" + x1="-8" + y1="98.130508" + x2="-8" + y2="126.82455" /> <radialGradient inkscape:collect="always" - xlink:href="#linearGradient7139" - id="radialGradient2366" + xlink:href="#linearGradient3272" + id="radialGradient3691" gradientUnits="userSpaceOnUse" - gradientTransform="matrix(0.9650814,0.2619502,-0.9201984,3.3902106,17.309062,-57.693239)" - cx="71.775223" - cy="16.0865" - fx="71.775223" - fy="16.0865" - r="3.15625" /> + gradientTransform="matrix(1,0,0,2.2075201,0,-112.90313)" + cx="88" + cy="93.5" + fx="88" + fy="93.5" + r="8" /> <linearGradient inkscape:collect="always" - xlink:href="#XMLID_5_" - id="linearGradient2368" + xlink:href="#linearGradient3578" + id="linearGradient3693" gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.0533333,0,0,0.9219945,7.5466667,4.9924269)" - x1="43.799026" - y1="32.051865" - x2="58.606159" - y2="96.363052" /> + gradientTransform="matrix(1,0,0,0.875,96,9.9999934)" + x1="-8" + y1="98.130508" + x2="-8" + y2="126.82455" /> <radialGradient inkscape:collect="always" - xlink:href="#linearGradient3710" - id="radialGradient2370" + xlink:href="#linearGradient3272" + id="radialGradient2653" gradientUnits="userSpaceOnUse" - gradientTransform="matrix(6.5079869,0,0,1.510917,-63.772161,-32.970115)" - cx="11.578125" - cy="64.53125" - fx="11.578125" - fy="64.53125" - r="3.578125" /> - <radialGradient - inkscape:collect="always" - xlink:href="#XMLID_5_" - id="radialGradient2372" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.519949,7.3519239e-8,-8.0632435e-8,1.2772114,-20.224726,-23.996639)" - cx="53.630272" - cy="79.055809" - fx="57.058514" - fy="91.805016" - r="50" /> + gradientTransform="matrix(1,0,0,2.2075201,0,-112.90313)" + cx="88" + cy="93.5" + fx="88" + fy="93.5" + r="8" /> <linearGradient inkscape:collect="always" - xlink:href="#linearGradient7151" - id="linearGradient2374" + xlink:href="#linearGradient3578" + id="linearGradient2655" gradientUnits="userSpaceOnUse" - gradientTransform="translate(20,0)" - x1="91.785248" - y1="112.5" - x2="91.992706" - y2="44.287056" /> - <linearGradient + gradientTransform="matrix(1,0,0,0.875,96,9.9999934)" + x1="-8" + y1="98.130508" + x2="-8" + y2="126.82455" /> + <radialGradient inkscape:collect="always" - xlink:href="#linearGradient7139" - id="linearGradient2376" + xlink:href="#linearGradient3272" + id="radialGradient2669" gradientUnits="userSpaceOnUse" - gradientTransform="translate(20,0)" - x1="91.785248" - y1="112.5" - x2="91.992706" - y2="44.287056" /> + gradientTransform="matrix(1,0,0,2.2075201,0,-112.90313)" + cx="88" + cy="93.5" + fx="88" + fy="93.5" + r="8" /> <linearGradient inkscape:collect="always" - xlink:href="#linearGradient7145" - id="linearGradient2378" + xlink:href="#linearGradient3578" + id="linearGradient2671" gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.0533333,0,0,0.9219945,11.76,4.9924269)" - x1="63.159035" - y1="21.171064" - x2="63.159035" - y2="80.12056" /> + gradientTransform="matrix(1,0,0,0.875,96,9.9999934)" + x1="-8" + y1="98.130508" + x2="-8" + y2="126.82455" /> <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient3710" - id="linearGradient2380" + y2="187.04779" + x2="304.47833" + y1="162.80251" + x1="304.47833" + gradientTransform="translate(-286,-37)" gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.0533333,0,0,0.9219945,11.76,4.9924269)" - x1="73.739265" - y1="69.923088" - x2="35.568035" - y2="48.212151" /> + id="linearGradient2727" + xlink:href="#linearGradient3499" + inkscape:collect="always" /> <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient3710" - id="linearGradient2382" + y2="187.04779" + x2="304.47833" + y1="162.80251" + x1="304.47833" + gradientTransform="translate(-286,-37)" gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.0533333,0,0,0.9219945,11.76,4.9924269)" - x1="63.159035" - y1="21.171064" - x2="63.159035" - y2="80.12056" /> - <radialGradient - r="3.578125" - fy="64.53125" - fx="11.578125" - cy="64.53125" - cx="11.578125" - gradientTransform="matrix(6.5079869,0,0,1.510917,-63.772161,-32.970115)" - gradientUnits="userSpaceOnUse" - id="radialGradient2343" - xlink:href="#linearGradient3710" + id="linearGradient2725" + xlink:href="#linearGradient3499" inkscape:collect="always" /> - <radialGradient - r="3.15625" - fy="16.0865" - fx="71.775223" - cy="16.0865" - cx="71.775223" - gradientTransform="matrix(0.9650814,0.2619502,-0.9201984,3.3902106,17.309062,-57.693239)" + <linearGradient + y2="187.04779" + x2="304.47833" + y1="162.80251" + x1="304.47833" + gradientTransform="translate(-286,-37)" gradientUnits="userSpaceOnUse" - id="radialGradient2341" - xlink:href="#linearGradient3689" + id="linearGradient2723" + xlink:href="#linearGradient3499" inkscape:collect="always" /> <linearGradient - y2="28.942928" - x2="46.225941" - y1="123.73875" - x1="71.626404" - gradientTransform="matrix(1.1772548,0,0,1.0772187,1.8462753,-4.9416701)" + y2="187.04779" + x2="304.47833" + y1="162.80251" + x1="304.47833" + gradientTransform="translate(-286,-37)" gradientUnits="userSpaceOnUse" - id="linearGradient2338" - xlink:href="#linearGradient3503" + id="linearGradient2721" + xlink:href="#linearGradient3499" inkscape:collect="always" /> - <radialGradient - r="3.15625" - fy="16.0865" - fx="71.775223" - cy="16.0865" - cx="71.775223" - gradientTransform="matrix(0.9650814,0.2619502,-0.9201984,3.3902106,33.309062,-57.693239)" + <linearGradient + y2="187.04779" + x2="304.47833" + y1="162.80251" + x1="304.47833" + gradientTransform="translate(-286,-37)" gradientUnits="userSpaceOnUse" - id="radialGradient2335" - xlink:href="#linearGradient3669" + id="linearGradient2719" + xlink:href="#linearGradient3499" inkscape:collect="always" /> <linearGradient - gradientTransform="matrix(1.1772548,0,0,1.0772187,6.5552946,-4.9416701)" - y2="46.089832" - x2="96.373123" - y1="120.42788" - x1="96.373123" + y2="187.04779" + x2="304.47833" + y1="162.80251" + x1="304.47833" + gradientTransform="translate(-286,-37)" gradientUnits="userSpaceOnUse" - id="linearGradient2332" - xlink:href="#linearGradient3511" + id="linearGradient2717" + xlink:href="#linearGradient3499" inkscape:collect="always" /> <linearGradient - y2="96.363052" - x2="58.606159" - y1="32.051865" - x1="43.799026" - gradientTransform="matrix(1.0533333,0,0,0.9219945,7.5466667,4.9924269)" + y2="187.04779" + x2="304.47833" + y1="162.80251" + x1="304.47833" + gradientTransform="translate(-286,-37)" gradientUnits="userSpaceOnUse" - id="linearGradient2328" - xlink:href="#linearGradient3294" + id="linearGradient2715" + xlink:href="#linearGradient3499" inkscape:collect="always" /> - <radialGradient - r="50" - fy="91.805016" - fx="57.058514" - cy="79.055809" - cx="53.630272" - gradientTransform="matrix(1.519949,7.3519239e-8,-8.0632435e-8,1.2772114,-20.224726,-23.996639)" + <linearGradient + y2="187.04779" + x2="304.47833" + y1="162.80251" + x1="304.47833" + gradientTransform="translate(-286,-37)" gradientUnits="userSpaceOnUse" - id="radialGradient2324" - xlink:href="#linearGradient3348" + id="linearGradient2713" + xlink:href="#linearGradient3499" inkscape:collect="always" /> <linearGradient - gradientTransform="translate(20,0)" - y2="44.287056" - x2="91.992706" - y1="112.5" - x1="91.785248" + y2="187.04779" + x2="304.47833" + y1="162.80251" + x1="304.47833" + gradientTransform="matrix(0.7413699,0,0,1,-208.99731,-117.06001)" gradientUnits="userSpaceOnUse" - id="linearGradient2321" - xlink:href="#linearGradient3400" + id="linearGradient2711" + xlink:href="#linearGradient3499" inkscape:collect="always" /> <linearGradient - gradientTransform="translate(20,0)" - y2="44.287056" - x2="91.992706" - y1="112.5" - x1="91.785248" + y2="187.04779" + x2="304.47833" + y1="162.80251" + x1="304.47833" + gradientTransform="translate(-286,-37)" gradientUnits="userSpaceOnUse" - id="linearGradient2318" - xlink:href="#linearGradient3400" + id="linearGradient14560" + xlink:href="#linearGradient4157" inkscape:collect="always" /> <linearGradient - gradientTransform="matrix(1.0533333,0,0,0.9219945,11.76,4.9924269)" - y2="80.12056" - x2="63.159035" - y1="21.171064" - x1="63.159035" + y2="187.04779" + x2="304.47833" + y1="162.80251" + x1="304.47833" + gradientTransform="matrix(0.7413793,0,0,1,-209,-159)" gradientUnits="userSpaceOnUse" - id="linearGradient2315" - xlink:href="#linearGradient3361" + id="linearGradient3514" + xlink:href="#linearGradient4157" inkscape:collect="always" /> <linearGradient - gradientTransform="matrix(1.0533333,0,0,0.9219945,11.76,4.9924269)" - y2="48.212151" - x2="35.568035" - y1="69.923088" - x1="73.739265" + y2="187.04779" + x2="304.47833" + y1="162.80251" + x1="304.47833" + gradientTransform="translate(-286,-37)" gradientUnits="userSpaceOnUse" - id="linearGradient2312" - xlink:href="#linearGradient3710" + id="linearGradient3512" + xlink:href="#linearGradient4157" inkscape:collect="always" /> <linearGradient - gradientTransform="matrix(1.0533333,0,0,0.9219945,11.76,4.9924269)" - y2="80.12056" - x2="63.159035" - y1="21.171064" - x1="63.159035" + y2="187.04779" + x2="304.47833" + y1="162.80251" + x1="304.47833" + gradientTransform="translate(-286,-37)" gradientUnits="userSpaceOnUse" - id="linearGradient2309" - xlink:href="#linearGradient3710" + id="linearGradient3510" + xlink:href="#linearGradient4157" inkscape:collect="always" /> <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient3503" - id="linearGradient3236" + y2="187.04779" + x2="304.47833" + y1="162.80251" + x1="304.47833" + gradientTransform="translate(-286,-37)" gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.1772548,0,0,1.0772187,1.8462753,-4.9416701)" - x1="71.626404" - y1="123.73875" - x2="46.225941" - y2="28.942928" /> - <radialGradient - inkscape:collect="always" - xlink:href="#linearGradient3669" - id="radialGradient3238" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(0.9650814,0.2619502,-0.9201984,3.3902106,33.309062,-57.693239)" - cx="71.775223" - cy="16.0865" - fx="71.775223" - fy="16.0865" - r="3.15625" /> + id="linearGradient3508" + xlink:href="#linearGradient4157" + inkscape:collect="always" /> <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient3511" - id="linearGradient3240" + y2="187.04779" + x2="304.47833" + y1="162.80251" + x1="304.47833" + gradientTransform="translate(-286,-37)" gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.1772548,0,0,1.0772187,6.5552946,-4.9416701)" - x1="96.373123" - y1="120.42788" - x2="96.373123" - y2="46.089832" /> - <radialGradient - inkscape:collect="always" - xlink:href="#linearGradient3689" - id="radialGradient3242" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(0.9650814,0.2619502,-0.9201984,3.3902106,17.309062,-57.693239)" - cx="71.775223" - cy="16.0865" - fx="71.775223" - fy="16.0865" - r="3.15625" /> + id="linearGradient3506" + xlink:href="#linearGradient4157" + inkscape:collect="always" /> <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient3294" - id="linearGradient3244" + y2="187.04779" + x2="304.47833" + y1="162.80251" + x1="304.47833" + gradientTransform="translate(-286,-37)" gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.0533333,0,0,0.9219945,7.5466667,4.9924269)" - x1="43.799026" - y1="32.051865" - x2="58.606159" - y2="96.363052" /> - <radialGradient - inkscape:collect="always" - xlink:href="#linearGradient3710" - id="radialGradient3246" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(6.5079869,0,0,1.510917,-63.772161,-32.970115)" - cx="11.578125" - cy="64.53125" - fx="11.578125" - fy="64.53125" - r="3.578125" /> - <radialGradient - inkscape:collect="always" - xlink:href="#linearGradient3348" - id="radialGradient3248" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.519949,7.3519239e-8,-8.0632435e-8,1.2772114,-20.224726,-23.996639)" - cx="53.630272" - cy="79.055809" - fx="57.058514" - fy="91.805016" - r="50" /> + id="linearGradient3504" + xlink:href="#linearGradient4157" + inkscape:collect="always" /> <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient3400" - id="linearGradient3250" + y2="187.04779" + x2="304.47833" + y1="162.80251" + x1="304.47833" + gradientTransform="translate(-286,-37)" gradientUnits="userSpaceOnUse" - gradientTransform="translate(20,0)" - x1="91.785248" - y1="112.5" - x2="91.992706" - y2="44.287056" /> + id="linearGradient3502" + xlink:href="#linearGradient4157" + inkscape:collect="always" /> <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient3400" - id="linearGradient3252" + y2="187.04779" + x2="304.47833" + y1="162.80251" + x1="304.47833" + gradientTransform="translate(-286,-37)" gradientUnits="userSpaceOnUse" - gradientTransform="translate(20,0)" - x1="91.785248" - y1="112.5" - x2="91.992706" - y2="44.287056" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient3361" - id="linearGradient3254" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.0533333,0,0,0.9219945,11.76,4.9924269)" - x1="63.159035" - y1="21.171064" - x2="63.159035" - y2="80.12056" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient3710" - id="linearGradient3256" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.0533333,0,0,0.9219945,11.76,4.9924269)" - x1="73.739265" - y1="69.923088" - x2="35.568035" - y2="48.212151" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient3710" - id="linearGradient3258" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.0533333,0,0,0.9219945,11.76,4.9924269)" - x1="63.159035" - y1="21.171064" - x2="63.159035" - y2="80.12056" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient3503" - id="linearGradient3716" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.1772548,0,0,1.0772187,1.8462753,-4.9416701)" - x1="71.626404" - y1="123.73875" - x2="46.225941" - y2="28.942928" /> - <radialGradient - inkscape:collect="always" - xlink:href="#linearGradient3669" - id="radialGradient3718" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(0.9650814,0.2619502,-0.9201984,3.3902106,33.309062,-57.693239)" - cx="71.775223" - cy="16.0865" - fx="71.775223" - fy="16.0865" - r="3.15625" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient3511" - id="linearGradient3720" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.1772548,0,0,1.0772187,6.5552946,-4.9416701)" - x1="96.373123" - y1="120.42788" - x2="96.373123" - y2="46.089832" /> - <radialGradient - inkscape:collect="always" - xlink:href="#linearGradient3689" - id="radialGradient3722" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(0.9650814,0.2619502,-0.9201984,3.3902106,17.309062,-57.693239)" - cx="71.775223" - cy="16.0865" - fx="71.775223" - fy="16.0865" - r="3.15625" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient3294" - id="linearGradient3724" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.0533333,0,0,0.9219945,7.5466667,4.9924269)" - x1="43.799026" - y1="32.051865" - x2="58.606159" - y2="96.363052" /> - <radialGradient - inkscape:collect="always" - xlink:href="#linearGradient3710" - id="radialGradient3726" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(6.5079869,0,0,1.510917,-63.772161,-32.970115)" - cx="11.578125" - cy="64.53125" - fx="11.578125" - fy="64.53125" - r="3.578125" /> - <radialGradient - inkscape:collect="always" - xlink:href="#linearGradient3348" - id="radialGradient3728" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.519949,7.3519239e-8,-8.0632435e-8,1.2772114,-20.224726,-23.996639)" - cx="53.630272" - cy="79.055809" - fx="57.058514" - fy="91.805016" - r="50" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient3400" - id="linearGradient3730" - gradientUnits="userSpaceOnUse" - gradientTransform="translate(20,0)" - x1="91.785248" - y1="112.5" - x2="91.992706" - y2="44.287056" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient3400" - id="linearGradient3732" - gradientUnits="userSpaceOnUse" - gradientTransform="translate(20,0)" - x1="91.785248" - y1="112.5" - x2="91.992706" - y2="44.287056" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient3361" - id="linearGradient3734" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.0533333,0,0,0.9219945,11.76,4.9924269)" - x1="63.159035" - y1="21.171064" - x2="63.159035" - y2="80.12056" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient3710" - id="linearGradient3736" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.0533333,0,0,0.9219945,11.76,4.9924269)" - x1="73.739265" - y1="69.923088" - x2="35.568035" - y2="48.212151" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient3710" - id="linearGradient3738" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.0533333,0,0,0.9219945,11.76,4.9924269)" - x1="63.159035" - y1="21.171064" - x2="63.159035" - y2="80.12056" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient8126" - id="linearGradient3874" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.1772548,0,0,1.0772187,1.8462753,-4.9416701)" - x1="71.626404" - y1="123.73875" - x2="46.225941" - y2="28.942928" /> - <radialGradient - inkscape:collect="always" - xlink:href="#linearGradient3669" - id="radialGradient3876" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(0.9650814,0.2619502,-0.9201984,3.3902106,33.309062,-57.693239)" - cx="71.775223" - cy="16.0865" - fx="71.775223" - fy="16.0865" - r="3.15625" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient8132" - id="linearGradient3878" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.1772548,0,0,1.0772187,6.5552946,-4.9416701)" - x1="96.373123" - y1="120.42788" - x2="96.373123" - y2="46.089832" /> - <radialGradient - inkscape:collect="always" - xlink:href="#linearGradient8138" - id="radialGradient3880" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(0.9650814,0.2619502,-0.9201984,3.3902106,17.309062,-57.693239)" - cx="71.775223" - cy="16.0865" - fx="71.775223" - fy="16.0865" - r="3.15625" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient8144" - id="linearGradient3882" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.0533333,0,0,0.9219945,7.5466667,4.9924269)" - x1="43.799026" - y1="32.051865" - x2="58.606159" - y2="96.363052" /> - <radialGradient - inkscape:collect="always" - xlink:href="#linearGradient3710" - id="radialGradient3884" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(6.5079869,0,0,1.510917,-63.772161,-32.970115)" - cx="11.578125" - cy="64.53125" - fx="11.578125" - fy="64.53125" - r="3.578125" /> - <radialGradient - inkscape:collect="always" - xlink:href="#linearGradient8150" - id="radialGradient3886" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.519949,7.3519239e-8,-8.0632435e-8,1.2772114,-20.224726,-23.996639)" - cx="53.630272" - cy="79.055809" - fx="57.058514" - fy="91.805016" - r="50" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient8162" - id="linearGradient3888" - gradientUnits="userSpaceOnUse" - gradientTransform="translate(20,0)" - x1="91.785248" - y1="112.5" - x2="91.992706" - y2="44.287056" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient8156" - id="linearGradient3890" - gradientUnits="userSpaceOnUse" - gradientTransform="translate(20,0)" - x1="91.785248" - y1="112.5" - x2="91.992706" - y2="44.287056" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient3711" - id="linearGradient3892" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.0533333,0,0,0.9219945,11.76,4.9924269)" - x1="63.159035" - y1="21.171064" - x2="63.159035" - y2="80.12056" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient3710" - id="linearGradient3894" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.0533333,0,0,0.9219945,11.76,4.9924269)" - x1="73.739265" - y1="69.923088" - x2="35.568035" - y2="48.212151" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient3710" - id="linearGradient3896" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.0533333,0,0,0.9219945,11.76,4.9924269)" - x1="63.159035" - y1="21.171064" - x2="63.159035" - y2="80.12056" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient3503" - id="linearGradient3922" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.1772548,0,0,1.0772187,1.8462753,-4.9416701)" - x1="71.626404" - y1="123.73875" - x2="46.225941" - y2="28.942928" /> - <radialGradient - inkscape:collect="always" - xlink:href="#linearGradient3669" - id="radialGradient3924" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(0.9650814,0.2619502,-0.9201984,3.3902106,33.309062,-57.693239)" - cx="71.775223" - cy="16.0865" - fx="71.775223" - fy="16.0865" - r="3.15625" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient3511" - id="linearGradient3926" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.1772548,0,0,1.0772187,6.5552946,-4.9416701)" - x1="96.373123" - y1="120.42788" - x2="96.373123" - y2="46.089832" /> - <radialGradient - inkscape:collect="always" - xlink:href="#linearGradient3689" - id="radialGradient3928" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(0.9650814,0.2619502,-0.9201984,3.3902106,17.309062,-57.693239)" - cx="71.775223" - cy="16.0865" - fx="71.775223" - fy="16.0865" - r="3.15625" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient3294" - id="linearGradient3930" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.0533333,0,0,0.9219945,7.5466667,4.9924269)" - x1="43.799026" - y1="32.051865" - x2="58.606159" - y2="96.363052" /> - <radialGradient - inkscape:collect="always" - xlink:href="#linearGradient3710" - id="radialGradient3932" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(6.5079869,0,0,1.510917,-63.772161,-32.970115)" - cx="11.578125" - cy="64.53125" - fx="11.578125" - fy="64.53125" - r="3.578125" /> - <radialGradient - inkscape:collect="always" - xlink:href="#linearGradient3348" - id="radialGradient3934" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.519949,7.3519239e-8,-8.0632435e-8,1.2772114,-20.224726,-23.996639)" - cx="53.630272" - cy="79.055809" - fx="57.058514" - fy="91.805016" - r="50" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient3400" - id="linearGradient3936" - gradientUnits="userSpaceOnUse" - gradientTransform="translate(20,0)" - x1="91.785248" - y1="112.5" - x2="91.992706" - y2="44.287056" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient3400" - id="linearGradient3938" - gradientUnits="userSpaceOnUse" - gradientTransform="translate(20,0)" - x1="91.785248" - y1="112.5" - x2="91.992706" - y2="44.287056" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient3361" - id="linearGradient3940" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.0533333,0,0,0.9219945,11.76,4.9924269)" - x1="63.159035" - y1="21.171064" - x2="63.159035" - y2="80.12056" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient3710" - id="linearGradient3942" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.0533333,0,0,0.9219945,11.76,4.9924269)" - x1="73.739265" - y1="69.923088" - x2="35.568035" - y2="48.212151" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient3710" - id="linearGradient3944" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.0533333,0,0,0.9219945,11.76,4.9924269)" - x1="63.159035" - y1="21.171064" - x2="63.159035" - y2="80.12056" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient3503" - id="linearGradient3946" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.1772548,0,0,1.0772187,1.8462753,-4.9416701)" - x1="71.626404" - y1="123.73875" - x2="46.225941" - y2="28.942928" /> - <radialGradient - inkscape:collect="always" - xlink:href="#linearGradient3669" - id="radialGradient3948" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(0.9650814,0.2619502,-0.9201984,3.3902106,33.309062,-57.693239)" - cx="71.775223" - cy="16.0865" - fx="71.775223" - fy="16.0865" - r="3.15625" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient3511" - id="linearGradient3950" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.1772548,0,0,1.0772187,6.5552946,-4.9416701)" - x1="96.373123" - y1="120.42788" - x2="96.373123" - y2="46.089832" /> - <radialGradient - inkscape:collect="always" - xlink:href="#linearGradient3689" - id="radialGradient3952" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(0.9650814,0.2619502,-0.9201984,3.3902106,17.309062,-57.693239)" - cx="71.775223" - cy="16.0865" - fx="71.775223" - fy="16.0865" - r="3.15625" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient3294" - id="linearGradient3954" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.0533333,0,0,0.9219945,7.5466667,4.9924269)" - x1="43.799026" - y1="32.051865" - x2="58.606159" - y2="96.363052" /> - <radialGradient - inkscape:collect="always" - xlink:href="#linearGradient3710" - id="radialGradient3956" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(6.5079869,0,0,1.510917,-63.772161,-32.970115)" - cx="11.578125" - cy="64.53125" - fx="11.578125" - fy="64.53125" - r="3.578125" /> - <radialGradient - inkscape:collect="always" - xlink:href="#linearGradient3348" - id="radialGradient3958" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.519949,7.3519239e-8,-8.0632435e-8,1.2772114,-20.224726,-23.996639)" - cx="53.630272" - cy="79.055809" - fx="57.058514" - fy="91.805016" - r="50" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient3400" - id="linearGradient3960" - gradientUnits="userSpaceOnUse" - gradientTransform="translate(20,0)" - x1="91.785248" - y1="112.5" - x2="91.992706" - y2="44.287056" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient3400" - id="linearGradient3962" - gradientUnits="userSpaceOnUse" - gradientTransform="translate(20,0)" - x1="91.785248" - y1="112.5" - x2="91.992706" - y2="44.287056" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient3361" - id="linearGradient3964" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.0533333,0,0,0.9219945,11.76,4.9924269)" - x1="63.159035" - y1="21.171064" - x2="63.159035" - y2="80.12056" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient3710" - id="linearGradient3966" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.0533333,0,0,0.9219945,11.76,4.9924269)" - x1="73.739265" - y1="69.923088" - x2="35.568035" - y2="48.212151" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient3710" - id="linearGradient3968" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.0533333,0,0,0.9219945,11.76,4.9924269)" - x1="63.159035" - y1="21.171064" - x2="63.159035" - y2="80.12056" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient3503" - id="linearGradient4028" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.1772548,0,0,1.0772187,1.8462753,-4.9416701)" - x1="71.626404" - y1="123.73875" - x2="46.225941" - y2="28.942928" /> - <radialGradient - inkscape:collect="always" - xlink:href="#linearGradient3669" - id="radialGradient4030" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(0.9650814,0.2619502,-0.9201984,3.3902106,33.309062,-57.693239)" - cx="71.775223" - cy="16.0865" - fx="71.775223" - fy="16.0865" - r="3.15625" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient3511" - id="linearGradient4032" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.1772548,0,0,1.0772187,6.5552946,-4.9416701)" - x1="96.373123" - y1="120.42788" - x2="96.373123" - y2="46.089832" /> - <radialGradient - inkscape:collect="always" - xlink:href="#linearGradient3689" - id="radialGradient4034" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(0.9650814,0.2619502,-0.9201984,3.3902106,17.309062,-57.693239)" - cx="71.775223" - cy="16.0865" - fx="71.775223" - fy="16.0865" - r="3.15625" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient3294" - id="linearGradient4036" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.0533333,0,0,0.9219945,7.5466667,4.9924269)" - x1="43.799026" - y1="32.051865" - x2="58.606159" - y2="96.363052" /> - <radialGradient - inkscape:collect="always" - xlink:href="#linearGradient3710" - id="radialGradient4038" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(6.5079869,0,0,1.510917,-63.772161,-32.970115)" - cx="11.578125" - cy="64.53125" - fx="11.578125" - fy="64.53125" - r="3.578125" /> - <radialGradient - inkscape:collect="always" - xlink:href="#linearGradient3348" - id="radialGradient4040" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.519949,7.3519239e-8,-8.0632435e-8,1.2772114,-20.224726,-23.996639)" - cx="53.630272" - cy="79.055809" - fx="57.058514" - fy="91.805016" - r="50" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient3400" - id="linearGradient4042" - gradientUnits="userSpaceOnUse" - gradientTransform="translate(20,0)" - x1="91.785248" - y1="112.5" - x2="91.992706" - y2="44.287056" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient3400" - id="linearGradient4044" - gradientUnits="userSpaceOnUse" - gradientTransform="translate(20,0)" - x1="91.785248" - y1="112.5" - x2="91.992706" - y2="44.287056" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient3361" - id="linearGradient4046" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.0533333,0,0,0.9219945,11.76,4.9924269)" - x1="63.159035" - y1="21.171064" - x2="63.159035" - y2="80.12056" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient3710" - id="linearGradient4048" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.0533333,0,0,0.9219945,11.76,4.9924269)" - x1="73.739265" - y1="69.923088" - x2="35.568035" - y2="48.212151" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient3710" - id="linearGradient4050" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.0533333,0,0,0.9219945,11.76,4.9924269)" - x1="63.159035" - y1="21.171064" - x2="63.159035" - y2="80.12056" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient3503" - id="linearGradient4052" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.1772548,0,0,1.0772187,1.8462753,-4.9416701)" - x1="71.626404" - y1="123.73875" - x2="46.225941" - y2="28.942928" /> - <radialGradient - inkscape:collect="always" - xlink:href="#linearGradient3669" - id="radialGradient4054" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(0.9650814,0.2619502,-0.9201984,3.3902106,33.309062,-57.693239)" - cx="71.775223" - cy="16.0865" - fx="71.775223" - fy="16.0865" - r="3.15625" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient3511" - id="linearGradient4056" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.1772548,0,0,1.0772187,6.5552946,-4.9416701)" - x1="96.373123" - y1="120.42788" - x2="96.373123" - y2="46.089832" /> - <radialGradient - inkscape:collect="always" - xlink:href="#linearGradient3689" - id="radialGradient4058" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(0.9650814,0.2619502,-0.9201984,3.3902106,17.309062,-57.693239)" - cx="71.775223" - cy="16.0865" - fx="71.775223" - fy="16.0865" - r="3.15625" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient3294" - id="linearGradient4060" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.0533333,0,0,0.9219945,7.5466667,4.9924269)" - x1="43.799026" - y1="32.051865" - x2="58.606159" - y2="96.363052" /> - <radialGradient - inkscape:collect="always" - xlink:href="#linearGradient3710" - id="radialGradient4062" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(6.5079869,0,0,1.510917,-63.772161,-32.970115)" - cx="11.578125" - cy="64.53125" - fx="11.578125" - fy="64.53125" - r="3.578125" /> - <radialGradient - inkscape:collect="always" - xlink:href="#linearGradient3348" - id="radialGradient4064" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.519949,7.3519239e-8,-8.0632435e-8,1.2772114,-20.224726,-23.996639)" - cx="53.630272" - cy="79.055809" - fx="57.058514" - fy="91.805016" - r="50" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient3400" - id="linearGradient4066" - gradientUnits="userSpaceOnUse" - gradientTransform="translate(20,0)" - x1="91.785248" - y1="112.5" - x2="91.992706" - y2="44.287056" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient3400" - id="linearGradient4068" - gradientUnits="userSpaceOnUse" - gradientTransform="translate(20,0)" - x1="91.785248" - y1="112.5" - x2="91.992706" - y2="44.287056" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient3361" - id="linearGradient4070" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.0533333,0,0,0.9219945,11.76,4.9924269)" - x1="63.159035" - y1="21.171064" - x2="63.159035" - y2="80.12056" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient3710" - id="linearGradient4072" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.0533333,0,0,0.9219945,11.76,4.9924269)" - x1="73.739265" - y1="69.923088" - x2="35.568035" - y2="48.212151" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient3710" - id="linearGradient4074" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.0533333,0,0,0.9219945,11.76,4.9924269)" - x1="63.159035" - y1="21.171064" - x2="63.159035" - y2="80.12056" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient3503" - id="linearGradient4158" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.1772548,0,0,1.0772187,1.8462753,-4.9416701)" - x1="71.626404" - y1="123.73875" - x2="46.225941" - y2="28.942928" /> - <radialGradient - inkscape:collect="always" - xlink:href="#linearGradient3669" - id="radialGradient4160" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(0.9650814,0.2619502,-0.9201984,3.3902106,33.309062,-57.693239)" - cx="71.775223" - cy="16.0865" - fx="71.775223" - fy="16.0865" - r="3.15625" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient3511" - id="linearGradient4162" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.1772548,0,0,1.0772187,6.5552946,-4.9416701)" - x1="96.373123" - y1="120.42788" - x2="96.373123" - y2="46.089832" /> - <radialGradient - inkscape:collect="always" - xlink:href="#linearGradient3689" - id="radialGradient4164" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(0.9650814,0.2619502,-0.9201984,3.3902106,17.309062,-57.693239)" - cx="71.775223" - cy="16.0865" - fx="71.775223" - fy="16.0865" - r="3.15625" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient3294" - id="linearGradient4166" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.0533333,0,0,0.9219945,7.5466667,4.9924269)" - x1="43.799026" - y1="32.051865" - x2="58.606159" - y2="96.363052" /> - <radialGradient - inkscape:collect="always" - xlink:href="#linearGradient3710" - id="radialGradient4168" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(6.5079869,0,0,1.510917,-63.772161,-32.970115)" - cx="11.578125" - cy="64.53125" - fx="11.578125" - fy="64.53125" - r="3.578125" /> - <radialGradient - inkscape:collect="always" - xlink:href="#linearGradient3348" - id="radialGradient4170" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.519949,7.3519239e-8,-8.0632435e-8,1.2772114,-20.224726,-23.996639)" - cx="53.630272" - cy="79.055809" - fx="57.058514" - fy="91.805016" - r="50" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient3400" - id="linearGradient4172" - gradientUnits="userSpaceOnUse" - gradientTransform="translate(20,0)" - x1="91.785248" - y1="112.5" - x2="91.992706" - y2="44.287056" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient3400" - id="linearGradient4174" - gradientUnits="userSpaceOnUse" - gradientTransform="translate(20,0)" - x1="91.785248" - y1="112.5" - x2="91.992706" - y2="44.287056" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient3361" - id="linearGradient4176" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.0533333,0,0,0.9219945,11.76,4.9924269)" - x1="63.159035" - y1="21.171064" - x2="63.159035" - y2="80.12056" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient3710" - id="linearGradient4178" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.0533333,0,0,0.9219945,11.76,4.9924269)" - x1="73.739265" - y1="69.923088" - x2="35.568035" - y2="48.212151" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient3710" - id="linearGradient4180" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.0533333,0,0,0.9219945,11.76,4.9924269)" - x1="63.159035" - y1="21.171064" - x2="63.159035" - y2="80.12056" /> - <linearGradient - gradientTransform="matrix(0,1,-1,0,-39.9985,140.0029)" - y2="-383.9975" - x2="-23.516129" - y1="-383.9971" - x1="-84.002403" - gradientUnits="userSpaceOnUse" - id="linearGradient3711"> - <stop - id="stop3713" - style="stop-color:white;stop-opacity:1;" - offset="0" /> - <stop - id="stop3715" - style="stop-color:white;stop-opacity:0;" - offset="1" /> - </linearGradient> - <linearGradient - gradientTransform="translate(18.73145,-130.4544)" - y2="157.6319" - x2="63.9995" - y1="25.1577" - x1="63.9995" - gradientUnits="userSpaceOnUse" - id="XMLID_7_"> - <stop - id="stop3374" - style="stop-color:#BFD9FF" - offset="0" /> - <stop - id="stop3376" - style="stop-color:#80B3FF" - offset="0.2189" /> - <stop - id="stop3378" - style="stop-color:#7badf5;stop-opacity:1;" - offset="0.2933" /> - <stop - id="stop3380" - style="stop-color:#4c8ad7;stop-opacity:1;" - offset="0.44260001" /> - <stop - id="stop3382" - style="stop-color:#327ad2;stop-opacity:1;" - offset="0.4941" /> - <stop - id="stop3384" - style="stop-color:#0065d1;stop-opacity:1;" - offset="0.69999999" /> - </linearGradient> - <radialGradient - gradientTransform="translate(18.73145,-130.4544)" - gradientUnits="userSpaceOnUse" - r="111.0006" - cy="-9" - cx="51.9995" - id="XMLID_5_"> - <stop - id="stop3312" - style="stop-color:#a3c8ff;stop-opacity:1;" - offset="0.15000001" /> - <stop - id="stop3314" - style="stop-color:#69A1F0" - offset="0.316" /> - <stop - id="stop3316" - style="stop-color:#4888DA" - offset="0.6029" /> - <stop - id="stop3318" - style="stop-color:#3378CC" - offset="0.8412" /> - <stop - id="stop3320" - style="stop-color:#2C72C7" - offset="1" /> - </radialGradient> - <linearGradient - gradientUnits="userSpaceOnUse" - y2="138.35936" - x2="21.697437" - y1="-8.5763578" - x1="106.37579" - id="linearGradient3278" - xlink:href="#linearGradient3272" + id="linearGradient3500" + xlink:href="#linearGradient4157" inkscape:collect="always" /> <linearGradient - id="linearGradient3272" - inkscape:collect="always"> + id="linearGradient4157"> <stop - id="stop3274" + id="stop4159" offset="0" - style="stop-color:white;stop-opacity:1;" /> + style="stop-color:#ffffff;stop-opacity:1;" /> <stop - id="stop3276" + id="stop4161" offset="1" - style="stop-color:white;stop-opacity:0;" /> + style="stop-color:#a3a3a3;stop-opacity:1;" /> </linearGradient> <linearGradient inkscape:collect="always" - xlink:href="#XMLID_7_" - id="linearGradient8227" + xlink:href="#linearGradient4157" + id="linearGradient4738" gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.1772548,0,0,1.0772187,1.8462753,-4.9416701)" - x1="71.626404" - y1="123.73875" - x2="46.225941" - y2="28.942928" /> - <radialGradient - inkscape:collect="always" - xlink:href="#linearGradient3669" - id="radialGradient8229" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(0.9650814,0.2619502,-0.9201984,3.3902106,33.309062,-57.693239)" - cx="71.775223" - cy="16.0865" - fx="71.775223" - fy="16.0865" - r="3.15625" /> + gradientTransform="translate(-336,-160)" + x1="304.47833" + y1="162.80251" + x2="304.47833" + y2="187.04779" /> <linearGradient inkscape:collect="always" - xlink:href="#linearGradient7133" - id="linearGradient8231" + xlink:href="#linearGradient4157" + id="linearGradient3769" gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.1772548,0,0,1.0772187,6.5552946,-4.9416701)" - x1="96.373123" - y1="120.42788" - x2="96.373123" - y2="46.089832" /> - <radialGradient - inkscape:collect="always" - xlink:href="#linearGradient7139" - id="radialGradient8233" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(0.9650814,0.2619502,-0.9201984,3.3902106,17.309062,-57.693239)" - cx="71.775223" - cy="16.0865" - fx="71.775223" - fy="16.0865" - r="3.15625" /> + gradientTransform="translate(-285,-160)" + x1="304.47833" + y1="162.80251" + x2="304.47833" + y2="187.04779" /> <linearGradient inkscape:collect="always" - xlink:href="#XMLID_5_" - id="linearGradient8235" + xlink:href="#linearGradient4157" + id="linearGradient3767" gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.0533333,0,0,0.9219945,7.5466667,4.9924269)" - x1="43.799026" - y1="32.051865" - x2="58.606159" - y2="96.363052" /> - <radialGradient - inkscape:collect="always" - xlink:href="#linearGradient3710" - id="radialGradient8237" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(6.5079869,0,0,1.510917,-63.772161,-32.970115)" - cx="11.578125" - cy="64.53125" - fx="11.578125" - fy="64.53125" - r="3.578125" /> - <radialGradient - inkscape:collect="always" - xlink:href="#XMLID_5_" - id="radialGradient8239" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.519949,7.3519239e-8,-8.0632435e-8,1.2772114,-20.224726,-23.996639)" - cx="53.630272" - cy="79.055809" - fx="57.058514" - fy="91.805016" - r="50" /> + gradientTransform="matrix(1,0,0,0.4615384,-285,-70.615377)" + x1="304.47833" + y1="162.80251" + x2="304.47833" + y2="187.04779" /> <linearGradient inkscape:collect="always" - xlink:href="#linearGradient7151" - id="linearGradient8241" + xlink:href="#linearGradient4157" + id="linearGradient3765" gradientUnits="userSpaceOnUse" - gradientTransform="translate(20,0)" - x1="91.785248" - y1="112.5" - x2="91.992706" - y2="44.287056" /> + gradientTransform="translate(-285,-167)" + x1="304.47833" + y1="162.80251" + x2="304.47833" + y2="187.04779" /> <linearGradient inkscape:collect="always" - xlink:href="#linearGradient7139" - id="linearGradient8243" + xlink:href="#linearGradient4157" + id="linearGradient3763" gradientUnits="userSpaceOnUse" - gradientTransform="translate(20,0)" - x1="91.785248" - y1="112.5" - x2="91.992706" - y2="44.287056" /> + gradientTransform="matrix(0.1034484,0,0,1,-25.00002,-167)" + x1="304.47833" + y1="162.80251" + x2="304.47833" + y2="187.04779" /> <linearGradient inkscape:collect="always" - xlink:href="#linearGradient7145" - id="linearGradient8245" + xlink:href="#linearGradient4157" + id="linearGradient3761" gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.0533333,0,0,0.9219945,11.76,4.9924269)" - x1="63.159035" - y1="21.171064" - x2="63.159035" - y2="80.12056" /> + gradientTransform="translate(-337,-167)" + x1="304.47833" + y1="162.80251" + x2="304.47833" + y2="187.04779" /> <linearGradient inkscape:collect="always" - xlink:href="#linearGradient3710" - id="linearGradient8247" + xlink:href="#linearGradient4157" + id="linearGradient3759" gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.0533333,0,0,0.9219945,11.76,4.9924269)" - x1="73.739265" - y1="69.923088" - x2="35.568035" - y2="48.212151" /> + gradientTransform="matrix(1,0,0,0.4615385,-337,-70.615389)" + x1="304.47833" + y1="162.80251" + x2="304.47833" + y2="187.04779" /> <linearGradient inkscape:collect="always" - xlink:href="#linearGradient3710" - id="linearGradient8249" + xlink:href="#linearGradient4157" + id="linearGradient3755" gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.0533333,0,0,0.9219945,11.76,4.9924269)" - x1="63.159035" - y1="21.171064" - x2="63.159035" - y2="80.12056" /> + gradientTransform="matrix(0.1034483,0,0,1,-24.99999,-160)" + x1="304.47833" + y1="162.80251" + x2="304.47833" + y2="187.04779" /> <linearGradient inkscape:collect="always" - xlink:href="#linearGradient8126" - id="linearGradient8251" + xlink:href="#linearGradient4157" + id="linearGradient3673" gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.1772548,0,0,1.0772187,1.8462753,-4.9416701)" - x1="71.626404" - y1="123.73875" - x2="46.225941" - y2="28.942928" /> - <radialGradient - inkscape:collect="always" - xlink:href="#linearGradient3669" - id="radialGradient8253" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(0.9650814,0.2619502,-0.9201984,3.3902106,33.309062,-57.693239)" - cx="71.775223" - cy="16.0865" - fx="71.775223" - fy="16.0865" - r="3.15625" /> + gradientTransform="matrix(0.1034483,0,0,0.4615384,-22,-44.615385)" + x1="304.47833" + y1="162.80251" + x2="304.47833" + y2="187.04779" /> <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient8132" - id="linearGradient8255" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.1772548,0,0,1.0772187,6.5552946,-4.9416701)" - x1="96.373123" - y1="120.42788" - x2="96.373123" - y2="46.089832" /> - <radialGradient - inkscape:collect="always" - xlink:href="#linearGradient8138" - id="radialGradient8257" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(0.9650814,0.2619502,-0.9201984,3.3902106,17.309062,-57.693239)" - cx="71.775223" - cy="16.0865" - fx="71.775223" - fy="16.0865" - r="3.15625" /> + id="linearGradient3499"> + <stop + style="stop-color:#a3a3a3;stop-opacity:1;" + offset="0" + id="stop3501" /> + <stop + style="stop-color:#ffffff;stop-opacity:1;" + offset="1" + id="stop3503" /> + </linearGradient> <linearGradient inkscape:collect="always" - xlink:href="#linearGradient8144" - id="linearGradient8259" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.0533333,0,0,0.9219945,7.5466667,4.9924269)" - x1="43.799026" - y1="32.051865" - x2="58.606159" - y2="96.363052" /> - <radialGradient - inkscape:collect="always" - xlink:href="#linearGradient3710" - id="radialGradient8261" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(6.5079869,0,0,1.510917,-63.772161,-32.970115)" - cx="11.578125" - cy="64.53125" - fx="11.578125" - fy="64.53125" - r="3.578125" /> - <radialGradient - inkscape:collect="always" - xlink:href="#linearGradient8150" - id="radialGradient8263" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.519949,7.3519239e-8,-8.0632435e-8,1.2772114,-20.224726,-23.996639)" - cx="53.630272" - cy="79.055809" - fx="57.058514" - fy="91.805016" - r="50" /> + xlink:href="#linearGradient4157" + id="linearGradient3784" + x1="5.625" + y1="96" + x2="5.625" + y2="108.01627" + gradientUnits="userSpaceOnUse" /> <linearGradient inkscape:collect="always" - xlink:href="#linearGradient8162" - id="linearGradient8265" - gradientUnits="userSpaceOnUse" - gradientTransform="translate(20,0)" - x1="91.785248" - y1="112.5" - x2="91.992706" - y2="44.287056" /> + xlink:href="#linearGradient4157" + id="linearGradient3792" + x1="-33.9375" + y1="95.976646" + x2="-33.9375" + y2="107.96875" + gradientUnits="userSpaceOnUse" /> <linearGradient inkscape:collect="always" - xlink:href="#linearGradient8156" - id="linearGradient8267" - gradientUnits="userSpaceOnUse" - gradientTransform="translate(20,0)" - x1="91.785248" - y1="112.5" - x2="91.992706" - y2="44.287056" /> + xlink:href="#linearGradient4157" + id="linearGradient3800" + x1="7" + y1="96" + x2="7" + y2="108" + gradientUnits="userSpaceOnUse" /> <linearGradient inkscape:collect="always" - xlink:href="#linearGradient3711" - id="linearGradient8269" + xlink:href="#linearGradient4157" + id="linearGradient3807" gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.0533333,0,0,0.9219945,11.76,4.9924269)" - x1="63.159035" - y1="21.171064" - x2="63.159035" - y2="80.12056" /> + x1="12.169124" + y1="95.972382" + x2="12.169124" + y2="108" + gradientTransform="matrix(-1,0,0,1,64.077922,22.025974)" /> <linearGradient inkscape:collect="always" - xlink:href="#linearGradient3710" - id="linearGradient8271" + xlink:href="#linearGradient4157" + id="linearGradient3817" gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.0533333,0,0,0.9219945,11.76,4.9924269)" - x1="73.739265" - y1="69.923088" - x2="35.568035" - y2="48.212151" /> + x1="5.7885823" + y1="96" + x2="5.7885823" + y2="108.05248" + gradientTransform="translate(50.077922,6.025974)" /> <linearGradient inkscape:collect="always" - xlink:href="#linearGradient3710" - id="linearGradient8273" + xlink:href="#linearGradient4157" + id="linearGradient3837" gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.0533333,0,0,0.9219945,11.76,4.9924269)" - x1="63.159035" - y1="21.171064" - x2="63.159035" - y2="80.12056" /> + x1="-32.05162" + y1="95.999352" + x2="-32.05162" + y2="107.97552" + gradientTransform="matrix(1.007874,0,0,1.0025224,50.204724,5.7578493)" /> <linearGradient inkscape:collect="always" - xlink:href="#XMLID_7_" - id="linearGradient8376" + xlink:href="#linearGradient4157" + id="linearGradient3866" gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.1772548,0,0,1.0772187,1.8462753,-4.9416701)" - x1="71.626404" - y1="123.73875" - x2="46.225941" - y2="28.942928" /> - <radialGradient - inkscape:collect="always" - xlink:href="#linearGradient3669" - id="radialGradient8378" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(0.9650814,0.2619502,-0.9201984,3.3902106,33.309062,-57.693239)" - cx="71.775223" - cy="16.0865" - fx="71.775223" - fy="16.0865" - r="3.15625" /> + x1="-33.9375" + y1="107.96875" + x2="-33.9375" + y2="96" + gradientTransform="matrix(0,1.007874,-1.002611,0,55.250652,80.204724)" /> <linearGradient inkscape:collect="always" - xlink:href="#linearGradient7133" - id="linearGradient8380" + xlink:href="#linearGradient4157" + id="linearGradient3875" gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.1772548,0,0,1.0772187,6.5552946,-4.9416701)" - x1="96.373123" - y1="120.42788" - x2="96.373123" - y2="46.089832" /> - <radialGradient - inkscape:collect="always" - xlink:href="#linearGradient7139" - id="radialGradient8382" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(0.9650814,0.2619502,-0.9201984,3.3902106,17.309062,-57.693239)" - cx="71.775223" - cy="16.0865" - fx="71.775223" - fy="16.0865" - r="3.15625" /> + x1="8.5" + y1="108" + x2="8.5" + y2="95.976585" + gradientTransform="matrix(0,1,-1,0,80,38.058976)" /> <linearGradient inkscape:collect="always" - xlink:href="#XMLID_5_" - id="linearGradient8384" + xlink:href="#linearGradient4157" + id="linearGradient3898" gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.0533333,0,0,0.9219945,7.5466667,4.9924269)" - x1="43.799026" - y1="32.051865" - x2="58.606159" - y2="96.363052" /> - <radialGradient - inkscape:collect="always" - xlink:href="#linearGradient3710" - id="radialGradient8386" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(6.5079869,0,0,1.510917,-63.772161,-32.970115)" - cx="11.578125" - cy="64.53125" - fx="11.578125" - fy="64.53125" - r="3.578125" /> - <radialGradient - inkscape:collect="always" - xlink:href="#XMLID_5_" - id="radialGradient8388" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.519949,7.3519239e-8,-8.0632435e-8,1.2772114,-20.224726,-23.996639)" - cx="53.630272" - cy="79.055809" - fx="57.058514" - fy="91.805016" - r="50" /> + x1="9.375001" + y1="108.0026" + x2="9.375001" + y2="95.999344" + gradientTransform="matrix(0,-1,-1,0,80,87.941024)" /> <linearGradient inkscape:collect="always" - xlink:href="#linearGradient7151" - id="linearGradient8390" + xlink:href="#linearGradient4157" + id="linearGradient4009" gradientUnits="userSpaceOnUse" - gradientTransform="translate(20,0)" - x1="91.785248" - y1="112.5" - x2="91.992706" - y2="44.287056" /> + gradientTransform="matrix(0,1,-1,0,80,38.058976)" + x1="8.5" + y1="108" + x2="8.5" + y2="95.976585" /> <linearGradient inkscape:collect="always" - xlink:href="#linearGradient7139" - id="linearGradient8392" + xlink:href="#linearGradient4157" + id="linearGradient4011" gradientUnits="userSpaceOnUse" - gradientTransform="translate(20,0)" - x1="91.785248" - y1="112.5" - x2="91.992706" - y2="44.287056" /> + gradientTransform="matrix(0,-1,-1,0,80,87.941024)" + x1="9.375001" + y1="108.0026" + x2="9.375001" + y2="95.999344" /> <linearGradient inkscape:collect="always" - xlink:href="#linearGradient7145" - id="linearGradient8394" + xlink:href="#linearGradient4157" + id="linearGradient4013" gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.0533333,0,0,0.9219945,11.76,4.9924269)" - x1="63.159035" - y1="21.171064" - x2="63.159035" - y2="80.12056" /> + gradientTransform="matrix(0,1.007874,-1.002611,0,55.250652,80.204724)" + x1="-33.9375" + y1="107.96875" + x2="-33.9375" + y2="96" /> <linearGradient inkscape:collect="always" - xlink:href="#linearGradient3710" - id="linearGradient8396" + xlink:href="#linearGradient4157" + id="linearGradient4061" gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.0533333,0,0,0.9219945,11.76,4.9924269)" - x1="73.739265" - y1="69.923088" - x2="35.568035" - y2="48.212151" /> + gradientTransform="translate(50.077922,6.025974)" + x1="5.7885823" + y1="96" + x2="5.7885823" + y2="108.05248" /> <linearGradient inkscape:collect="always" - xlink:href="#linearGradient3710" - id="linearGradient8398" + xlink:href="#linearGradient4157" + id="linearGradient4063" gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.0533333,0,0,0.9219945,11.76,4.9924269)" - x1="63.159035" - y1="21.171064" - x2="63.159035" - y2="80.12056" /> + gradientTransform="matrix(-1,0,0,1,64.077922,22.025974)" + x1="12.169124" + y1="95.972382" + x2="12.169124" + y2="108" /> <linearGradient inkscape:collect="always" - xlink:href="#linearGradient8126" - id="linearGradient8400" + xlink:href="#linearGradient4157" + id="linearGradient4065" gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.1772548,0,0,1.0772187,1.8462753,-4.9416701)" - x1="71.626404" - y1="123.73875" - x2="46.225941" - y2="28.942928" /> - <radialGradient - inkscape:collect="always" - xlink:href="#linearGradient3669" - id="radialGradient8402" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(0.9650814,0.2619502,-0.9201984,3.3902106,33.309062,-57.693239)" - cx="71.775223" - cy="16.0865" - fx="71.775223" - fy="16.0865" - r="3.15625" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient8132" - id="linearGradient8404" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.1772548,0,0,1.0772187,6.5552946,-4.9416701)" - x1="96.373123" - y1="120.42788" - x2="96.373123" - y2="46.089832" /> - <radialGradient - inkscape:collect="always" - xlink:href="#linearGradient8138" - id="radialGradient8406" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(0.9650814,0.2619502,-0.9201984,3.3902106,17.309062,-57.693239)" - cx="71.775223" - cy="16.0865" - fx="71.775223" - fy="16.0865" - r="3.15625" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient8144" - id="linearGradient8408" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.0533333,0,0,0.9219945,7.5466667,4.9924269)" - x1="43.799026" - y1="32.051865" - x2="58.606159" - y2="96.363052" /> - <radialGradient - inkscape:collect="always" - xlink:href="#linearGradient3710" - id="radialGradient8410" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(6.5079869,0,0,1.510917,-63.772161,-32.970115)" - cx="11.578125" - cy="64.53125" - fx="11.578125" - fy="64.53125" - r="3.578125" /> - <radialGradient - inkscape:collect="always" - xlink:href="#linearGradient8150" - id="radialGradient8412" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.519949,7.3519239e-8,-8.0632435e-8,1.2772114,-20.224726,-23.996639)" - cx="53.630272" - cy="79.055809" - fx="57.058514" - fy="91.805016" - r="50" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient8162" - id="linearGradient8414" - gradientUnits="userSpaceOnUse" - gradientTransform="translate(20,0)" - x1="91.785248" - y1="112.5" - x2="91.992706" - y2="44.287056" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient8156" - id="linearGradient8416" - gradientUnits="userSpaceOnUse" - gradientTransform="translate(20,0)" - x1="91.785248" - y1="112.5" - x2="91.992706" - y2="44.287056" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient3711" - id="linearGradient8418" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.0533333,0,0,0.9219945,11.76,4.9924269)" - x1="63.159035" - y1="21.171064" - x2="63.159035" - y2="80.12056" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient3710" - id="linearGradient8420" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.0533333,0,0,0.9219945,11.76,4.9924269)" - x1="73.739265" - y1="69.923088" - x2="35.568035" - y2="48.212151" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient3710" - id="linearGradient8422" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.0533333,0,0,0.9219945,11.76,4.9924269)" - x1="63.159035" - y1="21.171064" - x2="63.159035" - y2="80.12056" /> - <linearGradient - inkscape:collect="always" - xlink:href="#XMLID_7_" - id="linearGradient8480" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.1772548,0,0,1.0772187,1.8462753,-4.9416701)" - x1="71.626404" - y1="123.73875" - x2="46.225941" - y2="28.942928" /> - <radialGradient - inkscape:collect="always" - xlink:href="#linearGradient3669" - id="radialGradient8482" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(0.9650814,0.2619502,-0.9201984,3.3902106,33.309062,-57.693239)" - cx="71.775223" - cy="16.0865" - fx="71.775223" - fy="16.0865" - r="3.15625" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient7133" - id="linearGradient8484" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.1772548,0,0,1.0772187,6.5552946,-4.9416701)" - x1="96.373123" - y1="120.42788" - x2="96.373123" - y2="46.089832" /> - <radialGradient - inkscape:collect="always" - xlink:href="#linearGradient7139" - id="radialGradient8486" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(0.9650814,0.2619502,-0.9201984,3.3902106,17.309062,-57.693239)" - cx="71.775223" - cy="16.0865" - fx="71.775223" - fy="16.0865" - r="3.15625" /> - <linearGradient - inkscape:collect="always" - xlink:href="#XMLID_5_" - id="linearGradient8488" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.0533333,0,0,0.9219945,7.5466667,4.9924269)" - x1="43.799026" - y1="32.051865" - x2="58.606159" - y2="96.363052" /> - <radialGradient - inkscape:collect="always" - xlink:href="#linearGradient3710" - id="radialGradient8490" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(6.5079869,0,0,1.510917,-63.772161,-32.970115)" - cx="11.578125" - cy="64.53125" - fx="11.578125" - fy="64.53125" - r="3.578125" /> - <radialGradient - inkscape:collect="always" - xlink:href="#XMLID_5_" - id="radialGradient8492" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.519949,7.3519239e-8,-8.0632435e-8,1.2772114,-20.224726,-23.996639)" - cx="53.630272" - cy="79.055809" - fx="57.058514" - fy="91.805016" - r="50" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient7151" - id="linearGradient8494" - gradientUnits="userSpaceOnUse" - gradientTransform="translate(20,0)" - x1="91.785248" - y1="112.5" - x2="91.992706" - y2="44.287056" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient7139" - id="linearGradient8496" - gradientUnits="userSpaceOnUse" - gradientTransform="translate(20,0)" - x1="91.785248" - y1="112.5" - x2="91.992706" - y2="44.287056" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient7145" - id="linearGradient8498" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.0533333,0,0,0.9219945,11.76,4.9924269)" - x1="63.159035" - y1="21.171064" - x2="63.159035" - y2="80.12056" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient3710" - id="linearGradient8500" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.0533333,0,0,0.9219945,11.76,4.9924269)" - x1="73.739265" - y1="69.923088" - x2="35.568035" - y2="48.212151" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient3710" - id="linearGradient8502" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.0533333,0,0,0.9219945,11.76,4.9924269)" - x1="63.159035" - y1="21.171064" - x2="63.159035" - y2="80.12056" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient8126" - id="linearGradient8504" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.1772548,0,0,1.0772187,1.8462753,-4.9416701)" - x1="71.626404" - y1="123.73875" - x2="46.225941" - y2="28.942928" /> - <radialGradient - inkscape:collect="always" - xlink:href="#linearGradient3669" - id="radialGradient8506" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(0.9650814,0.2619502,-0.9201984,3.3902106,33.309062,-57.693239)" - cx="71.775223" - cy="16.0865" - fx="71.775223" - fy="16.0865" - r="3.15625" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient8132" - id="linearGradient8508" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.1772548,0,0,1.0772187,6.5552946,-4.9416701)" - x1="96.373123" - y1="120.42788" - x2="96.373123" - y2="46.089832" /> - <radialGradient - inkscape:collect="always" - xlink:href="#linearGradient8138" - id="radialGradient8510" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(0.9650814,0.2619502,-0.9201984,3.3902106,17.309062,-57.693239)" - cx="71.775223" - cy="16.0865" - fx="71.775223" - fy="16.0865" - r="3.15625" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient8144" - id="linearGradient8512" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.0533333,0,0,0.9219945,7.5466667,4.9924269)" - x1="43.799026" - y1="32.051865" - x2="58.606159" - y2="96.363052" /> - <radialGradient - inkscape:collect="always" - xlink:href="#linearGradient3710" - id="radialGradient8514" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(6.5079869,0,0,1.510917,-63.772161,-32.970115)" - cx="11.578125" - cy="64.53125" - fx="11.578125" - fy="64.53125" - r="3.578125" /> - <radialGradient - inkscape:collect="always" - xlink:href="#linearGradient8150" - id="radialGradient8516" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.519949,7.3519239e-8,-8.0632435e-8,1.2772114,-20.224726,-23.996639)" - cx="53.630272" - cy="79.055809" - fx="57.058514" - fy="91.805016" - r="50" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient8162" - id="linearGradient8518" - gradientUnits="userSpaceOnUse" - gradientTransform="translate(20,0)" - x1="91.785248" - y1="112.5" - x2="91.992706" - y2="44.287056" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient8156" - id="linearGradient8520" - gradientUnits="userSpaceOnUse" - gradientTransform="translate(20,0)" - x1="91.785248" - y1="112.5" - x2="91.992706" - y2="44.287056" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient3711" - id="linearGradient8522" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.0533333,0,0,0.9219945,11.76,4.9924269)" - x1="63.159035" - y1="21.171064" - x2="63.159035" - y2="80.12056" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient3710" - id="linearGradient8524" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.0533333,0,0,0.9219945,11.76,4.9924269)" - x1="73.739265" - y1="69.923088" - x2="35.568035" - y2="48.212151" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient3710" - id="linearGradient8526" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.0533333,0,0,0.9219945,11.76,4.9924269)" - x1="63.159035" - y1="21.171064" - x2="63.159035" - y2="80.12056" /> - <radialGradient - inkscape:collect="always" - xlink:href="#linearGradient3272" - id="radialGradient3600" - cx="88" - cy="93.5" - fx="88" - fy="93.5" - r="8" - gradientTransform="matrix(1,0,0,2.2075201,0,-112.90313)" - gradientUnits="userSpaceOnUse" /> - <radialGradient - inkscape:collect="always" - xlink:href="#linearGradient3272" - id="radialGradient3604" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1,0,0,2.2075201,0,-97.90313)" - cx="88" - cy="93.5" - fx="88" - fy="93.5" - r="8" /> - <radialGradient - inkscape:collect="always" - xlink:href="#linearGradient3272" - id="radialGradient3608" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.8125,0,0,2.2075201,-143.20779,-217.90313)" - cx="88" - cy="93.5" - fx="88" - fy="93.5" - r="8" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient3578" - id="linearGradient3620" - gradientUnits="userSpaceOnUse" - gradientTransform="translate(96,-4.0000076)" - x1="-8" - y1="98.130508" - x2="-8" - y2="126.82455" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient3578" - id="linearGradient3640" - gradientUnits="userSpaceOnUse" - gradientTransform="translate(96,-4.0000076)" - x1="-8" - y1="98.130508" - x2="-8" - y2="126.82455" /> - <radialGradient - inkscape:collect="always" - xlink:href="#linearGradient3272" - id="radialGradient3642" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1,0,0,2.2075201,0,-112.90313)" - cx="88" - cy="93.5" - fx="88" - fy="93.5" - r="8" /> - <radialGradient - inkscape:collect="always" - xlink:href="#linearGradient3272" - id="radialGradient3644" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1,0,0,2.2075201,0,-97.90313)" - cx="88" - cy="93.5" - fx="88" - fy="93.5" - r="8" /> - <radialGradient - inkscape:collect="always" - xlink:href="#linearGradient3272" - id="radialGradient3646" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.8125,0,0,2.2075201,-134,-173.90313)" - cx="88" - cy="93.5" - fx="88" - fy="93.5" - r="8" /> - <radialGradient - inkscape:collect="always" - xlink:href="#linearGradient3272" - id="radialGradient3649" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1,0,0,2.2075201,0,-97.90313)" - cx="88" - cy="93.5" - fx="88" - fy="93.5" - r="8" /> - <radialGradient - inkscape:collect="always" - xlink:href="#linearGradient3272" - id="radialGradient3652" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1,0,0,2.2075201,0,-112.90313)" - cx="88" - cy="93.5" - fx="88" - fy="93.5" - r="8" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient3578" - id="linearGradient3658" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1,0,0,0.875,96,9.9999934)" - x1="-8" - y1="98.130508" - x2="-8" - y2="126.82455" /> - <radialGradient - inkscape:collect="always" - xlink:href="#linearGradient3272" - id="radialGradient3691" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1,0,0,2.2075201,0,-112.90313)" - cx="88" - cy="93.5" - fx="88" - fy="93.5" - r="8" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient3578" - id="linearGradient3693" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1,0,0,0.875,96,9.9999934)" - x1="-8" - y1="98.130508" - x2="-8" - y2="126.82455" /> - <radialGradient - inkscape:collect="always" - xlink:href="#linearGradient3272" - id="radialGradient3695" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1,0,0,2.2075201,0,-97.90313)" - cx="88" - cy="93.5" - fx="88" - fy="93.5" - r="8" /> - <radialGradient - inkscape:collect="always" - xlink:href="#linearGradient3272" - id="radialGradient2653" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1,0,0,2.2075201,0,-112.90313)" - cx="88" - cy="93.5" - fx="88" - fy="93.5" - r="8" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient3578" - id="linearGradient2655" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1,0,0,0.875,96,9.9999934)" - x1="-8" - y1="98.130508" - x2="-8" - y2="126.82455" /> - <radialGradient - inkscape:collect="always" - xlink:href="#linearGradient3272" - id="radialGradient2669" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1,0,0,2.2075201,0,-112.90313)" - cx="88" - cy="93.5" - fx="88" - fy="93.5" - r="8" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient3578" - id="linearGradient2671" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1,0,0,0.875,96,9.9999934)" - x1="-8" - y1="98.130508" - x2="-8" - y2="126.82455" /> + gradientTransform="matrix(1.007874,0,0,1.0025224,50.204724,5.7578493)" + x1="-32.05162" + y1="95.999352" + x2="-32.05162" + y2="107.97552" /> </defs> <sodipodi:namedview id="base" @@ -2587,21 +602,34 @@ objecttolerance="10" inkscape:pageopacity="0.0" inkscape:pageshadow="2" - inkscape:zoom="3.4029514" - inkscape:cx="64.194623" - inkscape:cy="70.741477" + inkscape:zoom="1" + inkscape:cx="173.28073" + inkscape:cy="199.64214" inkscape:document-units="px" inkscape:current-layer="layer1" width="128px" height="128px" showgrid="true" - gridspacingx="1px" - gridspacingy="1px" - gridempspacing="2" - inkscape:window-width="792" - inkscape:window-height="728" - inkscape:window-x="55" - inkscape:window-y="165" /> + inkscape:window-width="1110" + inkscape:window-height="710" + inkscape:window-x="560" + inkscape:window-y="0" + inkscape:snap-nodes="true"> + <inkscape:grid + id="GridFromPre046Settings" + type="xygrid" + originx="0px" + originy="0px" + spacingx="1px" + spacingy="1px" + color="#0000ff" + empcolor="#0000ff" + opacity="0.2" + empopacity="0.4" + empspacing="2" + visible="true" + enabled="true" /> + </sodipodi:namedview> <metadata id="metadata7"> <rdf:RDF> @@ -2618,779 +646,27 @@ inkscape:groupmode="layer" id="layer1"> <rect + y="6.1168857" + x="25.441563" + height="52" + width="78" + id="rect2925" + style="opacity:1;fill:#0f0f0f;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.7750001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + transform="matrix(0,1,-1,0,0,0)" /> + <rect + style="opacity:1;fill:#0f0f0f;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.7750001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + id="rect3651" + width="78" + height="52" + x="-1.9220779" + y="86.025978" /> + <rect style="opacity:0.65;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" id="rect3610" width="32" height="36.20779" x="8" y="-0.20779037" /> - <g - id="south-maxslider" - transform="matrix(0,-0.1499001,0.1428242,0,30.859856,110.39441)"> - <path - transform="matrix(1.0533333,0,0,1.0173732,-5.0933333,-1.1118124)" - id="path3519" - d="M 87.875,12 C 87.009497,12.026935 86.176101,12.333976 85.5,12.875 L 25.5,60.875 C 24.550144,61.634129 24,62.784063 24,64 C 24,65.215937 24.550144,66.365871 25.5,67.125 L 85.5,115.125 C 86.700963,116.08613 88.332437,116.26025 89.71875,115.59375 C 91.105067,114.92725 92.000642,113.53821 92,112 L 92,88.3125 L 92,78.0625 L 90.5,76.875 C 89.299037,75.91387 87.667563,75.739753 86.28125,76.40625 C 84.894933,77.072748 83.999358,78.461793 84,80 L 84,103.6875 L 34.40625,64 L 84,24.3125 L 84,48 C 83.999358,49.538207 84.894936,50.927253 86.28125,51.59375 C 87.66756,52.260246 89.299037,52.08613 90.5,51.125 L 92,49.9375 L 92,39.6875 L 92,16 C 92.000417,14.917152 91.558627,13.878821 90.78125,13.125 C 90.003873,12.37118 88.957323,11.966273 87.875,12 z " - style="opacity:0.90526321;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#0020f4;stroke-width:0.9659996;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3533)" /> - <path - id="path3302" - d="M 91.17049,7.9849542 C 90.151573,8.0139691 89.170453,8.3447195 88.37451,8.9275206 L 17.739215,60.634018 C 16.620992,61.451766 15.973333,62.690496 15.973333,64.000327 C 15.973333,65.310157 16.620992,66.548887 17.739215,67.366635 L 88.37451,119.07313 C 89.788349,120.10848 91.70901,120.29604 93.341053,119.57808 C 94.973103,118.86011 96.027425,117.36381 96.026667,115.70683 L 96.026667,90.190206 L 96.026667,85.410048 L 96.026667,79.148715 L 96.026667,48.851939 L 96.026667,43.533172 L 96.026667,37.810447 L 96.026667,12.293829 C 96.027162,11.127365 95.507058,10.008855 94.591887,9.1968255 C 93.676716,8.3847962 92.44466,7.9486229 91.17049,7.9849542 z M 86.608627,21.248209 L 86.608627,42.455952 L 68.949804,42.455952 C 68.297605,42.455952 67.772548,42.936393 67.772548,43.533172 L 67.772548,85.410048 C 67.772548,86.006828 68.297605,86.487267 68.949804,86.487267 L 86.608627,86.487267 L 86.608627,106.75245 L 28.224141,64.000327 L 86.608627,21.248209 z " - style="fill:url(#linearGradient2360);fill-opacity:1.0;fill-rule:evenodd;stroke:none;stroke-width:8;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> - <path - transform="matrix(1.0533333,0,0,1.0173732,-5.0933333,-1.1118124)" - id="path3651" - d="M 87.875,12 C 87.075959,12.024867 86.302054,12.283948 85.65625,12.75 L 86.625,21.78125 L 91.96875,15.625 C 91.880958,14.678789 91.469257,13.792159 90.78125,13.125 C 90.003873,12.37118 88.957323,11.966273 87.875,12 z " - style="opacity:0.85;fill:url(#radialGradient2362);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:8;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3681)" /> - <path - id="path3509" - d="M 91.17049,7.9849542 C 90.151573,8.0139691 89.170453,8.3447195 88.37451,8.9275206 L 17.739215,60.634018 C 16.620992,61.451766 15.973333,62.690496 15.973333,64.000327 C 15.973333,65.310157 16.620992,66.548887 17.739215,67.366635 L 88.37451,119.07313 C 89.788349,120.10848 91.70901,120.29604 93.341053,119.57808 C 94.973103,118.86011 96.027425,117.36381 96.026667,115.70683 L 96.026667,90.190206 L 96.026667,85.410048 L 96.026667,84.66946 L 96.026667,79.148715 L 96.026667,48.851939 L 96.026667,43.533172 L 96.026667,43.331192 L 96.026667,37.810447 L 96.026667,12.293829 C 96.027162,11.127365 95.507058,10.008855 94.591887,9.1968255 C 93.676716,8.3847962 92.44466,7.9486229 91.17049,7.9849542 z M 86.608627,21.248209 L 86.608627,42.455952 L 68.949804,42.455952 C 68.297605,42.455952 67.772548,42.936393 67.772548,43.533172 L 67.772548,85.410048 C 67.772548,86.006828 68.297605,86.487267 68.949804,86.487267 L 86.608627,86.487267 L 86.608627,106.75245 L 28.224141,64.000327 L 86.608627,21.248209 z " - style="opacity:0.90526321;fill:url(#linearGradient2364);fill-opacity:1.0;fill-rule:evenodd;stroke:none;stroke-width:8;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> - <path - transform="matrix(1.0533333,0,0,-1.0173732,11.76,128.88743)" - style="opacity:0.35;fill:url(#radialGradient2366);fill-opacity:1.0;fill-rule:evenodd;stroke:none;stroke-width:8;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3681)" - d="M 71.875,12 C 71.075959,12.024867 70.302054,12.283948 69.65625,12.75 L 70.625,21.78125 L 75.96875,15.625 C 75.880958,14.678789 75.469257,13.792159 74.78125,13.125 C 74.003873,12.37118 72.957323,11.966273 71.875,12 z " - id="path3685" /> - <path - sodipodi:nodetypes="cccc" - id="path2323" - d="M 24.4,64.000073 L 87.6,19.744339 L 87.6,108.25581 L 24.4,64.000073 z " - style="fill:url(#linearGradient2368);fill-opacity:1.0;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> - <path - transform="matrix(1.0533333,0,0,-1.0173732,11.76,129.68423)" - id="path3705" - d="M 11.6875,59.125 L 9.5,60.875 C 8.5501441,61.634129 8,62.784063 8,64 C 8.0000001,65.215937 8.5501441,66.365871 9.5,67.125 L 13.03125,69.9375 L 15.15625,64.3125 L 11.6875,59.125 z " - style="opacity:0.5;fill:url(#radialGradient2370);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:8;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3722)" /> - <path - id="path3320" - d="M 87.6,19.744339 L 24.4,64.000073 L 87.6,108.25581 L 87.6,78.751985 L 87.6,49.248162 L 87.6,19.744339 z " - style="fill:url(#radialGradient2372);fill-opacity:1.0;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> - <path - transform="matrix(1.0533333,0,0,0.9219945,-9.3066667,4.9924269)" - id="path3394" - d="M 92,16 L 32,64 L 92,112 L 92,80 L 92,48 L 92,16 z " - style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient2374);stroke-width:1.0147357px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3396)" /> - <path - transform="matrix(1.0533333,0,0,0.9219945,-9.3066667,4.9924269)" - style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient2376);stroke-width:1.0147357px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3396)" - d="M 92,16 L 32,64 L 92,112 L 92,80 L 92,48 L 92,16 z " - id="path3895" /> - <path - id="path3897" - d="M 87.6,19.744339 L 24.531667,63.913636 C 31.325523,64.772472 38.548578,65.239004 46.059167,65.239003 C 61.572821,65.239003 75.930219,63.261985 87.6,59.908723 L 87.6,49.248162 L 87.6,19.744339 z " - style="fill:url(#linearGradient2378);fill-opacity:1.0;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> - <path - id="path3910" - d="M 87.6,19.744339 L 86.71125,20.37821 L 86.71125,48.84479 L 86.71125,59.361289 C 75.203203,62.668078 61.061565,64.605133 45.762917,64.605133 C 38.631436,64.605133 31.769756,64.182739 25.28875,63.395014 L 24.531667,63.913636 C 31.325523,64.772472 38.548578,65.239004 46.059167,65.239003 C 61.572821,65.239003 75.930219,63.261985 87.6,59.908723 L 87.6,49.248162 L 87.6,19.744339 z " - style="fill:url(#linearGradient2380);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> - <path - id="path3919" - d="M 87.6,19.744339 L 24.531667,63.913636 C 28.122981,64.367627 31.847249,64.698286 35.6575,64.922068 C 32.169447,64.704673 28.75029,64.35923 25.453333,63.942448 L 86.678333,21.069705 L 86.678333,49.709159 L 86.678333,60.052784 C 82.430956,61.273251 77.821812,62.321664 72.919167,63.135704 C 78.150964,62.285094 83.084328,61.206282 87.6,59.908723 L 87.6,49.248162 L 87.6,19.744339 z M 35.6575,64.922068 C 37.402503,65.024555 39.172559,65.101717 40.957083,65.152566 C 39.171728,65.097092 37.401526,65.030765 35.6575,64.922068 z " - style="fill:url(#linearGradient2382);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> - </g> - <g - id="east-minslider" - inkscape:label="Layer 1" - transform="matrix(0.1499001,0,0,0.1428242,109.60559,38.859855)"> - <path - transform="matrix(1.0533333,0,0,1.0173732,-5.0933333,-1.1118124)" - id="path2719" - d="M 87.875,12 C 87.009497,12.026935 86.176101,12.333976 85.5,12.875 L 25.5,60.875 C 24.550144,61.634129 24,62.784063 24,64 C 24,65.215937 24.550144,66.365871 25.5,67.125 L 85.5,115.125 C 86.700963,116.08613 88.332437,116.26025 89.71875,115.59375 C 91.105067,114.92725 92.000642,113.53821 92,112 L 92,88.3125 L 92,78.0625 L 90.5,76.875 C 89.299037,75.91387 87.667563,75.739753 86.28125,76.40625 C 84.894933,77.072748 83.999358,78.461793 84,80 L 84,103.6875 L 34.40625,64 L 84,24.3125 L 84,48 C 83.999358,49.538207 84.894936,50.927253 86.28125,51.59375 C 87.66756,52.260246 89.299037,52.08613 90.5,51.125 L 92,49.9375 L 92,39.6875 L 92,16 C 92.000417,14.917152 91.558627,13.878821 90.78125,13.125 C 90.003873,12.37118 88.957323,11.966273 87.875,12 z " - style="opacity:0.90526321;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#638000;stroke-width:0.9659996;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3533)" /> - <path - id="path2721" - d="M 91.17049,7.9849542 C 90.151573,8.0139691 89.170453,8.3447195 88.37451,8.9275206 L 17.739215,60.634018 C 16.620992,61.451766 15.973333,62.690496 15.973333,64.000327 C 15.973333,65.310157 16.620992,66.548887 17.739215,67.366635 L 88.37451,119.07313 C 89.788349,120.10848 91.70901,120.29604 93.341053,119.57808 C 94.973103,118.86011 96.027425,117.36381 96.026667,115.70683 L 96.026667,90.190206 L 96.026667,85.410048 L 96.026667,79.148715 L 96.026667,48.851939 L 96.026667,43.533172 L 96.026667,37.810447 L 96.026667,12.293829 C 96.027162,11.127365 95.507058,10.008855 94.591887,9.1968255 C 93.676716,8.3847962 92.44466,7.9486229 91.17049,7.9849542 z M 86.608627,21.248209 L 86.608627,42.455952 L 68.949804,42.455952 C 68.297605,42.455952 67.772548,42.936393 67.772548,43.533172 L 67.772548,85.410048 C 67.772548,86.006828 68.297605,86.487267 68.949804,86.487267 L 86.608627,86.487267 L 86.608627,106.75245 L 28.224141,64.000327 L 86.608627,21.248209 z " - style="fill:url(#linearGradient2338);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:8;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> - <path - transform="matrix(1.0533333,0,0,1.0173732,-5.0933333,-1.1118124)" - id="path2723" - d="M 87.875,12 C 87.075959,12.024867 86.302054,12.283948 85.65625,12.75 L 86.625,21.78125 L 91.96875,15.625 C 91.880958,14.678789 91.469257,13.792159 90.78125,13.125 C 90.003873,12.37118 88.957323,11.966273 87.875,12 z " - style="opacity:0.85;fill:url(#radialGradient2335);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:8;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3681)" /> - <path - id="path2725" - d="M 91.17049,7.9849542 C 90.151573,8.0139691 89.170453,8.3447195 88.37451,8.9275206 L 17.739215,60.634018 C 16.620992,61.451766 15.973333,62.690496 15.973333,64.000327 C 15.973333,65.310157 16.620992,66.548887 17.739215,67.366635 L 88.37451,119.07313 C 89.788349,120.10848 91.70901,120.29604 93.341053,119.57808 C 94.973103,118.86011 96.027425,117.36381 96.026667,115.70683 L 96.026667,90.190206 L 96.026667,85.410048 L 96.026667,84.66946 L 96.026667,79.148715 L 96.026667,48.851939 L 96.026667,43.533172 L 96.026667,43.331192 L 96.026667,37.810447 L 96.026667,12.293829 C 96.027162,11.127365 95.507058,10.008855 94.591887,9.1968255 C 93.676716,8.3847962 92.44466,7.9486229 91.17049,7.9849542 z M 86.608627,21.248209 L 86.608627,42.455952 L 68.949804,42.455952 C 68.297605,42.455952 67.772548,42.936393 67.772548,43.533172 L 67.772548,85.410048 C 67.772548,86.006828 68.297605,86.487267 68.949804,86.487267 L 86.608627,86.487267 L 86.608627,106.75245 L 28.224141,64.000327 L 86.608627,21.248209 z " - style="opacity:0.90526321;fill:url(#linearGradient2332);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:8;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> - <path - transform="matrix(1.0533333,0,0,-1.0173732,11.76,128.88743)" - style="opacity:0.35;fill:url(#radialGradient2341);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:8;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3681)" - d="M 71.875,12 C 71.075959,12.024867 70.302054,12.283948 69.65625,12.75 L 70.625,21.78125 L 75.96875,15.625 C 75.880958,14.678789 75.469257,13.792159 74.78125,13.125 C 74.003873,12.37118 72.957323,11.966273 71.875,12 z " - id="path2727" /> - <path - sodipodi:nodetypes="cccc" - id="path2729" - d="M 24.4,64.000073 L 87.6,19.744339 L 87.6,108.25581 L 24.4,64.000073 z " - style="fill:url(#linearGradient2328);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> - <path - transform="matrix(1.0533333,0,0,-1.0173732,11.76,129.68423)" - id="path2731" - d="M 11.6875,59.125 L 9.5,60.875 C 8.5501441,61.634129 8,62.784063 8,64 C 8.0000001,65.215937 8.5501441,66.365871 9.5,67.125 L 13.03125,69.9375 L 15.15625,64.3125 L 11.6875,59.125 z " - style="opacity:0.5;fill:url(#radialGradient2343);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:8;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3722)" /> - <path - id="path2733" - d="M 87.6,19.744339 L 24.4,64.000073 L 87.6,108.25581 L 87.6,78.751985 L 87.6,49.248162 L 87.6,19.744339 z " - style="fill:url(#radialGradient2324);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> - <path - transform="matrix(1.0533333,0,0,0.9219945,-9.3066667,4.9924269)" - id="path2735" - d="M 92,16 L 32,64 L 92,112 L 92,80 L 92,48 L 92,16 z " - style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient2321);stroke-width:1.0147357px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3396)" /> - <path - transform="matrix(1.0533333,0,0,0.9219945,-9.3066667,4.9924269)" - style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient2318);stroke-width:1.0147357px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3396)" - d="M 92,16 L 32,64 L 92,112 L 92,80 L 92,48 L 92,16 z " - id="path2737" /> - <path - id="path2739" - d="M 87.6,19.744339 L 24.531667,63.913636 C 31.325523,64.772472 38.548578,65.239004 46.059167,65.239003 C 61.572821,65.239003 75.930219,63.261985 87.6,59.908723 L 87.6,49.248162 L 87.6,19.744339 z " - style="fill:url(#linearGradient2315);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> - <path - id="path2741" - d="M 87.6,19.744339 L 86.71125,20.37821 L 86.71125,48.84479 L 86.71125,59.361289 C 75.203203,62.668078 61.061565,64.605133 45.762917,64.605133 C 38.631436,64.605133 31.769756,64.182739 25.28875,63.395014 L 24.531667,63.913636 C 31.325523,64.772472 38.548578,65.239004 46.059167,65.239003 C 61.572821,65.239003 75.930219,63.261985 87.6,59.908723 L 87.6,49.248162 L 87.6,19.744339 z " - style="fill:url(#linearGradient2312);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> - <path - id="path2743" - d="M 87.6,19.744339 L 24.531667,63.913636 C 28.122981,64.367627 31.847249,64.698286 35.6575,64.922068 C 32.169447,64.704673 28.75029,64.35923 25.453333,63.942448 L 86.678333,21.069705 L 86.678333,49.709159 L 86.678333,60.052784 C 82.430956,61.273251 77.821812,62.321664 72.919167,63.135704 C 78.150964,62.285094 83.084328,61.206282 87.6,59.908723 L 87.6,49.248162 L 87.6,19.744339 z M 35.6575,64.922068 C 37.402503,65.024555 39.172559,65.101717 40.957083,65.152566 C 39.171728,65.097092 37.401526,65.030765 35.6575,64.922068 z " - style="fill:url(#linearGradient2309);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> - </g> - <g - id="south-minslider" - inkscape:label="Layer 1" - transform="matrix(0.1428242,0,0,0.1499001,30.857407,108.4104)"> - <g - transform="matrix(0,1,1,0,1.7146484e-2,7.9733326)" - id="g3688"> - <path - style="opacity:0.90526321;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#638000;stroke-width:0.9659996;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3533)" - d="M 87.875,12 C 87.009497,12.026935 86.176101,12.333976 85.5,12.875 L 25.5,60.875 C 24.550144,61.634129 24,62.784063 24,64 C 24,65.215937 24.550144,66.365871 25.5,67.125 L 85.5,115.125 C 86.700963,116.08613 88.332437,116.26025 89.71875,115.59375 C 91.105067,114.92725 92.000642,113.53821 92,112 L 92,88.3125 L 92,78.0625 L 90.5,76.875 C 89.299037,75.91387 87.667563,75.739753 86.28125,76.40625 C 84.894933,77.072748 83.999358,78.461793 84,80 L 84,103.6875 L 34.40625,64 L 84,24.3125 L 84,48 C 83.999358,49.538207 84.894936,50.927253 86.28125,51.59375 C 87.66756,52.260246 89.299037,52.08613 90.5,51.125 L 92,49.9375 L 92,39.6875 L 92,16 C 92.000417,14.917152 91.558627,13.878821 90.78125,13.125 C 90.003873,12.37118 88.957323,11.966273 87.875,12 z " - id="path3690" - transform="matrix(1.0533333,0,0,1.0173732,-5.0933333,-1.1118124)" /> - <path - style="fill:url(#linearGradient3716);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:8;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" - d="M 91.17049,7.9849542 C 90.151573,8.0139691 89.170453,8.3447195 88.37451,8.9275206 L 17.739215,60.634018 C 16.620992,61.451766 15.973333,62.690496 15.973333,64.000327 C 15.973333,65.310157 16.620992,66.548887 17.739215,67.366635 L 88.37451,119.07313 C 89.788349,120.10848 91.70901,120.29604 93.341053,119.57808 C 94.973103,118.86011 96.027425,117.36381 96.026667,115.70683 L 96.026667,90.190206 L 96.026667,85.410048 L 96.026667,79.148715 L 96.026667,48.851939 L 96.026667,43.533172 L 96.026667,37.810447 L 96.026667,12.293829 C 96.027162,11.127365 95.507058,10.008855 94.591887,9.1968255 C 93.676716,8.3847962 92.44466,7.9486229 91.17049,7.9849542 z M 86.608627,21.248209 L 86.608627,42.455952 L 68.949804,42.455952 C 68.297605,42.455952 67.772548,42.936393 67.772548,43.533172 L 67.772548,85.410048 C 67.772548,86.006828 68.297605,86.487267 68.949804,86.487267 L 86.608627,86.487267 L 86.608627,106.75245 L 28.224141,64.000327 L 86.608627,21.248209 z " - id="path3692" /> - <path - style="opacity:0.85;fill:url(#radialGradient3718);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:8;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3681)" - d="M 87.875,12 C 87.075959,12.024867 86.302054,12.283948 85.65625,12.75 L 86.625,21.78125 L 91.96875,15.625 C 91.880958,14.678789 91.469257,13.792159 90.78125,13.125 C 90.003873,12.37118 88.957323,11.966273 87.875,12 z " - id="path3694" - transform="matrix(1.0533333,0,0,1.0173732,-5.0933333,-1.1118124)" /> - <path - style="opacity:0.90526321;fill:url(#linearGradient3720);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:8;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" - d="M 91.17049,7.9849542 C 90.151573,8.0139691 89.170453,8.3447195 88.37451,8.9275206 L 17.739215,60.634018 C 16.620992,61.451766 15.973333,62.690496 15.973333,64.000327 C 15.973333,65.310157 16.620992,66.548887 17.739215,67.366635 L 88.37451,119.07313 C 89.788349,120.10848 91.70901,120.29604 93.341053,119.57808 C 94.973103,118.86011 96.027425,117.36381 96.026667,115.70683 L 96.026667,90.190206 L 96.026667,85.410048 L 96.026667,84.66946 L 96.026667,79.148715 L 96.026667,48.851939 L 96.026667,43.533172 L 96.026667,43.331192 L 96.026667,37.810447 L 96.026667,12.293829 C 96.027162,11.127365 95.507058,10.008855 94.591887,9.1968255 C 93.676716,8.3847962 92.44466,7.9486229 91.17049,7.9849542 z M 86.608627,21.248209 L 86.608627,42.455952 L 68.949804,42.455952 C 68.297605,42.455952 67.772548,42.936393 67.772548,43.533172 L 67.772548,85.410048 C 67.772548,86.006828 68.297605,86.487267 68.949804,86.487267 L 86.608627,86.487267 L 86.608627,106.75245 L 28.224141,64.000327 L 86.608627,21.248209 z " - id="path3696" /> - <path - id="path3698" - d="M 71.875,12 C 71.075959,12.024867 70.302054,12.283948 69.65625,12.75 L 70.625,21.78125 L 75.96875,15.625 C 75.880958,14.678789 75.469257,13.792159 74.78125,13.125 C 74.003873,12.37118 72.957323,11.966273 71.875,12 z " - style="opacity:0.35;fill:url(#radialGradient3722);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:8;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3681)" - transform="matrix(1.0533333,0,0,-1.0173732,11.76,128.88743)" /> - <path - style="fill:url(#linearGradient3724);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - d="M 24.4,64.000073 L 87.6,19.744339 L 87.6,108.25581 L 24.4,64.000073 z " - id="path3700" - sodipodi:nodetypes="cccc" /> - <path - style="opacity:0.5;fill:url(#radialGradient3726);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:8;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3722)" - d="M 11.6875,59.125 L 9.5,60.875 C 8.5501441,61.634129 8,62.784063 8,64 C 8.0000001,65.215937 8.5501441,66.365871 9.5,67.125 L 13.03125,69.9375 L 15.15625,64.3125 L 11.6875,59.125 z " - id="path3702" - transform="matrix(1.0533333,0,0,-1.0173732,11.76,129.68423)" /> - <path - style="fill:url(#radialGradient3728);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - d="M 87.6,19.744339 L 24.4,64.000073 L 87.6,108.25581 L 87.6,78.751985 L 87.6,49.248162 L 87.6,19.744339 z " - id="path3704" /> - <path - style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient3730);stroke-width:1.0147357px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3396)" - d="M 92,16 L 32,64 L 92,112 L 92,80 L 92,48 L 92,16 z " - id="path3706" - transform="matrix(1.0533333,0,0,0.9219945,-9.3066667,4.9924269)" /> - <path - id="path3708" - d="M 92,16 L 32,64 L 92,112 L 92,80 L 92,48 L 92,16 z " - style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient3732);stroke-width:1.0147357px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3396)" - transform="matrix(1.0533333,0,0,0.9219945,-9.3066667,4.9924269)" /> - <path - style="fill:url(#linearGradient3734);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - d="M 87.6,19.744339 L 24.531667,63.913636 C 31.325523,64.772472 38.548578,65.239004 46.059167,65.239003 C 61.572821,65.239003 75.930219,63.261985 87.6,59.908723 L 87.6,49.248162 L 87.6,19.744339 z " - id="path3710" /> - <path - style="fill:url(#linearGradient3736);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - d="M 87.6,19.744339 L 86.71125,20.37821 L 86.71125,48.84479 L 86.71125,59.361289 C 75.203203,62.668078 61.061565,64.605133 45.762917,64.605133 C 38.631436,64.605133 31.769756,64.182739 25.28875,63.395014 L 24.531667,63.913636 C 31.325523,64.772472 38.548578,65.239004 46.059167,65.239003 C 61.572821,65.239003 75.930219,63.261985 87.6,59.908723 L 87.6,49.248162 L 87.6,19.744339 z " - id="path3712" /> - <path - style="fill:url(#linearGradient3738);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - d="M 87.6,19.744339 L 24.531667,63.913636 C 28.122981,64.367627 31.847249,64.698286 35.6575,64.922068 C 32.169447,64.704673 28.75029,64.35923 25.453333,63.942448 L 86.678333,21.069705 L 86.678333,49.709159 L 86.678333,60.052784 C 82.430956,61.273251 77.821812,62.321664 72.919167,63.135704 C 78.150964,62.285094 83.084328,61.206282 87.6,59.908723 L 87.6,49.248162 L 87.6,19.744339 z M 35.6575,64.922068 C 37.402503,65.024555 39.172559,65.101717 40.957083,65.152566 C 39.171728,65.097092 37.401526,65.030765 35.6575,64.922068 z " - id="path3714" /> - </g> - </g> - <g - transform="matrix(0,-0.1499001,0.1428242,0,54.859856,110.39441)" - id="south-offsetslider"> - <path - style="opacity:0.90526321;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#b8b8b8;stroke-width:0.9659996;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3533)" - d="M 87.875,12 C 87.009497,12.026935 86.176101,12.333976 85.5,12.875 L 25.5,60.875 C 24.550144,61.634129 24,62.784063 24,64 C 24,65.215937 24.550144,66.365871 25.5,67.125 L 85.5,115.125 C 86.700963,116.08613 88.332437,116.26025 89.71875,115.59375 C 91.105067,114.92725 92.000642,113.53821 92,112 L 92,88.3125 L 92,78.0625 L 90.5,76.875 C 89.299037,75.91387 87.667563,75.739753 86.28125,76.40625 C 84.894933,77.072748 83.999358,78.461793 84,80 L 84,103.6875 L 34.40625,64 L 84,24.3125 L 84,48 C 83.999358,49.538207 84.894936,50.927253 86.28125,51.59375 C 87.66756,52.260246 89.299037,52.08613 90.5,51.125 L 92,49.9375 L 92,39.6875 L 92,16 C 92.000417,14.917152 91.558627,13.878821 90.78125,13.125 C 90.003873,12.37118 88.957323,11.966273 87.875,12 z " - id="path3760" - transform="matrix(1.0533333,0,0,1.0173732,-5.0933333,-1.1118124)" /> - <path - style="fill:url(#linearGradient3874);fill-opacity:1.0;fill-rule:evenodd;stroke:none;stroke-width:8;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" - d="M 91.17049,7.9849542 C 90.151573,8.0139691 89.170453,8.3447195 88.37451,8.9275206 L 17.739215,60.634018 C 16.620992,61.451766 15.973333,62.690496 15.973333,64.000327 C 15.973333,65.310157 16.620992,66.548887 17.739215,67.366635 L 88.37451,119.07313 C 89.788349,120.10848 91.70901,120.29604 93.341053,119.57808 C 94.973103,118.86011 96.027425,117.36381 96.026667,115.70683 L 96.026667,90.190206 L 96.026667,85.410048 L 96.026667,79.148715 L 96.026667,48.851939 L 96.026667,43.533172 L 96.026667,37.810447 L 96.026667,12.293829 C 96.027162,11.127365 95.507058,10.008855 94.591887,9.1968255 C 93.676716,8.3847962 92.44466,7.9486229 91.17049,7.9849542 z M 86.608627,21.248209 L 86.608627,42.455952 L 68.949804,42.455952 C 68.297605,42.455952 67.772548,42.936393 67.772548,43.533172 L 67.772548,85.410048 C 67.772548,86.006828 68.297605,86.487267 68.949804,86.487267 L 86.608627,86.487267 L 86.608627,106.75245 L 28.224141,64.000327 L 86.608627,21.248209 z " - id="path3762" /> - <path - style="opacity:0.85;fill:url(#radialGradient3876);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:8;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3681)" - d="M 87.875,12 C 87.075959,12.024867 86.302054,12.283948 85.65625,12.75 L 86.625,21.78125 L 91.96875,15.625 C 91.880958,14.678789 91.469257,13.792159 90.78125,13.125 C 90.003873,12.37118 88.957323,11.966273 87.875,12 z " - id="path3764" - transform="matrix(1.0533333,0,0,1.0173732,-5.0933333,-1.1118124)" /> - <path - style="opacity:0.90526321;fill:url(#linearGradient3878);fill-opacity:1.0;fill-rule:evenodd;stroke:none;stroke-width:8;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" - d="M 91.17049,7.9849542 C 90.151573,8.0139691 89.170453,8.3447195 88.37451,8.9275206 L 17.739215,60.634018 C 16.620992,61.451766 15.973333,62.690496 15.973333,64.000327 C 15.973333,65.310157 16.620992,66.548887 17.739215,67.366635 L 88.37451,119.07313 C 89.788349,120.10848 91.70901,120.29604 93.341053,119.57808 C 94.973103,118.86011 96.027425,117.36381 96.026667,115.70683 L 96.026667,90.190206 L 96.026667,85.410048 L 96.026667,84.66946 L 96.026667,79.148715 L 96.026667,48.851939 L 96.026667,43.533172 L 96.026667,43.331192 L 96.026667,37.810447 L 96.026667,12.293829 C 96.027162,11.127365 95.507058,10.008855 94.591887,9.1968255 C 93.676716,8.3847962 92.44466,7.9486229 91.17049,7.9849542 z M 86.608627,21.248209 L 86.608627,42.455952 L 68.949804,42.455952 C 68.297605,42.455952 67.772548,42.936393 67.772548,43.533172 L 67.772548,85.410048 C 67.772548,86.006828 68.297605,86.487267 68.949804,86.487267 L 86.608627,86.487267 L 86.608627,106.75245 L 28.224141,64.000327 L 86.608627,21.248209 z " - id="path3766" /> - <path - id="path3768" - d="M 71.875,12 C 71.075959,12.024867 70.302054,12.283948 69.65625,12.75 L 70.625,21.78125 L 75.96875,15.625 C 75.880958,14.678789 75.469257,13.792159 74.78125,13.125 C 74.003873,12.37118 72.957323,11.966273 71.875,12 z " - style="opacity:0.35;fill:url(#radialGradient3880);fill-opacity:1.0;fill-rule:evenodd;stroke:none;stroke-width:8;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3681)" - transform="matrix(1.0533333,0,0,-1.0173732,11.76,128.88743)" /> - <path - style="fill:url(#linearGradient3882);fill-opacity:1.0;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - d="M 24.4,64.000073 L 87.6,19.744339 L 87.6,108.25581 L 24.4,64.000073 z " - id="path3770" - sodipodi:nodetypes="cccc" /> - <path - style="opacity:0.5;fill:url(#radialGradient3884);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:8;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3722)" - d="M 11.6875,59.125 L 9.5,60.875 C 8.5501441,61.634129 8,62.784063 8,64 C 8.0000001,65.215937 8.5501441,66.365871 9.5,67.125 L 13.03125,69.9375 L 15.15625,64.3125 L 11.6875,59.125 z " - id="path3772" - transform="matrix(1.0533333,0,0,-1.0173732,11.76,129.68423)" /> - <path - style="fill:url(#radialGradient3886);fill-opacity:1.0;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - d="M 87.6,19.744339 L 24.4,64.000073 L 87.6,108.25581 L 87.6,78.751985 L 87.6,49.248162 L 87.6,19.744339 z " - id="path3774" /> - <path - style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient3888);stroke-width:1.0147357px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3396)" - d="M 92,16 L 32,64 L 92,112 L 92,80 L 92,48 L 92,16 z " - id="path3776" - transform="matrix(1.0533333,0,0,0.9219945,-9.3066667,4.9924269)" /> - <path - id="path3778" - d="M 92,16 L 32,64 L 92,112 L 92,80 L 92,48 L 92,16 z " - style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient3890);stroke-width:1.0147357px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3396)" - transform="matrix(1.0533333,0,0,0.9219945,-9.3066667,4.9924269)" /> - <path - style="fill:url(#linearGradient3892);fill-opacity:1.0;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - d="M 87.6,19.744339 L 24.531667,63.913636 C 31.325523,64.772472 38.548578,65.239004 46.059167,65.239003 C 61.572821,65.239003 75.930219,63.261985 87.6,59.908723 L 87.6,49.248162 L 87.6,19.744339 z " - id="path3780" /> - <path - style="fill:url(#linearGradient3894);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - d="M 87.6,19.744339 L 86.71125,20.37821 L 86.71125,48.84479 L 86.71125,59.361289 C 75.203203,62.668078 61.061565,64.605133 45.762917,64.605133 C 38.631436,64.605133 31.769756,64.182739 25.28875,63.395014 L 24.531667,63.913636 C 31.325523,64.772472 38.548578,65.239004 46.059167,65.239003 C 61.572821,65.239003 75.930219,63.261985 87.6,59.908723 L 87.6,49.248162 L 87.6,19.744339 z " - id="path3782" /> - <path - style="fill:url(#linearGradient3896);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - d="M 87.6,19.744339 L 24.531667,63.913636 C 28.122981,64.367627 31.847249,64.698286 35.6575,64.922068 C 32.169447,64.704673 28.75029,64.35923 25.453333,63.942448 L 86.678333,21.069705 L 86.678333,49.709159 L 86.678333,60.052784 C 82.430956,61.273251 77.821812,62.321664 72.919167,63.135704 C 78.150964,62.285094 83.084328,61.206282 87.6,59.908723 L 87.6,49.248162 L 87.6,19.744339 z M 35.6575,64.922068 C 37.402503,65.024555 39.172559,65.101717 40.957083,65.152566 C 39.171728,65.097092 37.401526,65.030765 35.6575,64.922068 z " - id="path3784" /> - </g> - <g - id="north-minslider" - transform="matrix(0,-0.1499001,0.1428242,0,70.859856,22.394407)"> - <path - transform="matrix(1.0533333,0,0,1.0173732,-5.0933333,-1.1118124)" - id="path3972" - d="M 87.875,12 C 87.009497,12.026935 86.176101,12.333976 85.5,12.875 L 25.5,60.875 C 24.550144,61.634129 24,62.784063 24,64 C 24,65.215937 24.550144,66.365871 25.5,67.125 L 85.5,115.125 C 86.700963,116.08613 88.332437,116.26025 89.71875,115.59375 C 91.105067,114.92725 92.000642,113.53821 92,112 L 92,88.3125 L 92,78.0625 L 90.5,76.875 C 89.299037,75.91387 87.667563,75.739753 86.28125,76.40625 C 84.894933,77.072748 83.999358,78.461793 84,80 L 84,103.6875 L 34.40625,64 L 84,24.3125 L 84,48 C 83.999358,49.538207 84.894936,50.927253 86.28125,51.59375 C 87.66756,52.260246 89.299037,52.08613 90.5,51.125 L 92,49.9375 L 92,39.6875 L 92,16 C 92.000417,14.917152 91.558627,13.878821 90.78125,13.125 C 90.003873,12.37118 88.957323,11.966273 87.875,12 z " - style="opacity:0.90526321;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#638000;stroke-width:0.9659996;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3533)" /> - <path - id="path3974" - d="M 91.17049,7.9849542 C 90.151573,8.0139691 89.170453,8.3447195 88.37451,8.9275206 L 17.739215,60.634018 C 16.620992,61.451766 15.973333,62.690496 15.973333,64.000327 C 15.973333,65.310157 16.620992,66.548887 17.739215,67.366635 L 88.37451,119.07313 C 89.788349,120.10848 91.70901,120.29604 93.341053,119.57808 C 94.973103,118.86011 96.027425,117.36381 96.026667,115.70683 L 96.026667,90.190206 L 96.026667,85.410048 L 96.026667,79.148715 L 96.026667,48.851939 L 96.026667,43.533172 L 96.026667,37.810447 L 96.026667,12.293829 C 96.027162,11.127365 95.507058,10.008855 94.591887,9.1968255 C 93.676716,8.3847962 92.44466,7.9486229 91.17049,7.9849542 z M 86.608627,21.248209 L 86.608627,42.455952 L 68.949804,42.455952 C 68.297605,42.455952 67.772548,42.936393 67.772548,43.533172 L 67.772548,85.410048 C 67.772548,86.006828 68.297605,86.487267 68.949804,86.487267 L 86.608627,86.487267 L 86.608627,106.75245 L 28.224141,64.000327 L 86.608627,21.248209 z " - style="fill:url(#linearGradient4028);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:8;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> - <path - transform="matrix(1.0533333,0,0,1.0173732,-5.0933333,-1.1118124)" - id="path3976" - d="M 87.875,12 C 87.075959,12.024867 86.302054,12.283948 85.65625,12.75 L 86.625,21.78125 L 91.96875,15.625 C 91.880958,14.678789 91.469257,13.792159 90.78125,13.125 C 90.003873,12.37118 88.957323,11.966273 87.875,12 z " - style="opacity:0.85;fill:url(#radialGradient4030);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:8;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3681)" /> - <path - id="path3978" - d="M 91.17049,7.9849542 C 90.151573,8.0139691 89.170453,8.3447195 88.37451,8.9275206 L 17.739215,60.634018 C 16.620992,61.451766 15.973333,62.690496 15.973333,64.000327 C 15.973333,65.310157 16.620992,66.548887 17.739215,67.366635 L 88.37451,119.07313 C 89.788349,120.10848 91.70901,120.29604 93.341053,119.57808 C 94.973103,118.86011 96.027425,117.36381 96.026667,115.70683 L 96.026667,90.190206 L 96.026667,85.410048 L 96.026667,84.66946 L 96.026667,79.148715 L 96.026667,48.851939 L 96.026667,43.533172 L 96.026667,43.331192 L 96.026667,37.810447 L 96.026667,12.293829 C 96.027162,11.127365 95.507058,10.008855 94.591887,9.1968255 C 93.676716,8.3847962 92.44466,7.9486229 91.17049,7.9849542 z M 86.608627,21.248209 L 86.608627,42.455952 L 68.949804,42.455952 C 68.297605,42.455952 67.772548,42.936393 67.772548,43.533172 L 67.772548,85.410048 C 67.772548,86.006828 68.297605,86.487267 68.949804,86.487267 L 86.608627,86.487267 L 86.608627,106.75245 L 28.224141,64.000327 L 86.608627,21.248209 z " - style="opacity:0.90526321;fill:url(#linearGradient4032);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:8;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> - <path - transform="matrix(1.0533333,0,0,-1.0173732,11.76,128.88743)" - style="opacity:0.35;fill:url(#radialGradient4034);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:8;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3681)" - d="M 71.875,12 C 71.075959,12.024867 70.302054,12.283948 69.65625,12.75 L 70.625,21.78125 L 75.96875,15.625 C 75.880958,14.678789 75.469257,13.792159 74.78125,13.125 C 74.003873,12.37118 72.957323,11.966273 71.875,12 z " - id="path3980" /> - <path - sodipodi:nodetypes="cccc" - id="path3982" - d="M 24.4,64.000073 L 87.6,19.744339 L 87.6,108.25581 L 24.4,64.000073 z " - style="fill:url(#linearGradient4036);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> - <path - transform="matrix(1.0533333,0,0,-1.0173732,11.76,129.68423)" - id="path3984" - d="M 11.6875,59.125 L 9.5,60.875 C 8.5501441,61.634129 8,62.784063 8,64 C 8.0000001,65.215937 8.5501441,66.365871 9.5,67.125 L 13.03125,69.9375 L 15.15625,64.3125 L 11.6875,59.125 z " - style="opacity:0.5;fill:url(#radialGradient4038);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:8;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3722)" /> - <path - id="path3986" - d="M 87.6,19.744339 L 24.4,64.000073 L 87.6,108.25581 L 87.6,78.751985 L 87.6,49.248162 L 87.6,19.744339 z " - style="fill:url(#radialGradient4040);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> - <path - transform="matrix(1.0533333,0,0,0.9219945,-9.3066667,4.9924269)" - id="path3988" - d="M 92,16 L 32,64 L 92,112 L 92,80 L 92,48 L 92,16 z " - style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient4042);stroke-width:1.0147357px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3396)" /> - <path - transform="matrix(1.0533333,0,0,0.9219945,-9.3066667,4.9924269)" - style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient4044);stroke-width:1.0147357px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3396)" - d="M 92,16 L 32,64 L 92,112 L 92,80 L 92,48 L 92,16 z " - id="path3990" /> - <path - id="path3992" - d="M 87.6,19.744339 L 24.531667,63.913636 C 31.325523,64.772472 38.548578,65.239004 46.059167,65.239003 C 61.572821,65.239003 75.930219,63.261985 87.6,59.908723 L 87.6,49.248162 L 87.6,19.744339 z " - style="fill:url(#linearGradient4046);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> - <path - id="path3994" - d="M 87.6,19.744339 L 86.71125,20.37821 L 86.71125,48.84479 L 86.71125,59.361289 C 75.203203,62.668078 61.061565,64.605133 45.762917,64.605133 C 38.631436,64.605133 31.769756,64.182739 25.28875,63.395014 L 24.531667,63.913636 C 31.325523,64.772472 38.548578,65.239004 46.059167,65.239003 C 61.572821,65.239003 75.930219,63.261985 87.6,59.908723 L 87.6,49.248162 L 87.6,19.744339 z " - style="fill:url(#linearGradient4048);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> - <path - id="path3996" - d="M 87.6,19.744339 L 24.531667,63.913636 C 28.122981,64.367627 31.847249,64.698286 35.6575,64.922068 C 32.169447,64.704673 28.75029,64.35923 25.453333,63.942448 L 86.678333,21.069705 L 86.678333,49.709159 L 86.678333,60.052784 C 82.430956,61.273251 77.821812,62.321664 72.919167,63.135704 C 78.150964,62.285094 83.084328,61.206282 87.6,59.908723 L 87.6,49.248162 L 87.6,19.744339 z M 35.6575,64.922068 C 37.402503,65.024555 39.172559,65.101717 40.957083,65.152566 C 39.171728,65.097092 37.401526,65.030765 35.6575,64.922068 z " - style="fill:url(#linearGradient4050);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> - </g> - <g - id="west-minslider" - inkscape:label="Layer 1" - transform="matrix(0.1499001,0,0,0.1428242,3.2111921,38.857406)"> - <g - transform="matrix(-1,0,0,1,127.97333,1.7146484e-2)" - id="g4106"> - <path - style="opacity:0.90526321;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#638000;stroke-width:0.9659996;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3533)" - d="M 87.875,12 C 87.009497,12.026935 86.176101,12.333976 85.5,12.875 L 25.5,60.875 C 24.550144,61.634129 24,62.784063 24,64 C 24,65.215937 24.550144,66.365871 25.5,67.125 L 85.5,115.125 C 86.700963,116.08613 88.332437,116.26025 89.71875,115.59375 C 91.105067,114.92725 92.000642,113.53821 92,112 L 92,88.3125 L 92,78.0625 L 90.5,76.875 C 89.299037,75.91387 87.667563,75.739753 86.28125,76.40625 C 84.894933,77.072748 83.999358,78.461793 84,80 L 84,103.6875 L 34.40625,64 L 84,24.3125 L 84,48 C 83.999358,49.538207 84.894936,50.927253 86.28125,51.59375 C 87.66756,52.260246 89.299037,52.08613 90.5,51.125 L 92,49.9375 L 92,39.6875 L 92,16 C 92.000417,14.917152 91.558627,13.878821 90.78125,13.125 C 90.003873,12.37118 88.957323,11.966273 87.875,12 z " - id="path4108" - transform="matrix(1.0533333,0,0,1.0173732,-5.0933333,-1.1118124)" /> - <path - style="fill:url(#linearGradient4158);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:8;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" - d="M 91.17049,7.9849542 C 90.151573,8.0139691 89.170453,8.3447195 88.37451,8.9275206 L 17.739215,60.634018 C 16.620992,61.451766 15.973333,62.690496 15.973333,64.000327 C 15.973333,65.310157 16.620992,66.548887 17.739215,67.366635 L 88.37451,119.07313 C 89.788349,120.10848 91.70901,120.29604 93.341053,119.57808 C 94.973103,118.86011 96.027425,117.36381 96.026667,115.70683 L 96.026667,90.190206 L 96.026667,85.410048 L 96.026667,79.148715 L 96.026667,48.851939 L 96.026667,43.533172 L 96.026667,37.810447 L 96.026667,12.293829 C 96.027162,11.127365 95.507058,10.008855 94.591887,9.1968255 C 93.676716,8.3847962 92.44466,7.9486229 91.17049,7.9849542 z M 86.608627,21.248209 L 86.608627,42.455952 L 68.949804,42.455952 C 68.297605,42.455952 67.772548,42.936393 67.772548,43.533172 L 67.772548,85.410048 C 67.772548,86.006828 68.297605,86.487267 68.949804,86.487267 L 86.608627,86.487267 L 86.608627,106.75245 L 28.224141,64.000327 L 86.608627,21.248209 z " - id="path4110" /> - <path - style="opacity:0.85;fill:url(#radialGradient4160);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:8;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3681)" - d="M 87.875,12 C 87.075959,12.024867 86.302054,12.283948 85.65625,12.75 L 86.625,21.78125 L 91.96875,15.625 C 91.880958,14.678789 91.469257,13.792159 90.78125,13.125 C 90.003873,12.37118 88.957323,11.966273 87.875,12 z " - id="path4112" - transform="matrix(1.0533333,0,0,1.0173732,-5.0933333,-1.1118124)" /> - <path - style="opacity:0.90526321;fill:url(#linearGradient4162);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:8;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" - d="M 91.17049,7.9849542 C 90.151573,8.0139691 89.170453,8.3447195 88.37451,8.9275206 L 17.739215,60.634018 C 16.620992,61.451766 15.973333,62.690496 15.973333,64.000327 C 15.973333,65.310157 16.620992,66.548887 17.739215,67.366635 L 88.37451,119.07313 C 89.788349,120.10848 91.70901,120.29604 93.341053,119.57808 C 94.973103,118.86011 96.027425,117.36381 96.026667,115.70683 L 96.026667,90.190206 L 96.026667,85.410048 L 96.026667,84.66946 L 96.026667,79.148715 L 96.026667,48.851939 L 96.026667,43.533172 L 96.026667,43.331192 L 96.026667,37.810447 L 96.026667,12.293829 C 96.027162,11.127365 95.507058,10.008855 94.591887,9.1968255 C 93.676716,8.3847962 92.44466,7.9486229 91.17049,7.9849542 z M 86.608627,21.248209 L 86.608627,42.455952 L 68.949804,42.455952 C 68.297605,42.455952 67.772548,42.936393 67.772548,43.533172 L 67.772548,85.410048 C 67.772548,86.006828 68.297605,86.487267 68.949804,86.487267 L 86.608627,86.487267 L 86.608627,106.75245 L 28.224141,64.000327 L 86.608627,21.248209 z " - id="path4114" /> - <path - id="path4116" - d="M 71.875,12 C 71.075959,12.024867 70.302054,12.283948 69.65625,12.75 L 70.625,21.78125 L 75.96875,15.625 C 75.880958,14.678789 75.469257,13.792159 74.78125,13.125 C 74.003873,12.37118 72.957323,11.966273 71.875,12 z " - style="opacity:0.35;fill:url(#radialGradient4164);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:8;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3681)" - transform="matrix(1.0533333,0,0,-1.0173732,11.76,128.88743)" /> - <path - style="fill:url(#linearGradient4166);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - d="M 24.4,64.000073 L 87.6,19.744339 L 87.6,108.25581 L 24.4,64.000073 z " - id="path4118" - sodipodi:nodetypes="cccc" /> - <path - style="opacity:0.5;fill:url(#radialGradient4168);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:8;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3722)" - d="M 11.6875,59.125 L 9.5,60.875 C 8.5501441,61.634129 8,62.784063 8,64 C 8.0000001,65.215937 8.5501441,66.365871 9.5,67.125 L 13.03125,69.9375 L 15.15625,64.3125 L 11.6875,59.125 z " - id="path4120" - transform="matrix(1.0533333,0,0,-1.0173732,11.76,129.68423)" /> - <path - style="fill:url(#radialGradient4170);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - d="M 87.6,19.744339 L 24.4,64.000073 L 87.6,108.25581 L 87.6,78.751985 L 87.6,49.248162 L 87.6,19.744339 z " - id="path4122" /> - <path - style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient4172);stroke-width:1.0147357px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3396)" - d="M 92,16 L 32,64 L 92,112 L 92,80 L 92,48 L 92,16 z " - id="path4124" - transform="matrix(1.0533333,0,0,0.9219945,-9.3066667,4.9924269)" /> - <path - id="path4126" - d="M 92,16 L 32,64 L 92,112 L 92,80 L 92,48 L 92,16 z " - style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient4174);stroke-width:1.0147357px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3396)" - transform="matrix(1.0533333,0,0,0.9219945,-9.3066667,4.9924269)" /> - <path - style="fill:url(#linearGradient4176);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - d="M 87.6,19.744339 L 24.531667,63.913636 C 31.325523,64.772472 38.548578,65.239004 46.059167,65.239003 C 61.572821,65.239003 75.930219,63.261985 87.6,59.908723 L 87.6,49.248162 L 87.6,19.744339 z " - id="path4128" /> - <path - style="fill:url(#linearGradient4178);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - d="M 87.6,19.744339 L 86.71125,20.37821 L 86.71125,48.84479 L 86.71125,59.361289 C 75.203203,62.668078 61.061565,64.605133 45.762917,64.605133 C 38.631436,64.605133 31.769756,64.182739 25.28875,63.395014 L 24.531667,63.913636 C 31.325523,64.772472 38.548578,65.239004 46.059167,65.239003 C 61.572821,65.239003 75.930219,63.261985 87.6,59.908723 L 87.6,49.248162 L 87.6,19.744339 z " - id="path4130" /> - <path - style="fill:url(#linearGradient4180);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - d="M 87.6,19.744339 L 24.531667,63.913636 C 28.122981,64.367627 31.847249,64.698286 35.6575,64.922068 C 32.169447,64.704673 28.75029,64.35923 25.453333,63.942448 L 86.678333,21.069705 L 86.678333,49.709159 L 86.678333,60.052784 C 82.430956,61.273251 77.821812,62.321664 72.919167,63.135704 C 78.150964,62.285094 83.084328,61.206282 87.6,59.908723 L 87.6,49.248162 L 87.6,19.744339 z M 35.6575,64.922068 C 37.402503,65.024555 39.172559,65.101717 40.957083,65.152566 C 39.171728,65.097092 37.401526,65.030765 35.6575,64.922068 z " - id="path4132" /> - </g> - </g> - <g - transform="matrix(0.1499001,0,0,0.1428242,21.605596,38.859856)" - id="west-maxslider"> - <path - style="opacity:0.90526321;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#001280;stroke-width:0.9659996;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3533)" - d="M 87.875,12 C 87.009497,12.026935 86.176101,12.333976 85.5,12.875 L 25.5,60.875 C 24.550144,61.634129 24,62.784063 24,64 C 24,65.215937 24.550144,66.365871 25.5,67.125 L 85.5,115.125 C 86.700963,116.08613 88.332437,116.26025 89.71875,115.59375 C 91.105067,114.92725 92.000642,113.53821 92,112 L 92,88.3125 L 92,78.0625 L 90.5,76.875 C 89.299037,75.91387 87.667563,75.739753 86.28125,76.40625 C 84.894933,77.072748 83.999358,78.461793 84,80 L 84,103.6875 L 34.40625,64 L 84,24.3125 L 84,48 C 83.999358,49.538207 84.894936,50.927253 86.28125,51.59375 C 87.66756,52.260246 89.299037,52.08613 90.5,51.125 L 92,49.9375 L 92,39.6875 L 92,16 C 92.000417,14.917152 91.558627,13.878821 90.78125,13.125 C 90.003873,12.37118 88.957323,11.966273 87.875,12 z " - id="path8173" - transform="matrix(1.0533333,0,0,1.0173732,-5.0933333,-1.1118124)" /> - <path - style="fill:url(#linearGradient8227);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:8;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" - d="M 91.17049,7.9849542 C 90.151573,8.0139691 89.170453,8.3447195 88.37451,8.9275206 L 17.739215,60.634018 C 16.620992,61.451766 15.973333,62.690496 15.973333,64.000327 C 15.973333,65.310157 16.620992,66.548887 17.739215,67.366635 L 88.37451,119.07313 C 89.788349,120.10848 91.70901,120.29604 93.341053,119.57808 C 94.973103,118.86011 96.027425,117.36381 96.026667,115.70683 L 96.026667,90.190206 L 96.026667,85.410048 L 96.026667,79.148715 L 96.026667,48.851939 L 96.026667,43.533172 L 96.026667,37.810447 L 96.026667,12.293829 C 96.027162,11.127365 95.507058,10.008855 94.591887,9.1968255 C 93.676716,8.3847962 92.44466,7.9486229 91.17049,7.9849542 z M 86.608627,21.248209 L 86.608627,42.455952 L 68.949804,42.455952 C 68.297605,42.455952 67.772548,42.936393 67.772548,43.533172 L 67.772548,85.410048 C 67.772548,86.006828 68.297605,86.487267 68.949804,86.487267 L 86.608627,86.487267 L 86.608627,106.75245 L 28.224141,64.000327 L 86.608627,21.248209 z " - id="path8175" /> - <path - style="opacity:0.85;fill:url(#radialGradient8229);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:8;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3681)" - d="M 87.875,12 C 87.075959,12.024867 86.302054,12.283948 85.65625,12.75 L 86.625,21.78125 L 91.96875,15.625 C 91.880958,14.678789 91.469257,13.792159 90.78125,13.125 C 90.003873,12.37118 88.957323,11.966273 87.875,12 z " - id="path8177" - transform="matrix(1.0533333,0,0,1.0173732,-5.0933333,-1.1118124)" /> - <path - style="opacity:0.90526321;fill:url(#linearGradient8231);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:8;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" - d="M 91.17049,7.9849542 C 90.151573,8.0139691 89.170453,8.3447195 88.37451,8.9275206 L 17.739215,60.634018 C 16.620992,61.451766 15.973333,62.690496 15.973333,64.000327 C 15.973333,65.310157 16.620992,66.548887 17.739215,67.366635 L 88.37451,119.07313 C 89.788349,120.10848 91.70901,120.29604 93.341053,119.57808 C 94.973103,118.86011 96.027425,117.36381 96.026667,115.70683 L 96.026667,90.190206 L 96.026667,85.410048 L 96.026667,84.66946 L 96.026667,79.148715 L 96.026667,48.851939 L 96.026667,43.533172 L 96.026667,43.331192 L 96.026667,37.810447 L 96.026667,12.293829 C 96.027162,11.127365 95.507058,10.008855 94.591887,9.1968255 C 93.676716,8.3847962 92.44466,7.9486229 91.17049,7.9849542 z M 86.608627,21.248209 L 86.608627,42.455952 L 68.949804,42.455952 C 68.297605,42.455952 67.772548,42.936393 67.772548,43.533172 L 67.772548,85.410048 C 67.772548,86.006828 68.297605,86.487267 68.949804,86.487267 L 86.608627,86.487267 L 86.608627,106.75245 L 28.224141,64.000327 L 86.608627,21.248209 z " - id="path8179" /> - <path - id="path8181" - d="M 71.875,12 C 71.075959,12.024867 70.302054,12.283948 69.65625,12.75 L 70.625,21.78125 L 75.96875,15.625 C 75.880958,14.678789 75.469257,13.792159 74.78125,13.125 C 74.003873,12.37118 72.957323,11.966273 71.875,12 z " - style="opacity:0.35;fill:url(#radialGradient8233);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:8;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3681)" - transform="matrix(1.0533333,0,0,-1.0173732,11.76,128.88743)" /> - <path - style="fill:url(#linearGradient8235);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - d="M 24.4,64.000073 L 87.6,19.744339 L 87.6,108.25581 L 24.4,64.000073 z " - id="path8183" - sodipodi:nodetypes="cccc" /> - <path - style="opacity:0.5;fill:url(#radialGradient8237);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:8;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3722)" - d="M 11.6875,59.125 L 9.5,60.875 C 8.5501441,61.634129 8,62.784063 8,64 C 8.0000001,65.215937 8.5501441,66.365871 9.5,67.125 L 13.03125,69.9375 L 15.15625,64.3125 L 11.6875,59.125 z " - id="path8185" - transform="matrix(1.0533333,0,0,-1.0173732,11.76,129.68423)" /> - <path - style="fill:url(#radialGradient8239);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - d="M 87.6,19.744339 L 24.4,64.000073 L 87.6,108.25581 L 87.6,78.751985 L 87.6,49.248162 L 87.6,19.744339 z " - id="path8187" /> - <path - style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient8241);stroke-width:1.0147357px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3396)" - d="M 92,16 L 32,64 L 92,112 L 92,80 L 92,48 L 92,16 z " - id="path8189" - transform="matrix(1.0533333,0,0,0.9219945,-9.3066667,4.9924269)" /> - <path - id="path8191" - d="M 92,16 L 32,64 L 92,112 L 92,80 L 92,48 L 92,16 z " - style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient8243);stroke-width:1.0147357px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3396)" - transform="matrix(1.0533333,0,0,0.9219945,-9.3066667,4.9924269)" /> - <path - style="fill:url(#linearGradient8245);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - d="M 87.6,19.744339 L 24.531667,63.913636 C 31.325523,64.772472 38.548578,65.239004 46.059167,65.239003 C 61.572821,65.239003 75.930219,63.261985 87.6,59.908723 L 87.6,49.248162 L 87.6,19.744339 z " - id="path8193" /> - <path - style="fill:url(#linearGradient8247);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - d="M 87.6,19.744339 L 86.71125,20.37821 L 86.71125,48.84479 L 86.71125,59.361289 C 75.203203,62.668078 61.061565,64.605133 45.762917,64.605133 C 38.631436,64.605133 31.769756,64.182739 25.28875,63.395014 L 24.531667,63.913636 C 31.325523,64.772472 38.548578,65.239004 46.059167,65.239003 C 61.572821,65.239003 75.930219,63.261985 87.6,59.908723 L 87.6,49.248162 L 87.6,19.744339 z " - id="path8195" /> - <path - style="fill:url(#linearGradient8249);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - d="M 87.6,19.744339 L 24.531667,63.913636 C 28.122981,64.367627 31.847249,64.698286 35.6575,64.922068 C 32.169447,64.704673 28.75029,64.35923 25.453333,63.942448 L 86.678333,21.069705 L 86.678333,49.709159 L 86.678333,60.052784 C 82.430956,61.273251 77.821812,62.321664 72.919167,63.135704 C 78.150964,62.285094 83.084328,61.206282 87.6,59.908723 L 87.6,49.248162 L 87.6,19.744339 z M 35.6575,64.922068 C 37.402503,65.024555 39.172559,65.101717 40.957083,65.152566 C 39.171728,65.097092 37.401526,65.030765 35.6575,64.922068 z " - id="path8197" /> - </g> - <g - id="west-offsetslider" - transform="matrix(0.1499001,0,0,0.1428242,21.605596,62.859856)"> - <path - transform="matrix(1.0533333,0,0,1.0173732,-5.0933333,-1.1118124)" - id="path8201" - d="M 87.875,12 C 87.009497,12.026935 86.176101,12.333976 85.5,12.875 L 25.5,60.875 C 24.550144,61.634129 24,62.784063 24,64 C 24,65.215937 24.550144,66.365871 25.5,67.125 L 85.5,115.125 C 86.700963,116.08613 88.332437,116.26025 89.71875,115.59375 C 91.105067,114.92725 92.000642,113.53821 92,112 L 92,88.3125 L 92,78.0625 L 90.5,76.875 C 89.299037,75.91387 87.667563,75.739753 86.28125,76.40625 C 84.894933,77.072748 83.999358,78.461793 84,80 L 84,103.6875 L 34.40625,64 L 84,24.3125 L 84,48 C 83.999358,49.538207 84.894936,50.927253 86.28125,51.59375 C 87.66756,52.260246 89.299037,52.08613 90.5,51.125 L 92,49.9375 L 92,39.6875 L 92,16 C 92.000417,14.917152 91.558627,13.878821 90.78125,13.125 C 90.003873,12.37118 88.957323,11.966273 87.875,12 z " - style="opacity:0.90526321;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#b8b8b8;stroke-width:0.9659996;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3533)" /> - <path - id="path8203" - d="M 91.17049,7.9849542 C 90.151573,8.0139691 89.170453,8.3447195 88.37451,8.9275206 L 17.739215,60.634018 C 16.620992,61.451766 15.973333,62.690496 15.973333,64.000327 C 15.973333,65.310157 16.620992,66.548887 17.739215,67.366635 L 88.37451,119.07313 C 89.788349,120.10848 91.70901,120.29604 93.341053,119.57808 C 94.973103,118.86011 96.027425,117.36381 96.026667,115.70683 L 96.026667,90.190206 L 96.026667,85.410048 L 96.026667,79.148715 L 96.026667,48.851939 L 96.026667,43.533172 L 96.026667,37.810447 L 96.026667,12.293829 C 96.027162,11.127365 95.507058,10.008855 94.591887,9.1968255 C 93.676716,8.3847962 92.44466,7.9486229 91.17049,7.9849542 z M 86.608627,21.248209 L 86.608627,42.455952 L 68.949804,42.455952 C 68.297605,42.455952 67.772548,42.936393 67.772548,43.533172 L 67.772548,85.410048 C 67.772548,86.006828 68.297605,86.487267 68.949804,86.487267 L 86.608627,86.487267 L 86.608627,106.75245 L 28.224141,64.000327 L 86.608627,21.248209 z " - style="fill:url(#linearGradient8251);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:8;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> - <path - transform="matrix(1.0533333,0,0,1.0173732,-5.0933333,-1.1118124)" - id="path8205" - d="M 87.875,12 C 87.075959,12.024867 86.302054,12.283948 85.65625,12.75 L 86.625,21.78125 L 91.96875,15.625 C 91.880958,14.678789 91.469257,13.792159 90.78125,13.125 C 90.003873,12.37118 88.957323,11.966273 87.875,12 z " - style="opacity:0.85;fill:url(#radialGradient8253);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:8;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3681)" /> - <path - id="path8207" - d="M 91.17049,7.9849542 C 90.151573,8.0139691 89.170453,8.3447195 88.37451,8.9275206 L 17.739215,60.634018 C 16.620992,61.451766 15.973333,62.690496 15.973333,64.000327 C 15.973333,65.310157 16.620992,66.548887 17.739215,67.366635 L 88.37451,119.07313 C 89.788349,120.10848 91.70901,120.29604 93.341053,119.57808 C 94.973103,118.86011 96.027425,117.36381 96.026667,115.70683 L 96.026667,90.190206 L 96.026667,85.410048 L 96.026667,84.66946 L 96.026667,79.148715 L 96.026667,48.851939 L 96.026667,43.533172 L 96.026667,43.331192 L 96.026667,37.810447 L 96.026667,12.293829 C 96.027162,11.127365 95.507058,10.008855 94.591887,9.1968255 C 93.676716,8.3847962 92.44466,7.9486229 91.17049,7.9849542 z M 86.608627,21.248209 L 86.608627,42.455952 L 68.949804,42.455952 C 68.297605,42.455952 67.772548,42.936393 67.772548,43.533172 L 67.772548,85.410048 C 67.772548,86.006828 68.297605,86.487267 68.949804,86.487267 L 86.608627,86.487267 L 86.608627,106.75245 L 28.224141,64.000327 L 86.608627,21.248209 z " - style="opacity:0.90526321;fill:url(#linearGradient8255);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:8;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> - <path - transform="matrix(1.0533333,0,0,-1.0173732,11.76,128.88743)" - style="opacity:0.35;fill:url(#radialGradient8257);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:8;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3681)" - d="M 71.875,12 C 71.075959,12.024867 70.302054,12.283948 69.65625,12.75 L 70.625,21.78125 L 75.96875,15.625 C 75.880958,14.678789 75.469257,13.792159 74.78125,13.125 C 74.003873,12.37118 72.957323,11.966273 71.875,12 z " - id="path8209" /> - <path - sodipodi:nodetypes="cccc" - id="path8211" - d="M 24.4,64.000073 L 87.6,19.744339 L 87.6,108.25581 L 24.4,64.000073 z " - style="fill:url(#linearGradient8259);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> - <path - transform="matrix(1.0533333,0,0,-1.0173732,11.76,129.68423)" - id="path8213" - d="M 11.6875,59.125 L 9.5,60.875 C 8.5501441,61.634129 8,62.784063 8,64 C 8.0000001,65.215937 8.5501441,66.365871 9.5,67.125 L 13.03125,69.9375 L 15.15625,64.3125 L 11.6875,59.125 z " - style="opacity:0.5;fill:url(#radialGradient8261);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:8;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3722)" /> - <path - id="path8215" - d="M 87.6,19.744339 L 24.4,64.000073 L 87.6,108.25581 L 87.6,78.751985 L 87.6,49.248162 L 87.6,19.744339 z " - style="fill:url(#radialGradient8263);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> - <path - transform="matrix(1.0533333,0,0,0.9219945,-9.3066667,4.9924269)" - id="path8217" - d="M 92,16 L 32,64 L 92,112 L 92,80 L 92,48 L 92,16 z " - style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient8265);stroke-width:1.0147357px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3396)" /> - <path - transform="matrix(1.0533333,0,0,0.9219945,-9.3066667,4.9924269)" - style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient8267);stroke-width:1.0147357px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3396)" - d="M 92,16 L 32,64 L 92,112 L 92,80 L 92,48 L 92,16 z " - id="path8219" /> - <path - id="path8221" - d="M 87.6,19.744339 L 24.531667,63.913636 C 31.325523,64.772472 38.548578,65.239004 46.059167,65.239003 C 61.572821,65.239003 75.930219,63.261985 87.6,59.908723 L 87.6,49.248162 L 87.6,19.744339 z " - style="fill:url(#linearGradient8269);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> - <path - id="path8223" - d="M 87.6,19.744339 L 86.71125,20.37821 L 86.71125,48.84479 L 86.71125,59.361289 C 75.203203,62.668078 61.061565,64.605133 45.762917,64.605133 C 38.631436,64.605133 31.769756,64.182739 25.28875,63.395014 L 24.531667,63.913636 C 31.325523,64.772472 38.548578,65.239004 46.059167,65.239003 C 61.572821,65.239003 75.930219,63.261985 87.6,59.908723 L 87.6,49.248162 L 87.6,19.744339 z " - style="fill:url(#linearGradient8271);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> - <path - id="path8225" - d="M 87.6,19.744339 L 24.531667,63.913636 C 28.122981,64.367627 31.847249,64.698286 35.6575,64.922068 C 32.169447,64.704673 28.75029,64.35923 25.453333,63.942448 L 86.678333,21.069705 L 86.678333,49.709159 L 86.678333,60.052784 C 82.430956,61.273251 77.821812,62.321664 72.919167,63.135704 C 78.150964,62.285094 83.084328,61.206282 87.6,59.908723 L 87.6,49.248162 L 87.6,19.744339 z M 35.6575,64.922068 C 37.402503,65.024555 39.172559,65.101717 40.957083,65.152566 C 39.171728,65.097092 37.401526,65.030765 35.6575,64.922068 z " - style="fill:url(#linearGradient8273);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> - </g> - <g - transform="matrix(0,0.1499001,0.1428242,0,70.859855,21.605593)" - id="north-maxslider"> - <path - style="opacity:0.90526321;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#0020f4;stroke-width:0.9659996;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3533)" - d="M 87.875,12 C 87.009497,12.026935 86.176101,12.333976 85.5,12.875 L 25.5,60.875 C 24.550144,61.634129 24,62.784063 24,64 C 24,65.215937 24.550144,66.365871 25.5,67.125 L 85.5,115.125 C 86.700963,116.08613 88.332437,116.26025 89.71875,115.59375 C 91.105067,114.92725 92.000642,113.53821 92,112 L 92,88.3125 L 92,78.0625 L 90.5,76.875 C 89.299037,75.91387 87.667563,75.739753 86.28125,76.40625 C 84.894933,77.072748 83.999358,78.461793 84,80 L 84,103.6875 L 34.40625,64 L 84,24.3125 L 84,48 C 83.999358,49.538207 84.894936,50.927253 86.28125,51.59375 C 87.66756,52.260246 89.299037,52.08613 90.5,51.125 L 92,49.9375 L 92,39.6875 L 92,16 C 92.000417,14.917152 91.558627,13.878821 90.78125,13.125 C 90.003873,12.37118 88.957323,11.966273 87.875,12 z " - id="path8322" - transform="matrix(1.0533333,0,0,1.0173732,-5.0933333,-1.1118124)" /> - <path - style="fill:url(#linearGradient8376);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:8;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" - d="M 91.17049,7.9849542 C 90.151573,8.0139691 89.170453,8.3447195 88.37451,8.9275206 L 17.739215,60.634018 C 16.620992,61.451766 15.973333,62.690496 15.973333,64.000327 C 15.973333,65.310157 16.620992,66.548887 17.739215,67.366635 L 88.37451,119.07313 C 89.788349,120.10848 91.70901,120.29604 93.341053,119.57808 C 94.973103,118.86011 96.027425,117.36381 96.026667,115.70683 L 96.026667,90.190206 L 96.026667,85.410048 L 96.026667,79.148715 L 96.026667,48.851939 L 96.026667,43.533172 L 96.026667,37.810447 L 96.026667,12.293829 C 96.027162,11.127365 95.507058,10.008855 94.591887,9.1968255 C 93.676716,8.3847962 92.44466,7.9486229 91.17049,7.9849542 z M 86.608627,21.248209 L 86.608627,42.455952 L 68.949804,42.455952 C 68.297605,42.455952 67.772548,42.936393 67.772548,43.533172 L 67.772548,85.410048 C 67.772548,86.006828 68.297605,86.487267 68.949804,86.487267 L 86.608627,86.487267 L 86.608627,106.75245 L 28.224141,64.000327 L 86.608627,21.248209 z " - id="path8324" /> - <path - style="opacity:0.85;fill:url(#radialGradient8378);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:8;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3681)" - d="M 87.875,12 C 87.075959,12.024867 86.302054,12.283948 85.65625,12.75 L 86.625,21.78125 L 91.96875,15.625 C 91.880958,14.678789 91.469257,13.792159 90.78125,13.125 C 90.003873,12.37118 88.957323,11.966273 87.875,12 z " - id="path8326" - transform="matrix(1.0533333,0,0,1.0173732,-5.0933333,-1.1118124)" /> - <path - style="opacity:0.90526321;fill:url(#linearGradient8380);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:8;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" - d="M 91.17049,7.9849542 C 90.151573,8.0139691 89.170453,8.3447195 88.37451,8.9275206 L 17.739215,60.634018 C 16.620992,61.451766 15.973333,62.690496 15.973333,64.000327 C 15.973333,65.310157 16.620992,66.548887 17.739215,67.366635 L 88.37451,119.07313 C 89.788349,120.10848 91.70901,120.29604 93.341053,119.57808 C 94.973103,118.86011 96.027425,117.36381 96.026667,115.70683 L 96.026667,90.190206 L 96.026667,85.410048 L 96.026667,84.66946 L 96.026667,79.148715 L 96.026667,48.851939 L 96.026667,43.533172 L 96.026667,43.331192 L 96.026667,37.810447 L 96.026667,12.293829 C 96.027162,11.127365 95.507058,10.008855 94.591887,9.1968255 C 93.676716,8.3847962 92.44466,7.9486229 91.17049,7.9849542 z M 86.608627,21.248209 L 86.608627,42.455952 L 68.949804,42.455952 C 68.297605,42.455952 67.772548,42.936393 67.772548,43.533172 L 67.772548,85.410048 C 67.772548,86.006828 68.297605,86.487267 68.949804,86.487267 L 86.608627,86.487267 L 86.608627,106.75245 L 28.224141,64.000327 L 86.608627,21.248209 z " - id="path8328" /> - <path - id="path8330" - d="M 71.875,12 C 71.075959,12.024867 70.302054,12.283948 69.65625,12.75 L 70.625,21.78125 L 75.96875,15.625 C 75.880958,14.678789 75.469257,13.792159 74.78125,13.125 C 74.003873,12.37118 72.957323,11.966273 71.875,12 z " - style="opacity:0.35;fill:url(#radialGradient8382);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:8;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3681)" - transform="matrix(1.0533333,0,0,-1.0173732,11.76,128.88743)" /> - <path - style="fill:url(#linearGradient8384);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - d="M 24.4,64.000073 L 87.6,19.744339 L 87.6,108.25581 L 24.4,64.000073 z " - id="path8332" - sodipodi:nodetypes="cccc" /> - <path - style="opacity:0.5;fill:url(#radialGradient8386);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:8;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3722)" - d="M 11.6875,59.125 L 9.5,60.875 C 8.5501441,61.634129 8,62.784063 8,64 C 8.0000001,65.215937 8.5501441,66.365871 9.5,67.125 L 13.03125,69.9375 L 15.15625,64.3125 L 11.6875,59.125 z " - id="path8334" - transform="matrix(1.0533333,0,0,-1.0173732,11.76,129.68423)" /> - <path - style="fill:url(#radialGradient8388);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - d="M 87.6,19.744339 L 24.4,64.000073 L 87.6,108.25581 L 87.6,78.751985 L 87.6,49.248162 L 87.6,19.744339 z " - id="path8336" /> - <path - style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient8390);stroke-width:1.0147357px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3396)" - d="M 92,16 L 32,64 L 92,112 L 92,80 L 92,48 L 92,16 z " - id="path8338" - transform="matrix(1.0533333,0,0,0.9219945,-9.3066667,4.9924269)" /> - <path - id="path8340" - d="M 92,16 L 32,64 L 92,112 L 92,80 L 92,48 L 92,16 z " - style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient8392);stroke-width:1.0147357px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3396)" - transform="matrix(1.0533333,0,0,0.9219945,-9.3066667,4.9924269)" /> - <path - style="fill:url(#linearGradient8394);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - d="M 87.6,19.744339 L 24.531667,63.913636 C 31.325523,64.772472 38.548578,65.239004 46.059167,65.239003 C 61.572821,65.239003 75.930219,63.261985 87.6,59.908723 L 87.6,49.248162 L 87.6,19.744339 z " - id="path8342" /> - <path - style="fill:url(#linearGradient8396);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - d="M 87.6,19.744339 L 86.71125,20.37821 L 86.71125,48.84479 L 86.71125,59.361289 C 75.203203,62.668078 61.061565,64.605133 45.762917,64.605133 C 38.631436,64.605133 31.769756,64.182739 25.28875,63.395014 L 24.531667,63.913636 C 31.325523,64.772472 38.548578,65.239004 46.059167,65.239003 C 61.572821,65.239003 75.930219,63.261985 87.6,59.908723 L 87.6,49.248162 L 87.6,19.744339 z " - id="path8344" /> - <path - style="fill:url(#linearGradient8398);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - d="M 87.6,19.744339 L 24.531667,63.913636 C 28.122981,64.367627 31.847249,64.698286 35.6575,64.922068 C 32.169447,64.704673 28.75029,64.35923 25.453333,63.942448 L 86.678333,21.069705 L 86.678333,49.709159 L 86.678333,60.052784 C 82.430956,61.273251 77.821812,62.321664 72.919167,63.135704 C 78.150964,62.285094 83.084328,61.206282 87.6,59.908723 L 87.6,49.248162 L 87.6,19.744339 z M 35.6575,64.922068 C 37.402503,65.024555 39.172559,65.101717 40.957083,65.152566 C 39.171728,65.097092 37.401526,65.030765 35.6575,64.922068 z " - id="path8346" /> - </g> - <g - id="north-offsetslider" - transform="matrix(0,0.1499001,0.1428242,0,46.859855,21.605593)"> - <path - transform="matrix(1.0533333,0,0,1.0173732,-5.0933333,-1.1118124)" - id="path8350" - d="M 87.875,12 C 87.009497,12.026935 86.176101,12.333976 85.5,12.875 L 25.5,60.875 C 24.550144,61.634129 24,62.784063 24,64 C 24,65.215937 24.550144,66.365871 25.5,67.125 L 85.5,115.125 C 86.700963,116.08613 88.332437,116.26025 89.71875,115.59375 C 91.105067,114.92725 92.000642,113.53821 92,112 L 92,88.3125 L 92,78.0625 L 90.5,76.875 C 89.299037,75.91387 87.667563,75.739753 86.28125,76.40625 C 84.894933,77.072748 83.999358,78.461793 84,80 L 84,103.6875 L 34.40625,64 L 84,24.3125 L 84,48 C 83.999358,49.538207 84.894936,50.927253 86.28125,51.59375 C 87.66756,52.260246 89.299037,52.08613 90.5,51.125 L 92,49.9375 L 92,39.6875 L 92,16 C 92.000417,14.917152 91.558627,13.878821 90.78125,13.125 C 90.003873,12.37118 88.957323,11.966273 87.875,12 z " - style="opacity:0.90526321;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#b8b8b8;stroke-width:0.9659996;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3533)" /> - <path - id="path8352" - d="M 91.17049,7.9849542 C 90.151573,8.0139691 89.170453,8.3447195 88.37451,8.9275206 L 17.739215,60.634018 C 16.620992,61.451766 15.973333,62.690496 15.973333,64.000327 C 15.973333,65.310157 16.620992,66.548887 17.739215,67.366635 L 88.37451,119.07313 C 89.788349,120.10848 91.70901,120.29604 93.341053,119.57808 C 94.973103,118.86011 96.027425,117.36381 96.026667,115.70683 L 96.026667,90.190206 L 96.026667,85.410048 L 96.026667,79.148715 L 96.026667,48.851939 L 96.026667,43.533172 L 96.026667,37.810447 L 96.026667,12.293829 C 96.027162,11.127365 95.507058,10.008855 94.591887,9.1968255 C 93.676716,8.3847962 92.44466,7.9486229 91.17049,7.9849542 z M 86.608627,21.248209 L 86.608627,42.455952 L 68.949804,42.455952 C 68.297605,42.455952 67.772548,42.936393 67.772548,43.533172 L 67.772548,85.410048 C 67.772548,86.006828 68.297605,86.487267 68.949804,86.487267 L 86.608627,86.487267 L 86.608627,106.75245 L 28.224141,64.000327 L 86.608627,21.248209 z " - style="fill:url(#linearGradient8400);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:8;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> - <path - transform="matrix(1.0533333,0,0,1.0173732,-5.0933333,-1.1118124)" - id="path8354" - d="M 87.875,12 C 87.075959,12.024867 86.302054,12.283948 85.65625,12.75 L 86.625,21.78125 L 91.96875,15.625 C 91.880958,14.678789 91.469257,13.792159 90.78125,13.125 C 90.003873,12.37118 88.957323,11.966273 87.875,12 z " - style="opacity:0.85;fill:url(#radialGradient8402);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:8;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3681)" /> - <path - id="path8356" - d="M 91.17049,7.9849542 C 90.151573,8.0139691 89.170453,8.3447195 88.37451,8.9275206 L 17.739215,60.634018 C 16.620992,61.451766 15.973333,62.690496 15.973333,64.000327 C 15.973333,65.310157 16.620992,66.548887 17.739215,67.366635 L 88.37451,119.07313 C 89.788349,120.10848 91.70901,120.29604 93.341053,119.57808 C 94.973103,118.86011 96.027425,117.36381 96.026667,115.70683 L 96.026667,90.190206 L 96.026667,85.410048 L 96.026667,84.66946 L 96.026667,79.148715 L 96.026667,48.851939 L 96.026667,43.533172 L 96.026667,43.331192 L 96.026667,37.810447 L 96.026667,12.293829 C 96.027162,11.127365 95.507058,10.008855 94.591887,9.1968255 C 93.676716,8.3847962 92.44466,7.9486229 91.17049,7.9849542 z M 86.608627,21.248209 L 86.608627,42.455952 L 68.949804,42.455952 C 68.297605,42.455952 67.772548,42.936393 67.772548,43.533172 L 67.772548,85.410048 C 67.772548,86.006828 68.297605,86.487267 68.949804,86.487267 L 86.608627,86.487267 L 86.608627,106.75245 L 28.224141,64.000327 L 86.608627,21.248209 z " - style="opacity:0.90526321;fill:url(#linearGradient8404);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:8;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> - <path - transform="matrix(1.0533333,0,0,-1.0173732,11.76,128.88743)" - style="opacity:0.35;fill:url(#radialGradient8406);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:8;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3681)" - d="M 71.875,12 C 71.075959,12.024867 70.302054,12.283948 69.65625,12.75 L 70.625,21.78125 L 75.96875,15.625 C 75.880958,14.678789 75.469257,13.792159 74.78125,13.125 C 74.003873,12.37118 72.957323,11.966273 71.875,12 z " - id="path8358" /> - <path - sodipodi:nodetypes="cccc" - id="path8360" - d="M 24.4,64.000073 L 87.6,19.744339 L 87.6,108.25581 L 24.4,64.000073 z " - style="fill:url(#linearGradient8408);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> - <path - transform="matrix(1.0533333,0,0,-1.0173732,11.76,129.68423)" - id="path8362" - d="M 11.6875,59.125 L 9.5,60.875 C 8.5501441,61.634129 8,62.784063 8,64 C 8.0000001,65.215937 8.5501441,66.365871 9.5,67.125 L 13.03125,69.9375 L 15.15625,64.3125 L 11.6875,59.125 z " - style="opacity:0.5;fill:url(#radialGradient8410);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:8;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3722)" /> - <path - id="path8364" - d="M 87.6,19.744339 L 24.4,64.000073 L 87.6,108.25581 L 87.6,78.751985 L 87.6,49.248162 L 87.6,19.744339 z " - style="fill:url(#radialGradient8412);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> - <path - transform="matrix(1.0533333,0,0,0.9219945,-9.3066667,4.9924269)" - id="path8366" - d="M 92,16 L 32,64 L 92,112 L 92,80 L 92,48 L 92,16 z " - style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient8414);stroke-width:1.0147357px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3396)" /> - <path - transform="matrix(1.0533333,0,0,0.9219945,-9.3066667,4.9924269)" - style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient8416);stroke-width:1.0147357px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3396)" - d="M 92,16 L 32,64 L 92,112 L 92,80 L 92,48 L 92,16 z " - id="path8368" /> - <path - id="path8370" - d="M 87.6,19.744339 L 24.531667,63.913636 C 31.325523,64.772472 38.548578,65.239004 46.059167,65.239003 C 61.572821,65.239003 75.930219,63.261985 87.6,59.908723 L 87.6,49.248162 L 87.6,19.744339 z " - style="fill:url(#linearGradient8418);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> - <path - id="path8372" - d="M 87.6,19.744339 L 86.71125,20.37821 L 86.71125,48.84479 L 86.71125,59.361289 C 75.203203,62.668078 61.061565,64.605133 45.762917,64.605133 C 38.631436,64.605133 31.769756,64.182739 25.28875,63.395014 L 24.531667,63.913636 C 31.325523,64.772472 38.548578,65.239004 46.059167,65.239003 C 61.572821,65.239003 75.930219,63.261985 87.6,59.908723 L 87.6,49.248162 L 87.6,19.744339 z " - style="fill:url(#linearGradient8420);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> - <path - id="path8374" - d="M 87.6,19.744339 L 24.531667,63.913636 C 28.122981,64.367627 31.847249,64.698286 35.6575,64.922068 C 32.169447,64.704673 28.75029,64.35923 25.453333,63.942448 L 86.678333,21.069705 L 86.678333,49.709159 L 86.678333,60.052784 C 82.430956,61.273251 77.821812,62.321664 72.919167,63.135704 C 78.150964,62.285094 83.084328,61.206282 87.6,59.908723 L 87.6,49.248162 L 87.6,19.744339 z M 35.6575,64.922068 C 37.402503,65.024555 39.172559,65.101717 40.957083,65.152566 C 39.171728,65.097092 37.401526,65.030765 35.6575,64.922068 z " - style="fill:url(#linearGradient8422);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> - </g> - <g - id="east-maxslider" - transform="matrix(-0.1499001,0,0,0.1428242,110.3944,38.859855)"> - <path - transform="matrix(1.0533333,0,0,1.0173732,-5.0933333,-1.1118124)" - id="path8426" - d="M 87.875,12 C 87.009497,12.026935 86.176101,12.333976 85.5,12.875 L 25.5,60.875 C 24.550144,61.634129 24,62.784063 24,64 C 24,65.215937 24.550144,66.365871 25.5,67.125 L 85.5,115.125 C 86.700963,116.08613 88.332437,116.26025 89.71875,115.59375 C 91.105067,114.92725 92.000642,113.53821 92,112 L 92,88.3125 L 92,78.0625 L 90.5,76.875 C 89.299037,75.91387 87.667563,75.739753 86.28125,76.40625 C 84.894933,77.072748 83.999358,78.461793 84,80 L 84,103.6875 L 34.40625,64 L 84,24.3125 L 84,48 C 83.999358,49.538207 84.894936,50.927253 86.28125,51.59375 C 87.66756,52.260246 89.299037,52.08613 90.5,51.125 L 92,49.9375 L 92,39.6875 L 92,16 C 92.000417,14.917152 91.558627,13.878821 90.78125,13.125 C 90.003873,12.37118 88.957323,11.966273 87.875,12 z " - style="opacity:0.90526321;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#001280;stroke-width:0.9659996;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3533)" /> - <path - id="path8428" - d="M 91.17049,7.9849542 C 90.151573,8.0139691 89.170453,8.3447195 88.37451,8.9275206 L 17.739215,60.634018 C 16.620992,61.451766 15.973333,62.690496 15.973333,64.000327 C 15.973333,65.310157 16.620992,66.548887 17.739215,67.366635 L 88.37451,119.07313 C 89.788349,120.10848 91.70901,120.29604 93.341053,119.57808 C 94.973103,118.86011 96.027425,117.36381 96.026667,115.70683 L 96.026667,90.190206 L 96.026667,85.410048 L 96.026667,79.148715 L 96.026667,48.851939 L 96.026667,43.533172 L 96.026667,37.810447 L 96.026667,12.293829 C 96.027162,11.127365 95.507058,10.008855 94.591887,9.1968255 C 93.676716,8.3847962 92.44466,7.9486229 91.17049,7.9849542 z M 86.608627,21.248209 L 86.608627,42.455952 L 68.949804,42.455952 C 68.297605,42.455952 67.772548,42.936393 67.772548,43.533172 L 67.772548,85.410048 C 67.772548,86.006828 68.297605,86.487267 68.949804,86.487267 L 86.608627,86.487267 L 86.608627,106.75245 L 28.224141,64.000327 L 86.608627,21.248209 z " - style="fill:url(#linearGradient8480);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:8;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> - <path - transform="matrix(1.0533333,0,0,1.0173732,-5.0933333,-1.1118124)" - id="path8430" - d="M 87.875,12 C 87.075959,12.024867 86.302054,12.283948 85.65625,12.75 L 86.625,21.78125 L 91.96875,15.625 C 91.880958,14.678789 91.469257,13.792159 90.78125,13.125 C 90.003873,12.37118 88.957323,11.966273 87.875,12 z " - style="opacity:0.85;fill:url(#radialGradient8482);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:8;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3681)" /> - <path - id="path8432" - d="M 91.17049,7.9849542 C 90.151573,8.0139691 89.170453,8.3447195 88.37451,8.9275206 L 17.739215,60.634018 C 16.620992,61.451766 15.973333,62.690496 15.973333,64.000327 C 15.973333,65.310157 16.620992,66.548887 17.739215,67.366635 L 88.37451,119.07313 C 89.788349,120.10848 91.70901,120.29604 93.341053,119.57808 C 94.973103,118.86011 96.027425,117.36381 96.026667,115.70683 L 96.026667,90.190206 L 96.026667,85.410048 L 96.026667,84.66946 L 96.026667,79.148715 L 96.026667,48.851939 L 96.026667,43.533172 L 96.026667,43.331192 L 96.026667,37.810447 L 96.026667,12.293829 C 96.027162,11.127365 95.507058,10.008855 94.591887,9.1968255 C 93.676716,8.3847962 92.44466,7.9486229 91.17049,7.9849542 z M 86.608627,21.248209 L 86.608627,42.455952 L 68.949804,42.455952 C 68.297605,42.455952 67.772548,42.936393 67.772548,43.533172 L 67.772548,85.410048 C 67.772548,86.006828 68.297605,86.487267 68.949804,86.487267 L 86.608627,86.487267 L 86.608627,106.75245 L 28.224141,64.000327 L 86.608627,21.248209 z " - style="opacity:0.90526321;fill:url(#linearGradient8484);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:8;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> - <path - transform="matrix(1.0533333,0,0,-1.0173732,11.76,128.88743)" - style="opacity:0.35;fill:url(#radialGradient8486);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:8;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3681)" - d="M 71.875,12 C 71.075959,12.024867 70.302054,12.283948 69.65625,12.75 L 70.625,21.78125 L 75.96875,15.625 C 75.880958,14.678789 75.469257,13.792159 74.78125,13.125 C 74.003873,12.37118 72.957323,11.966273 71.875,12 z " - id="path8434" /> - <path - sodipodi:nodetypes="cccc" - id="path8436" - d="M 24.4,64.000073 L 87.6,19.744339 L 87.6,108.25581 L 24.4,64.000073 z " - style="fill:url(#linearGradient8488);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> - <path - transform="matrix(1.0533333,0,0,-1.0173732,11.76,129.68423)" - id="path8438" - d="M 11.6875,59.125 L 9.5,60.875 C 8.5501441,61.634129 8,62.784063 8,64 C 8.0000001,65.215937 8.5501441,66.365871 9.5,67.125 L 13.03125,69.9375 L 15.15625,64.3125 L 11.6875,59.125 z " - style="opacity:0.5;fill:url(#radialGradient8490);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:8;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3722)" /> - <path - id="path8440" - d="M 87.6,19.744339 L 24.4,64.000073 L 87.6,108.25581 L 87.6,78.751985 L 87.6,49.248162 L 87.6,19.744339 z " - style="fill:url(#radialGradient8492);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> - <path - transform="matrix(1.0533333,0,0,0.9219945,-9.3066667,4.9924269)" - id="path8442" - d="M 92,16 L 32,64 L 92,112 L 92,80 L 92,48 L 92,16 z " - style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient8494);stroke-width:1.0147357px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3396)" /> - <path - transform="matrix(1.0533333,0,0,0.9219945,-9.3066667,4.9924269)" - style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient8496);stroke-width:1.0147357px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3396)" - d="M 92,16 L 32,64 L 92,112 L 92,80 L 92,48 L 92,16 z " - id="path8444" /> - <path - id="path8446" - d="M 87.6,19.744339 L 24.531667,63.913636 C 31.325523,64.772472 38.548578,65.239004 46.059167,65.239003 C 61.572821,65.239003 75.930219,63.261985 87.6,59.908723 L 87.6,49.248162 L 87.6,19.744339 z " - style="fill:url(#linearGradient8498);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> - <path - id="path8448" - d="M 87.6,19.744339 L 86.71125,20.37821 L 86.71125,48.84479 L 86.71125,59.361289 C 75.203203,62.668078 61.061565,64.605133 45.762917,64.605133 C 38.631436,64.605133 31.769756,64.182739 25.28875,63.395014 L 24.531667,63.913636 C 31.325523,64.772472 38.548578,65.239004 46.059167,65.239003 C 61.572821,65.239003 75.930219,63.261985 87.6,59.908723 L 87.6,49.248162 L 87.6,19.744339 z " - style="fill:url(#linearGradient8500);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> - <path - id="path8450" - d="M 87.6,19.744339 L 24.531667,63.913636 C 28.122981,64.367627 31.847249,64.698286 35.6575,64.922068 C 32.169447,64.704673 28.75029,64.35923 25.453333,63.942448 L 86.678333,21.069705 L 86.678333,49.709159 L 86.678333,60.052784 C 82.430956,61.273251 77.821812,62.321664 72.919167,63.135704 C 78.150964,62.285094 83.084328,61.206282 87.6,59.908723 L 87.6,49.248162 L 87.6,19.744339 z M 35.6575,64.922068 C 37.402503,65.024555 39.172559,65.101717 40.957083,65.152566 C 39.171728,65.097092 37.401526,65.030765 35.6575,64.922068 z " - style="fill:url(#linearGradient8502);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> - </g> - <g - transform="matrix(-0.1499001,0,0,0.1428242,110.3944,62.859855)" - id="east-offsetslider"> - <path - style="opacity:0.90526321;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#b8b8b8;stroke-width:0.9659996;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3533)" - d="M 87.875,12 C 87.009497,12.026935 86.176101,12.333976 85.5,12.875 L 25.5,60.875 C 24.550144,61.634129 24,62.784063 24,64 C 24,65.215937 24.550144,66.365871 25.5,67.125 L 85.5,115.125 C 86.700963,116.08613 88.332437,116.26025 89.71875,115.59375 C 91.105067,114.92725 92.000642,113.53821 92,112 L 92,88.3125 L 92,78.0625 L 90.5,76.875 C 89.299037,75.91387 87.667563,75.739753 86.28125,76.40625 C 84.894933,77.072748 83.999358,78.461793 84,80 L 84,103.6875 L 34.40625,64 L 84,24.3125 L 84,48 C 83.999358,49.538207 84.894936,50.927253 86.28125,51.59375 C 87.66756,52.260246 89.299037,52.08613 90.5,51.125 L 92,49.9375 L 92,39.6875 L 92,16 C 92.000417,14.917152 91.558627,13.878821 90.78125,13.125 C 90.003873,12.37118 88.957323,11.966273 87.875,12 z " - id="path8454" - transform="matrix(1.0533333,0,0,1.0173732,-5.0933333,-1.1118124)" /> - <path - style="fill:url(#linearGradient8504);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:8;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" - d="M 91.17049,7.9849542 C 90.151573,8.0139691 89.170453,8.3447195 88.37451,8.9275206 L 17.739215,60.634018 C 16.620992,61.451766 15.973333,62.690496 15.973333,64.000327 C 15.973333,65.310157 16.620992,66.548887 17.739215,67.366635 L 88.37451,119.07313 C 89.788349,120.10848 91.70901,120.29604 93.341053,119.57808 C 94.973103,118.86011 96.027425,117.36381 96.026667,115.70683 L 96.026667,90.190206 L 96.026667,85.410048 L 96.026667,79.148715 L 96.026667,48.851939 L 96.026667,43.533172 L 96.026667,37.810447 L 96.026667,12.293829 C 96.027162,11.127365 95.507058,10.008855 94.591887,9.1968255 C 93.676716,8.3847962 92.44466,7.9486229 91.17049,7.9849542 z M 86.608627,21.248209 L 86.608627,42.455952 L 68.949804,42.455952 C 68.297605,42.455952 67.772548,42.936393 67.772548,43.533172 L 67.772548,85.410048 C 67.772548,86.006828 68.297605,86.487267 68.949804,86.487267 L 86.608627,86.487267 L 86.608627,106.75245 L 28.224141,64.000327 L 86.608627,21.248209 z " - id="path8456" /> - <path - style="opacity:0.85;fill:url(#radialGradient8506);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:8;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3681)" - d="M 87.875,12 C 87.075959,12.024867 86.302054,12.283948 85.65625,12.75 L 86.625,21.78125 L 91.96875,15.625 C 91.880958,14.678789 91.469257,13.792159 90.78125,13.125 C 90.003873,12.37118 88.957323,11.966273 87.875,12 z " - id="path8458" - transform="matrix(1.0533333,0,0,1.0173732,-5.0933333,-1.1118124)" /> - <path - style="opacity:0.90526321;fill:url(#linearGradient8508);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:8;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" - d="M 91.17049,7.9849542 C 90.151573,8.0139691 89.170453,8.3447195 88.37451,8.9275206 L 17.739215,60.634018 C 16.620992,61.451766 15.973333,62.690496 15.973333,64.000327 C 15.973333,65.310157 16.620992,66.548887 17.739215,67.366635 L 88.37451,119.07313 C 89.788349,120.10848 91.70901,120.29604 93.341053,119.57808 C 94.973103,118.86011 96.027425,117.36381 96.026667,115.70683 L 96.026667,90.190206 L 96.026667,85.410048 L 96.026667,84.66946 L 96.026667,79.148715 L 96.026667,48.851939 L 96.026667,43.533172 L 96.026667,43.331192 L 96.026667,37.810447 L 96.026667,12.293829 C 96.027162,11.127365 95.507058,10.008855 94.591887,9.1968255 C 93.676716,8.3847962 92.44466,7.9486229 91.17049,7.9849542 z M 86.608627,21.248209 L 86.608627,42.455952 L 68.949804,42.455952 C 68.297605,42.455952 67.772548,42.936393 67.772548,43.533172 L 67.772548,85.410048 C 67.772548,86.006828 68.297605,86.487267 68.949804,86.487267 L 86.608627,86.487267 L 86.608627,106.75245 L 28.224141,64.000327 L 86.608627,21.248209 z " - id="path8460" /> - <path - id="path8462" - d="M 71.875,12 C 71.075959,12.024867 70.302054,12.283948 69.65625,12.75 L 70.625,21.78125 L 75.96875,15.625 C 75.880958,14.678789 75.469257,13.792159 74.78125,13.125 C 74.003873,12.37118 72.957323,11.966273 71.875,12 z " - style="opacity:0.35;fill:url(#radialGradient8510);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:8;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3681)" - transform="matrix(1.0533333,0,0,-1.0173732,11.76,128.88743)" /> - <path - style="fill:url(#linearGradient8512);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - d="M 24.4,64.000073 L 87.6,19.744339 L 87.6,108.25581 L 24.4,64.000073 z " - id="path8464" - sodipodi:nodetypes="cccc" /> - <path - style="opacity:0.5;fill:url(#radialGradient8514);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:8;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3722)" - d="M 11.6875,59.125 L 9.5,60.875 C 8.5501441,61.634129 8,62.784063 8,64 C 8.0000001,65.215937 8.5501441,66.365871 9.5,67.125 L 13.03125,69.9375 L 15.15625,64.3125 L 11.6875,59.125 z " - id="path8466" - transform="matrix(1.0533333,0,0,-1.0173732,11.76,129.68423)" /> - <path - style="fill:url(#radialGradient8516);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - d="M 87.6,19.744339 L 24.4,64.000073 L 87.6,108.25581 L 87.6,78.751985 L 87.6,49.248162 L 87.6,19.744339 z " - id="path8468" /> - <path - style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient8518);stroke-width:1.0147357px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3396)" - d="M 92,16 L 32,64 L 92,112 L 92,80 L 92,48 L 92,16 z " - id="path8470" - transform="matrix(1.0533333,0,0,0.9219945,-9.3066667,4.9924269)" /> - <path - id="path8472" - d="M 92,16 L 32,64 L 92,112 L 92,80 L 92,48 L 92,16 z " - style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient8520);stroke-width:1.0147357px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3396)" - transform="matrix(1.0533333,0,0,0.9219945,-9.3066667,4.9924269)" /> - <path - style="fill:url(#linearGradient8522);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - d="M 87.6,19.744339 L 24.531667,63.913636 C 31.325523,64.772472 38.548578,65.239004 46.059167,65.239003 C 61.572821,65.239003 75.930219,63.261985 87.6,59.908723 L 87.6,49.248162 L 87.6,19.744339 z " - id="path8474" /> - <path - style="fill:url(#linearGradient8524);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - d="M 87.6,19.744339 L 86.71125,20.37821 L 86.71125,48.84479 L 86.71125,59.361289 C 75.203203,62.668078 61.061565,64.605133 45.762917,64.605133 C 38.631436,64.605133 31.769756,64.182739 25.28875,63.395014 L 24.531667,63.913636 C 31.325523,64.772472 38.548578,65.239004 46.059167,65.239003 C 61.572821,65.239003 75.930219,63.261985 87.6,59.908723 L 87.6,49.248162 L 87.6,19.744339 z " - id="path8476" /> - <path - style="fill:url(#linearGradient8526);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - d="M 87.6,19.744339 L 24.531667,63.913636 C 28.122981,64.367627 31.847249,64.698286 35.6575,64.922068 C 32.169447,64.704673 28.75029,64.35923 25.453333,63.942448 L 86.678333,21.069705 L 86.678333,49.709159 L 86.678333,60.052784 C 82.430956,61.273251 77.821812,62.321664 72.919167,63.135704 C 78.150964,62.285094 83.084328,61.206282 87.6,59.908723 L 87.6,49.248162 L 87.6,19.744339 z M 35.6575,64.922068 C 37.402503,65.024555 39.172559,65.101717 40.957083,65.152566 C 39.171728,65.097092 37.401526,65.030765 35.6575,64.922068 z " - id="path8478" /> - </g> <rect y="122" x="80" @@ -3565,5 +841,703 @@ inkscape:transform-center-y="12" inkscape:transform-center-x="1.038961" /> </g> + <g + id="south-left-limit-slider"> + <path + sodipodi:nodetypes="cccccccc" + id="rect2879" + d="M 46.386898,102.02597 L 68.018946,102.02597 C 70.267619,102.02597 72.077922,103.72979 72.077922,105.84618 L 72.058976,112.17979 C 72.058976,114.29618 70.248673,116 68,116 L 55.058976,116 C 48.683976,116 42.077922,110.20576 42.077922,106.02597 C 42.077922,103.90958 44.138225,102.02597 46.386898,102.02597 z" + style="fill:url(#linearGradient3817);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.7750001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" /> + <g + transform="translate(0,0.4419416)" + style="fill:#ffffff;fill-opacity:1" + id="g3825"> + <rect + ry="1" + rx="1" + y="103.55806" + x="56.000004" + height="10" + width="2" + id="rect3827" + style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.7750001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + <rect + transform="matrix(0.6773596,-0.735652,0.6952605,0.7187579,0,0)" + style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.7750001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + id="rect3829" + width="1.9562796" + height="7.7827229" + x="-34.722744" + y="115.2485" + rx="0.97813982" + ry="0.97700471" /> + <rect + ry="0.97700465" + rx="0.97813988" + y="-31.648996" + x="116.17191" + height="7.7827225" + width="1.9562798" + id="rect3831" + style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.7750001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + transform="matrix(0.6773596,0.735652,0.6952605,-0.7187579,0,0)" /> + <rect + transform="matrix(0,1,-1,0,0,0)" + style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.7750001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + id="rect3833" + width="2" + height="13" + x="107.55806" + y="-70" + rx="1" + ry="1" /> + </g> + <g + id="g3819"> + <rect + style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.7750001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + id="rect3668" + width="2" + height="10" + x="56.077923" + y="103.02597" + rx="1" + ry="1" /> + <rect + ry="0.97700465" + rx="0.97813988" + y="114.94488" + x="-34.296085" + height="7.7827225" + width="1.9562798" + id="rect3670" + style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.7750001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + transform="matrix(0.6773596,-0.735652,0.6952605,0.7187579,0,0)" /> + <rect + transform="matrix(0.6773596,0.735652,0.6952605,-0.7187579,0,0)" + style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.7750001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + id="rect3672" + width="1.9562796" + height="7.7827229" + x="116.48637" + y="-32.067432" + rx="0.97813982" + ry="0.97700471" /> + <rect + ry="1" + rx="1" + y="-70.077919" + x="107.02597" + height="13" + width="2" + id="rect3674" + style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.7750001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + transform="matrix(0,1,-1,0,0,0)" /> + </g> + </g> + <g + id="south-right-limit-slider"> + <path + style="fill:url(#linearGradient3807);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.7750001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" + d="M 67.768946,118.02597 L 46.136898,118.02597 C 43.888225,118.02597 42.077922,119.72979 42.077922,121.84618 L 42,128 C 42,130.11639 43.810303,131.82021 46.058976,131.82021 L 59,131.82021 C 65.375,131.82021 72.077922,126.20576 72.077922,122.02597 C 72.077922,119.90958 70.017619,118.02597 67.768946,118.02597 z" + id="path3699" + sodipodi:nodetypes="cccccccc" /> + <path + style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.7750001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + d="M 52,120 C 51.757465,120.00313 51.527277,120.11318 51.34375,120.3125 C 50.976696,120.71114 50.967433,121.32972 51.34375,121.71875 L 53.5625,124 L 45,124 C 44.446,124 44,124.446 44,125 C 44,125.554 44.446,126 45,126 L 53.5625,126 L 51.34375,128.28125 C 50.967434,128.67029 50.976696,129.28886 51.34375,129.6875 C 51.710805,130.08614 52.311183,130.10779 52.6875,129.71875 L 56,126.25 L 56,129 C 56,129.554 56.446,130 57,130 C 57.554,130 58,129.554 58,129 L 58,121 C 58,120.446 57.554,120 57,120 C 56.446,120 56,120.446 56,121 L 56,123.71875 L 52.6875,120.28125 C 52.499341,120.08673 52.242535,119.99687 52,120 z" + id="path3810" /> + <path + id="rect3701" + d="M 52.0625,119.03125 C 51.819965,119.03438 51.589777,119.14443 51.40625,119.34375 C 51.039196,119.74239 51.029933,120.36097 51.40625,120.75 L 53.625,123.03125 L 45.0625,123.03125 C 44.5085,123.03125 44.0625,123.47725 44.0625,124.03125 C 44.0625,124.58525 44.5085,125.03125 45.0625,125.03125 L 53.625,125.03125 L 51.40625,127.3125 C 51.029934,127.70154 51.039196,128.32011 51.40625,128.71875 C 51.773305,129.11739 52.373683,129.13904 52.75,128.75 L 56.0625,125.28125 L 56.0625,128.03125 C 56.0625,128.58525 56.5085,129.03125 57.0625,129.03125 C 57.6165,129.03125 58.0625,128.58525 58.0625,128.03125 L 58.0625,120.03125 C 58.0625,119.47725 57.6165,119.03125 57.0625,119.03125 C 56.5085,119.03125 56.0625,119.47725 56.0625,120.03125 L 56.0625,122.75 L 52.75,119.3125 C 52.561841,119.11798 52.305035,119.02812 52.0625,119.03125 z" + style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.7750001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + </g> + <g + id="south-offset-slider"> + <path + sodipodi:nodetypes="cszscc" + id="path3713" + d="M 8.0032728,102 C 5.7368938,102 4.0000003,103.99209 4.0000003,106.01009 C 4.0000023,109.93852 10.01744,116 16,116 C 22.008534,116 28,110.03465 28,106.01009 C 28,103.9984 26.257584,102 23.991205,102 L 8.0032728,102 z" + style="fill:url(#linearGradient3837);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.7750001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" /> + <path + style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + d="M 11.000079,108.33903 C 10.996945,108.58199 11.086821,108.83924 11.28136,109.02773 L 14.812993,112.40864 C 15.028065,112.63581 15.34574,112.99361 16.000621,112.99821 C 16.65091,113.00278 17.037754,112.60474 17.219503,112.40864 L 20.719881,109.02773 C 21.108964,108.65075 21.087312,108.04933 20.688629,107.68162 C 20.289944,107.31393 19.671308,107.30464 19.282225,107.68162 L 17.000728,109.90427 L 17.000728,106 C 17.000728,105.44503 16.554681,104.99825 16.000621,104.99825 C 15.44656,104.99825 15,105.44503 15,106 L 15,109.90427 L 12.719015,107.68162 C 12.32994,107.30464 11.711299,107.31393 11.312613,107.68162 C 11.113271,107.86548 11.003214,108.09607 11.000079,108.33903 z" + id="path3839" + sodipodi:nodetypes="ccczccscccscccsc" /> + <path + sodipodi:nodetypes="ccczccscccscccsc" + id="rect3717" + d="M 11.000079,107.34078 C 10.996945,107.58374 11.086821,107.84099 11.28136,108.02948 L 14.812993,111.41039 C 15.028065,111.63756 15.34574,111.99536 16.000621,111.99996 C 16.65091,112.00453 17.037754,111.60649 17.219503,111.41039 L 20.719881,108.02948 C 21.108964,107.6525 21.087312,107.05108 20.688629,106.68337 C 20.289944,106.31568 19.671308,106.30639 19.282225,106.68337 L 17.000728,108.90602 L 17.000728,105.00175 C 17.000728,104.44678 16.554681,104 16.000621,104 C 15.44656,104 15,104.44678 15,105.00175 L 15,108.90602 L 12.719015,106.68337 C 12.32994,106.30639 11.711299,106.31568 11.312613,106.68337 C 11.113271,106.86723 11.003214,107.09782 11.000079,107.34078 z" + style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.7750001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + </g> + <g + id="west-left-limit-slider"> + <path + style="fill:url(#linearGradient3875);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.7750001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" + d="M -15,34.367952 L -15,56 C -15,58.248673 -16.70382,60.058976 -18.82021,60.058976 L -24.17979,60.058976 C -26.29618,60.058976 -28,58.248673 -28,56 L -28,43.058976 C -28,36.683976 -23.17979,30.058976 -19.000003,30.058976 C -16.883613,30.058976 -15,32.119279 -15,34.367952 z" + id="path2897" + sodipodi:nodetypes="cccccccc" /> + <g + transform="translate(1,-5.897522e-2)" + style="fill:#ffffff;fill-opacity:1" + id="g3883"> + <rect + transform="matrix(0,1,-1,0,0,0)" + style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.7750001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + id="rect3885" + width="2" + height="10" + x="44.058975" + y="17" + rx="1" + ry="1" /> + <rect + ry="0.97700465" + rx="0.97813988" + y="47.72015" + x="16.961395" + height="7.7827225" + width="1.9562798" + id="rect3887" + style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.7750001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + transform="matrix(0.735652,0.6773596,-0.7187579,0.6952605,0,0)" /> + <rect + transform="matrix(-0.735652,0.6773596,0.7187579,0.6952605,0,0)" + style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.7750001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + id="rect3889" + width="1.9562798" + height="7.7827225" + x="47.608047" + y="17.862579" + rx="0.97813988" + ry="0.97700465" /> + <rect + ry="1" + rx="1" + y="-58.058975" + x="21" + height="13" + width="2" + id="rect3891" + style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.7750001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + transform="scale(-1,-1)" /> + </g> + <g + id="g3877"> + <rect + ry="1" + rx="1" + y="17" + x="44.058975" + height="10" + width="2" + id="rect2899" + style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.7750001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + transform="matrix(0,1,-1,0,0,0)" /> + <rect + transform="matrix(0.735652,0.6773596,-0.7187579,0.6952605,0,0)" + style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.7750001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + id="rect2901" + width="1.9562798" + height="7.7827225" + x="16.961395" + y="47.72015" + rx="0.97813988" + ry="0.97700465" /> + <rect + ry="0.97700465" + rx="0.97813988" + y="17.862579" + x="47.608047" + height="7.7827225" + width="1.9562798" + id="rect2903" + style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.7750001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + transform="matrix(-0.735652,0.6773596,0.7187579,0.6952605,0,0)" /> + <rect + transform="scale(-1,-1)" + style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.7750001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + id="rect2905" + width="2" + height="13" + x="21" + y="-58.058975" + rx="1" + ry="1" /> + </g> + </g> + <g + id="west-right-limit-slider"> + <path + sodipodi:nodetypes="cccccccc" + id="path2909" + d="M -15,91.632048 L -15,70 C -15,67.751327 -16.70382,65.941024 -18.82021,65.941024 L -24.17979,65.941024 C -26.29618,65.941024 -28,67.751327 -28,70 L -28,82.941024 C -28,89.316024 -23.17979,95.941024 -19.000003,95.941024 C -16.883613,95.941024 -15,93.880721 -15,91.632048 z" + style="fill:url(#linearGradient3898);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.7750001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" /> + <g + transform="translate(1,5.897522e-2)" + style="fill:#ffffff;fill-opacity:1" + id="g3906"> + <rect + transform="matrix(0,-1,-1,0,0,0)" + ry="1" + rx="1" + y="17" + x="-81.941025" + height="10" + width="2" + id="rect3908" + style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.7750001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + <rect + transform="matrix(0.735652,-0.6773596,-0.7187579,-0.6952605,0,0)" + style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.7750001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + id="rect3910" + width="1.9562798" + height="7.7827225" + x="-73.75383" + y="-45.127308" + rx="0.97813988" + ry="0.97700465" /> + <rect + ry="0.97700465" + rx="0.97813988" + y="-74.984879" + x="-43.107178" + height="7.7827225" + width="1.9562798" + id="rect3912" + style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.7750001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + transform="matrix(-0.735652,-0.6773596,0.7187579,-0.6952605,0,0)" /> + <rect + transform="scale(-1,1)" + style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.7750001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + id="rect3914" + width="2" + height="13" + x="21" + y="67.941025" + rx="1" + ry="1" /> + </g> + <g + id="g3900"> + <rect + style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.7750001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + id="rect2911" + width="2" + height="10" + x="-81.941025" + y="17" + rx="1" + ry="1" + transform="matrix(0,-1,-1,0,0,0)" /> + <rect + ry="0.97700465" + rx="0.97813988" + y="-45.127308" + x="-73.75383" + height="7.7827225" + width="1.9562798" + id="rect2913" + style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.7750001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + transform="matrix(0.735652,-0.6773596,-0.7187579,-0.6952605,0,0)" /> + <rect + transform="matrix(-0.735652,-0.6773596,0.7187579,-0.6952605,0,0)" + style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.7750001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + id="rect2915" + width="1.9562798" + height="7.7827225" + x="-43.107178" + y="-74.984879" + rx="0.97813988" + ry="0.97700465" /> + <rect + ry="1" + rx="1" + y="67.941025" + x="21" + height="13" + width="2" + id="rect2917" + style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.7750001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + transform="scale(-1,1)" /> + </g> + </g> + <rect + transform="matrix(0,1,1,0,0,0)" + style="opacity:1;fill:#0f0f0f;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.7750001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + id="rect2927" + width="78" + height="52" + x="25.441563" + y="128.06493" /> + <rect + y="-39.740265" + x="45.454544" + height="52" + width="78" + id="rect2959" + style="opacity:1;fill:#0f0f0f;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.7750001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + transform="scale(1,-1)" /> + <g + id="west-offset-slider"> + <path + style="fill:url(#linearGradient3866);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.7750001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" + d="M -40,38.012068 C -40,35.745688 -41.992266,34.008795 -44.010444,34.008795 C -47.939225,34.008797 -52,40.030121 -52,46.012681 C -52,52.021215 -48.035355,58.008795 -44.010444,58.008795 C -41.998577,58.008795 -40,56.266379 -40,54 L -40,38.012068 z" + id="path2624" + sodipodi:nodetypes="cszscc" /> + <path + sodipodi:nodetypes="ccczccscccscccsc" + id="path3868" + d="M -45.339234,40.999351 C -45.582216,40.996217 -45.839486,41.086093 -46.027997,41.280632 L -49.409203,44.812265 C -49.636394,45.027337 -49.994226,45.345012 -49.998828,45.999893 C -50.0034,46.650182 -49.605323,47.037026 -49.409203,47.218775 L -46.027997,50.719153 C -45.650986,51.108236 -45.049509,51.086584 -44.681772,50.687901 C -44.314044,50.289216 -44.30476,49.67058 -44.681772,49.281497 L -46.90461,47 L -43,47 C -42.44498,47 -41.99816,46.553953 -41.99816,45.999893 C -41.99816,45.445832 -42.44498,44.999272 -43,44.999272 L -46.90461,44.999272 L -44.681772,42.718287 C -44.30476,42.329212 -44.314044,41.710571 -44.681772,41.311885 C -44.86564,41.112543 -45.096251,41.002486 -45.339234,40.999351 z" + style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.7750001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + <path + style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.7750001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + d="M -46.341254,41.000079 C -46.584236,40.996945 -46.841506,41.086821 -47.030017,41.28136 L -50.411223,44.812993 C -50.638414,45.028065 -50.996246,45.34574 -51.000848,46.000621 C -51.00542,46.65091 -50.607343,47.037754 -50.411223,47.219503 L -47.030017,50.719881 C -46.653006,51.108964 -46.051529,51.087312 -45.683792,50.688629 C -45.316064,50.289944 -45.30678,49.671308 -45.683792,49.282225 L -47.90663,47.000728 L -44.00202,47.000728 C -43.447,47.000728 -43.00018,46.554681 -43.00018,46.000621 C -43.00018,45.44656 -43.447,45 -44.00202,45 L -47.90663,45 L -45.683792,42.719015 C -45.30678,42.32994 -45.316064,41.711299 -45.683792,41.312613 C -45.86766,41.113271 -46.098271,41.003214 -46.341254,41.000079 z" + id="path2626" + sodipodi:nodetypes="ccczccscccscccsc" /> + </g> + <g + id="north-right-limit-slider" + transform="matrix(0,1,-1,0,147.05898,20)"> + <path + sodipodi:nodetypes="cccccccc" + id="path3955" + d="M -15,34.367952 L -15,56 C -15,58.248673 -16.70382,60.058976 -18.82021,60.058976 L -24.17979,60.058976 C -26.29618,60.058976 -28,58.248673 -28,56 L -28,43.058976 C -28,36.683976 -23.17979,30.058976 -19.000003,30.058976 C -16.883613,30.058976 -15,32.119279 -15,34.367952 z" + style="fill:url(#linearGradient4009);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.7750001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" /> + <g + id="g3957" + style="fill:#ffffff;fill-opacity:1" + transform="translate(1,-5.897522e-2)"> + <rect + ry="1" + rx="1" + y="17" + x="44.058975" + height="10" + width="2" + id="rect3959" + style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.7750001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + transform="matrix(0,1,-1,0,0,0)" /> + <rect + transform="matrix(0.735652,0.6773596,-0.7187579,0.6952605,0,0)" + style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.7750001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + id="rect3961" + width="1.9562798" + height="7.7827225" + x="16.961395" + y="47.72015" + rx="0.97813988" + ry="0.97700465" /> + <rect + ry="0.97700465" + rx="0.97813988" + y="17.862579" + x="47.608047" + height="7.7827225" + width="1.9562798" + id="rect3963" + style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.7750001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + transform="matrix(-0.735652,0.6773596,0.7187579,0.6952605,0,0)" /> + <rect + transform="scale(-1,-1)" + style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.7750001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + id="rect3965" + width="2" + height="13" + x="21" + y="-58.058975" + rx="1" + ry="1" /> + </g> + <g + id="g3967"> + <rect + transform="matrix(0,1,-1,0,0,0)" + style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.7750001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + id="rect3969" + width="2" + height="10" + x="44.058975" + y="17" + rx="1" + ry="1" /> + <rect + ry="0.97700465" + rx="0.97813988" + y="47.72015" + x="16.961395" + height="7.7827225" + width="1.9562798" + id="rect3971" + style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.7750001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + transform="matrix(0.735652,0.6773596,-0.7187579,0.6952605,0,0)" /> + <rect + transform="matrix(-0.735652,0.6773596,0.7187579,0.6952605,0,0)" + style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.7750001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + id="rect3973" + width="1.9562798" + height="7.7827225" + x="47.608047" + y="17.862579" + rx="0.97813988" + ry="0.97700465" /> + <rect + ry="1" + rx="1" + y="-58.058975" + x="21" + height="13" + width="2" + id="rect3975" + style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.7750001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + transform="scale(-1,-1)" /> + </g> + </g> + <g + id="north-left-limit-slider" + transform="matrix(0,1,-1,0,182,39)"> + <path + style="fill:url(#linearGradient4011);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.7750001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" + d="M -15,91.632048 L -15,70 C -15,67.751327 -16.70382,65.941024 -18.82021,65.941024 L -24.17979,65.941024 C -26.29618,65.941024 -28,67.751327 -28,70 L -28,82.941024 C -28,89.316024 -23.17979,95.941024 -19.000003,95.941024 C -16.883613,95.941024 -15,93.880721 -15,91.632048 z" + id="path3979" + sodipodi:nodetypes="cccccccc" /> + <g + id="g3981" + style="fill:#ffffff;fill-opacity:1" + transform="translate(1,5.897522e-2)"> + <rect + style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.7750001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + id="rect3983" + width="2" + height="10" + x="-81.941025" + y="17" + rx="1" + ry="1" + transform="matrix(0,-1,-1,0,0,0)" /> + <rect + ry="0.97700465" + rx="0.97813988" + y="-45.127308" + x="-73.75383" + height="7.7827225" + width="1.9562798" + id="rect3985" + style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.7750001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + transform="matrix(0.735652,-0.6773596,-0.7187579,-0.6952605,0,0)" /> + <rect + transform="matrix(-0.735652,-0.6773596,0.7187579,-0.6952605,0,0)" + style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.7750001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + id="rect3987" + width="1.9562798" + height="7.7827225" + x="-43.107178" + y="-74.984879" + rx="0.97813988" + ry="0.97700465" /> + <rect + ry="1" + rx="1" + y="67.941025" + x="21" + height="13" + width="2" + id="rect3989" + style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.7750001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + transform="scale(-1,1)" /> + </g> + <g + id="g3991"> + <rect + transform="matrix(0,-1,-1,0,0,0)" + ry="1" + rx="1" + y="17" + x="-81.941025" + height="10" + width="2" + id="rect3993" + style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.7750001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + <rect + transform="matrix(0.735652,-0.6773596,-0.7187579,-0.6952605,0,0)" + style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.7750001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + id="rect3995" + width="1.9562798" + height="7.7827225" + x="-73.75383" + y="-45.127308" + rx="0.97813988" + ry="0.97700465" /> + <rect + ry="0.97700465" + rx="0.97813988" + y="-74.984879" + x="-43.107178" + height="7.7827225" + width="1.9562798" + id="rect3997" + style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.7750001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + transform="matrix(-0.735652,-0.6773596,0.7187579,-0.6952605,0,0)" /> + <rect + transform="scale(-1,1)" + style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.7750001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + id="rect3999" + width="2" + height="13" + x="21" + y="67.941025" + rx="1" + ry="1" /> + </g> + </g> + <g + id="north-offset-slider" + transform="matrix(0,1,-1,0,110,64)"> + <path + sodipodi:nodetypes="cszscc" + id="path4003" + d="M -40,38.012068 C -40,35.745688 -41.992266,34.008795 -44.010444,34.008795 C -47.939225,34.008797 -52,40.030121 -52,46.012681 C -52,52.021215 -48.035355,58.008795 -44.010444,58.008795 C -41.998577,58.008795 -40,56.266379 -40,54 L -40,38.012068 z" + style="fill:url(#linearGradient4013);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.7750001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" /> + <path + style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.7750001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + d="M -45.339234,40.999351 C -45.582216,40.996217 -45.839486,41.086093 -46.027997,41.280632 L -49.409203,44.812265 C -49.636394,45.027337 -49.994226,45.345012 -49.998828,45.999893 C -50.0034,46.650182 -49.605323,47.037026 -49.409203,47.218775 L -46.027997,50.719153 C -45.650986,51.108236 -45.049509,51.086584 -44.681772,50.687901 C -44.314044,50.289216 -44.30476,49.67058 -44.681772,49.281497 L -46.90461,47 L -43,47 C -42.44498,47 -41.99816,46.553953 -41.99816,45.999893 C -41.99816,45.445832 -42.44498,44.999272 -43,44.999272 L -46.90461,44.999272 L -44.681772,42.718287 C -44.30476,42.329212 -44.314044,41.710571 -44.681772,41.311885 C -44.86564,41.112543 -45.096251,41.002486 -45.339234,40.999351 z" + id="path4005" + sodipodi:nodetypes="ccczccscccscccsc" /> + <path + sodipodi:nodetypes="ccczccscccscccsc" + id="path4007" + d="M -46.341254,41.000079 C -46.584236,40.996945 -46.841506,41.086821 -47.030017,41.28136 L -50.411223,44.812993 C -50.638414,45.028065 -50.996246,45.34574 -51.000848,46.000621 C -51.00542,46.65091 -50.607343,47.037754 -50.411223,47.219503 L -47.030017,50.719881 C -46.653006,51.108964 -46.051529,51.087312 -45.683792,50.688629 C -45.316064,50.289944 -45.30678,49.671308 -45.683792,49.282225 L -47.90663,47.000728 L -44.00202,47.000728 C -43.447,47.000728 -43.00018,46.554681 -43.00018,46.000621 C -43.00018,45.44656 -43.447,45 -44.00202,45 L -47.90663,45 L -45.683792,42.719015 C -45.30678,42.32994 -45.316064,41.711299 -45.683792,41.312613 C -45.86766,41.113271 -46.098271,41.003214 -46.341254,41.000079 z" + style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.7750001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + </g> + <g + id="east-right-limit-slider" + transform="matrix(0,-1,1,0,33.999999,137)"> + <path + style="fill:url(#linearGradient4061);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.7750001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" + d="M 46.386898,102.02597 L 68.018946,102.02597 C 70.267619,102.02597 72.077922,103.72979 72.077922,105.84618 L 72.058976,112.17979 C 72.058976,114.29618 70.248673,116 68,116 L 55.058976,116 C 48.683976,116 42.077922,110.20576 42.077922,106.02597 C 42.077922,103.90958 44.138225,102.02597 46.386898,102.02597 z" + id="path4023" + sodipodi:nodetypes="cccccccc" /> + <g + id="g4025" + style="fill:#ffffff;fill-opacity:1" + transform="translate(0,0.4419416)"> + <rect + style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.7750001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + id="rect4027" + width="2" + height="10" + x="56.000004" + y="103.55806" + rx="1" + ry="1" /> + <rect + ry="0.97700471" + rx="0.97813982" + y="115.2485" + x="-34.722744" + height="7.7827229" + width="1.9562796" + id="rect4029" + style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.7750001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + transform="matrix(0.6773596,-0.735652,0.6952605,0.7187579,0,0)" /> + <rect + transform="matrix(0.6773596,0.735652,0.6952605,-0.7187579,0,0)" + style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.7750001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + id="rect4031" + width="1.9562798" + height="7.7827225" + x="116.17191" + y="-31.648996" + rx="0.97813988" + ry="0.97700465" /> + <rect + ry="1" + rx="1" + y="-70" + x="107.55806" + height="13" + width="2" + id="rect4033" + style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.7750001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + transform="matrix(0,1,-1,0,0,0)" /> + </g> + <g + id="g4035"> + <rect + ry="1" + rx="1" + y="103.02597" + x="56.077923" + height="10" + width="2" + id="rect4037" + style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.7750001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + <rect + transform="matrix(0.6773596,-0.735652,0.6952605,0.7187579,0,0)" + style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.7750001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + id="rect4039" + width="1.9562798" + height="7.7827225" + x="-34.296085" + y="114.94488" + rx="0.97813988" + ry="0.97700465" /> + <rect + ry="0.97700471" + rx="0.97813982" + y="-32.067432" + x="116.48637" + height="7.7827229" + width="1.9562796" + id="rect4041" + style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.7750001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + transform="matrix(0.6773596,0.735652,0.6952605,-0.7187579,0,0)" /> + <rect + transform="matrix(0,1,-1,0,0,0)" + style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.7750001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + id="rect4043" + width="2" + height="13" + x="107.02597" + y="-70.077919" + rx="1" + ry="1" /> + </g> + </g> + <g + id="east-left-limit-slider" + transform="matrix(0,-1,1,0,18,101.5625)"> + <path + sodipodi:nodetypes="cccccccc" + id="path4047" + d="M 67.768946,118.02597 L 46.136898,118.02597 C 43.888225,118.02597 42.077922,119.72979 42.077922,121.84618 L 42,128 C 42,130.11639 43.810303,131.82021 46.058976,131.82021 L 59,131.82021 C 65.375,131.82021 72.077922,126.20576 72.077922,122.02597 C 72.077922,119.90958 70.017619,118.02597 67.768946,118.02597 z" + style="fill:url(#linearGradient4063);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.7750001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" /> + <path + id="path4049" + d="M 52,120 C 51.757465,120.00313 51.527277,120.11318 51.34375,120.3125 C 50.976696,120.71114 50.967433,121.32972 51.34375,121.71875 L 53.5625,124 L 45,124 C 44.446,124 44,124.446 44,125 C 44,125.554 44.446,126 45,126 L 53.5625,126 L 51.34375,128.28125 C 50.967434,128.67029 50.976696,129.28886 51.34375,129.6875 C 51.710805,130.08614 52.311183,130.10779 52.6875,129.71875 L 56,126.25 L 56,129 C 56,129.554 56.446,130 57,130 C 57.554,130 58,129.554 58,129 L 58,121 C 58,120.446 57.554,120 57,120 C 56.446,120 56,120.446 56,121 L 56,123.71875 L 52.6875,120.28125 C 52.499341,120.08673 52.242535,119.99687 52,120 z" + style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.7750001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + <path + style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.7750001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + d="M 52.0625,119.03125 C 51.819965,119.03438 51.589777,119.14443 51.40625,119.34375 C 51.039196,119.74239 51.029933,120.36097 51.40625,120.75 L 53.625,123.03125 L 45.0625,123.03125 C 44.5085,123.03125 44.0625,123.47725 44.0625,124.03125 C 44.0625,124.58525 44.5085,125.03125 45.0625,125.03125 L 53.625,125.03125 L 51.40625,127.3125 C 51.029934,127.70154 51.039196,128.32011 51.40625,128.71875 C 51.773305,129.11739 52.373683,129.13904 52.75,128.75 L 56.0625,125.28125 L 56.0625,128.03125 C 56.0625,128.58525 56.5085,129.03125 57.0625,129.03125 C 57.6165,129.03125 58.0625,128.58525 58.0625,128.03125 L 58.0625,120.03125 C 58.0625,119.47725 57.6165,119.03125 57.0625,119.03125 C 56.5085,119.03125 56.0625,119.47725 56.0625,120.03125 L 56.0625,122.75 L 52.75,119.3125 C 52.561841,119.11798 52.305035,119.02812 52.0625,119.03125 z" + id="path4051" /> + </g> + <g + id="east-offset-slider" + transform="matrix(0,-1,1,0,58.97227,60.719881)"> + <path + style="fill:url(#linearGradient4065);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.7750001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" + d="M 8.0032728,102 C 5.7368938,102 4.0000003,103.99209 4.0000003,106.01009 C 4.0000023,109.93852 10.01744,116 16,116 C 22.008534,116 28,110.03465 28,106.01009 C 28,103.9984 26.257584,102 23.991205,102 L 8.0032728,102 z" + id="path4055" + sodipodi:nodetypes="cszscc" /> + <path + sodipodi:nodetypes="ccczccscccscccsc" + id="path4057" + d="M 11.000079,108.33903 C 10.996945,108.58199 11.086821,108.83924 11.28136,109.02773 L 14.812993,112.40864 C 15.028065,112.63581 15.34574,112.99361 16.000621,112.99821 C 16.65091,113.00278 17.037754,112.60474 17.219503,112.40864 L 20.719881,109.02773 C 21.108964,108.65075 21.087312,108.04933 20.688629,107.68162 C 20.289944,107.31393 19.671308,107.30464 19.282225,107.68162 L 17.000728,109.90427 L 17.000728,106 C 17.000728,105.44503 16.554681,104.99825 16.000621,104.99825 C 15.44656,104.99825 15,105.44503 15,106 L 15,109.90427 L 12.719015,107.68162 C 12.32994,107.30464 11.711299,107.31393 11.312613,107.68162 C 11.113271,107.86548 11.003214,108.09607 11.000079,108.33903 z" + style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + <path + style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.7750001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + d="M 11.000079,107.34078 C 10.996945,107.58374 11.086821,107.84099 11.28136,108.02948 L 14.812993,111.41039 C 15.028065,111.63756 15.34574,111.99536 16.000621,111.99996 C 16.65091,112.00453 17.037754,111.60649 17.219503,111.41039 L 20.719881,108.02948 C 21.108964,107.6525 21.087312,107.05108 20.688629,106.68337 C 20.289944,106.31568 19.671308,106.30639 19.282225,106.68337 L 17.000728,108.90602 L 17.000728,105.00175 C 17.000728,104.44678 16.554681,104 16.000621,104 C 15.44656,104 15,104.44678 15,105.00175 L 15,108.90602 L 12.719015,106.68337 C 12.32994,106.30639 11.711299,106.31568 11.312613,106.68337 C 11.113271,106.86723 11.003214,107.09782 11.000079,107.34078 z" + id="path4059" + sodipodi:nodetypes="ccczccscccscccsc" /> + </g> </g> </svg> --- desktoptheme/metadata.desktop +++ desktoptheme/metadata.desktop @@ -1,5 +1,6 @@ [Desktop Entry] Name=Oxygen +Name[ar]=أكسجين Name[csb]=Krziseń Name[es]=Oxígeno Name[gu]=ઓક્સિજન --- runners/shell/plasma-runner-shell.desktop +++ runners/shell/plasma-runner-shell.desktop @@ -20,7 +20,7 @@ Name[he]=שורת פקודה Name[hu]=Parancssor Name[is]=Skipanalína -Name[it]=Linea di comando +Name[it]=Riga di comando Name[ja]=コマンドライン Name[kk]=Команда жолы Name[km]=បន្ទាត់ពាក្យបញ្ជា --- runners/bookmarks/plasma-runner-bookmarks.desktop +++ runners/bookmarks/plasma-runner-bookmarks.desktop @@ -59,8 +59,8 @@ Name[se]=Girjemearkkat Name[sk]=Záložky Name[sl]=Zaznamki -Name[sr]=маркери -Name[sr@latin]=markeri +Name[sr]=Маркери +Name[sr@latin]=Markeri Name[sv]=Bokmärken Name[ta]=நினைவுக்குறிகள் Name[te]=పేజి గుర్తులు @@ -123,8 +123,8 @@ Comment[ru]=Открыть закладку Comment[se]=Raba girjemearkka Comment[sl]=Odpri zaznamek -Comment[sr]=Отвори маркер -Comment[sr@latin]=Otvori marker +Comment[sr]=Отворите маркер +Comment[sr@latin]=Otvorite marker Comment[sv]=Öppna bokmärke Comment[tg]=Кушодани хатчӯб Comment[th]=เปิดที่คั่นหน้า --- runners/calculator/plasma-runner-calculator.desktop +++ runners/calculator/plasma-runner-calculator.desktop @@ -1,5 +1,6 @@ [Desktop Entry] Name=Calculator +Name[ar]=آلة حاسبة Name[bg]=Калкулатор Name[bn_IN]=ক্যালকুলেটর Name[ca]=Calculadora @@ -90,7 +91,7 @@ Comment[nds]=Utdrück utreken Comment[ne]=अभिव्यक्ति गणना गर्नुहोस् Comment[nl]=Expressies berekenen -Comment[nn]=Rekn ut mattestykke +Comment[nn]=Grafisk kalkulator Comment[pa]=ਸਮੀਕਰਨ ਕੱਢੋ Comment[pl]=Obliczenie wartości wyrażenia Comment[pt]=Calcular expressões --- runners/webshortcuts/plasma-runner-webshortcuts.desktop +++ runners/webshortcuts/plasma-runner-webshortcuts.desktop @@ -59,7 +59,7 @@ Name[sk]=Internetové skratky Name[sl]=Spletne bližnjice Name[sr]=веб пречице -Name[sr@latin]=web prečice +Name[sr@latin]=veb prečice Name[sv]=Webbgenvägar Name[ta]=இணைய சுருக்கு வழிகள் Name[tg]=Тугмаҳои тез --- containments/panel/plasma-containment-panel.desktop +++ containments/panel/plasma-containment-panel.desktop @@ -111,7 +111,7 @@ Comment[zh_TW]=面板容器 Icon= Type=Service -X-KDE-ServiceTypes=Plasma/Applet,Plasma/Containment +X-KDE-ServiceTypes=Plasma/Applet NoDisplay=true X-KDE-Library=plasma_containment_panel --- containments/panel/panel.cpp +++ containments/panel/panel.cpp @@ -83,6 +83,7 @@ KConfigGroup cg = config("Configuration"); setMinimumSize(cg.readEntry("minimumSize", m_currentSize)); setMaximumSize(cg.readEntry("maximumSize", m_currentSize)); + setDrawWallpaper(false); } QList<QAction*> Panel::contextualActions() @@ -182,7 +183,7 @@ panel->setScreen(screen()); panel->setLocation(Plasma::TopEdge); - // trigger an instant layout so we immediately have a proper geometry + // trigger an instant layout so we immediately have a proper geometry // rather than waiting around for the event loop panel->updateConstraints(Plasma::StartupCompletedConstraint); panel->flushPendingConstraintsEvents(); @@ -320,7 +321,7 @@ QRectF screenRect = screen() >= 0 ? QApplication::desktop()->screenGeometry(screen()) : geometry(); - if ((formFactor() == Horizontal && m_currentSize.width() >= screenRect.width()) || + if ((formFactor() == Horizontal && m_currentSize.width() >= screenRect.width()) || (formFactor() == Vertical && m_currentSize.height() >= screenRect.height())) { m_background->setElementPrefix(location()); } else { @@ -410,7 +411,7 @@ painter->resetTransform(); const Containment::StyleOption *containmentOpt = qstyleoption_cast<const Containment::StyleOption *>(option); - + QRect viewGeom; if (containmentOpt) { viewGeom = containmentOpt->view->geometry(); @@ -419,6 +420,9 @@ if (viewGeom != m_lastViewGeom) { m_lastViewGeom = viewGeom; updateBorders(viewGeom); + if (containmentOpt && containmentOpt->view) { + containmentOpt->view->setMask(m_background->mask()); + } } // blit the background (saves all the per-pixel-products that blending does) @@ -427,10 +431,6 @@ m_background->paintPanel(painter, contentsRect); - if (containmentOpt && containmentOpt->view) { - containmentOpt->view->setMask(m_background->mask()); - } - // restore transformation and composition mode painter->restore(); } --- containments/desktop/plasma-themes.knsrc +++ containments/desktop/plasma-themes.knsrc @@ -1,4 +0,0 @@ -[KNewStuff2] -ProvidersUrl=http://download.kde.org/khotnewstuff/plasmathemes-providers.xml -TargetDir=desktoptheme -Uncompress=true --- containments/desktop/backgrounddialog.cpp +++ containments/desktop/backgrounddialog.cpp @@ -1,966 +0,0 @@ -/* - Copyright (c) 2007 Paolo Capriotti <p.capriotti@gmail.com> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. -*/ - -#define USE_BACKGROUND_PACKAGES - -#include "backgrounddialog.h" -#include <memory> -#include <QAbstractItemView> -#include <QAbstractListModel> -#include <QComboBox> -#include <QDir> -#include <QFileInfo> -#include <QGroupBox> -#include <QLabel> -#include <QList> -#include <QListWidget> -#include <QPainter> -#include <QStackedWidget> -#include <QTimeEdit> -#include <QToolButton> -#include <QVBoxLayout> -#include <QCheckBox> -#include <KColorButton> -#include <KColorScheme> -#include <KDebug> -#include <KDesktopFile> -#include <KDirSelectDialog> -#include <KDirWatch> -#include <KFileDialog> -#include <KGlobalSettings> -#include <KImageFilePreview> -#include <KLocalizedString> -#include <KPushButton> -#include <KSeparator> -#include <KStandardDirs> -#include <knewstuff2/engine.h> -#include <ThreadWeaver/Weaver> -#include <KAboutData> - -#ifdef USE_BACKGROUND_PACKAGES - -#include <plasma/packagemetadata.h> -#include <plasma/panelsvg.h> -#include <plasma/package.h> -#include <plasma/theme.h> - -#endif - -class ThemeInfo -{ -public: - QString package; - Plasma::PanelSvg *svg; -}; - -class ThemeModel : public QAbstractListModel -{ -public: - enum { PackageNameRole = Qt::UserRole, - SvgRole = Qt::UserRole + 1 - }; - - ThemeModel(QObject *parent = 0); - virtual ~ThemeModel(); - - virtual int rowCount(const QModelIndex &parent = QModelIndex()) const; - virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; - int indexOf(const QString &path) const; - void reload(); -private: - QMap<QString, ThemeInfo> m_themes; -}; - -ThemeModel::ThemeModel( QObject *parent ) -: QAbstractListModel( parent ) -{ - reload(); -} - -ThemeModel::~ThemeModel() -{ -} - -void ThemeModel::reload() -{ - reset(); - //TODO: the svg objects don't get deleted until the dialog goes away! - m_themes.clear(); - - // get all desktop themes - KStandardDirs dirs; - QStringList themes = dirs.findAllResources("data", "desktoptheme/*/metadata.desktop", KStandardDirs::NoDuplicates); - foreach (const QString &theme, themes) { - kDebug() << theme; - int themeSepIndex = theme.lastIndexOf("/", -1); - QString themeRoot = theme.left(themeSepIndex); - int themeNameSepIndex = themeRoot.lastIndexOf("/", -1); - QString packageName = themeRoot.right(themeRoot.length() - themeNameSepIndex - 1); - - KDesktopFile df(theme); - QString name = df.readName(); - if (name.isEmpty()) { - name = packageName; - } - - Plasma::PanelSvg *svg = new Plasma::PanelSvg(this); - svg->setImagePath(themeRoot + "/widgets/background.svg"); - svg->setEnabledBorders(Plasma::PanelSvg::AllBorders); - ThemeInfo info; - info.package = packageName; - info.svg = svg; - m_themes[name] = info; - } - - beginInsertRows(QModelIndex(), 0, m_themes.size()); - endInsertRows(); -} - -int ThemeModel::rowCount(const QModelIndex &) const -{ - return m_themes.size(); -} - -QVariant ThemeModel::data(const QModelIndex &index, int role) const -{ - if (!index.isValid()) { - return QVariant(); - } - - if (index.row() >= m_themes.size()) { - return QVariant(); - } - - QMap<QString, ThemeInfo>::const_iterator it = m_themes.constBegin(); - for (int i = 0; i < index.row(); ++i) { - ++it; - } - - switch (role) { - case Qt::DisplayRole: - return it.key(); - case PackageNameRole: - return (*it).package; - case SvgRole: - return qVariantFromValue((void*)(*it).svg); - default: - return QVariant(); - } -} - -int ThemeModel::indexOf(const QString &name) const -{ - QMapIterator<QString, ThemeInfo> it(m_themes); - int i = -1; - while (it.hasNext()) { - ++i; - if (it.next().value().package == name) { - return i; - } - } - - return -1; -} - - - -class ThemeDelegate : public QAbstractItemDelegate -{ -public: - ThemeDelegate( QObject * parent = 0 ); - - virtual void paint(QPainter *painter, - const QStyleOptionViewItem &option, - const QModelIndex &index) const; - virtual QSize sizeHint(const QStyleOptionViewItem &option, - const QModelIndex &index) const; -private: - static const int MARGIN = 5; -}; - -ThemeDelegate::ThemeDelegate( QObject * parent ) -: QAbstractItemDelegate( parent ) -{ - kDebug(); -} - -void ThemeDelegate::paint(QPainter *painter, - const QStyleOptionViewItem &option, - const QModelIndex &index) const -{ - QString title = index.model()->data(index, Qt::DisplayRole).toString(); - QString package = index.model()->data(index, ThemeModel::PackageNameRole).toString(); - - // highlight selected item - painter->save(); - if (option.state & QStyle::State_Selected) { - painter->setBrush(option.palette.color(QPalette::Highlight)); - } else { - painter->setBrush(Qt::gray); - } - painter->drawRect(option.rect); - painter->restore(); - - // draw image - Plasma::PanelSvg *svg = static_cast<Plasma::PanelSvg *>(index.model()->data(index, ThemeModel::SvgRole).value<void *>()); - svg->resizePanel(QSize(option.rect.width()-(2*MARGIN), 100-(2*MARGIN))); - QRect imgRect = QRect(option.rect.topLeft(), QSize( option.rect.width()-(2*MARGIN), 100-(2*MARGIN) )). - translated(MARGIN, MARGIN); - svg->paintPanel( painter, imgRect, QPoint(option.rect.left() + MARGIN, option.rect.top() + MARGIN) ); - - // draw text - painter->save(); - QFont font = painter->font(); - font.setWeight(QFont::Bold); - QString colorFile = KStandardDirs::locate("data", "desktoptheme/" + package + "/colors"); - if (!colorFile.isEmpty()) { - KSharedConfigPtr colors = KSharedConfig::openConfig(colorFile); - KColorScheme colorScheme(QPalette::Active, KColorScheme::Window, colors); - painter->setPen(colorScheme.foreground(KColorScheme::NormalText).color()); - } - painter->setFont(font); - painter->drawText(option.rect, Qt::AlignCenter | Qt::TextWordWrap, title); - painter->restore(); -} - -QSize ThemeDelegate::sizeHint(const QStyleOptionViewItem &, const QModelIndex &) const -{ - return QSize(200, 100); -} - - -class BackgroundContainer -{ -public: - virtual ~BackgroundContainer(); - virtual bool contains(const QString &path) const = 0; -}; - -QList<Background *> -findAllBackgrounds(const BackgroundContainer *container, - const QString &path, - float ratio) -{ - QList<Background *> res; - -#ifdef USE_BACKGROUND_PACKAGES - - // get all packages in this directory - QStringList packages = Plasma::Package::listInstalled(path); - foreach (const QString &packagePath, packages) - { - kDebug() << packagePath; - std::auto_ptr<Background> pkg( - new BackgroundPackage(path+packagePath, ratio)); -// kDebug() << "Package is valid?" << pkg->isValid(); -// kDebug() << "Path passed to the constructor" << path+packagePath; - if (pkg->isValid() && - (!container || !container->contains(pkg->path()))) { - res.append(pkg.release()); - } - } -// kDebug() << packages << res; - -#endif - - // search normal wallpapers - QDir dir(path); - QStringList filters; - filters << "*.png" << "*.jpeg" << "*.jpg" << "*.svg" << "*.svgz"; - dir.setNameFilters(filters); - dir.setFilter(QDir::Files | QDir::Hidden); - QFileInfoList files = dir.entryInfoList(); - foreach (const QFileInfo &wp, files) - { - if (!container || !container->contains(wp.filePath())) { - res.append(new BackgroundFile(wp.filePath(), ratio)); - } - } - - return res; -} - -BackgroundContainer::~BackgroundContainer() -{ -} - -class BackgroundListModel : public QAbstractListModel - , public BackgroundContainer -{ -public: - BackgroundListModel(float ratio, QObject *listener); - virtual ~BackgroundListModel(); - - virtual int rowCount(const QModelIndex &parent = QModelIndex()) const; - virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; - Background* package(int index) const; - - void reload(); - void reload(const QStringList &selected); - void addBackground(const QString &path); - int indexOf(const QString &path) const; - void removeBackground(const QString &path); - virtual bool contains(const QString &bg) const; -private: - QObject *m_listener; - QList<Background*> m_packages; - float m_ratio; - KDirWatch m_dirwatch; -}; - -class BackgroundDelegate : public QAbstractItemDelegate -{ -public: - enum { - AuthorRole = Qt::UserRole, - ScreenshotRole - }; - - BackgroundDelegate(QObject *listener, - float ratio, QObject *parent = 0); - - virtual void paint(QPainter *painter, - const QStyleOptionViewItem &option, - const QModelIndex &index) const; - virtual QSize sizeHint(const QStyleOptionViewItem &option, - const QModelIndex &index) const; -private: - static const int MARGIN = 5; - QObject *m_listener; - float m_ratio; -}; - -BackgroundListModel::BackgroundListModel(float ratio, QObject *listener) -: m_listener(listener) -, m_ratio(ratio) -{ - connect(&m_dirwatch, SIGNAL(deleted(QString)), listener, SLOT(removeBackground(QString))); -} - -void BackgroundListModel::removeBackground(const QString &path) -{ - int index; - while ((index = indexOf(path)) != -1) { - beginRemoveRows(QModelIndex(), index, index); - m_packages.removeAt(index); - endRemoveRows(); - } -} - -void BackgroundListModel::reload() -{ - reload(QStringList()); -} - -void BackgroundListModel::reload(const QStringList& selected) -{ - QStringList dirs = KGlobal::dirs()->findDirs("wallpaper", ""); - QList<Background *> tmp; - foreach (const QString &file, selected) { - if (!contains(file) && QFile::exists(file)) { - tmp << new BackgroundFile(file, m_ratio); - } - } - foreach (const QString &dir, dirs) { - tmp += findAllBackgrounds(this, dir, m_ratio); - } - - // add new files to dirwatch - foreach (Background *b, tmp) { - if (!m_dirwatch.contains(b->path())) { - m_dirwatch.addFile(b->path()); - } - } - - if (!tmp.isEmpty()) { - beginInsertRows(QModelIndex(), 0, tmp.size() - 1); - m_packages = tmp + m_packages; - endInsertRows(); - } -} - -void BackgroundListModel::addBackground(const QString& path) { - if (!contains(path)) { - if (!m_dirwatch.contains(path)) { - m_dirwatch.addFile(path); - } - beginInsertRows(QModelIndex(), 0, 0); - m_packages.prepend(new BackgroundFile(path, m_ratio)); - endInsertRows(); - } -} - -int BackgroundListModel::indexOf(const QString &path) const -{ - for (int i = 0; i < m_packages.size(); i++) { - if (path.startsWith(m_packages[i]->path())) { - return i; - } - } - return -1; -} - -bool BackgroundListModel::contains(const QString &path) const -{ - return indexOf(path) != -1; -} - -BackgroundListModel::~BackgroundListModel() -{ - foreach (Background* pkg, m_packages) { - delete pkg; - } -} - -int BackgroundListModel::rowCount(const QModelIndex &) const -{ - return m_packages.size(); -} - -QVariant BackgroundListModel::data(const QModelIndex &index, int role) const -{ - if (!index.isValid()) { - return QVariant(); - } - - if (index.row() >= m_packages.size()) { - return QVariant(); - } - - Background *b = package(index.row()); - if (!b) { - return QVariant(); - } - - switch (role) { - case Qt::DisplayRole: - return b->title(); - case BackgroundDelegate::ScreenshotRole: { - QPixmap pix = b->screenshot(); - if (pix.isNull() && !b->screenshotGenerationStarted()) { - connect(b, SIGNAL(screenshotDone(QPersistentModelIndex)), - m_listener, SLOT(updateScreenshot(QPersistentModelIndex)), - Qt::QueuedConnection); - b->generateScreenshot(index); - } - return pix; - } - case BackgroundDelegate::AuthorRole: - return b->author(); - default: - return QVariant(); - } -} - -Background* BackgroundListModel::package(int index) const -{ - return m_packages.at(index); -} - -BackgroundDelegate::BackgroundDelegate(QObject *listener, - float ratio, QObject *parent) -: QAbstractItemDelegate(parent) -, m_listener(listener) -, m_ratio(ratio) -{ -} - -void BackgroundDelegate::paint(QPainter *painter, - const QStyleOptionViewItem &option, - const QModelIndex &index) const -{ - QString title = index.model()->data(index, Qt::DisplayRole).toString(); - QString author = index.model()->data(index, AuthorRole).toString(); - QPixmap pix = index.model()->data(index, ScreenshotRole).value<QPixmap>(); - - // draw selection outline - if (option.state & QStyle::State_Selected) { - QPen oldPen = painter->pen(); - painter->setPen(option.palette.color(QPalette::Highlight)); - painter->drawRect(option.rect.adjusted(2, 2, -2, -2)); - painter->setPen(oldPen); - } - - // draw pixmap - int maxheight = Background::SCREENSHOT_HEIGHT; - int maxwidth = int(maxheight * m_ratio); - if (!pix.isNull()) { - QSize sz = pix.size(); - int x = MARGIN + (maxwidth - pix.width()) / 2; - int y = MARGIN + (maxheight - pix.height()) / 2; - QRect imgRect = QRect(option.rect.topLeft(), pix.size()).translated(x, y); - painter->drawPixmap(imgRect, pix); - } - - // draw text - painter->save(); - QFont font = painter->font(); - font.setWeight(QFont::Bold); - painter->setFont(font); - int x = option.rect.left() + MARGIN * 5 + maxwidth; - - QRect textRect(x, - option.rect.top() + MARGIN, - option.rect.width() - x - MARGIN * 2, - maxheight); - QString text = title; - QString authorCaption; - if (!author.isEmpty()) { - authorCaption = i18nc("Caption to wallpaper preview, %1 author name", - "by %1", author); - text += '\n' + authorCaption; - } - QRect boundingRect = painter->boundingRect( - textRect, Qt::AlignVCenter | Qt::TextWordWrap, text); - painter->drawText(boundingRect, Qt::TextWordWrap, title); - if (!author.isEmpty()) { - QRect titleRect = painter->boundingRect(boundingRect, Qt::TextWordWrap, title); - QRect authorRect(titleRect.bottomLeft(), textRect.size()); - painter->setFont(KGlobalSettings::smallestReadableFont()); - painter->drawText(authorRect, Qt::TextWordWrap, authorCaption); - } - - painter->restore(); -} - -QSize BackgroundDelegate::sizeHint(const QStyleOptionViewItem &, - const QModelIndex &) const -{ - return QSize(100, Background::SCREENSHOT_HEIGHT + MARGIN * 2); -} - - -BackgroundDialog::BackgroundDialog(const QSize &res, - const KConfigGroup &config, - const KConfigGroup &globalConfig, - QWidget *parent) -: KDialog(parent) -, m_res(res) -, m_ratio((float) res.width() / res.height()) -, m_currentSlide(-1) -, m_preview_renderer(QSize(128, 101), (float) 128 / res.width()) -{ - setWindowIcon(KIcon("preferences-desktop-wallpaper")); - setCaption(i18n("Desktop Settings")); - setButtons(Ok | Cancel | Apply); - - QWidget * main = new QWidget(this); - setupUi(main); - - // static, slideshow or none? - connect(m_mode, SIGNAL(currentIndexChanged(int)), - this, SLOT(changeBackgroundMode(int))); - - // static picture - m_model = new BackgroundListModel(m_ratio, this); - m_view->setModel(m_model); - m_view->setItemDelegate(new BackgroundDelegate(m_view->view(), m_ratio, this)); - m_view->view()->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel); - connect(m_view, SIGNAL(currentIndexChanged(int)), - this, SLOT(update())); - m_pictureUrlButton->setIcon(KIcon("document-open")); - connect(m_pictureUrlButton, SIGNAL(clicked()), this, SLOT(showFileDialog())); - - // resize method - m_resizeMethod->addItem(i18n("Scaled & Cropped"), - Background::ScaleCrop); - m_resizeMethod->addItem(i18n("Scaled"), - Background::Scale); - m_resizeMethod->addItem(i18n("Centered"), - Background::Center); - m_resizeMethod->addItem(i18n("Tiled"), - Background::Tiled); - m_resizeMethod->addItem(i18n("Center Tiled"), - Background::CenterTiled); - connect(m_resizeMethod, SIGNAL(currentIndexChanged(int)), - this, SLOT(update())); - - // color - m_color->setColor(palette().color(QPalette::Window)); - connect(m_color, SIGNAL(changed(QColor)), this, SLOT(update())); - - // slideshow - m_addDir->setIcon(KIcon("list-add")); - connect(m_addDir, SIGNAL(clicked()), this, SLOT(slotAddDir())); - m_removeDir->setIcon(KIcon("list-remove")); - connect(m_removeDir, SIGNAL(clicked()), this, SLOT(slotRemoveDir())); - connect(m_dirlist, SIGNAL(currentRowChanged(int)), this, SLOT(updateSlideshow())); - - m_slideshowDelay->setMinimumTime(QTime(0, 0, 30)); - - // preview - QString monitorPath = KStandardDirs::locate("data", "kcontrol/pics/monitor.png"); - - // Size of monitor image: 200x186 - // Geometry of "display" part of monitor image: (23,14)-[151x115] - qreal previewRatio = 128.0 / (101.0 * m_ratio); - QSize monitorSize(200, int(186 * previewRatio)); - QRect previewRect(23, int(14 * previewRatio), 151, int(115 * previewRatio)); - m_preview_renderer.setSize(previewRect.size()); - - m_monitor->setPixmap(QPixmap(monitorPath).scaled(monitorSize)); - m_monitor->setWhatsThis(i18n( - "This picture of a monitor contains a preview of " - "what the current settings will look like on your desktop.")); - m_preview = new QLabel(m_monitor); - m_preview->setScaledContents(true); - m_preview->setGeometry(previewRect); - - connect(m_newStuff, SIGNAL(clicked()), this, SLOT(getNewWallpaper())); - connect(m_newThemeButton, SIGNAL(clicked()), this, SLOT(getNewThemes())); - - qRegisterMetaType<QImage>("QImage"); - connect(&m_preview_timer, SIGNAL(timeout()), this, SLOT(updateSlideshowPreview())); - connect(&m_preview_renderer, SIGNAL(done(int, const QImage &)), - this, SLOT(previewRenderingDone(int, const QImage &))); - connect(this, SIGNAL(finished(int)), this, SLOT(cleanup())); - - m_themeModel = new ThemeModel(this); - m_theme->setModel(m_themeModel); - m_theme->setItemDelegate(new ThemeDelegate(m_theme->view())); - m_theme->view()->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel); - - setMainWidget(main); - m_emailLine->setTextInteractionFlags(Qt::TextSelectableByMouse); - - reloadConfig(config, globalConfig); - adjustSize(); -} - -void BackgroundDialog::reloadConfig(const KConfigGroup &config, const KConfigGroup &globalConfig) -{ - Q_UNUSED(globalConfig) - - // initialize - int mode = config.readEntry("backgroundmode", int(kStaticBackground)); - m_mode->setCurrentIndex(mode); - int delay = config.readEntry("slideTimer", 60); - QTime time(0, 0, 0); - time = time.addSecs(delay); - m_slideshowDelay->setTime(time); - - // we go from index -> data -> config file entry (data) -> index. oi vey. - int resizeMethod = m_resizeMethod->itemData(m_resizeMethod->currentIndex()).toInt(); - resizeMethod = config.readEntry("wallpaperposition", resizeMethod); - resizeMethod = m_resizeMethod->findData(resizeMethod); - m_resizeMethod->setCurrentIndex(resizeMethod); - - m_dirlist->clear(); - QStringList dirs = config.readEntry("slidepaths", QStringList()); - if (dirs.isEmpty()) { - dirs << KStandardDirs::installPath("wallpaper"); - } - foreach (const QString &dir, dirs) { - m_dirlist->addItem(dir); - } - m_selected = config.readEntry("selected", QStringList()); - m_model->reload(m_selected); - QString defaultPath = Plasma::Theme::defaultTheme()->wallpaperPath(); - QString currentPath = config.readEntry("wallpaper", defaultPath); - - kDebug() << "Default would be" << defaultPath << "but we're loading" << currentPath << "instead"; - - int index = m_model->indexOf(currentPath); - if (index != -1) { - m_view->setCurrentIndex(index); - } - - m_color->setColor(config.readEntry("wallpapercolor", m_color->color())); - m_theme->setCurrentIndex(m_themeModel->indexOf(Plasma::Theme::defaultTheme()->themeName())); - - if (mode == kSlideshowBackground) { - updateSlideshow(); - } else { - update(); - } -} - -void BackgroundDialog::saveConfig(KConfigGroup config, KConfigGroup globalConfig) -{ - Q_UNUSED(globalConfig) - int mode = m_mode->currentIndex(); - config.writeEntry("backgroundmode", mode); - if (mode == kStaticBackground) { - config.writeEntry("wallpaper", m_img); - config.writeEntry("wallpapercolor", m_color->color()); - config.writeEntry("wallpaperposition", - m_resizeMethod->itemData(m_resizeMethod->currentIndex()).toInt()); - config.writeEntry("selected", m_selected); - } else if (mode == kNoBackground) { - config.writeEntry("wallpaper", QString()); - config.writeEntry("wallpapercolor", m_color->color()); - } else { - QStringList dirs; - for (int i = 0; i < m_dirlist->count(); i++) { - dirs << m_dirlist->item(i)->text(); - } - config.writeEntry("slidepaths", dirs); - int seconds = QTime(0, 0, 0).secsTo(m_slideshowDelay->time()); - config.writeEntry("slideTimer", seconds); - } - - QString newTheme = m_theme->itemData(m_theme->currentIndex(), ThemeModel::PackageNameRole).toString(); - Plasma::Theme::defaultTheme()->setThemeName(newTheme); -} - -void BackgroundDialog::getNewWallpaper() -{ - KNS::Engine engine(0); - if (engine.init("wallpaper.knsrc")) { - KNS::Entry::List entries = engine.downloadDialogModal(this); - - if (entries.size() > 0) { - m_model->reload(); - } - } -} - -void BackgroundDialog::getNewThemes() -{ - KNS::Engine engine(0); - if (engine.init("plasma-themes.knsrc")) { - KNS::Entry::List entries = engine.downloadDialogModal(this); - - if (entries.size() > 0) { - m_themeModel->reload(); - m_theme->setCurrentIndex(m_themeModel->indexOf(Plasma::Theme::defaultTheme()->themeName())); - } - } -} - -void BackgroundDialog::showFileDialog() -{ - m_dialog = new KFileDialog(KUrl(), "*.png *.jpeg *.jpg *.svg *.svgz", this); - KImageFilePreview *previewWidget = new KImageFilePreview(m_dialog); - m_dialog->setPreviewWidget(previewWidget); - m_dialog->setOperationMode(KFileDialog::Opening); - m_dialog->setCaption(i18n("Select Wallpaper Image File")); - m_dialog->setModal(false); - m_dialog->show(); - m_dialog->raise(); - m_dialog->activateWindow(); - - connect(m_dialog, SIGNAL(okClicked()), this, SLOT(browse())); -} - -void BackgroundDialog::browse() -{ - QString wallpaper = m_dialog->selectedFile(); - disconnect(m_dialog, SIGNAL(okClicked()), this, SLOT(browse())); - - m_dialog->deleteLater(); - - if (wallpaper.isEmpty()) { - return; - } - - // add background to the model - m_model->addBackground(wallpaper); - - // select it - int index = m_model->indexOf(wallpaper); - if (index != -1) { - m_view->setCurrentIndex(index); - } - - // save it - m_selected << wallpaper; -} - -bool BackgroundDialog::setMetadata(QLabel *label, - const QString &text) -{ - if (text.isEmpty()) { - label->hide(); - return false; - } - else { - label->show(); - label->setText(text); - return true; - } -} - -void BackgroundDialog::update() -{ - if (m_mode->currentIndex() == kNoBackground) { - m_img.clear(); - setPreview(m_img, Background::Scale); - return; - } - int index = m_view->currentIndex(); - if (index == -1) { - return; - } - Background *b = m_model->package(index); - if (!b) { - return; - } - - // Prepare more user-friendly forms of some pieces of data. - // - license by config is more a of a key value, - // try to get the proper name if one of known licenses. - QString license = b->license(); - KAboutLicense knownLicense = KAboutLicense::byKeyword(license); - if (knownLicense.key() != KAboutData::License_Custom) { - license = knownLicense.name(KAboutData::ShortName); - } - // - last ditch attempt to localize author's name, if not such by config - // (translators can "hook" names from outside if resolute enough). - QString author = i18nc("Wallpaper info, author name", "%1", b->author()); - - // FIXME the second parameter is not used, get rid of it. - bool someMetadata = setMetadata(m_authorLine, author); - someMetadata = setMetadata(m_licenseLine, license) || someMetadata; - someMetadata = setMetadata(m_emailLine, b->email()) || someMetadata; - //m_authorLabel->setVisible(someMetadata); - //m_emailLabel->setVisible(someMetadata); - //m_licenseLabel->setVisible(someMetadata); -// m_metadataSeparator->setVisible(someMetadata); - - - Background::ResizeMethod method = (Background::ResizeMethod) - m_resizeMethod->itemData(m_resizeMethod->currentIndex()).value<int>(); - - m_img = b->findBackground(m_res, method); - setPreview(m_img, method); -} - -void BackgroundDialog::setPreview(const QString& img, Background::ResizeMethod method) -{ - m_preview_token = m_preview_renderer.render(img, m_color->color(), method, Qt::FastTransformation); -} - -void BackgroundDialog::slotAddDir() -{ - KUrl empty; - KDirSelectDialog dialog(empty, true, this); - if (dialog.exec()) { - m_dirlist->addItem(dialog.url().path()); - updateSlideshow(); - } -} - -void BackgroundDialog::slotRemoveDir() -{ - int row = m_dirlist->currentRow(); - if (row != -1) { - m_dirlist->takeItem(row); - updateSlideshow(); - } -} - -void BackgroundDialog::updateSlideshow() -{ - int row = m_dirlist->currentRow(); - m_removeDir->setEnabled(row != -1); - - // populate background list - m_slideshowBackgrounds.clear(); - for (int i = 0; i < m_dirlist->count(); i++) { - QString dir = m_dirlist->item(i)->text(); - m_slideshowBackgrounds += findAllBackgrounds(0, dir, m_ratio); - } - - // start preview - if (m_slideshowBackgrounds.isEmpty()) { - m_preview->setPixmap(QPixmap()); - m_preview_timer.stop(); - } - else { - m_currentSlide = -1; - if (!m_preview_timer.isActive()) { - m_preview_timer.start(3000); - } - } -} - -void BackgroundDialog::updateSlideshowPreview() -{ - if (!m_slideshowBackgrounds.isEmpty()) { - // increment current slide index - m_currentSlide++; - m_currentSlide = m_currentSlide % m_slideshowBackgrounds.count(); - - Background *slide = m_slideshowBackgrounds[m_currentSlide]; - Q_ASSERT(slide); - - const Background::ResizeMethod method = Background::Scale; - m_img = slide->findBackground(m_res, method); - setPreview(m_img, method); - } - else { - m_preview->setPixmap(QPixmap()); - } -} - -void BackgroundDialog::changeBackgroundMode(int mode) -{ - switch (mode) - { - case kStaticBackground: - m_preview_timer.stop(); - stackedWidget->setCurrentIndex(0); - enableButtons(true); - update(); - break; - case kNoBackground: - m_preview_timer.stop(); - stackedWidget->setCurrentIndex(0); - enableButtons(false); - update(); - break; - case kSlideshowBackground: - stackedWidget->setCurrentIndex(1); - updateSlideshow(); - enableButtons(true); - break; - } -} - -void BackgroundDialog::enableButtons(bool enabled) -{ - m_view->setEnabled(enabled); - m_resizeMethod->setEnabled(enabled); - m_pictureUrlButton->setEnabled(enabled); -} - -bool BackgroundDialog::contains(const QString &path) const -{ - foreach (Background *bg, m_slideshowBackgrounds) - { - if (bg->path() == path) { - return true; - } - } - return false; -} - -void BackgroundDialog::previewRenderingDone(int token, const QImage &image) -{ - // display preview only if it is the latest rendered file - if (token == m_preview_token) { - m_preview->setPixmap(QPixmap::fromImage(image)); - } -} - -void BackgroundDialog::updateScreenshot(QPersistentModelIndex index) -{ - m_view->view()->update(index); -} - -void BackgroundDialog::cleanup() -{ - m_preview_timer.stop(); -} - -void BackgroundDialog::removeBackground(const QString &path) -{ - m_model->removeBackground(path); -} --- containments/desktop/backgroundpackage.h +++ containments/desktop/backgroundpackage.h @@ -1,137 +0,0 @@ -/* - * Copyright (c) 2007 Paolo Capriotti <p.capriotti@gmail.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2, - * or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details - * - * You should have received a copy of the GNU Library General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef BACKGROUNDPACKAGE_H -#define BACKGROUNDPACKAGE_H - -#include <memory> -#include <QImage> -#include <QPersistentModelIndex> -#include <QPixmap> -#include <QSize> -#include <QThread> -#include <QVariant> -#include <ThreadWeaver/Job> -#include <plasma/package.h> - -namespace Plasma { class PackageMetadata; } - -class DummyObject : public QObject -{ -Q_OBJECT -signals: - void done(ThreadWeaver::Job *); -}; - -class Background : public QObject -{ -Q_OBJECT -public: - enum ResizeMethod { - Scale, - Center, - ScaleCrop, - Tiled, - CenterTiled - }; - - static const int SCREENSHOT_HEIGHT = 60; - - virtual ~Background(); - - virtual QString path() const = 0; - virtual QString findBackground(const QSize &resolution, - ResizeMethod method) const = 0; - virtual QPixmap screenshot() const = 0; - virtual bool screenshotGenerationStarted() const = 0; - virtual void generateScreenshot(QPersistentModelIndex index) const = 0; - virtual QString title() const = 0; - virtual QString author() const = 0; - virtual QString email() const = 0; - virtual QString license() const = 0; - - virtual bool isValid() const = 0; - -protected: - static QImage defaultScreenshot(); - static QImage createScreenshot(const QString &path, float ratio); - friend class ResizeThread; -}; - -class BackgroundPackage : public Background, - public Plasma::Package -{ -Q_OBJECT -public: - BackgroundPackage(const QString &path, float ratio); - - virtual QString path() const; - virtual QString findBackground(const QSize &resolution, - ResizeMethod method) const; - virtual QPixmap screenshot() const; - virtual bool screenshotGenerationStarted() const; - virtual void generateScreenshot(QPersistentModelIndex index) const; - virtual QString author() const; - virtual QString title() const; - virtual QString email() const; - virtual QString license() const; - virtual bool isValid() const; -private: - QString resString(const QSize &size) const; - QSize resSize(const QString &res) const; - - float distance(const QSize &size, - const QSize &desired, - ResizeMethod method) const; - - QString m_path; - float m_ratio; - mutable QPixmap m_screenshot; -}; - -class BackgroundFile : public Background -{ -Q_OBJECT -public: - BackgroundFile(const QString &file, float ratio); - virtual ~BackgroundFile(); - - virtual QString path() const; - virtual QString findBackground(const QSize &resolution, - ResizeMethod method) const; - virtual bool screenshotGenerationStarted() const; - virtual void generateScreenshot(QPersistentModelIndex index) const; - virtual QPixmap screenshot() const; - virtual QString author() const; - virtual QString title() const; - virtual QString email() const; - virtual QString license() const; - virtual bool isValid() const; -private: - QString m_file; - float m_ratio; - - mutable bool m_resizer_started; - mutable QPixmap m_screenshot; -private slots: - void updateScreenshot(ThreadWeaver::Job *); -signals: - void screenshotDone(QPersistentModelIndex index); -}; - -#endif // BACKGROUNDPACKAGE_H --- containments/desktop/backgrounddialog.h +++ containments/desktop/backgrounddialog.h @@ -1,122 +0,0 @@ -/* - Copyright (c) 2007 Paolo Capriotti <p.capriotti@gmail.com> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. -*/ - -#ifndef BACKGROUNDDIALOG_H -#define BACKGROUNDDIALOG_H - -#include <QSize> -#include <QTimer> -#include <KDialog> - -#include "backgroundpackage.h" -#include "renderthread.h" - -#include "ui_BackgroundDialog.h" - -class BackgroundContainer; -class ThemeModel; -class BackgroundListModel; -class QComboBox; -class QLabel; -class QListWidget; -class QPushButton; -class QTimeEdit; -class QCheckBox; -class KColorButton; -class KFileDialog; -class KSeparator; - -class BackgroundDialog : public KDialog, public Ui::BackgroundDialog -{ -Q_OBJECT -public: - enum BackgroundMode { - kStaticBackground, - kSlideshowBackground, - kNoBackground - }; - - // FIXME seems that we're leaking, make a destructor - BackgroundDialog(const QSize &res, - const KConfigGroup &config, - const KConfigGroup &globalConfig, - QWidget *parent = 0); - - void reloadConfig(const KConfigGroup &config, const KConfigGroup &globalConfig); - void saveConfig(KConfigGroup config, KConfigGroup globalConfig); - - QString path() const; - int mode(); -private: - //QComboBox *m_mode; - //QComboBox *m_view; - BackgroundListModel *m_model; - ThemeModel *m_themeModel; - - //QLabel *m_authorLabel; - //QLabel *m_emailLabel; - //QLabel *m_licenseLabel; - //QLabel *m_authorLine; - //QLabel *m_emailLine; - //QLabel *m_licenseLine; - QLabel *m_preview; - - //QPushButton *m_newStuff; - - //QComboBox *m_resizeMethod; - //KColorButton *m_color; - - //QListWidget *m_dirlist; - //QPushButton *m_addDir; - //QPushButton *m_removeDir; - //QTimeEdit *m_slideshowDelay; - KFileDialog *m_dialog; - - QString m_img; - QSize m_res; - float m_ratio; - - QTimer m_preview_timer; - QList<Background *> m_slideshowBackgrounds; - int m_currentSlide; - - QStringList m_selected; - - RenderThread m_preview_renderer; - int m_preview_token; - - //QCheckBox *m_alignToGrid; - //QCheckBox *m_showIcons; - - bool setMetadata(QLabel *label, - const QString &text); - void setPreview(const QString &img, Background::ResizeMethod method); - virtual bool contains(const QString &path) const; -private slots: - void update(); - void getNewWallpaper(); - void getNewThemes(); - void browse(); - void showFileDialog(); - void enableButtons(bool enabled); - - void slotAddDir(); - void slotRemoveDir(); - void updateSlideshow(); - void updateSlideshowPreview(); - - void changeBackgroundMode(int mode); - void previewRenderingDone(int token, const QImage &pix); - - void updateScreenshot(QPersistentModelIndex index); - void cleanup(); - void removeBackground(const QString &path); -}; - -#endif // BACKGROUNDDIALOG_H --- containments/desktop/wallpaper.knsrc +++ containments/desktop/wallpaper.knsrc @@ -1,4 +0,0 @@ -[KNewStuff2] -ProvidersUrl=http://download.kde.org/khotnewstuff/wallpaper-providers.xml -StandardResource=wallpaper -CachePolicy=resident --- containments/desktop/renderthread.cpp +++ containments/desktop/renderthread.cpp @@ -1,236 +0,0 @@ -/* - Copyright (c) 2007 Paolo Capriotti <p.capriotti@gmail.com> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. -*/ - -#include "renderthread.h" - -#include <QPainter> -#include <QFile> -#include <KDebug> -#include <KSvgRenderer> - -RenderThread::RenderThread(const QSize &size, float ratio) -: m_current_token(-1) -, m_size(size) -, m_ratio(ratio) -{ - m_abort = false; - m_restart = false; -} - -RenderThread::~RenderThread() -{ - { - // abort computation - QMutexLocker lock(&m_mutex); - m_abort = true; - m_condition.wakeOne(); - } - - wait(); -} - -void RenderThread::setSize(const QSize& size) -{ - QMutexLocker lock(&m_mutex); - m_size = size; -} - -int RenderThread::render(const QString &file, - const QColor &color, - Background::ResizeMethod method, - Qt::TransformationMode mode) -{ - int token; - { - QMutexLocker lock(&m_mutex); - m_file = file; - m_color = color; - m_method = method; - m_mode = mode; - m_restart = true; - token = ++m_current_token; - } - - if (!isRunning()) { - start(); - } - else { - m_condition.wakeOne(); - } - - return token; -} - -void RenderThread::run() -{ - QString file; - QColor color; - QSize size; - float ratio; - Background::ResizeMethod method; - Qt::TransformationMode mode; - int token; - - forever { - { - QMutexLocker lock(&m_mutex); - while (!m_restart && !m_abort) { - m_condition.wait(&m_mutex); - } - if (m_abort) { - return; - } - m_restart = false; - - // load all parameters in nonshared variables - token = m_current_token; - file = m_file; - color = m_color; - size = m_size; - ratio = m_ratio; - method = m_method; - mode = m_mode; - } - - QImage result(size, QImage::Format_ARGB32_Premultiplied); - result.fill(color.rgba()); - - if (file.isEmpty() || !QFile::exists(file)) { - emit done(token, result); - continue; - } - - QPoint pos(0, 0); - bool tiled = false; - bool scalable = file.endsWith("svg") || file.endsWith("svgz"); - QSize scaledSize; - QImage img; - - // load nonscalable image - if (!scalable) { - img = QImage(file); - } - - // set image size - QSize imgSize; - if (scalable) { - // scalable: image can be of any size - imgSize = size; - } - else { - // otherwise, use the natural size of the loaded image - imgSize = img.size(); - } - imgSize *= ratio; - - // if any of them is zero we may run into a div-by-zero below. - if (imgSize.width() == 0) { - imgSize.setWidth(1); - } - if (imgSize.height() == 0) { - imgSize.setHeight(1); - } - - // set render parameters according to resize mode - switch (method) - { - case Background::Scale: - scaledSize = size; - break; - case Background::Center: - scaledSize = imgSize; - pos = QPoint((size.width() - scaledSize.width()) / 2, - (size.height() - scaledSize.height()) / 2); - - //If the picture is bigger than the screen, shrink it - if( size.width() < imgSize.width() && imgSize.width() > imgSize.height() ) - { - int width = size.width(); - int height = width * scaledSize.height() / imgSize.width(); - scaledSize = QSize(width, height); - pos = QPoint((size.width() - scaledSize.width()) / 2, - (size.height() - scaledSize.height()) / 2); - } - else if( size.height() < imgSize.height() ) - { - int height = size.height(); - int width = height * imgSize.width() / imgSize.height(); - scaledSize = QSize(width, height); - pos = QPoint((size.width() - scaledSize.width()) / 2, - (size.height() - scaledSize.height()) / 2); - } - - break; - case Background::ScaleCrop: { - float xratio = (float) size.width() / imgSize.width(); - float yratio = (float) size.height() / imgSize.height(); - if (xratio > yratio) { - int width = size.width(); - int height = width * imgSize.height() / imgSize.width(); - scaledSize = QSize(width, height); - } - else { - int height = size.height(); - int width = height * imgSize.width() / imgSize.height(); - scaledSize = QSize(width, height); - } - pos = QPoint((size.width() - scaledSize.width()) / 2, - (size.height() - scaledSize.height()) / 2); - break; - } - case Background::Tiled: - scaledSize = imgSize; - tiled = true; - break; - case Background::CenterTiled: - scaledSize = imgSize; - pos = QPoint( - -scaledSize.width() + - ((size.width() - scaledSize.width()) / 2) % scaledSize.width(), - -scaledSize.height() + - ((size.height() - scaledSize.height()) / 2) % scaledSize.height()); - tiled = true; - break; - } - - QPainter p(&result); - if (scalable) { - // tiling is ignored for scalable wallpapers - KSvgRenderer svg(file); - if (m_restart) { - continue; - } - svg.render(&p); - } - else { - QImage scaled = img.scaled(scaledSize, Qt::IgnoreAspectRatio, mode); - if (m_restart) { - continue; - } - if (tiled) { - for (int x = pos.x(); x < size.width(); x += scaledSize.width()) { - for (int y = pos.y(); y < size.height(); y += scaledSize.height()) { - p.drawImage(QPoint(x, y), scaled); - if (m_restart) { - goto endLoop; - } - } - } - } - else { - p.drawImage(pos, scaled); - } - } - - // signal we're done - emit done(token, result); - - endLoop: continue; - } -} --- containments/desktop/BackgroundDialog.ui +++ containments/desktop/BackgroundDialog.ui @@ -1,609 +0,0 @@ -<ui version="4.0" > - <class>BackgroundDialog</class> - <widget class="QWidget" name="BackgroundDialog" > - <property name="geometry" > - <rect> - <x>0</x> - <y>0</y> - <width>644</width> - <height>419</height> - </rect> - </property> - <property name="sizePolicy" > - <sizepolicy vsizetype="Expanding" hsizetype="Expanding" > - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="baseSize" > - <size> - <width>200</width> - <height>700</height> - </size> - </property> - <layout class="QGridLayout" name="gridLayout_2" > - <item row="0" column="0" > - <widget class="QGroupBox" name="groupBox" > - <property name="sizePolicy" > - <sizepolicy vsizetype="Maximum" hsizetype="Preferred" > - <horstretch>0</horstretch> - <verstretch>10</verstretch> - </sizepolicy> - </property> - <property name="title" > - <string>Wallpaper</string> - </property> - <property name="flat" > - <bool>true</bool> - </property> - <layout class="QGridLayout" name="gridLayout" > - <item row="0" column="0" > - <layout class="QVBoxLayout" > - <item> - <widget class="QComboBox" name="m_mode" > - <property name="sizePolicy" > - <sizepolicy vsizetype="Fixed" hsizetype="Preferred" > - <horstretch>1</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <item> - <property name="text" > - <string>Image</string> - </property> - </item> - <item> - <property name="text" > - <string>Slideshow</string> - </property> - </item> - <item> - <property name="text" > - <string>None</string> - </property> - </item> - </widget> - </item> - <item> - <widget class="QStackedWidget" name="stackedWidget" > - <property name="sizePolicy" > - <sizepolicy vsizetype="Preferred" hsizetype="Preferred" > - <horstretch>1</horstretch> - <verstretch>2</verstretch> - </sizepolicy> - </property> - <property name="minimumSize" > - <size> - <width>350</width> - <height>51</height> - </size> - </property> - <property name="currentIndex" > - <number>0</number> - </property> - <widget class="QWidget" name="page" > - <property name="geometry" > - <rect> - <x>0</x> - <y>0</y> - <width>439</width> - <height>237</height> - </rect> - </property> - <layout class="QGridLayout" > - <property name="leftMargin" > - <number>0</number> - </property> - <property name="topMargin" > - <number>6</number> - </property> - <property name="rightMargin" > - <number>0</number> - </property> - <property name="bottomMargin" > - <number>0</number> - </property> - <item row="0" column="0" > - <widget class="QLabel" name="label" > - <property name="minimumSize" > - <size> - <width>75</width> - <height>0</height> - </size> - </property> - <property name="text" > - <string>&Picture:</string> - </property> - <property name="alignment" > - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> - </property> - <property name="buddy" > - <cstring>m_view</cstring> - </property> - </widget> - </item> - <item row="0" column="1" colspan="3" > - <layout class="QHBoxLayout" > - <item> - <widget class="QComboBox" name="m_view" > - <property name="sizePolicy" > - <sizepolicy vsizetype="Fixed" hsizetype="Preferred" > - <horstretch>1</horstretch> - <verstretch>1</verstretch> - </sizepolicy> - </property> - </widget> - </item> - <item> - <widget class="QToolButton" name="m_pictureUrlButton" > - <property name="toolTip" > - <string>Browse</string> - </property> - <property name="text" > - <string>...</string> - </property> - </widget> - </item> - </layout> - </item> - <item row="1" column="1" > - <widget class="QLabel" name="m_authorLabel" > - <property name="text" > - <string>Author:</string> - </property> - <property name="alignment" > - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> - </property> - </widget> - </item> - <item row="1" column="2" colspan="2" > - <widget class="QLabel" name="m_authorLine" > - <property name="sizePolicy" > - <sizepolicy vsizetype="Fixed" hsizetype="Preferred" > - <horstretch>1</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text" > - <string/> - </property> - </widget> - </item> - <item row="2" column="1" > - <widget class="QLabel" name="m_emailLabel" > - <property name="text" > - <string>Email:</string> - </property> - <property name="alignment" > - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> - </property> - </widget> - </item> - <item row="2" column="2" colspan="2" > - <widget class="QLabel" name="m_emailLine" > - <property name="sizePolicy" > - <sizepolicy vsizetype="Fixed" hsizetype="Preferred" > - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text" > - <string/> - </property> - </widget> - </item> - <item row="3" column="1" > - <widget class="QLabel" name="m_licenseLabel" > - <property name="text" > - <string>License:</string> - </property> - <property name="alignment" > - <set>Qt::AlignRight|Qt::AlignTop|Qt::AlignTrailing</set> - </property> - </widget> - </item> - <item row="3" column="2" colspan="2" > - <widget class="QLabel" name="m_licenseLine" > - <property name="sizePolicy" > - <sizepolicy vsizetype="Fixed" hsizetype="Preferred" > - <horstretch>1</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text" > - <string/> - </property> - <property name="alignment" > - <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set> - </property> - </widget> - </item> - <item row="4" column="0" > - <widget class="QLabel" name="label_4" > - <property name="minimumSize" > - <size> - <width>75</width> - <height>0</height> - </size> - </property> - <property name="text" > - <string>P&ositioning:</string> - </property> - <property name="alignment" > - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> - </property> - <property name="buddy" > - <cstring>m_resizeMethod</cstring> - </property> - </widget> - </item> - <item row="4" column="1" colspan="3" > - <widget class="QComboBox" name="m_resizeMethod" > - <property name="sizePolicy" > - <sizepolicy vsizetype="Fixed" hsizetype="Preferred" > - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - </widget> - </item> - <item row="5" column="0" > - <widget class="QLabel" name="label_5" > - <property name="text" > - <string>&Color:</string> - </property> - <property name="alignment" > - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> - </property> - <property name="buddy" > - <cstring>m_color</cstring> - </property> - </widget> - </item> - <item row="5" column="1" colspan="2" > - <widget class="KColorButton" name="m_color" > - <property name="sizePolicy" > - <sizepolicy vsizetype="Fixed" hsizetype="Minimum" > - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="minimumSize" > - <size> - <width>0</width> - <height>30</height> - </size> - </property> - <property name="color" > - <color> - <red>70</red> - <green>90</green> - <blue>130</blue> - </color> - </property> - <property name="defaultColor" > - <color> - <red>70</red> - <green>90</green> - <blue>130</blue> - </color> - </property> - </widget> - </item> - <item row="5" column="3" > - <spacer> - <property name="orientation" > - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" stdset="0" > - <size> - <width>40</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - <item row="6" column="0" colspan="2" > - <spacer name="verticalSpacer_2" > - <property name="orientation" > - <enum>Qt::Vertical</enum> - </property> - <property name="sizeHint" stdset="0" > - <size> - <width>1</width> - <height>1</height> - </size> - </property> - </spacer> - </item> - </layout> - </widget> - <widget class="QWidget" name="page_3" > - <property name="geometry" > - <rect> - <x>0</x> - <y>0</y> - <width>466</width> - <height>167</height> - </rect> - </property> - <layout class="QVBoxLayout" > - <property name="leftMargin" > - <number>0</number> - </property> - <property name="topMargin" > - <number>6</number> - </property> - <property name="rightMargin" > - <number>0</number> - </property> - <property name="bottomMargin" > - <number>0</number> - </property> - <item> - <layout class="QHBoxLayout" > - <item> - <widget class="KListWidget" name="m_dirlist" /> - </item> - <item> - <layout class="QVBoxLayout" > - <item> - <widget class="KPushButton" name="m_addDir" > - <property name="text" > - <string>&Add Folder...</string> - </property> - </widget> - </item> - <item> - <widget class="KPushButton" name="m_removeDir" > - <property name="enabled" > - <bool>false</bool> - </property> - <property name="text" > - <string>&Remove Folder</string> - </property> - </widget> - </item> - <item> - <widget class="QWidget" native="1" name="widget" /> - </item> - <item> - <spacer> - <property name="orientation" > - <enum>Qt::Vertical</enum> - </property> - <property name="sizeHint" stdset="0" > - <size> - <width>20</width> - <height>40</height> - </size> - </property> - </spacer> - </item> - </layout> - </item> - </layout> - </item> - <item> - <layout class="QHBoxLayout" > - <item> - <widget class="QLabel" name="label_2" > - <property name="text" > - <string>&Change images every:</string> - </property> - <property name="buddy" > - <cstring>m_slideshowDelay</cstring> - </property> - </widget> - </item> - <item> - <widget class="QTimeEdit" name="m_slideshowDelay" > - <property name="dateTime" > - <datetime> - <hour>0</hour> - <minute>0</minute> - <second>0</second> - <year>2000</year> - <month>1</month> - <day>1</day> - </datetime> - </property> - <property name="currentSection" > - <enum>QDateTimeEdit::HourSection</enum> - </property> - <property name="displayFormat" > - <string comment="(qtdt-format) Please do not change the quotes (') and translate only the content of the quotes." >hh 'Hours' mm 'Mins' ss 'Secs'</string> - </property> - <property name="time" > - <time> - <hour>0</hour> - <minute>0</minute> - <second>0</second> - </time> - </property> - </widget> - </item> - <item> - <spacer> - <property name="orientation" > - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" stdset="0" > - <size> - <width>40</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - </layout> - </item> - </layout> - </widget> - </widget> - </item> - </layout> - </item> - <item row="0" column="1" > - <layout class="QVBoxLayout" name="verticalLayout" > - <item> - <layout class="QHBoxLayout" name="horizontalLayout" > - <item> - <spacer name="horizontalSpacer" > - <property name="orientation" > - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" stdset="0" > - <size> - <width>40</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QLabel" name="m_monitor" > - <property name="sizePolicy" > - <sizepolicy vsizetype="Fixed" hsizetype="Fixed" > - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text" > - <string>Monitor</string> - </property> - <property name="alignment" > - <set>Qt::AlignCenter</set> - </property> - </widget> - </item> - <item> - <spacer name="horizontalSpacer_2" > - <property name="orientation" > - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" stdset="0" > - <size> - <width>40</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - </layout> - </item> - <item> - <widget class="QPushButton" name="m_newStuff" > - <property name="toolTip" > - <string>Download new wallpapers</string> - </property> - <property name="text" > - <string>New Wallpaper...</string> - </property> - </widget> - </item> - <item> - <spacer> - <property name="orientation" > - <enum>Qt::Vertical</enum> - </property> - <property name="sizeType" > - <enum>QSizePolicy::Expanding</enum> - </property> - <property name="sizeHint" stdset="0" > - <size> - <width>159</width> - <height>113</height> - </size> - </property> - </spacer> - </item> - </layout> - </item> - </layout> - </widget> - </item> - <item row="1" column="0" > - <spacer> - <property name="orientation" > - <enum>Qt::Vertical</enum> - </property> - <property name="sizeType" > - <enum>QSizePolicy::Expanding</enum> - </property> - <property name="sizeHint" stdset="0" > - <size> - <width>636</width> - <height>0</height> - </size> - </property> - </spacer> - </item> - <item row="2" column="0" > - <widget class="QGroupBox" name="groupBox_3" > - <property name="title" > - <string>Desktop Theme</string> - </property> - <property name="flat" > - <bool>true</bool> - </property> - <property name="checkable" > - <bool>false</bool> - </property> - <layout class="QGridLayout" > - <item row="0" column="0" > - <layout class="QHBoxLayout" > - <item> - <widget class="QLabel" name="label_3" > - <property name="text" > - <string>Theme:</string> - </property> - </widget> - </item> - <item> - <widget class="QComboBox" name="m_theme" > - <property name="sizePolicy" > - <sizepolicy vsizetype="Fixed" hsizetype="Expanding" > - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - </widget> - </item> - <item> - <widget class="QPushButton" name="m_newThemeButton" > - <property name="enabled" > - <bool>true</bool> - </property> - <property name="text" > - <string>New Theme...</string> - </property> - </widget> - </item> - </layout> - </item> - </layout> - </widget> - </item> - </layout> - </widget> - <customwidgets> - <customwidget> - <class>KColorButton</class> - <extends>QPushButton</extends> - <header>kcolorbutton.h</header> - </customwidget> - <customwidget> - <class>KListWidget</class> - <extends>QListWidget</extends> - <header>klistwidget.h</header> - </customwidget> - <customwidget> - <class>KPushButton</class> - <extends>QPushButton</extends> - <header>kpushbutton.h</header> - </customwidget> - </customwidgets> - <resources/> - <connections/> -</ui> --- containments/desktop/backgroundpackage.cpp +++ containments/desktop/backgroundpackage.cpp @@ -1,393 +0,0 @@ -/* - * Copyright (c) 2007 Paolo Capriotti <p.capriotti@gmail.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2, - * or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details - * - * You should have received a copy of the GNU Library General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "backgroundpackage.h" -#include <cmath> -// <cmath> does not define fabs (by the standard, even if it does with gcc) -#include <math.h> -#include <float.h> // FLT_MAX - -#include <QFileInfo> -#include <QPainter> -#include <KDebug> -#include <KLocalizedString> -#include <KStandardDirs> -#include <KSvgRenderer> -#include <plasma/packagestructure.h> -#include <plasma/packagemetadata.h> -#include <ThreadWeaver/Weaver> - -using namespace Plasma; - -class ResizeThread : public ThreadWeaver::Job -{ -public: - ResizeThread(const QString &path, float ratio, QObject *parent = 0); - virtual ~ResizeThread(); - - virtual void start(QPersistentModelIndex index); - virtual void run(); - - QImage result() const; - QPersistentModelIndex index() const; - bool isInitialized() const; -private: - QString m_path; - QImage m_result; - float m_ratio; - QPersistentModelIndex m_index; -}; - -ResizeThread::ResizeThread(const QString &path, float ratio, QObject *parent) -: ThreadWeaver::Job(parent) -, m_path(path) -, m_ratio(ratio) -{ -} - -ResizeThread::~ResizeThread() { -} - -void ResizeThread::start(QPersistentModelIndex index) -{ - m_index = index; - ThreadWeaver::Weaver::instance()->enqueue(this); -} - -bool ResizeThread::isInitialized() const -{ - return m_index.isValid(); -} - -void ResizeThread::run() -{ - m_result = Background::createScreenshot(m_path, m_ratio); -} - -QImage ResizeThread::result() const -{ - if (isFinished()) { - return m_result; - } - else { - return QImage(); - } -} - -QPersistentModelIndex ResizeThread::index() const -{ - return m_index; -} - -Background::~Background() -{ -} - -QImage Background::createScreenshot(const QString &path, float ratio) -{ - if (path.endsWith("svg") || path.endsWith("svgz")) { - KSvgRenderer renderer(path); - QImage img(QSize(int(SCREENSHOT_HEIGHT * ratio), SCREENSHOT_HEIGHT), - QImage::Format_ARGB32_Premultiplied); - img.fill(0); - QPainter p(&img); - renderer.render(&p); - return img; - } - else { - QImage img(path); - if (!img.isNull()) { - return img.scaled(int(SCREENSHOT_HEIGHT * ratio), - SCREENSHOT_HEIGHT, - Qt::KeepAspectRatio); - } - else { - return defaultScreenshot(); - } - } - -} - -QImage Background::defaultScreenshot() -{ - static QImage defaultScreenshotImage; - - if (defaultScreenshotImage.isNull()) { - QImage img(QSize(SCREENSHOT_HEIGHT, SCREENSHOT_HEIGHT), QImage::Format_ARGB32_Premultiplied); - img.fill(Qt::white); - QPainter p(&img); - p.drawText(QRect(0, 0, SCREENSHOT_HEIGHT, SCREENSHOT_HEIGHT), - Qt::AlignHCenter | Qt::AlignVCenter, - "Preview\nnot\navailable"); - defaultScreenshotImage = img; - } - return defaultScreenshotImage; -} - - -class BackgroundPackageStructure : public PackageStructure -{ -public: - static const PackageStructure::Ptr self(); -private: - BackgroundPackageStructure(); // should be used as a singleton - void addResolution(const char *res); -}; - -BackgroundPackageStructure::BackgroundPackageStructure() -: PackageStructure(0, "Background") -{ - QStringList mimetypes; - mimetypes << "image/svg" << "image/png" << "image/jpeg" << "image/jpg"; - setDefaultMimetypes(mimetypes); - - addDirectoryDefinition("images", "images", i18n("Images")); - addFileDefinition("screenshot", "screenshot.png", i18n("Screenshot")); -} - - -const PackageStructure::Ptr BackgroundPackageStructure::self() -{ - static BackgroundPackageStructure::Ptr instance(0); - - if (!instance) { - instance = new BackgroundPackageStructure; - } - - return instance; -} - - - -BackgroundPackage::BackgroundPackage(const QString &path, float ratio) -: Package(path, BackgroundPackageStructure::self()) -, m_path(path) -, m_ratio(ratio) -{ -} - -QString BackgroundPackage::resString(const QSize &size) const -{ - return QString::number(size.width()) + 'x' + QString::number(size.height()); -} - -QSize BackgroundPackage::resSize(const QString &str) const -{ - int index = str.indexOf('x'); - if (index != -1) { - return QSize(str.left(index).toInt(), - str.mid(index + 1).toInt()); - } - else { - return QSize(); - } -} - -QString BackgroundPackage::findBackground(const QSize &size, - ResizeMethod method) const -{ - QStringList images = entryList("images"); - if (images.empty()) { - return QString(); - } - - // choose the nearest resolution - float best = FLT_MAX; - QString bestImage; - foreach (const QString &entry, images) { - QSize candidate = resSize(QFileInfo(entry).baseName()); - if (candidate == QSize()) { - continue; - } - - double dist = distance(candidate, size, method); - kDebug() << "candidate" << candidate << "distance" << dist; - if (bestImage.isNull() || dist < best) { - bestImage = filePath("images", entry); - best = dist; - kDebug() << "best" << bestImage; - if (dist == 0) { - break; - } - } - } - - kDebug() << "best image" << bestImage; - return bestImage; -} - -float BackgroundPackage::distance(const QSize& size, - const QSize& desired, - ResizeMethod method) const -{ - // compute difference of areas - float delta = size.width() * size.height() - - desired.width() * desired.height(); - // scale down to about 1.0 - delta /= 1000000.0; - - switch (method) { - case Scale: { - // Consider first the difference in aspect ratio, - // then in areas. Prefer scaling down. - float deltaRatio = size.width() / size.height() - - desired.width() / desired.height(); - return fabs(deltaRatio) * 3.0 + - (delta >= 0.0 ? delta : -delta + 5.0); - } - case ScaleCrop: - // Difference of areas, slight preference to scale down - return delta >= 0.0 ? delta : -delta + 2.0; - case Center: - default: - // Difference in areas - return fabs(delta); - } -} - -QPixmap BackgroundPackage::screenshot() const -{ - if (m_screenshot.isNull()) { - QString screenshotPath = filePath("screenshot"); - if (!screenshotPath.isEmpty()) { - QImage img = createScreenshot(screenshotPath, m_ratio); - m_screenshot = QPixmap::fromImage(img); - } - } - - return m_screenshot; -} - -bool BackgroundPackage::screenshotGenerationStarted() const -{ - return true; -} - -void BackgroundPackage::generateScreenshot(QPersistentModelIndex) const -{ -} - -QString BackgroundPackage::title() const -{ - QString title = metadata()->name(); - if (title.isEmpty()) { - title = metadata()->pluginName(); - title.replace("_", " "); - } - return title; -} - -QString BackgroundPackage::author() const -{ - return metadata()->author(); -} - -QString BackgroundPackage::email() const -{ - return metadata()->email(); -} - -QString BackgroundPackage::license() const -{ - return metadata()->license(); -} - -bool BackgroundPackage::isValid() const -{ - return Package::isValid(); -} - -QString BackgroundPackage::path() const -{ - return m_path; -} - - -BackgroundFile::BackgroundFile(const QString &file, float ratio) -: m_file(file) -, m_ratio(ratio) -, m_resizer_started(false) -{ -} - -BackgroundFile::~BackgroundFile() -{ -} - -QString BackgroundFile::findBackground(const QSize &, - ResizeMethod) const -{ - return m_file; -} - -QPixmap BackgroundFile::screenshot() const -{ - return m_screenshot; -} - -bool BackgroundFile::screenshotGenerationStarted() const -{ - return m_resizer_started; -} - -void BackgroundFile::generateScreenshot(QPersistentModelIndex index) const -{ - ResizeThread *resizer = new ResizeThread(m_file, m_ratio); - connect(resizer, SIGNAL(done(ThreadWeaver::Job *)), - this, SLOT(updateScreenshot(ThreadWeaver::Job *))); - m_resizer_started = true; - resizer->start(index); -} - -void BackgroundFile::updateScreenshot(ThreadWeaver::Job *job) -{ - ResizeThread *resizer = static_cast<ResizeThread *>(job); - m_screenshot = QPixmap::fromImage(resizer->result()); - emit screenshotDone(resizer->index()); - resizer->deleteLater(); -} - -QString BackgroundFile::author() const -{ - return QString(); -} - -QString BackgroundFile::title() const -{ - return QFileInfo(m_file).baseName(); -} - -QString BackgroundFile::email() const -{ - return QString(); -} - -QString BackgroundFile::license() const -{ - return QString(); -} - -bool BackgroundFile::isValid() const -{ - return true; -} - -QString BackgroundFile::path() const -{ - return m_file; -} --- containments/desktop/renderthread.h +++ containments/desktop/renderthread.h @@ -1,54 +0,0 @@ -/* - Copyright (c) 2007 Paolo Capriotti <p.capriotti@gmail.com> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. -*/ - -#ifndef RENDERTHREAD_H -#define RENDERTHREAD_H - -#include "backgroundpackage.h" -#include <QColor> -#include <QImage> -#include <QMutex> -#include <QThread> -#include <QWaitCondition> - -class RenderThread : public QThread -{ -Q_OBJECT -public: - RenderThread(const QSize &size, float ratio); - virtual ~RenderThread(); - - int render(const QString &file, - const QColor &color, - Background::ResizeMethod method, - Qt::TransformationMode mode); - - void setSize(const QSize &size); -protected: - virtual void run(); -private: - QMutex m_mutex; // to protect parameters - QWaitCondition m_condition; - - // protected by mutex - int m_current_token; - QString m_file; - QColor m_color; - QSize m_size; - float m_ratio; - Background::ResizeMethod m_method; - Qt::TransformationMode m_mode; - - bool m_abort; - bool m_restart; -signals: - void done(int token, const QImage &pixmap); -}; - -#endif // RENDERTHREAD_H --- containments/desktop/desktop.h +++ containments/desktop/desktop.h @@ -33,9 +33,6 @@ #include <plasma/containment.h> #include <plasma/animator.h> -#include "renderthread.h" - -class BackgroundDialog; class QAction; class QTimeLine; @@ -45,11 +42,6 @@ class Svg; } -namespace Ui -{ - class config; -} - /*class Tool : public QObject, public QGraphicsItem { Q_OBJECT @@ -73,32 +65,17 @@ QList<QAction*> contextualActions(); - /** - * Paints a default background image. Nothing fancy, but that's what plugins - * are for. Reimplemented from Plasma::Containment; - */ - void paintInterface(QPainter *painter, - const QStyleOptionGraphicsItem *option, - const QRect& contentsRect); - protected Q_SLOTS: void runCommand(); void configure(); - void applyConfig(); - void nextSlide(bool skipUpdates=false); void lockScreen(); void logout(); - void updateBackground(); - void updateBackground(int, const QImage &img); - void addPanel(); private: - void reloadConfig(); QSize resolution() const; - void suspendStartup(bool suspend); // for ksmserver QAction *m_lockDesktopAction; QAction *m_appletBrowserAction; @@ -109,25 +86,6 @@ QAction *m_logoutAction; QAction *m_separator; QAction *m_separator2; - - BackgroundDialog *m_configDialog; - - int m_backgroundMode; - - // slideshow settings - // the index of which m_slidePath is currently visible - int m_currentSlide; - QTimer m_slideshowTimer; - QStringList m_slideFiles; - - QPixmap m_bitmapBackground; - QString m_wallpaperPath; - - int m_wallpaperPosition; - QColor m_wallpaperColor; - - RenderThread m_renderer; - int m_rendererToken; }; #endif // PLASMA_PANEL_H --- containments/desktop/plasma-containment-desktop.desktop +++ containments/desktop/plasma-containment-desktop.desktop @@ -56,8 +56,8 @@ Name[se]=Čállinbeavdi Name[sk]=Plocha Name[sl]=Namizje -Name[sr]=.Десктоп -Name[sr@latin]=.Desktop +Name[sr]=Површ +Name[sr@latin]=Površ Name[sv]=Skrivbord Name[ta]=பணிமேசை Name[te]=రంగస్ఠలం @@ -72,7 +72,8 @@ Name[x-test]=xxDesktopxx Name[zh_CN]=桌面 Name[zh_TW]=桌面 -Icon=Plasma +Comment=Default desktop containment +Icon=user-desktop Type=Service X-KDE-ServiceTypes=Plasma/Applet,Plasma/Containment NoDisplay=true --- containments/desktop/desktop.cpp +++ containments/desktop/desktop.cpp @@ -48,10 +48,7 @@ #include "krunner_interface.h" #include "screensaver_interface.h" -#include "ksmserver_interface.h" -#include "backgrounddialog.h" - using namespace Plasma; DefaultDesktop::DefaultDesktop(QObject *parent, const QVariantList &args) @@ -61,50 +58,17 @@ m_addPanelAction(0), m_runCommandAction(0), m_lockScreenAction(0), - m_logoutAction(0), - m_configDialog(0), - m_wallpaperPath(0), - m_wallpaperPosition(0), - m_renderer(resolution(), 1.0), - m_rendererToken(-1) + m_logoutAction(0) { qRegisterMetaType<QImage>("QImage"); qRegisterMetaType<QPersistentModelIndex>("QPersistentModelIndex"); - connect(&m_renderer, SIGNAL(done(int, QImage)), - this, SLOT(updateBackground(int, QImage))); - connect(&m_slideshowTimer, SIGNAL(timeout()), - this, SLOT(nextSlide())); //kDebug() << "!!! loading desktop"; } DefaultDesktop::~DefaultDesktop() { - delete m_configDialog; } -void DefaultDesktop::nextSlide(bool skipUpdates) -{ - if (++m_currentSlide >= m_slideFiles.size()) { - m_currentSlide = 0; - } - - if (m_slideFiles.size() > 0) { - // do not change to the same background if we have a choice - // if there is only one background, it may be changed by someone else - if (m_slideFiles.size() > 1 && m_wallpaperPath == m_slideFiles[m_currentSlide]) { - // try next one, they can't be the same (at least the same path) - if (++m_currentSlide >= m_slideFiles.size()) { - m_currentSlide = 0; - } - } - - m_wallpaperPath = m_slideFiles[m_currentSlide]; - if (!skipUpdates) { - updateBackground(); - } - } -} - QSize DefaultDesktop::resolution() const { return QApplication::desktop()->screenGeometry(screen()).size(); @@ -112,21 +76,6 @@ void DefaultDesktop::constraintsEvent(Plasma::Constraints constraints) { - if (constraints & Plasma::StartupCompletedConstraint) { - qsrand(QTime(0,0,0).msecsTo(QTime::currentTime()) + id()); - reloadConfig(); - } - - if (constraints & Plasma::SizeConstraint) { - m_renderer.setSize(size().toSize()); - - if (m_rendererToken != -1) { - // if the renderer token is still -1, then we haven't actually started up yet - // and there is no point in touching the renderer at this point - updateBackground(); - } - } - if (constraints & Plasma::ImmutableConstraint && m_appletBrowserAction) { // we need to update the menu items that have already been created bool locked = immutability() != Mutable; @@ -136,137 +85,9 @@ void DefaultDesktop::configure() { - KConfigGroup cg = config(); - KConfigGroup gcg = globalConfig(); - if (m_configDialog == 0) { - const QSize resolution = - QApplication::desktop()->screenGeometry(screen()).size(); - m_configDialog = new BackgroundDialog(resolution, cg, gcg, 0); - connect(m_configDialog, SIGNAL(okClicked()), - this, SLOT(applyConfig())); - connect(m_configDialog, SIGNAL(applyClicked()), - this, SLOT(applyConfig())); - } - else { - m_configDialog->reloadConfig(cg, gcg); - } - - m_configDialog->show(); - KWindowSystem::setOnDesktop(m_configDialog->winId(), KWindowSystem::currentDesktop()); - KWindowSystem::activateWindow(m_configDialog->winId()); + emit configureRequested(); } -void DefaultDesktop::applyConfig() -{ - Q_ASSERT(m_configDialog); - m_configDialog->saveConfig(config(), globalConfig()); - emit configNeedsSaving(); - - reloadConfig(); -} - -void DefaultDesktop::reloadConfig() -{ - KConfigGroup cg = config(); - - // store the state of the existing wallpaper config so we can determine later - // if we need to trigger updates - QString oldWallpaperPath(m_wallpaperPath); - QColor old_wallpaperColor = m_wallpaperColor; - int old_wallPaperPosition = m_wallpaperPosition; - - // If no wallpaper is set, a default will be set in updateBackground() - // which is called as soon as constraints are updated. - m_wallpaperPath = cg.readEntry("wallpaper", QString()); - m_backgroundMode = cg.readEntry("backgroundmode", int(BackgroundDialog::kStaticBackground)); - - if (m_backgroundMode != BackgroundDialog::kNoBackground && - (m_wallpaperPath.isEmpty() || !KStandardDirs::exists(m_wallpaperPath))) { - m_wallpaperPath = Plasma::Theme::defaultTheme()->wallpaperPath(size().toSize()); - cg.writeEntry("wallpaper", m_wallpaperPath); - } - - if (!m_wallpaperPath.isEmpty()) { - kDebug() << "Using configured wallpaper" << m_wallpaperPath; - } - - // used in both modes, so read it no matter which mode we are in - m_wallpaperPosition = cg.readEntry("wallpaperposition", int(Background::ScaleCrop)); - m_wallpaperColor = cg.readEntry("wallpapercolor", QColor(Qt::black)); - - if (m_backgroundMode == BackgroundDialog::kStaticBackground || - m_backgroundMode == BackgroundDialog::kNoBackground) { - m_slideshowTimer.stop(); - // Only set the wallpaper if constraints have been loaded - // and background image has changed - if (oldWallpaperPath != m_wallpaperPath || - m_wallpaperPosition != old_wallPaperPosition || - m_wallpaperColor != old_wallpaperColor) { - updateBackground(); - } - } else { - QStringList dirs = cg.readEntry("slidepaths", QStringList()); - QStringList filters; - filters << "*.png" << "*.jpeg" << "*.jpg" << "*.svg" << "*.svgz"; - - m_slideFiles.clear(); - - for (int i = 0; i < dirs.size(); ++i) { - QString path = dirs[i]; - // TODO load packages, too - QDir dir(path); - dir.setNameFilters(filters); - dir.setFilter(QDir::Files | QDir::Hidden); - - QFileInfoList files = dir.entryInfoList(); - foreach (const QFileInfo &wp, files) { - int position = m_slideFiles.size() == 0 ? 0 : qrand() % m_slideFiles.size(); - m_slideFiles.insert(position, wp.filePath()); - } - - // now make it look in sub-dirs - dir.setFilter(QDir::AllDirs | QDir::NoDotAndDotDot); - QFileInfoList subdirs = dir.entryInfoList(); - foreach (const QFileInfo &wp, subdirs) { - dirs.append(wp.filePath()); - } - } - - int delay = cg.readEntry("slideTimer", 60); - m_slideshowTimer.setInterval(delay * 1000); - if (!m_slideshowTimer.isActive()) { - m_slideshowTimer.start(); - } - m_currentSlide = -1; - nextSlide(false); - } -} - -void DefaultDesktop::updateBackground() -{ - if (m_wallpaperPath.isEmpty() && m_backgroundMode != BackgroundDialog::kNoBackground) { - m_wallpaperPath = Plasma::Theme::defaultTheme()->wallpaperPath(size().toSize()); - kDebug() << "Setting wallpaper to default" << m_wallpaperPath; - emit configNeedsSaving(); - } - - m_rendererToken = - m_renderer.render(m_wallpaperPath, - m_wallpaperColor, - (Background::ResizeMethod)m_wallpaperPosition, - Qt::SmoothTransformation); - suspendStartup( true ); // during KDE startup, make ksmserver until the wallpaper is ready -} - -void DefaultDesktop::updateBackground(int token, const QImage &img) -{ - if (m_rendererToken == token) { - m_bitmapBackground = QPixmap::fromImage(img); - update(); - suspendStartup( false ); - } -} - void DefaultDesktop::addPanel() { if (corona()) { @@ -275,9 +96,18 @@ panel->showConfigurationInterface(); panel->setScreen(screen()); - panel->setLocation(Plasma::TopEdge); + if (corona()->containments().count()==2) { + panel->setLocation(Plasma::BottomEdge); + if (!corona()->loadDefaultApplets(panel, true)) { + panel->destroy(false); + return; + } + } + else { + panel->setLocation(Plasma::TopEdge); + } - // trigger an instant layout so we immediately have a proper geometry + // trigger an instant layout so we immediately have a proper geometry // rather than waiting around for the event loop panel->updateConstraints(Plasma::StartupCompletedConstraint); panel->flushPendingConstraintsEvents(); @@ -298,17 +128,6 @@ } } -void DefaultDesktop::suspendStartup(bool suspend) -{ - org::kde::KSMServerInterface ksmserver("org.kde.ksmserver", "/KSMServer", QDBusConnection::sessionBus()); - const QString startupID("desktop wallaper"); - if (suspend) { - ksmserver.suspendStartup(startupID); - } else { - ksmserver.resumeStartup(startupID); - } -} - void DefaultDesktop::lockScreen() { if (!KAuthorized::authorizeKAction("lock_screen")) { @@ -338,7 +157,7 @@ connect(m_runCommandAction, SIGNAL(triggered(bool)), this, SLOT(runCommand())); m_runCommandAction->setIcon(KIcon("system-run")); - m_setupDesktopAction = new QAction(i18n("Desktop Settings..."), this); + m_setupDesktopAction = new QAction(i18n("Desktop Settings"), this); m_setupDesktopAction->setIcon(KIcon("configure")); connect(m_setupDesktopAction, SIGNAL(triggered()), this, SLOT(configure())); @@ -400,35 +219,6 @@ #endif } -void DefaultDesktop::paintInterface(QPainter *painter, - const QStyleOptionGraphicsItem *option, - const QRect& contentsRect) -{ - //kDebug() << "paintInterface of background"; - if (m_bitmapBackground.isNull()) { - Containment::paintInterface(painter, option, contentsRect); - return; - } - - painter->save(); - - if (painter->worldMatrix() == QMatrix()) { - // draw the background untransformed when possible;(saves lots of per-pixel-math) - painter->resetTransform(); - } - - // blit the background (saves all the per-pixel-products that blending does) - painter->setCompositionMode(QPainter::CompositionMode_Source); - - // for pixmaps we draw only the exposed part (untransformed since the - // bitmapBackground already has the size of the viewport) - painter->drawPixmap(option->exposedRect, m_bitmapBackground, option->exposedRect); - //kDebug() << "draw pixmap of background to" << option->exposedRect; - - // restore transformation and composition mode - painter->restore(); -} - K_EXPORT_PLASMA_APPLET(desktop, DefaultDesktop) #include "desktop.moc" --- containments/desktop/CMakeLists.txt +++ containments/desktop/CMakeLists.txt @@ -1,29 +1,19 @@ set(desktop_SRCS - desktop.cpp - backgrounddialog.cpp - backgroundpackage.cpp - renderthread.cpp) + desktop.cpp) -kde4_add_ui_files( desktop_SRCS BackgroundDialog.ui ) - set(krunner_xml ${KDEBASE_WORKSPACE_SOURCE_DIR}/krunner/org.kde.krunner.Interface.xml) QT4_ADD_DBUS_INTERFACE(desktop_SRCS ${krunner_xml} krunner_interface) set(screensaver_xml ${KDEBASE_WORKSPACE_SOURCE_DIR}/krunner/org.freedesktop.ScreenSaver.xml) QT4_ADD_DBUS_INTERFACE(desktop_SRCS ${screensaver_xml} screensaver_interface) -set(ksmserver_xml ${KDEBASE_WORKSPACE_SOURCE_DIR}/ksmserver/org.kde.KSMServerInterface.xml) -QT4_ADD_DBUS_INTERFACE(desktop_SRCS ${ksmserver_xml} ksmserver_interface) - kde4_add_plugin(plasma_containment_desktop ${desktop_SRCS}) if(WIN32) -target_link_libraries(plasma_containment_desktop plasma ${KDE4_KNEWSTUFF2_LIBS} ${KDE4_KIO_LIBS} ${KDE4_KFILE_LIBS} ${KDE4_THREADWEAVER_LIBRARY}) +target_link_libraries(plasma_containment_desktop plasma ${KDE4_KIO_LIBS} ${KDE4_KFILE_LIBS}) else(WIN32) -target_link_libraries(plasma_containment_desktop plasma kworkspace ${KDE4_KNEWSTUFF2_LIBS} ${KDE4_KIO_LIBS} ${KDE4_KFILE_LIBS} ${KDE4_THREADWEAVER_LIBRARY}) +target_link_libraries(plasma_containment_desktop plasma kworkspace ${KDE4_KIO_LIBS} ${KDE4_KFILE_LIBS}) endif(WIN32) install(TARGETS plasma_containment_desktop DESTINATION ${PLUGIN_INSTALL_DIR}) install(FILES plasma-containment-desktop.desktop DESTINATION ${SERVICES_INSTALL_DIR}) install(FILES plasma_desktop_containment.kwinrules DESTINATION ${DATA_INSTALL_DIR}/kwin/default_rules) - -install( FILES wallpaper.knsrc plasma-themes.knsrc DESTINATION ${CONFIG_INSTALL_DIR} ) --- containments/CMakeLists.txt +++ containments/CMakeLists.txt @@ -1,2 +1,3 @@ add_subdirectory(desktop) add_subdirectory(panel) +add_subdirectory(plaindesktop) --- containments/plaindesktop/desktop.h +++ containments/plaindesktop/desktop.h @@ -0,0 +1,91 @@ +/* +* Copyright 2007 by Aaron Seigo <aseigo@kde.org> +* Copyright 2008 by Alexis Ménard <darktears31@gmail.com> +* +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU Library General Public License version 2, +* or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details +* +* You should have received a copy of the GNU Library General Public +* License along with this program; if not, write to the +* Free Software Foundation, Inc., +* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#ifndef PLASMA_PLAINDESKTOP_H +#define PLASMA_PLAINDESKTOP_H + +#include <QGraphicsItem> +#include <QList> +#include <QObject> +#include <QStyleOptionGraphicsItem> +#include <QTimer> + +#include <KDialog> +#include <KIcon> + +#include <plasma/containment.h> +#include <plasma/animator.h> + +class QAction; +class QTimeLine; + +namespace Plasma +{ + class AppletBrowser; + class Svg; +} + +/*class Tool : public QObject, public QGraphicsItem +{ + Q_OBJECT + +public: + explicit Tool(QGraphicsItem *parent = 0); + QRectF boundingRect() const; + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0); + +};*/ + +class DefaultDesktop : public Plasma::Containment +{ + Q_OBJECT + +public: + DefaultDesktop(QObject *parent, const QVariantList &args); + ~DefaultDesktop(); + + void constraintsEvent(Plasma::Constraints constraints); + + QList<QAction*> contextualActions(); + +protected Q_SLOTS: + void runCommand(); + void configure(); + + void lockScreen(); + void logout(); + + void addPanel(); + +private: + QSize resolution() const; + + QAction *m_lockDesktopAction; + QAction *m_appletBrowserAction; + QAction *m_addPanelAction; + QAction *m_runCommandAction; + QAction *m_setupDesktopAction; + QAction *m_lockScreenAction; + QAction *m_logoutAction; + QAction *m_separator; + QAction *m_separator2; +}; + +#endif // PLASMA_PLAINDESKTOP_H --- containments/plaindesktop/desktop.cpp +++ containments/plaindesktop/desktop.cpp @@ -0,0 +1,224 @@ +/* +* Copyright 2007 by Aaron Seigo <aseigo@kde.org> +* Copyright 2008 by Alexis Ménard <darktears31@gmail.com> +* +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU Library General Public License version 2, +* or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details +* +* You should have received a copy of the GNU Library General Public +* License along with this program; if not, write to the +* Free Software Foundation, Inc., +* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include "desktop.h" + +#include <QAction> +#include <QApplication> +#include <QDesktopWidget> +#include <QFile> +#include <QFileInfo> +#include <QGraphicsScene> +#include <QGraphicsView> +#include <QPainter> +#include <QTimeLine> + +#include <KAuthorized> +#include <KComboBox> +#include <KDebug> +#include <KFileDialog> +#include <KImageFilePreview> +#include <KRun> +#include <KStandardDirs> +#include <KWindowSystem> + +#include "plasma/corona.h" +#include "plasma/appletbrowser.h" +#include "plasma/animator.h" +#include "plasma/theme.h" +#include "kworkspace/kworkspace.h" +#include "knewstuff2/engine.h" + +#include "krunner_interface.h" +#include "screensaver_interface.h" + +using namespace Plasma; + +DefaultDesktop::DefaultDesktop(QObject *parent, const QVariantList &args) + : Containment(parent, args, false), + m_lockDesktopAction(0), + m_appletBrowserAction(0), + m_addPanelAction(0), + m_runCommandAction(0), + m_lockScreenAction(0), + m_logoutAction(0) +{ + qRegisterMetaType<QImage>("QImage"); + qRegisterMetaType<QPersistentModelIndex>("QPersistentModelIndex"); + //kDebug() << "!!! loading desktop"; +} + +DefaultDesktop::~DefaultDesktop() +{ +} + +QSize DefaultDesktop::resolution() const +{ + return QApplication::desktop()->screenGeometry(screen()).size(); +} + +void DefaultDesktop::constraintsEvent(Plasma::Constraints constraints) +{ + if (constraints & Plasma::ImmutableConstraint && m_appletBrowserAction) { + // we need to update the menu items that have already been created + bool locked = immutability() != Mutable; + m_addPanelAction->setVisible(!locked); + } +} + +void DefaultDesktop::configure() +{ + emit configureRequested(); +} + +void DefaultDesktop::addPanel() +{ + if (corona()) { + // make a panel at the top + Containment* panel = corona()->addContainment("panel"); + panel->showConfigurationInterface(); + + panel->setScreen(screen()); + if (corona()->containments().count()==2) { + panel->setLocation(Plasma::BottomEdge); + if (!corona()->loadDefaultApplets(panel, true)) { + panel->destroy(false); + return; + } + } + else { + panel->setLocation(Plasma::TopEdge); + } + + // trigger an instant layout so we immediately have a proper geometry + // rather than waiting around for the event loop + panel->updateConstraints(Plasma::StartupCompletedConstraint); + panel->flushPendingConstraintsEvents(); + } +} + +void DefaultDesktop::runCommand() +{ + if (!KAuthorized::authorizeKAction("run_command")) { + return; + } + + QString interface("org.kde.krunner"); + org::kde::krunner::Interface krunner(interface, "/Interface", + QDBusConnection::sessionBus()); + if (krunner.isValid()) { + krunner.display(); + } +} + +void DefaultDesktop::lockScreen() +{ + if (!KAuthorized::authorizeKAction("lock_screen")) { + return; + } + + QString interface("org.freedesktop.ScreenSaver"); + org::freedesktop::ScreenSaver screensaver(interface, "/ScreenSaver", + QDBusConnection::sessionBus()); + if (screensaver.isValid()) { + screensaver.Lock(); + } +} + +QList<QAction*> DefaultDesktop::contextualActions() +{ + //TODO: should we offer "Switch User" here? + + if (!m_appletBrowserAction) { + m_appletBrowserAction = action("add widgets"); + + m_addPanelAction = new QAction(i18n("Add Panel"), this); + connect(m_addPanelAction, SIGNAL(triggered(bool)), this, SLOT(addPanel())); + m_addPanelAction->setIcon(KIcon("list-add")); + + m_runCommandAction = new QAction(i18n("Run Command..."), this); + connect(m_runCommandAction, SIGNAL(triggered(bool)), this, SLOT(runCommand())); + m_runCommandAction->setIcon(KIcon("system-run")); + + m_setupDesktopAction = new QAction(i18n("Desktop Settings"), this); + m_setupDesktopAction->setIcon(KIcon("configure")); + connect(m_setupDesktopAction, SIGNAL(triggered()), this, SLOT(configure())); + + m_lockDesktopAction = action("lock widgets"); + + m_lockScreenAction = new QAction(i18n("Lock Screen"), this); + m_lockScreenAction->setIcon(KIcon("system-lock-screen")); + connect(m_lockScreenAction, SIGNAL(triggered(bool)), this, SLOT(lockScreen())); + + m_logoutAction = new QAction(i18n("Leave..."), this); + m_logoutAction->setIcon(KIcon("system-shutdown")); + connect(m_logoutAction, SIGNAL(triggered(bool)), this, SLOT(logout())); + constraintsEvent(Plasma::ImmutableConstraint); + + m_separator = new QAction(this); + m_separator->setSeparator(true); + + m_separator2 = new QAction(this); + m_separator2->setSeparator(true); + } + + QList<QAction*> actions; + + if (KAuthorized::authorizeKAction("run_command")) { + actions.append(m_runCommandAction); + } + + actions.append(m_appletBrowserAction); + actions.append(m_addPanelAction); + actions.append(m_setupDesktopAction); + if (screen() == -1) { + actions.append(action("remove")); + } + + actions.append(m_lockDesktopAction); + + actions.append(m_separator); + + if (KAuthorized::authorizeKAction("lock_screen")) { + actions.append(m_lockScreenAction); + } + + if (KAuthorized::authorizeKAction("logout")) { + actions.append(m_logoutAction); + } + + return actions; +} + +void DefaultDesktop::logout() +{ + if (!KAuthorized::authorizeKAction("logout")) { + return; + } +#ifndef Q_WS_WIN + KWorkSpace::requestShutDown(KWorkSpace::ShutdownConfirmDefault, + KWorkSpace::ShutdownTypeDefault, + KWorkSpace::ShutdownModeDefault); +#endif +} + +K_EXPORT_PLASMA_APPLET(desktop, DefaultDesktop) + +#include "desktop.moc" --- containments/plaindesktop/CMakeLists.txt +++ containments/plaindesktop/CMakeLists.txt @@ -0,0 +1,18 @@ +set(desktop_SRCS + desktop.cpp) + +set(krunner_xml ${KDEBASE_WORKSPACE_SOURCE_DIR}/krunner/org.kde.krunner.Interface.xml) +QT4_ADD_DBUS_INTERFACE(desktop_SRCS ${krunner_xml} krunner_interface) + +set(screensaver_xml ${KDEBASE_WORKSPACE_SOURCE_DIR}/krunner/org.freedesktop.ScreenSaver.xml) +QT4_ADD_DBUS_INTERFACE(desktop_SRCS ${screensaver_xml} screensaver_interface) + +kde4_add_plugin(plasma_containment_plaindesktop ${desktop_SRCS}) +if(WIN32) +target_link_libraries(plasma_containment_plaindesktop plasma ${KDE4_KIO_LIBS} ${KDE4_KFILE_LIBS}) +else(WIN32) +target_link_libraries(plasma_containment_plaindesktop plasma kworkspace ${KDE4_KIO_LIBS} ${KDE4_KFILE_LIBS}) +endif(WIN32) + +install(TARGETS plasma_containment_plaindesktop DESTINATION ${PLUGIN_INSTALL_DIR}) +install(FILES plasma-containment-plaindesktop.desktop DESTINATION ${SERVICES_INSTALL_DIR}) --- containments/plaindesktop/plasma-containment-plaindesktop.desktop +++ containments/plaindesktop/plasma-containment-plaindesktop.desktop @@ -0,0 +1,90 @@ +[Desktop Entry] +Name=Plain Desktop +Name[af]=Werkskerm +Name[ar]=سطح المكتب +Name[be]=Працоўны стол +Name[bg]=Работен плот +Name[bn]=ডেস্কটপ +Name[bn_IN]=ডেস্কটপ +Name[br]=Gorretaol +Name[ca]=Escriptori +Name[cs]=Pracovní plocha +Name[csb]=Pùlt +Name[cy]=Penbwrdd +Name[de]=Arbeitsfläche +Name[el]=Επιφάνεια εργασίας +Name[eo]=Labortablo +Name[es]=Escritorio +Name[et]=Töölaud +Name[eu]=Mahaigaina +Name[fa]=رومیزی +Name[fi]=Työpöytä +Name[fr]=Bureau +Name[fy]=Buroblêd +Name[ga]=Deasc +Name[gl]=Escritorio +Name[gu]=ડેસ્કટોપ +Name[he]=שולחן עבודה +Name[hi]=डेस्कटॉप +Name[hr]=Radna površina +Name[hu]=Munkaasztal +Name[is]=Skjáborð +Name[ja]=デスクトップ +Name[ka]=სამუშაო დაფა +Name[kk]=Жұмыс үстелі +Name[km]=ផ្ទៃតុ +Name[kn]=ಗಣಕತೆರೆ +Name[ko]=데스크톱 +Name[ku]=Sermasê +Name[lt]=Darbastalis +Name[lv]=Darbvirsma +Name[mk]=Работна површина +Name[ml]=പണിയിടം +Name[mr]=डेस्कटॉप +Name[ms]=Ruang Kerja +Name[nb]=Skrivebord +Name[nds]=Schriefdisch +Name[ne]=डेस्कटप +Name[nl]=Bureaublad +Name[nn]=Skrivebord +Name[oc]=Burèu +Name[pa]=ਡੈਸਕਟਾਪ +Name[pl]=Pulpit +Name[pt]=Ambiente de Trabalho +Name[pt_BR]=Área de Trabalho +Name[ru]=Рабочий стол +Name[se]=Čállinbeavdi +Name[sk]=Plocha +Name[sl]=Namizje +Name[sr]=Радна површ +Name[sr@latin]=Radna površ +Name[sv]=Skrivbord +Name[ta]=பணிமேசை +Name[te]=రంగస్ఠలం +Name[tg]=Мизи корӣ +Name[th]=พื้นที่ทำงาน +Name[tr]=Masaüstü +Name[uk]=Стільниця +Name[uz]=Ish stoli +Name[uz@cyrillic]=Иш столи +Name[vi]=Màn hình nền +Name[wa]=Sicribanne +Name[x-test]=xxDesktopxx +Name[zh_CN]=桌面 +Name[zh_TW]=桌面 +Comment=Desktop without toolbox +Icon=user-desktop +Type=Service +X-KDE-ServiceTypes=Plasma/Applet,Plasma/Containment +NoDisplay=true + +X-KDE-Library=plasma_containment_plaindesktop +X-KDE-PluginInfo-Author=The Plasma Team +X-KDE-PluginInfo-Email=panel-devel@kde.org +X-KDE-PluginInfo-Name=plaindesktop +X-KDE-PluginInfo-Version=0.1 +X-KDE-PluginInfo-Website=http://plasma.kde.org/ +X-KDE-PluginInfo-Category=Containments +X-KDE-PluginInfo-Depends= +X-KDE-PluginInfo-License=GPL +X-KDE-PluginInfo-EnabledByDefault=true --- applets/devicenotifier/devicenotifier.cpp +++ applets/devicenotifier/devicenotifier.cpp @@ -138,6 +138,8 @@ } isNotificationEnabled = true; + Plasma::ToolTipManager::self()->registerWidget(this); + //connect to engine when a device is plug connect(m_solidEngine, SIGNAL(sourceAdded(const QString&)), this, SLOT(onSourceAdded(const QString&))); @@ -295,6 +297,30 @@ } } +void DeviceNotifier::toolTipAboutToShow() +{ + Plasma::ToolTipManager::ToolTipContent toolTip; + toolTip.mainText = i18n("Device Notifier"); + if (!m_lastPlugged.isEmpty()) { + Solid::Device *device = new Solid::Device(m_lastPlugged.last()); + + toolTip.subText = i18n("Last plugged in device: %1", device->product()); + toolTip.image = KIcon(device->icon()).pixmap(IconSize(KIconLoader::Desktop)); + + delete device; + } else { + toolTip.subText = i18n("No devices plugged in"); + toolTip.image = KIcon("drive-removable-media-usb-pendrive").pixmap(IconSize(KIconLoader::Desktop)); + } + + Plasma::ToolTipManager::self()->setToolTipContent(this, toolTip); +} + +void DeviceNotifier::toolTipHidden() +{ + Plasma::ToolTipManager::self()->setToolTipContent(this, Plasma::ToolTipManager::ToolTipContent()); +} + void DeviceNotifier::onSourceAdded(const QString &name) { kDebug() << "DeviceNotifier:: source added" << name; @@ -316,6 +342,7 @@ m_solidEngine->connectSource(name, this); m_solidDeviceEngine->connectSource(name, this); + m_lastPlugged<<name; //sets the "action" column QStandardItem *actionItem = new QStandardItem(); @@ -339,6 +366,8 @@ if (m_icon && m_hotplugModel->rowCount() == 0) { m_widget->hide(); } + + m_lastPlugged.removeAll(name); } QModelIndex DeviceNotifier::indexForUdi(const QString &udi) const --- applets/devicenotifier/devicenotifier.h +++ applets/devicenotifier/devicenotifier.h @@ -23,6 +23,8 @@ #include <solid/solidnamespace.h> #include <plasma/applet.h> #include <plasma/dataengine.h> +#include <plasma/tooltipmanager.h> + #include <plasma/animator.h> #include <plasma/dialog.h> #include <KIcon> @@ -84,6 +86,8 @@ void slotOnItemClicked(const QModelIndex &); void onTimerExpired(); void onClickNotifier(); + void toolTipAboutToShow(); + void toolTipHidden(); protected: void createConfigurationInterface(KConfigDialog *parent); @@ -114,6 +118,9 @@ bool isNotificationEnabled; QGraphicsLinearLayout *m_layout; + ///last plugged udi + QList<QString> m_lastPlugged; + /// Designer Config file Ui::solidNotifierConfig ui; --- applets/libplasmaclock/clockapplet.cpp +++ applets/libplasmaclock/clockapplet.cpp @@ -58,6 +58,7 @@ : Plasma::Applet(parent, args), d(new Private) { + Plasma::ToolTipManager::self()->registerWidget(this); } ClockApplet::~ClockApplet() @@ -66,18 +67,67 @@ delete d; } -void ClockApplet::updateToolTipContent() { - //QString timeString = KGlobal::locale()->formatTime(d->time, d->showSeconds); - //TODO port to TOOLTIP manager - /*Plasma::ToolTipData tipData; +void ClockApplet::toolTipAboutToShow() +{ + updateContent(); +} - tipData.mainText = "";//d->time.toString(timeString); - tipData.subText = "";//d->date.toString(); - //tipData.image = d->toolTipIcon; +void ClockApplet::toolTipHidden() +{ + Plasma::ToolTipManager::self()->clearToolTipContent(this); +} - setToolTip(tipData);*/ +void ClockApplet::updateContent() +{ + Plasma::ToolTipManager::ToolTipContent tipData; + + { + // the main text contains the current timezone's time and date + Plasma::DataEngine::Data data = dataEngine("time")->query(currentTimezone()); + QString mainText; + mainText += KGlobal::locale()->formatTime(data["Time"].toTime(), false) + "<br>"; + mainText += KGlobal::locale()->formatDate(data["Date"].toDate()); + tipData.mainText = mainText; + } + + QString subText; +/* if (!isLocalTimezone()) { + d->addTzToTipText(subText, localTimezone()); + } + foreach (const QString &tz, getSelectedTimezones()) { + if (tz == currentTimezone()) { + continue; + } + d->addTzToTipText(subText, tz); + }*/ + tipData.subText = subText; + + // query for custom content + Plasma::ToolTipManager::ToolTipContent customContent = toolTipContent(); + if (customContent.image.isNull()) { + tipData.image = KIcon("chronometer").pixmap(IconSize(KIconLoader::Desktop)); + } else { + tipData.image = customContent.image; + } + + if (!customContent.mainText.isEmpty()) { + // add their main text + tipData.mainText = customContent.mainText + "<br>" + tipData.mainText; + } + + if (!customContent.subText.isEmpty()) { + // add their sub text + tipData.subText = customContent.subText + "<br>" + tipData.subText; + } + + Plasma::ToolTipManager::self()->setToolTipContent(this, tipData); } +Plasma::ToolTipManager::ToolTipContent ClockApplet::toolTipContent() +{ + return Plasma::ToolTipManager::ToolTipContent(); +} + void ClockApplet::mousePressEvent(QGraphicsSceneMouseEvent *event) { if (event->buttons() == Qt::LeftButton) { --- applets/libplasmaclock/clockapplet.h +++ applets/libplasmaclock/clockapplet.h @@ -27,6 +27,8 @@ #include <plasma/applet.h> #include <plasma/dataengine.h> #include <plasma/dialog.h> +#include <plasma/tooltipmanager.h> + #include "ui_calendar.h" #include "plasmaclock_export.h" @@ -51,17 +53,21 @@ static QString localTimezone(); + public Q_SLOTS: + void toolTipAboutToShow(); + void toolTipHidden(); + protected: void mousePressEvent(QGraphicsSceneMouseEvent *event); void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); + virtual Plasma::ToolTipManager::ToolTipContent toolTipContent(); + void updateContent(); protected Q_SLOTS: void setCurrentTimezone(const QString &tz); void showCalendar(QGraphicsSceneMouseEvent *event); private: - void updateToolTipContent(); - class Private; Private * const d; }; --- applets/lock_logout/Messages.sh +++ applets/lock_logout/Messages.sh @@ -0,0 +1,2 @@ +#! /usr/bin/env bash +$XGETTEXT *.cpp -o $podir/plasma_applet_lock_logout.pot Property changes on: applets/lock_logout/Messages.sh ___________________________________________________________________ Added: svn:executable + * --- applets/lock_logout/lockout.cpp +++ applets/lock_logout/lockout.cpp @@ -21,11 +21,13 @@ // Plasma #include <plasma/widgets/icon.h> +#include <plasma/containment.h> // Qt #include <QtDBus/QDBusInterface> #include <QtDBus/QDBusReply> #include <QGraphicsLinearLayout> +#include <QAction> // KDE #include <KIcon> @@ -47,18 +49,41 @@ m_layout->setSpacing(0); Plasma::Icon *icon_lock = new Plasma::Icon(KIcon("system-lock-screen"), "", this); - m_layout->addItem(icon_lock); connect(icon_lock, SIGNAL(clicked()), this, SLOT(clickLock())); Plasma::Icon *icon_logout = new Plasma::Icon(KIcon("system-shutdown"), "", this); - m_layout->addItem(icon_logout); connect(icon_logout, SIGNAL(clicked()), this, SLOT(clickLogout())); + + KConfigGroup cg = config(); + if (cg.readEntry("AlternateButtonOrder", false)) { + m_layout->addItem(icon_lock); + m_layout->addItem(icon_logout); + } + else { + m_layout->addItem(icon_logout); + m_layout->addItem(icon_lock); + } + + QAction *switcher = new QAction(i18n("Alternate Button Order"), this); + m_actions.append(switcher); + connect(switcher, SIGNAL(triggered(bool)), this, SLOT(switchOrder())); } LockOut::~LockOut() { } +void LockOut::switchOrder() +{ + KConfigGroup cg = config(); + cg.writeEntry("AlternateButtonOrder", !cg.readEntry("AlternateButtonOrder", false)); + emit configNeedsSaving(); + + QGraphicsLayoutItem* item = m_layout->itemAt(0); + m_layout->removeAt(0); + m_layout->addItem(item); +} + void LockOut::checkLayout() { Qt::Orientation direction; @@ -131,5 +156,9 @@ KWorkSpace::ShutdownModeDefault); } +QList<QAction*> LockOut::contextualActions() +{ + return m_actions; +} #include "lockout.moc" --- applets/lock_logout/lockout.h +++ applets/lock_logout/lockout.h @@ -33,13 +33,16 @@ ~LockOut(); void init(); virtual void constraintsEvent(Plasma::Constraints constraints); + virtual QList<QAction*> contextualActions(); public slots: void clickLogout(); void clickLock(); + void switchOrder(); private: QGraphicsLinearLayout *m_layout; + QList<QAction*> m_actions; void checkLayout(); }; --- applets/trash/trash.cpp +++ applets/trash/trash.cpp @@ -45,6 +45,7 @@ //Plasma #include <plasma/widgets/icon.h> #include <plasma/containment.h> +#include <plasma/tooltipmanager.h> //Solid #include <solid/devicenotifier.h> @@ -200,17 +201,20 @@ void Trash::setIcon() { + Plasma::ToolTipManager::ToolTipContent data; + data.mainText = i18n("Trash"); + if (m_count > 0) { m_icon->setIcon(KIcon("user-trash-full")); - //FIXME PORT TO TOOLTIP MANAGER - //m_data.subText = i18np("One item", "%1 items", m_count); + + data.subText = i18np("One item", "%1 items", m_count); if (m_showText) { m_icon->setInfoText(i18np("One item", "%1 items", m_count)); } } else { m_icon->setIcon(KIcon("user-trash")); - //FIXME PORT TO TOOLTIP MANAGER - //m_data.subText = i18nc("The trash is empty. This is not an action, but a state", "Empty"); + + data.subText = i18nc("The trash is empty. This is not an action, but a state", "Empty"); if (m_showText){ m_icon->setInfoText(i18nc("The trash is empty. This is not an action, but a state", "Empty")); } @@ -218,14 +222,13 @@ m_icon->update(); - //FIXME TOOLTIP MANAGER - /*m_data.image = m_icon->icon().pixmap(IconSize(KIconLoader::Desktop)); + data.image = m_icon->icon().pixmap(IconSize(KIconLoader::Desktop)); if (!m_showText) { - m_icon->setToolTip(m_data); + Plasma::ToolTipManager::self()->setToolTipContent(this, data); } else { - m_icon->setToolTip(Plasma::ToolTipData()); - }*/ + Plasma::ToolTipManager::self()->setToolTipContent(this, Plasma::ToolTipManager::ToolTipContent()); + } emptyTrash->setEnabled(m_count>0); } --- applets/systemtray/systemtray.cpp +++ applets/systemtray/systemtray.cpp @@ -1,198 +0,0 @@ -/*************************************************************************** - * systemtray.cpp * - * * - * Copyright (C) 2007 Alexander Rodin <rodin.alexander@gmail.com> * - * Copyright (C) 2007 Jason Stubbs <jasonbstubbs@gmail.com> * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * - ***************************************************************************/ - -// Own -#include "systemtray.h" - -// Qt -#include <QApplication> -#include <QGraphicsView> -#include <QTimer> - -//Plasma -#include <plasma/panelsvg.h> - -SystemTray::SystemTray(QObject *parent, const QVariantList &arguments) - : Plasma::Applet(parent, arguments), - m_startUpDelayShowTimer(0), - m_showOwnBackground(false) -{ - // Revert to Qt-4.4.0 behaviour so that the SystemTrayWidget is always on - // top. Note, if a sibling widget requires a native window for other - // reasons the problem could reoccur. - // Another alternative is to raise() during SystemTrayWidget construction - // and then have it listen for ChildAdded events on its parent. However, - // this causes a lot of flashes of white and so should be avoided if - // possible. - // See http://bugs.kde.org/show_bug.cgi?id=168007 - // and http://mail.kde.org/pipermail/plasma-devel/2008-August/000258.html - -#if QT_VERSION < 0x040401 - Qt::ApplicationAttribute attr = (Qt::ApplicationAttribute)4; -#else - Qt::ApplicationAttribute attr = Qt::AA_DontCreateNativeWidgetSiblings; -#endif - if (!QApplication::testAttribute(attr)) { - QApplication::setAttribute(attr); - } - - m_background = new Plasma::PanelSvg(this); - m_background->setImagePath("widgets/systemtray"); - connect(this, SIGNAL(geometryChanged()), this, SLOT(updateWidgetGeometry())); -} - -SystemTray::~SystemTray() -{ - // Get rid of our SystemTrayWidget if we still have one - delete m_systemTrayWidget; -} - -void SystemTray::constraintsEvent(Plasma::Constraints constraints) -{ - if (constraints & (Plasma::LocationConstraint | Plasma::FormFactorConstraint)) { - updateWidgetOrientation(); - } - - if (constraints & (Plasma::StartupCompletedConstraint | Plasma::FormFactorConstraint)) { - updateWidgetGeometry(); - } -} - -void SystemTray::paintInterface(QPainter *painter, - const QStyleOptionGraphicsItem *option, - const QRect& contentsRect) -{ - Q_UNUSED(option) - - if (m_showOwnBackground) { - m_background->paintPanel(painter, contentsRect); - } -} - -void SystemTray::updateWidgetOrientation() -{ - if (!m_systemTrayWidget) { - return; - } - // TODO: Handle other form factors - if (formFactor() == Plasma::Horizontal) { - m_systemTrayWidget->setOrientation(Qt::Horizontal); - } else if (formFactor() == Plasma::Vertical) { - m_systemTrayWidget->setOrientation(Qt::Vertical); - } else { // desktop - m_systemTrayWidget->setOrientation(Qt::Horizontal); - } -} - -void SystemTray::updateWidgetGeometry() -{ - QGraphicsView *parentView = view(); - if (!parentView) { - kDebug() << "Problem view is NULL"; - return; - } - - if (!m_systemTrayWidget || m_systemTrayWidget->parentWidget() != parentView) { - delete m_systemTrayWidget; - m_systemTrayWidget = new SystemTrayWidget(parentView); - updateWidgetOrientation(); - connect(m_systemTrayWidget, SIGNAL(sizeShouldChange()), - this, SLOT(updateWidgetGeometry())); - - if (! m_startUpDelayShowTimer) { - m_startUpDelayShowTimer = new QTimer(this); - connect(m_startUpDelayShowTimer, SIGNAL(timeout()), this, SLOT(startupDelayer())); - } - } - - if (m_startUpDelayShowTimer) { - kDebug() << "start up delay"; - m_startUpDelayShowTimer->start(STARTUP_TIMER_DELAY); - return; // don't relayout yet. - } - - // Figure out the margins set by the background svg and disable the svg - // if there won't be enough room for a single row of icons - qreal leftMargin, topMargin, rightMargin, bottomMargin; - if (formFactor() == Plasma::Vertical || formFactor() == Plasma::Horizontal) { - m_background->setElementPrefix(QString()); - m_background->getMargins(leftMargin, topMargin, rightMargin, bottomMargin); - - if (geometry().width() - leftMargin - rightMargin < 22 || - geometry().height() - topMargin - bottomMargin < 22) { - m_showOwnBackground = false; - leftMargin = topMargin = rightMargin = bottomMargin = 0; - } else { - m_showOwnBackground = true; - m_background->resizePanel(size()); - update(); - } - } else { - getContentsMargins(&leftMargin, &topMargin, &rightMargin, &bottomMargin); - } - - // Update our preferred size based on the wystem tray widget's size and any margins - QRectF rf = mapFromView(parentView, QRect(m_systemTrayWidget->pos(), - m_systemTrayWidget->minimumSize())); - rf.setWidth(rf.width() + leftMargin + rightMargin); - rf.setHeight(rf.height() + topMargin + bottomMargin); - - - if (m_systemTrayWidget->orientation() == Qt::Vertical) { - setMinimumHeight(rf.height()); - setMinimumWidth(22 + leftMargin + rightMargin); - } else { - setMinimumWidth(rf.width()); - setMinimumHeight(22 + topMargin + bottomMargin); - } - setPreferredSize(rf.size()); - - // Calculate the rect usable by the system tray widget - rf = rect(); - rf.moveLeft(rf.left() + leftMargin); - rf.setWidth(rf.width() - leftMargin - rightMargin); - rf.moveTop(rf.top() + topMargin); - rf.setHeight(rf.height() - topMargin - bottomMargin); - - // Set the widget's maximum size to the size to the available size. - // The widget will use this size to calculate how many rows/columns - // can be displayed. - QRect r = mapToView(parentView, rf); - m_systemTrayWidget->setMaximumSize(r.size()); - - // Center the widget within the available area - QSize s = m_systemTrayWidget->minimumSize(); - r.moveLeft(r.left() + (r.width() - s.width()) / 2); - r.moveTop(r.top() + (r.height() - s.height()) / 2); - r.setSize(s); - m_systemTrayWidget->setGeometry(r); -} - -void SystemTray::startupDelayer() -{ - delete m_startUpDelayShowTimer; - m_startUpDelayShowTimer = 0; - m_systemTrayWidget->setVisible(true); - m_systemTrayWidget->init(); -} - -#include "systemtray.moc" --- applets/systemtray/systemtraycontainer.cpp +++ applets/systemtray/systemtraycontainer.cpp @@ -1,133 +0,0 @@ -/*************************************************************************** - * systemtraywidget.h * - * * - * Copyright (C) 2007 Jason Stubbs <jasonbstubbs@gmail.com> * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * - ***************************************************************************/ - -// Own -#include "systemtraycontainer.h" - -// KDE -#include <KDebug> -#include <plasma/theme.h> - -// Qt -#include <QX11Info> - -// Xlib -#include <X11/Xlib.h> - -SystemTrayContainer::SystemTrayContainer(QWidget *parent) - : QX11EmbedContainer(parent) -{ - connect(this, SIGNAL(clientClosed()), SLOT(deleteLater())); - connect(this, SIGNAL(error(QX11EmbedContainer::Error)), SLOT(handleError(QX11EmbedContainer::Error))); - - connect(Plasma::Theme::defaultTheme(), SIGNAL(themeChanged()), this, SLOT(updateBackground())); - updateBackground(); - - // Tray icons have a fixed size of 22x22 - setMaximumSize(22, 22); -} - -void SystemTrayContainer::embedSystemTrayClient( WId clientId ) -{ - kDebug() << "attempting to embed" << clientId; - if( !prepareFor(clientId)) { // temporary hack, until QX11EmbedContainer gets fixed - deleteLater(); - return; - } - - embedClient(clientId); - - // check if we still have a valid clientId since there may cases where we don't any - // longer after calling embedClient like e.g. if there is already a pidgin-instance - // running and it got started again. In that case those guniqueapplication starts - // and fires a SYSTEM_TRAY_REQUEST_DOCK with another clientId up, exists and passes - // commandline-arguments on to the other running instance and embedClient does fail - // without emitting a clientClosed() or error() signal. - XWindowAttributes attr; - if( !XGetWindowAttributes(QX11Info::display(), clientId, &attr) /*|| attr.map_state == IsUnmapped*/ ) { - deleteLater(); - } -} - -bool SystemTrayContainer::x11Event(XEvent *event) -{ - bool ok = QX11EmbedContainer::x11Event(event); - if (event->type == ReparentNotify) { - setMinimumSize(22,22); - } - return ok; -} - -void SystemTrayContainer::updateBackground() -{ - // Qt's regular quasi-transparent background doesn't work so set it to the - // theme's background color instead. - QPalette p = palette(); - p.setBrush(QPalette::Window, Plasma::Theme::defaultTheme()->color(Plasma::Theme::BackgroundColor)); - setPalette(p); - setBackgroundRole(QPalette::Window); -} - -void SystemTrayContainer::handleError(QX11EmbedContainer::Error error) -{ - Q_UNUSED(error); - deleteLater(); -} - -// Temporary hack to change X window used by QX11EmbedContainer so that it matches -// the window embedded into it (#153193). -bool SystemTrayContainer::prepareFor(WId w) -{ - Display* dpy = QX11Info::display(); - - XWindowAttributes ga; - if( !XGetWindowAttributes(dpy, w, &ga)) - return false; - - XSetWindowAttributes sa; - sa.background_pixel = WhitePixel(dpy, DefaultScreen(dpy)); - sa.border_pixel = BlackPixel(dpy, DefaultScreen(dpy)); - sa.colormap = ga.colormap; - - Window ww = XCreateWindow(dpy, parentWidget() ? parentWidget()->winId() : DefaultRootWindow(dpy), - 0, 0, 22, 22, 0, ga.depth, InputOutput, ga.visual, - CWBackPixel | CWBorderPixel | CWColormap, &sa); - create(ww, true, true); - - // repeat everything from QX11EmbedContainer's ctor that might be relevant - setFocusPolicy(Qt::StrongFocus); - setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - setAcceptDrops(true); - setEnabled(false); - - XSelectInput(dpy, ww, - KeyPressMask | KeyReleaseMask | - ButtonPressMask | ButtonReleaseMask | ButtonMotionMask | - KeymapStateMask | - PointerMotionMask | - EnterWindowMask | LeaveWindowMask | - FocusChangeMask | - ExposureMask | - StructureNotifyMask | - SubstructureNotifyMask); - XFlush(dpy); - return true; -} --- applets/systemtray/systemtraywidget.cpp +++ applets/systemtray/systemtraywidget.cpp @@ -1,206 +0,0 @@ -/*************************************************************************** - * systemtraywidget.h * - * * - * Copyright (C) 2007 Alexander Rodin <rodin.alexander@gmail.com> * - * Copyright (C) 2007 Jason Stubbs <jasonbstubbs@gmail.com> * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * - ***************************************************************************/ - -// Own -#include "systemtraywidget.h" -#include "systemtraycontainer.h" - -// Qt -#include <QX11Info> - -// Xlib -#include <X11/Xlib.h> - -namespace -{ -enum -{ - SYSTEM_TRAY_REQUEST_DOCK, - SYSTEM_TRAY_BEGIN_MESSAGE, - SYSTEM_TRAY_CANCEL_MESSAGE -}; -} - -SystemTrayWidget::SystemTrayWidget(QWidget *parent) - : QWidget(parent), - m_orientation(Qt::Horizontal), - m_maxCount(0), - m_nextRow(0), - m_nextColumn(0) -{ - m_mainLayout = new QGridLayout(this); - - // Override spacing set by the current style - m_mainLayout->setContentsMargins(0, 0, 0, 0); - m_mainLayout->setSpacing(4); -} - -void SystemTrayWidget::init() -{ - Display *display = QX11Info::display(); - - m_selectionAtom = XInternAtom(display, "_NET_SYSTEM_TRAY_S" + QByteArray::number(QX11Info::appScreen()), false); - m_opcodeAtom = XInternAtom(display, "_NET_SYSTEM_TRAY_OPCODE", false); - XSetSelectionOwner(display, m_selectionAtom, winId(), CurrentTime); - - if (XGetSelectionOwner(display, m_selectionAtom) == winId()) { - WId root = QX11Info::appRootWindow(); - XClientMessageEvent xev; - - xev.type = ClientMessage; - xev.window = root; - xev.message_type = XInternAtom(display, "MANAGER", false); - xev.format = 32; - xev.data.l[0] = CurrentTime; - xev.data.l[1] = m_selectionAtom; - xev.data.l[2] = winId(); - xev.data.l[3] = 0; // manager specific data - xev.data.l[4] = 0; // manager specific data - - XSendEvent(display, root, false, StructureNotifyMask, (XEvent*)&xev); - } -} - -bool SystemTrayWidget::x11Event(XEvent *event) -{ - if (event->type == ClientMessage) { - if (event->xclient.message_type == m_opcodeAtom && - event->xclient.data.l[1] == SYSTEM_TRAY_REQUEST_DOCK) { - const WId systemTrayClientId = (WId)event->xclient.data.l[2]; - if (systemTrayClientId == 0) { - return true; - } - foreach(SystemTrayContainer *c, findChildren<SystemTrayContainer*>()) { - if (c->clientWinId() == systemTrayClientId) { - return true; - } - } - - // Set up a SystemTrayContainer for the client - SystemTrayContainer *container = new SystemTrayContainer(this); - connect(container, SIGNAL(destroyed(QObject *)), this, SLOT(relayoutContainers(QObject *))); - connect(container, SIGNAL(clientIsEmbedded()), this, SIGNAL(sizeShouldChange())); - addWidgetToLayout(container); - - container->embedSystemTrayClient(systemTrayClientId); - return true; - } - } - return QWidget::x11Event(event); -} - -void SystemTrayWidget::setOrientation(Qt::Orientation orientation) -{ - if (orientation != m_orientation) { - m_orientation = orientation; - relayoutContainers(); - } -} - -Qt::Orientation SystemTrayWidget::orientation() const -{ - return m_orientation; -} - -void SystemTrayWidget::setMaximumSize(QSize s) -{ - bool doLayout = (m_orientation == Qt::Horizontal && s.height() != maximumHeight()); - doLayout |= (m_orientation == Qt::Vertical && s.width() != maximumWidth()); - - QWidget::setMaximumSize(s); - if (doLayout) { - relayoutContainers(); - } -} - -void SystemTrayWidget::addWidgetToLayout(QWidget *widget) -{ - // Add the widget to the layout - m_mainLayout->setRowMinimumHeight(m_nextRow, 22); - m_mainLayout->setColumnMinimumWidth(m_nextColumn, 22); - widget->resize(22,22); - m_mainLayout->addWidget(widget, m_nextRow, m_nextColumn, 1, 1, Qt::AlignCenter); - - // Figure out where the next widget should go - if (m_orientation == Qt::Horizontal) { - // Calculate the items that fit into a column - m_maxCount = (maximumHeight() + m_mainLayout->spacing()) / (widget->height() + m_mainLayout->spacing()) -1; - - setMinimumSize(QSize(22 * (m_nextColumn + 1) + m_mainLayout->spacing() * m_nextColumn, - 22 * (m_maxCount + 1) + m_mainLayout->spacing() * m_maxCount)); - - // Add down then across when horizontal - m_nextRow++; - if (m_nextRow > m_maxCount){ - m_nextColumn++; - m_nextRow = 0; - } - } else { - // Calculate the items that fit into a row - m_maxCount = (maximumWidth() + m_mainLayout->spacing()) / (widget->width() + m_mainLayout->spacing()) -1; - - setMinimumSize(QSize(22 * (m_maxCount + 1) + m_mainLayout->spacing() * m_maxCount, - 22 * (m_nextRow + 1) + m_mainLayout->spacing() * m_nextRow)); - - // Add across then down when vertical - m_nextColumn++; - if (m_nextColumn > m_maxCount) { - m_nextRow++; - m_nextColumn = 0; - } - } -} - -void SystemTrayWidget::relayoutContainers(QObject *removeContainer) -{ - // Pull all widgets from our container, skipping over the one that was just - // deleted - QList<QWidget *> remainingWidgets; - while (QLayoutItem* item = m_mainLayout->takeAt(0)) { - if (item->widget() && item->widget() != removeContainer) { - remainingWidgets.append(item->widget()); - } - delete item; - } - - // Reset the widths and heights in our layout to 0 so that the removed - // widget's space isn't kept - // (Why doesn't QGridLayout do this automatically?) - for (int row = 0; row < m_mainLayout->rowCount(); row++) { - m_mainLayout->setRowMinimumHeight(row, 0); - } - for (int column = 0; column < m_mainLayout->columnCount(); column++) { - m_mainLayout->setColumnMinimumWidth(column, 0); - } - - // Re-add remaining widgets - m_maxCount = 0; - m_nextRow = 0; - m_nextColumn = 0; - foreach (QWidget *widget, remainingWidgets) { - addWidgetToLayout(widget); - } - - emit sizeShouldChange(); -} - -#include "systemtraywidget.moc" --- applets/systemtray/systemtray.h +++ applets/systemtray/systemtray.h @@ -1,74 +0,0 @@ -/*************************************************************************** - * systemtray.h * - * * - * Copyright (C) 2007 Alexander Rodin <rodin.alexander@gmail.com> * - * Copyright (C) 2007 Jason Stubbs <jasonbstubbs@gmail.com> * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * - ***************************************************************************/ - -#ifndef SYSTEMTRAY_H -#define SYSTEMTRAY_H - -// Own -#include "systemtraywidget.h" - -// Qt -#include <QPointer> - -// Plasma -#include <plasma/applet.h> - -class QTimer; - -namespace Plasma -{ - class PanelSvg; -} - -class SystemTray: public Plasma::Applet -{ -Q_OBJECT - -public: - explicit SystemTray(QObject *parent, const QVariantList &arguments = QVariantList()); - ~SystemTray(); - - void constraintsEvent(Plasma::Constraints constraints); - void paintInterface(QPainter *painter, - const QStyleOptionGraphicsItem *option, - const QRect &contentsRect); - -private slots: - void updateWidgetGeometry(); - void startupDelayer(); - -private: - void updateWidgetOrientation(); - - static const int STARTUP_TIMER_DELAY = 1500; - - Plasma::PanelSvg *m_background; - QTimer *m_startUpDelayShowTimer; - bool m_showOwnBackground; - - // The parent widget might delete this so we guard it - QPointer<SystemTrayWidget> m_systemTrayWidget; -}; - -K_EXPORT_PLASMA_APPLET(systemtray, SystemTray) - -#endif // SYSTEMTRAY_H --- applets/systemtray/systemtraycontainer.h +++ applets/systemtray/systemtraycontainer.h @@ -1,47 +0,0 @@ -/*************************************************************************** - * systemtraywidget.h * - * * - * Copyright (C) 2007 Jason Stubbs <jasonbstubbs@gmail.com> * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * - ***************************************************************************/ - -#ifndef SYSTEMTRAYCONTAINER_H -#define SYSTEMTRAYCONTAINER_H - -// Qt -#include <QX11EmbedContainer> - -class SystemTrayContainer : public QX11EmbedContainer -{ -Q_OBJECT - -public: - explicit SystemTrayContainer(QWidget *parent); - void embedSystemTrayClient( WId clientId ); - -protected: - bool x11Event(XEvent *event); - -private: - bool prepareFor( WId id ); - -private slots: - void handleError(QX11EmbedContainer::Error error); - void updateBackground(); -}; - -#endif // SYSTRAYCONTAINER_H --- applets/systemtray/systemtraywidget.h +++ applets/systemtray/systemtraywidget.h @@ -1,70 +0,0 @@ -/*************************************************************************** - * systemtraywidget.h * - * * - * Copyright (C) 2007 Alexander Rodin <rodin.alexander@gmail.com> * - * Copyright (C) 2007 Jason Stubbs <jasonbstubbs@gmail.com> * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * - ***************************************************************************/ - -#ifndef SYSTEMTRAYWIDGET_H -#define SYSTEMTRAYWIDGET_H - -// Qt -#include <QGridLayout> -#include <QWidget> - -// Xlib -#include <X11/Xdefs.h> - -class SystemTrayWidget: public QWidget -{ -Q_OBJECT - -public: - SystemTrayWidget(QWidget *parent); - - void init(); - - void setOrientation(Qt::Orientation); - Qt::Orientation orientation() const; - void setMaximumSize(QSize s); - -protected: - bool x11Event(XEvent *event); - -Q_SIGNALS: - void sizeShouldChange(); - -private slots: - void relayoutContainers(QObject *removeContainer = 0); - -private: - void addWidgetToLayout(QWidget *widget); - void doSizeChange(); - - QGridLayout *m_mainLayout; - Qt::Orientation m_orientation; - int m_maxCount; - int m_nextRow; - int m_nextColumn; - - // These need to remain allocated for the duration of our lifetime - Atom m_selectionAtom; - Atom m_opcodeAtom; -}; - -#endif // SYSTEMTRAYWIDGET_H --- applets/systemtray/Messages.sh +++ applets/systemtray/Messages.sh @@ -0,0 +1,2 @@ +#! /usr/bin/env bash +$XGETTEXT ui/*.cpp -o $podir/plasma_applet_systemtray.pot Property changes on: applets/systemtray/Messages.sh ___________________________________________________________________ Added: svn:executable + * --- applets/systemtray/protocols/fdo/fdoselectionmanager.h +++ applets/systemtray/protocols/fdo/fdoselectionmanager.h @@ -0,0 +1,72 @@ +/*************************************************************************** + * fdoselectionmanager.h * + * * + * Copyright (C) 2008 Jason Stubbs <jasonbstubbs@gmail.com> * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#ifndef FDOSELECTIONMANAGER_H +#define FDOSELECTIONMANAGER_H + +#include <QtGui/QWidget> + +namespace SystemTray +{ + class Task; +} + + +namespace SystemTray +{ +namespace FDO +{ + +class SelectionManager : public QWidget +{ + Q_OBJECT + +public: + class Singleton; + static SelectionManager* self(); + + void addDamageWatch(QWidget *container, WId client); + void removeDamageWatch(QWidget *container); + bool haveComposite() const; + +signals: + void taskCreated(SystemTray::Task *task); + +protected: + bool x11Event(XEvent *event); + +private slots: + void initSelection(); + void cleanupTask(WId winId); + +private: + SelectionManager(); + ~SelectionManager(); + + class Private; + Private* const d; +}; + +} +} + + +#endif --- applets/systemtray/protocols/fdo/x11embedcontainer.h +++ applets/systemtray/protocols/fdo/x11embedcontainer.h @@ -0,0 +1,59 @@ +/*************************************************************************** + * x11embedcontainer.h * + * * + * Copyright (C) 2008 Jason Stubbs <jasonbstubbs@gmail.com> * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#ifndef X11EMBEDCONTAINER_H +#define X11EMBEDCONTAINER_H + +#include <QtGui/QX11EmbedContainer> + + +namespace SystemTray +{ +namespace FDO +{ + +class X11EmbedContainer : public QX11EmbedContainer +{ + Q_OBJECT + +public: + X11EmbedContainer(QWidget *parent = 0); + ~X11EmbedContainer(); + + void embedSystemTrayClient(WId id); + +protected: + void paintEvent(QPaintEvent *event); + +private slots: + void ensureValidSize(); + void updateBackgroundImage(); + +private: + class Private; + Private* const d; +}; + +} +} + + +#endif --- applets/systemtray/protocols/fdo/fdotask.h +++ applets/systemtray/protocols/fdo/fdotask.h @@ -0,0 +1,61 @@ +/*************************************************************************** + * fdotask.h * + * * + * Copyright (C) 2008 Jason Stubbs <jasonbstubbs@gmail.com> * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#ifndef FDOTASK_H +#define FDOTASK_H + +#include "../../core/task.h" + + +namespace SystemTray +{ +namespace FDO +{ + +class Task : public SystemTray::Task +{ + Q_OBJECT + +public: + Task(WId winId); + virtual ~Task(); + + virtual bool isEmbeddable() const; + virtual QString name() const; + virtual QString typeId() const; + virtual QIcon icon() const; + +signals: + void taskDeleted(WId winId); + +protected: + virtual QGraphicsWidget* createWidget(Plasma::Applet *applet); + +private: + class Private; + Private* const d; +}; + + +} +} + +#endif --- applets/systemtray/protocols/fdo/x11embeddelegate.cpp +++ applets/systemtray/protocols/fdo/x11embeddelegate.cpp @@ -0,0 +1,97 @@ +/*************************************************************************** + * x11embeddelegate.cpp * + * * + * Copyright (C) 2008 Jason Stubbs <jasonbstubbs@gmail.com> * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#include "x11embedcontainer.h" +#include "x11embeddelegate.h" + +#include <QtCore/QEvent> + + +namespace SystemTray +{ +namespace FDO +{ + + +class X11EmbedDelegate::Private +{ +public: + X11EmbedContainer *container; +}; + + +X11EmbedDelegate::X11EmbedDelegate(QWidget *parent) + : QWidget(parent), + d(new Private()) +{ + d->container = new X11EmbedContainer(this); + d->container->move(0, 0); + d->container->show(); +} + + +X11EmbedDelegate::~X11EmbedDelegate() +{ + delete d; +} + + +void X11EmbedDelegate::setParent(QWidget *newParent) +{ + if (parent()) { + parent()->removeEventFilter(this); + } + QWidget::setParent(newParent); + if (newParent) { + newParent->installEventFilter(this); + } +} + + +void X11EmbedDelegate::resizeEvent(QResizeEvent *event) +{ + Q_UNUSED(event); + d->container->resize(size()); +} + + +X11EmbedContainer* X11EmbedDelegate::container() +{ + return d->container; +} + + +bool X11EmbedDelegate::eventFilter(QObject *watched, QEvent *event) +{ + bool ret = QWidget::eventFilter(watched, event); + + if (event->type() == QEvent::Hide) { + setParent(0); + } + + return ret; +} + + +} +} + +#include "x11embeddelegate.moc" --- applets/systemtray/protocols/fdo/fdographicswidget.h +++ applets/systemtray/protocols/fdo/fdographicswidget.h @@ -0,0 +1,62 @@ +/*************************************************************************** + * fdographicswidget.h * + * * + * Copyright (C) 2008 Jason Stubbs <jasonbstubbs@gmail.com> * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#ifndef FDOGRAPHICSWIDGET_H +#define FDOGRAPHICSWIDGET_H + +#include <QtGui/QGraphicsWidget> +#include <QtGui/QX11EmbedContainer> + + +namespace SystemTray +{ +namespace FDO +{ + +class GraphicsWidget : public QGraphicsWidget +{ + Q_OBJECT + +public: + GraphicsWidget(WId winId); + ~GraphicsWidget(); + + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0); + +signals: + void clientClosed(); + +private slots: + void handleClientEmbedded(); + void handleClientClosed(); + void handleClientError(QX11EmbedContainer::Error); + void updateWidgetBackground(); + +private: + class Private; + Private* const d; +}; + +} +} + + +#endif --- applets/systemtray/protocols/fdo/fdotaskprotocol.h +++ applets/systemtray/protocols/fdo/fdotaskprotocol.h @@ -0,0 +1,51 @@ +/*************************************************************************** + * fdoprotocol.h * + * * + * Copyright (C) 2008 Jason Stubbs <jasonbstubbs@gmail.com> * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#ifndef FDOTASKPROTOCOL_H +#define FDOTASKPROTOCOL_H + +#include "../../core/taskprotocol.h" + + +namespace SystemTray +{ +namespace FDO +{ + +class TaskProtocol : public SystemTray::TaskProtocol +{ + Q_OBJECT + +public: + TaskProtocol(QObject *parent); + ~TaskProtocol(); + void init(); + +private: + class Private; + Private* const d; +}; + +} +} + + +#endif --- applets/systemtray/protocols/fdo/x11embeddelegate.h +++ applets/systemtray/protocols/fdo/x11embeddelegate.h @@ -0,0 +1,67 @@ +/*************************************************************************** + * x11embeddelegate.h * + * * + * Copyright (C) 2008 Jason Stubbs <jasonbstubbs@gmail.com> * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#ifndef X11EMBEDDELEGATE_H +#define X11EMBEDDELEGATE_H + +#include <QWidget> + +namespace SystemTray +{ +namespace FDO +{ + class X11EmbedContainer; +} +} + + +namespace SystemTray +{ +namespace FDO +{ + +class X11EmbedDelegate : public QWidget +{ + Q_OBJECT + +public: + X11EmbedDelegate(QWidget *parent = 0); + ~X11EmbedDelegate(); + + void setParent(QWidget *parent); + X11EmbedContainer* container(); + + bool eventFilter(QObject *watched, QEvent *event); + +protected: + void resizeEvent(QResizeEvent *event); + +private: + class Private; + Private* const d; +}; + + +} +} + + +#endif --- applets/systemtray/protocols/fdo/fdoselectionmanager.cpp +++ applets/systemtray/protocols/fdo/fdoselectionmanager.cpp @@ -0,0 +1,368 @@ +/*************************************************************************** + * fdoselectionmanager.cpp * + * * + * Copyright (C) 2008 Jason Stubbs <jasonbstubbs@gmail.com> * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#include "fdoselectionmanager.h" +#include "fdotask.h" + +#include <KDebug> + +#include <QtCore/QCoreApplication> +#include <QtCore/QHash> +#include <QtCore/QTimer> + +#include <QtGui/QTextDocument> +#include <QtGui/QX11Info> + +#include <KGlobal> + +#include <config-X11.h> + +#include <X11/Xlib.h> +#include <X11/Xatom.h> +#include <X11/extensions/Xrender.h> + +#ifdef HAVE_XFIXES +# include <X11/extensions/Xfixes.h> +#endif + +#ifdef HAVE_XDAMAGE +# include <X11/extensions/Xdamage.h> +#endif + +#ifdef HAVE_XCOMPOSITE +# include <X11/extensions/Xcomposite.h> +#endif + +#define SYSTEM_TRAY_REQUEST_DOCK 0 +#define SYSTEM_TRAY_BEGIN_MESSAGE 1 +#define SYSTEM_TRAY_CANCEL_MESSAGE 2 + + +namespace SystemTray +{ +namespace FDO +{ + +#if defined(HAVE_XFIXES) && defined(HAVE_XDAMAGE) && defined(HAVE_XCOMPOSITE) +struct DamageWatch +{ + QWidget *container; + Damage damage; +}; + +static int damageEventBase; +static QMap<WId, DamageWatch*> damageWatches; +static QCoreApplication::EventFilter oldEventFilter; + +// Global event filter for intercepting damage events +static bool x11EventFilter(void *message, long int *result) +{ + XEvent *event = reinterpret_cast<XEvent*>(message); + if (event->type == damageEventBase + XDamageNotify) { + XDamageNotifyEvent *e = reinterpret_cast<XDamageNotifyEvent*>(event); + if (DamageWatch *damageWatch = damageWatches.value(e->drawable)) { + // Create a new region and empty the damage region into it. + // The window is small enough that we don't really care about the region; + // we'll just throw it away and schedule a full repaint of the container. + XserverRegion region = XFixesCreateRegion(e->display, 0, 0); + XDamageSubtract(e->display, e->damage, None, region); + XFixesDestroyRegion(e->display, region); + damageWatch->container->update(); + } + } + + if (oldEventFilter && oldEventFilter != &x11EventFilter) { + return oldEventFilter(message, result); + } else { + return false; + } +} +#endif + + +class SelectionManager::Singleton +{ +public: + SelectionManager instance; +}; + +K_GLOBAL_STATIC(SelectionManager::Singleton, singleton) + + +struct MessageRequest +{ + long messageId; + long timeout; + long bytesRemaining; + QByteArray message; +}; + + +class SelectionManager::Private +{ +public: + Private(SelectionManager *q) + : q(q), haveComposite(false) + { + display = QX11Info::display(); + selectionAtom = XInternAtom(display, "_NET_SYSTEM_TRAY_S" + QByteArray::number(QX11Info::appScreen()), false); + opcodeAtom = XInternAtom(display, "_NET_SYSTEM_TRAY_OPCODE", false); + messageAtom = XInternAtom(display, "_NET_SYSTEM_TRAY_MESSAGE_DATA", false); + visualAtom = XInternAtom(display, "_NET_SYSTEM_TRAY_VISUAL", false); + +#if defined(HAVE_XFIXES) && defined(HAVE_XDAMAGE) && defined(HAVE_XCOMPOSITE) + int eventBase, errorBase; + bool haveXfixes = XFixesQueryExtension(display, &eventBase, &errorBase); + bool haveXdamage = XDamageQueryExtension(display, &damageEventBase, &errorBase); + bool haveXComposite = XCompositeQueryExtension(display, &eventBase, &errorBase); + + if (haveXfixes && haveXdamage && haveXComposite) { + haveComposite = true; + oldEventFilter = QCoreApplication::instance()->setEventFilter(x11EventFilter); + } +#endif + } + + void handleRequestDock(const XClientMessageEvent &event); + void handleBeginMessage(const XClientMessageEvent &event); + void handleMessageData(const XClientMessageEvent &event); + void handleCancelMessage(const XClientMessageEvent &event); + + Display *display; + Atom selectionAtom; + Atom opcodeAtom; + Atom messageAtom; + Atom visualAtom; + + QHash<WId, MessageRequest> messageRequests; + QHash<WId, Task*> tasks; + + SelectionManager *q; + bool haveComposite; +}; + + +SelectionManager* SelectionManager::self() +{ + return &singleton->instance; +} + + +SelectionManager::SelectionManager() + : d(new SelectionManager::Private(this)) +{ + // Init the selection later just to ensure that no signals are sent + // until after construction is done and the creating object has a + // chance to connect. + QTimer::singleShot(0, this, SLOT(initSelection())); +} + + +SelectionManager::~SelectionManager() +{ +#if defined(HAVE_XFIXES) && defined(HAVE_XDAMAGE) && defined(HAVE_XCOMPOSITE) + if (d->haveComposite && QCoreApplication::instance()) { + QCoreApplication::instance()->setEventFilter(oldEventFilter); + } +#endif + delete d; +} + + +void SelectionManager::addDamageWatch(QWidget *container, WId client) +{ +#if defined(HAVE_XFIXES) && defined(HAVE_XDAMAGE) && defined(HAVE_XCOMPOSITE) + DamageWatch *damage = new DamageWatch; + damage->container = container; + damage->damage = XDamageCreate(QX11Info::display(), client, XDamageReportNonEmpty); + damageWatches.insert(client, damage); +#endif +} + +void SelectionManager::removeDamageWatch(QWidget *container) +{ +#if defined(HAVE_XFIXES) && defined(HAVE_XDAMAGE) && defined(HAVE_XCOMPOSITE) + for (QMap<WId, DamageWatch*>::Iterator it = damageWatches.begin(); it != damageWatches.end(); ++it) + { + DamageWatch *damage = *(it); + if (damage->container == container) { + XDamageDestroy(QX11Info::display(), damage->damage); + damageWatches.erase(it); + delete damage; + break; + } + } +#endif +} + + +bool SelectionManager::haveComposite() const +{ + return d->haveComposite; +} + + +bool SelectionManager::x11Event(XEvent *event) +{ + if (event->type == ClientMessage) { + if (event->xclient.message_type == d->opcodeAtom) { + switch (event->xclient.data.l[1]) { + case SYSTEM_TRAY_REQUEST_DOCK: + d->handleRequestDock(event->xclient); + return true; + case SYSTEM_TRAY_BEGIN_MESSAGE: + d->handleBeginMessage(event->xclient); + return true; + case SYSTEM_TRAY_CANCEL_MESSAGE: + d->handleCancelMessage(event->xclient); + return true; + } + } else if (event->xclient.message_type == d->messageAtom) { + d->handleMessageData(event->xclient); + return true; + } + } + + return QWidget::x11Event(event); +} + + +void SelectionManager::initSelection() +{ + XSetSelectionOwner(d->display, d->selectionAtom, winId(), CurrentTime); + + WId selectionOwner = XGetSelectionOwner(d->display, d->selectionAtom); + if (selectionOwner != winId()) { + // FIXME: Hmmm... Reading the docs on XSetSelectionOwner, + // this should not be possible. + kDebug() << "Tried to set selection owner to" << winId() << "but it is set to" << selectionOwner; + return; + } + + // Prefer the ARGB32 visual if available + int nvi; + VisualID visual = XVisualIDFromVisual((Visual*)QX11Info::appVisual()); + XVisualInfo templ; + templ.screen = DefaultScreen(d->display); + templ.depth = 32; + templ.c_class = TrueColor; + XVisualInfo *xvi = XGetVisualInfo(d->display, VisualScreenMask | VisualDepthMask | VisualClassMask, + &templ, &nvi); + for (int i = 0; i < nvi; i++) { + XRenderPictFormat *format = XRenderFindVisualFormat(d->display, xvi[i].visual); + if (format->type == PictTypeDirect && format->direct.alphaMask) { + visual = xvi[i].visualid; + break; + } + } + + XChangeProperty(d->display, winId(), d->visualAtom, XA_VISUALID, 32, + PropModeReplace, (const unsigned char*)&visual, 1); + + WId root = QX11Info::appRootWindow(); + XClientMessageEvent xev; + + xev.type = ClientMessage; + xev.window = root; + xev.message_type = XInternAtom(d->display, "MANAGER", false); + xev.format = 32; + xev.data.l[0] = CurrentTime; + xev.data.l[1] = d->selectionAtom; + xev.data.l[2] = winId(); + xev.data.l[3] = 0; + xev.data.l[4] = 0; + + XSendEvent(d->display, root, false, StructureNotifyMask, (XEvent*)&xev); +} + + +void SelectionManager::Private::handleRequestDock(const XClientMessageEvent &event) +{ + const WId winId = (WId)event.data.l[2]; + + if (tasks.contains(winId)) { + kDebug() << "got a dock request from an already existing task"; + return; + } + + Task *task = new Task(winId); + + tasks[winId] = task; + q->connect(task, SIGNAL(taskDeleted(WId)), q, SLOT(cleanupTask(WId))); + + emit q->taskCreated(task); +} + + +void SelectionManager::cleanupTask(WId winId) +{ + d->tasks.remove(winId); +} + + +void SelectionManager::Private::handleBeginMessage(const XClientMessageEvent &event) +{ + const WId winId = event.window; + + MessageRequest request; + request.messageId = event.data.l[4]; + request.timeout = event.data.l[2]; + request.bytesRemaining = event.data.l[3]; + + if (request.bytesRemaining) { + messageRequests[winId] = request; + } +} + + +void SelectionManager::Private::handleMessageData(const XClientMessageEvent &event) +{ + const WId winId = event.window; + const char *messageData = event.data.b; + + if (!messageRequests.contains(winId)) { + kDebug() << "Unexpected message data from" << winId; + return; + } + + MessageRequest &request = messageRequests[winId]; + const int messageSize = qMin(request.bytesRemaining, 20l); + request.bytesRemaining -= messageSize; + request.message += QByteArray(messageData, messageSize); + + if (request.bytesRemaining == 0) { +// createNotification(winId); + messageRequests.remove(winId); + } +} + +void SelectionManager::Private::handleCancelMessage(const XClientMessageEvent &event) +{ + const WId winId = event.window; + const long messageId = event.data.l[2]; + + if (messageRequests.contains(winId) && messageRequests[winId].messageId == messageId) { + messageRequests.remove(winId); + } +} + +} +} --- applets/systemtray/protocols/fdo/x11embedcontainer.cpp +++ applets/systemtray/protocols/fdo/x11embedcontainer.cpp @@ -0,0 +1,270 @@ +/*************************************************************************** + * systemtraywidget.h * + * * + * Copyright (C) 2008 Jason Stubbs <jasonbstubbs@gmail.com> * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#include "x11embedcontainer.h" +#include "fdoselectionmanager.h" + +// KDE +#include <KDebug> + +// Qt +#include <QtCore/QTimer> +#include <QtGui/QPainter> +#include <QtGui/QX11Info> + +// Xlib +#include <config-X11.h> + +#include <X11/Xlib.h> +#include <X11/extensions/Xrender.h> + +#ifdef HAVE_XCOMPOSITE +# include <X11/extensions/Xcomposite.h> +#endif + + + +namespace SystemTray +{ +namespace FDO +{ + + +class X11EmbedContainer::Private +{ +public: + Private(X11EmbedContainer *q) + : q(q), + picture(None), + updatingBackground(false) + { + } + ~Private() + { + if (picture) { + XRenderFreePicture(QX11Info::display(), picture); + } + } + + void updateClientBackground(); + void sendExposeToClient(); + + X11EmbedContainer *q; + + XWindowAttributes attr; + Picture picture; + QImage bgImage; + bool updatingBackground; +}; + + +X11EmbedContainer::X11EmbedContainer(QWidget *parent) + : QX11EmbedContainer(parent), + d(new Private(this)) +{ + connect(this, SIGNAL(clientIsEmbedded()), + this, SLOT(ensureValidSize())); +} + + +X11EmbedContainer::~X11EmbedContainer() +{ + SelectionManager::self()->removeDamageWatch(this); + delete d; +} + + +void X11EmbedContainer::embedSystemTrayClient(WId clientId) +{ + Display *display = QX11Info::display(); + + if (!XGetWindowAttributes(display, clientId, &d->attr)) { + emit error(QX11EmbedContainer::Unknown); + return; + } + + XSetWindowAttributes sAttr; + sAttr.background_pixel = BlackPixel(display, DefaultScreen(display)); + sAttr.border_pixel = BlackPixel(display, DefaultScreen(display)); + sAttr.colormap = d->attr.colormap; + + WId parentId = parentWidget() ? parentWidget()->winId() : DefaultRootWindow(display); + Window winId = XCreateWindow(display, parentId, 0, 0, d->attr.width, d->attr.height, + 0, d->attr.depth, InputOutput, d->attr.visual, + CWBackPixel | CWBorderPixel | CWColormap, &sAttr); + create(winId); + +#if defined(HAVE_XCOMPOSITE) && defined(HAVE_XFIXES) && defined(HAVE_XDAMAGE) + XRenderPictFormat *format = XRenderFindVisualFormat(display, d->attr.visual); + if (format->type == PictTypeDirect && format->direct.alphaMask && + SelectionManager::self()->haveComposite()) + { + // Redirect ARGB windows to offscreen storage so we can composite them ourselves + XRenderPictureAttributes attr; + attr.subwindow_mode = IncludeInferiors; + + d->picture = XRenderCreatePicture(display, clientId, format, CPSubwindowMode, &attr); + XCompositeRedirectSubwindows(display, winId, CompositeRedirectManual); + SelectionManager::self()->addDamageWatch(this, clientId); + + kDebug() << "Embedded client uses an ARGB visual -> compositing."; + } else { + kDebug() << "Embedded client is not using an ARGB visual."; + } +#endif + + // repeat everything from QX11EmbedContainer's ctor that might be relevant + setFocusPolicy(Qt::StrongFocus); + setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + setAcceptDrops(true); + setEnabled(false); + + XSelectInput(display, winId, + KeyPressMask | KeyReleaseMask | + ButtonPressMask | ButtonReleaseMask | ButtonMotionMask | + KeymapStateMask | + PointerMotionMask | + EnterWindowMask | LeaveWindowMask | + FocusChangeMask | + ExposureMask | + StructureNotifyMask | + SubstructureNotifyMask); + + XFlush(display); + + embedClient(clientId); + + // FIXME: This checks that the client is still valid. Qt won't pick it up + // if the client closes before embedding completes. However, what happens + // if the close happens after this point? Should checks happen on a timer + // until embedding completes perhaps? + if (!XGetWindowAttributes(QX11Info::display(), clientId, &d->attr)) { + emit error(QX11EmbedContainer::Unknown); + return; + } +} + + +void X11EmbedContainer::ensureValidSize() +{ + QSize s = QSize(qBound(minimumSize().width(), width(), maximumSize().width()), + qBound(minimumSize().height(), height(), maximumSize().height())); + resize(s); +} + + +void X11EmbedContainer::paintEvent(QPaintEvent *event) +{ + Q_UNUSED(event); + + if (!d->picture) { + if (!d->updatingBackground) { + QTimer::singleShot(0, this, SLOT(updateBackgroundImage())); + } + return; + } + + // Taking a detour via a QPixmap is unfortunately the only way we can get + // the window contents into Qt's backing store. + QPixmap pixmap(size()); + pixmap.fill(Qt::transparent); + + XRenderComposite(x11Info().display(), PictOpSrc, d->picture, None, pixmap.x11PictureHandle(), + 0, 0, 0, 0, 0, 0, width(), height()); + + QPainter p(this); + p.drawPixmap(0, 0, pixmap); +} + + +void X11EmbedContainer::updateBackgroundImage() +{ + QWidget *topWidget = this; + while (topWidget->parentWidget()) { + topWidget = topWidget->parentWidget(); + } + + QImage bgImage = QImage(size(), QImage::Format_RGB32); + + d->updatingBackground = true; + topWidget->render(&bgImage, QPoint(0, 0), QRect(mapTo(topWidget, QPoint(0, 0)), size())); + d->updatingBackground = false; + + // FIXME: The client background isn't painted correctly after a parent + // widget is reparented, so currently need to update it all the time. + //if (d->bgImage != bgImage) { + d->bgImage = bgImage; + d->updateClientBackground(); + //} +} + + +void X11EmbedContainer::Private::updateClientBackground() +{ + if (!q->clientWinId()) { + return; + } + + QPixmap bgPixmap = QPixmap::fromImage(bgImage); + + Display *display = QX11Info::display(); + Pixmap bg = XCreatePixmap(display, q->clientWinId(), q->width(), q->height(), attr.depth); + + XRenderPictFormat *format = XRenderFindVisualFormat(display, attr.visual); + Picture picture = XRenderCreatePicture(display, bg, format, 0, 0); + + XRenderComposite(display, PictOpSrc, bgPixmap.x11PictureHandle(), + None, picture, 0, 0, 0, 0, 0, 0, q->width(), q->height()); + + XSetWindowBackgroundPixmap(display, q->clientWinId(), bg); + + XRenderFreePicture(display, picture); + XFreePixmap(display, bg); + + sendExposeToClient(); +} + + +void +X11EmbedContainer::Private::sendExposeToClient() +{ + Display *display = QX11Info::display(); + + XExposeEvent expose; + expose.type = Expose; + expose.serial = 0; + expose.send_event = True; + expose.display = display; + expose.window = q->clientWinId(); + expose.x = 0; + expose.y = 0; + expose.width = q->width(); + expose.height = q->height(); + expose.count = 0; + + XSendEvent(display, q->clientWinId(), True, 0, (XEvent*)&expose); +} + + +} +} + +#include "x11embedcontainer.moc" --- applets/systemtray/protocols/fdo/fdotask.cpp +++ applets/systemtray/protocols/fdo/fdotask.cpp @@ -0,0 +1,112 @@ +/*************************************************************************** + * fdotask.cpp * + * * + * Copyright (C) 2008 Jason Stubbs <jasonbstubbs@gmail.com> * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#include "fdographicswidget.h" +#include "fdotask.h" + +#include <KWindowSystem> + + +namespace SystemTray +{ +namespace FDO +{ + + +class Task::Private +{ +public: + Private(WId winId) + : winId(winId) + { + KWindowInfo info = KWindowSystem::windowInfo(winId, NET::WMName, NET::WM2WindowClass); + + // FIXME: This isn't unique + typeId = info.windowClassName(); + + name = info.name(); + if (name.isEmpty()) { + name = typeId; + } + + icon = KWindowSystem::icon(winId); + } + + WId winId; + QString name; + QString typeId; + QIcon icon; +}; + + +Task::Task(WId winId) + : d(new Private(winId)) +{ +} + + +Task::~Task() +{ + emit taskDeleted(d->winId); + delete d; +} + + +bool Task::isEmbeddable() const +{ + return associatedWidgets().count() == 0; +} + + +QString Task::name() const +{ + return d->name; +} + + +QString Task::typeId() const +{ + return d->typeId; +} + + +QIcon Task::icon() const +{ + return d->icon; +} + + +QGraphicsWidget* Task::createWidget(Plasma::Applet *applet) +{ + Q_UNUSED(applet) + + QGraphicsWidget *widget = new GraphicsWidget(d->winId); + connect(widget, SIGNAL(clientClosed()), + this, SLOT(deleteLater())); + return widget; +} + + +} +} + + +#include "fdotask.moc" --- applets/systemtray/protocols/fdo/fdographicswidget.cpp +++ applets/systemtray/protocols/fdo/fdographicswidget.cpp @@ -0,0 +1,188 @@ +/*************************************************************************** + * fdographicswidget.cpp * + * * + * Copyright (C) 2008 Jason Stubbs <jasonbstubbs@gmail.com> * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#include "fdographicswidget.h" +#include "x11embeddelegate.h" +#include "x11embedcontainer.h" + +#include <QtCore/QPointer> + +#include <QtGui/QApplication> +#include <QtGui/QGraphicsView> + +#include <plasma/theme.h> + + +namespace SystemTray +{ +namespace FDO +{ + + +class GraphicsWidget::Private +{ +public: + Private() + : clientEmbedded(false) + { + } + + ~Private() + { + delete widget; + } + + WId winId; + bool clientEmbedded; + QPointer<X11EmbedDelegate> widget; +}; + + +GraphicsWidget::GraphicsWidget(WId winId) + : d(new GraphicsWidget::Private()) +{ + d->winId = winId; + + setMinimumSize(22, 22); + setMaximumSize(22, 22); + resize(22, 22); + + setCacheMode(QGraphicsItem::NoCache); + + connect(Plasma::Theme::defaultTheme(), SIGNAL(themeChanged()), + this, SLOT(updateWidgetBackground())); +} + + +GraphicsWidget::~GraphicsWidget() +{ + delete d; +} + + +void GraphicsWidget::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *parentWidget) +{ + QGraphicsWidget::paint(painter, option, parentWidget); + + QGraphicsView *parentView = 0; + foreach (QGraphicsView *view, scene()->views()) { + if (view->isVisible() && view->sceneRect().intersects(sceneBoundingRect())) { + parentView = view; + } + } + + if (!parentView) { + return; + } + + if (!d->widget) { +#if QT_VERSION < 0x040401 + const Qt::ApplicationAttribute attr = (Qt::ApplicationAttribute)4; +#else + const Qt::ApplicationAttribute attr = Qt::AA_DontCreateNativeWidgetSiblings; +#endif + if (!QApplication::testAttribute(attr)) { + QApplication::setAttribute(attr); + } + + d->widget = new X11EmbedDelegate(); + d->widget->setMinimumSize(22, 22); + d->widget->setMaximumSize(22, 22); + d->widget->resize(22, 22); + + connect(d->widget->container(), SIGNAL(clientIsEmbedded()), + this, SLOT(handleClientEmbedded())); + connect(d->widget->container(), SIGNAL(clientClosed()), + this, SLOT(handleClientClosed())); + connect(d->widget->container(), SIGNAL(error(QX11EmbedContainer::Error)), + this, SLOT(handleClientError(QX11EmbedContainer::Error))); + + d->widget->container()->embedSystemTrayClient(d->winId); + + return; + + } else if (!d->clientEmbedded) { + return; + } + + if (d->widget->parentWidget() != parentView) { + kDebug() << "embedding into" << parentView->metaObject()->className() << "(" << d->winId << ")"; + d->widget->setParent(parentView); + } + + QPoint pos = parentView->mapFromScene(scenePos()); + if (d->widget->pos() != pos) { + d->widget->move(pos); + } + + if (!d->widget->isVisible()) { + d->widget->show(); + } + + if (parentView->childAt(pos) != d->widget->container()) { + d->widget->raise(); + } +} + + +void GraphicsWidget::updateWidgetBackground() +{ + if (!d->widget) { + return; + } + + QPalette palette = d->widget->palette(); + palette.setBrush(QPalette::Window, Plasma::Theme::defaultTheme()->color(Plasma::Theme::BackgroundColor)); + d->widget->setPalette(palette); + d->widget->setBackgroundRole(QPalette::Window); +} + + +void GraphicsWidget::handleClientEmbedded() +{ + kDebug() << "client embedded (" << d->winId << ")"; + + d->clientEmbedded = true; + update(); +} + + +void GraphicsWidget::handleClientClosed() +{ + emit clientClosed(); + kDebug() << "client closed (" << d->winId << ")"; +} + + +void GraphicsWidget::handleClientError(QX11EmbedContainer::Error error) +{ + Q_UNUSED(error); + + kDebug() << "client error (" << d->winId << ")"; + emit clientClosed(); +} + + +} +} + + +#include "fdographicswidget.moc" --- applets/systemtray/protocols/fdo/fdotaskprotocol.cpp +++ applets/systemtray/protocols/fdo/fdotaskprotocol.cpp @@ -0,0 +1,63 @@ +/*************************************************************************** + * fdoprotocol.cpp * + * * + * Copyright (C) 2008 Jason Stubbs <jasonbstubbs@gmail.com> * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#include "fdotaskprotocol.h" + +#include "fdoselectionmanager.h" + + +namespace SystemTray +{ +namespace FDO +{ + + +class TaskProtocol::Private +{ +public: +}; + + +TaskProtocol::TaskProtocol(QObject *parent) + : SystemTray::TaskProtocol(parent), + d(new TaskProtocol::Private) +{ +} + + +TaskProtocol::~TaskProtocol() +{ + delete d; +} + + +void TaskProtocol::init() +{ + connect(SelectionManager::self(), SIGNAL(taskCreated(SystemTray::Task*)), + this, SIGNAL(taskCreated(SystemTray::Task*))); +} + + +} +} + + +#include "fdotaskprotocol.moc" --- applets/systemtray/protocols/plasmoid/plasmoidtask.h +++ applets/systemtray/protocols/plasmoid/plasmoidtask.h @@ -0,0 +1,63 @@ +/*************************************************************************** + * plasmoidtask.h * + * * + * Copyright (C) 2008 Jason Stubbs <jasonbstubbs@gmail.com> * + * Copyright (C) 2008 Sebastian Kügler <sebas@kde.org> * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#ifndef PLASMOIDTASK_H +#define PLASMOIDTASK_H + +#include "../../core/task.h" + + +namespace SystemTray +{ +namespace Plasmoid +{ + +class Task : public SystemTray::Task +{ + Q_OBJECT + +public: + Task(QString appletName); + virtual ~Task(); + + bool isValid() const; + virtual bool isEmbeddable() const; + virtual QString name() const; + virtual QString typeId() const; + virtual QIcon icon() const; + +signals: + void taskDeleted(QString typeId); + +protected: + virtual QGraphicsWidget* createWidget(Plasma::Applet *applet); + +private: + class Private; + Private* const d; +}; + + +} +} + +#endif --- applets/systemtray/protocols/plasmoid/plasmoidtaskprotocol.h +++ applets/systemtray/protocols/plasmoid/plasmoidtaskprotocol.h @@ -0,0 +1,57 @@ +/*************************************************************************** + * plasmoidprotocol.h * + * * + * Copyright (C) 2008 Jason Stubbs <jasonbstubbs@gmail.com> * + * Copyright (C) 2008 Sebastian Kügler <sebas@kde.org> * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#ifndef PLASMOIDTASKPROTOCOL_H +#define PLASMOIDTASKPROTOCOL_H + +#include "../../core/taskprotocol.h" + + +namespace SystemTray +{ +namespace Plasmoid +{ + +class TaskProtocol : public SystemTray::TaskProtocol +{ + Q_OBJECT + +public: + TaskProtocol(QObject *parent); + ~TaskProtocol(); + + void init(); + +private slots: + void cleanupTask(QString typeId); + void newTask(QString appletName); + +private: + class Private; + Private* const d; +}; + +} +} + + +#endif --- applets/systemtray/protocols/plasmoid/plasmoidtask.cpp +++ applets/systemtray/protocols/plasmoid/plasmoidtask.cpp @@ -0,0 +1,135 @@ +/*************************************************************************** + * plasmoidtask.cpp * + * * + * Copyright (C) 2008 Jason Stubbs <jasonbstubbs@gmail.com> * + * Copyright (C) 2008 Sebastian Kügler <sebas@kde.org> * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#include "plasmoidtask.h" +#include <fixx11h.h> + +#include <plasma/applet.h> + + +namespace SystemTray +{ +namespace Plasmoid +{ + + +class Task::Private +{ +public: + Private(QString name, Task *q) + : q(q), + name(name), + typeId(name), + applet(0) + { + if (!name.isEmpty()) { + setupApplet(); + } + } + + void setupApplet(); + + Task *q; + QString name; + QString typeId; + QIcon icon; + Plasma::Applet *applet; +}; + + +Task::Task(QString appletname) + : d(new Private(appletname, this)) +{ +} + + +Task::~Task() +{ + emit taskDeleted(d->typeId); + delete d; +} + + +bool Task::isEmbeddable() const +{ + return d->applet != 0; +} + +bool Task::isValid() const +{ + return !d->name.isEmpty(); +} + +QString Task::name() const +{ + return d->name; +} + + +QString Task::typeId() const +{ + return d->typeId; +} + + +QIcon Task::icon() const +{ + return d->icon; +} + + +QGraphicsWidget* Task::createWidget(Plasma::Applet *host) +{ + Q_UNUSED(host) + return static_cast<QGraphicsWidget*>(d->applet); +} + + +void Task::Private::setupApplet() +{ + applet = Plasma::Applet::load(name); + + if (!applet) { + kDebug() << "Could not load applet" << name; + name = QString(); + return; + } + + applet->setParent(q); + applet->setFlag(QGraphicsItem::ItemIsMovable, false); + + //connect(applet, SIGNAL(destroyed(QObject*)), this, SLOT(appletDestroyed(QObject*))); + applet->init(); + applet->setBackgroundHints(Plasma::Applet::NoBackground); + + // TODO: We'll need the preferred item size here + // The applet does need a size, otherwise it won't show up correctly. + applet->setMinimumSize(22, 22); + kDebug() << applet->name() << " Applet loaded"; +} + + +} +} + + +#include "plasmoidtask.moc" --- applets/systemtray/protocols/plasmoid/plasmoidtaskprotocol.cpp +++ applets/systemtray/protocols/plasmoid/plasmoidtaskprotocol.cpp @@ -0,0 +1,100 @@ +/*************************************************************************** + * plasmoidprotocol.cpp * + * * + * Copyright (C) 2008 Jason Stubbs <jasonbstubbs@gmail.com> * + * Copyright (C) 2008 Sebastian Kügler <sebas@kde.org> * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#include "plasmoidtask.h" +#include "plasmoidtaskprotocol.h" + +#include <KDebug> + +#include <QtCore/QHash> + + +namespace SystemTray +{ +namespace Plasmoid +{ + + +class TaskProtocol::Private +{ +public: + QHash<QString, Task*> tasks; +}; + + +TaskProtocol::TaskProtocol(QObject *parent) + : SystemTray::TaskProtocol(parent), + d(new TaskProtocol::Private) +{ +} + + +TaskProtocol::~TaskProtocol() +{ + delete d; +} + + +void TaskProtocol::init() +{ + // TODO: Load plasmoids from config + //newTask("battery"); + //newTask("notify"); + //newTask("kuiserver"); + //newTask("mid_control"); +} + + +void TaskProtocol::newTask(QString appletName) +{ + if (d->tasks.contains(appletName)) { + kDebug() << "Task " << appletName << "is already in here."; + return; + } + + kDebug() << "Registering task with the manager" << appletName; + Task *task = new Task(appletName); + + if (!task->isValid()) { + // we failed to load our applet *sob* + delete task; + return; + } + + d->tasks[appletName] = task; + connect(task, SIGNAL(taskDeleted(QString)), this, SLOT(cleanupTask(QString))); + emit taskCreated(task); +} + + +void TaskProtocol::cleanupTask(QString typeId) +{ + kDebug() << "task with typeId" << typeId << "removed"; + d->tasks.remove(typeId); +} + + +} +} + + +#include "plasmoidtaskprotocol.moc" --- applets/systemtray/core/manager.h +++ applets/systemtray/core/manager.h @@ -0,0 +1,83 @@ +/*************************************************************************** + * manager.h * + * * + * Copyright (C) 2008 Jason Stubbs <jasonbstubbs@gmail.com> * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#ifndef SYSTEMTRAYMANAGER_H +#define SYSTEMTRAYMANAGER_H + +#include <QtCore/QObject> + +namespace SystemTray +{ + class Task; + +/** + * @short Creator and amalgamator of the supported system tray specifications + **/ +class Manager : public QObject +{ + Q_OBJECT + +public: + class Singleton; + + /** + * @return the global Manager instance + **/ + static Manager* self(); + + /** + * @return a list of all known Task instances + **/ + QList<Task*> tasks() const; + +signals: + /** + * Emitted when a new task has been added + **/ + void taskAdded(SystemTray::Task *task); + + /** + * Emitted when something about a task changes (such as it changing from + * non-embeddable to embeddable) + **/ + void taskChanged(SystemTray::Task *task); + + /** + * Emitted when a task has been removed + **/ + void taskRemoved(SystemTray::Task *task); + +private slots: + void addTask(SystemTray::Task *task); + void removeTask(SystemTray::Task *task); + +private: + Manager(); + ~Manager(); + + class Private; + Private* const d; +}; + +} + + +#endif --- applets/systemtray/core/task.cpp +++ applets/systemtray/core/task.cpp @@ -0,0 +1,84 @@ +/*************************************************************************** + * task.cpp * + * * + * Copyright (C) 2008 Jason Stubbs <jasonbstubbs@gmail.com> * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#include "task.h" + +#include <QtGui/QGraphicsWidget> + + +namespace SystemTray +{ + + +class Task::Private +{ +public: + QList<QGraphicsWidget*> associatedWidgets; +}; + + +Task::Task() + : d(new Private) +{ +} + + +Task::~Task() +{ + emit destroyed(this); + delete d; +} + + +QGraphicsWidget* Task::widget(Plasma::Applet *host) +{ + Q_ASSERT(host); + + QGraphicsWidget *widget; + widget = createWidget(host); + d->associatedWidgets.append(widget); + connect(widget, SIGNAL(destroyed()), this, SLOT(widgetDeleted())); + connect(this, SIGNAL(destroyed()), widget, SLOT(deleteLater())); + + return widget; +} + + +void Task::widgetDeleted() +{ + bool wasEmbeddable = isEmbeddable(); + d->associatedWidgets.removeAll(static_cast<QGraphicsWidget*>(sender())); + if (!wasEmbeddable && isEmbeddable()) { + emit changed(this); + } +} + + +QList<QGraphicsWidget*> Task::associatedWidgets() const +{ + return d->associatedWidgets; +} + + +} + + +#include "task.moc" --- applets/systemtray/core/taskprotocol.cpp +++ applets/systemtray/core/taskprotocol.cpp @@ -0,0 +1,38 @@ +/*************************************************************************** + * taskprotocol.cpp * + * * + * Copyright (C) 2008 Jason Stubbs <jasonbstubbs@gmail.com> * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#include "taskprotocol.h" + + +namespace SystemTray +{ + + +TaskProtocol::TaskProtocol(QObject *parent) + : QObject(parent) +{ +} + + +} + + +#include "taskprotocol.moc" --- applets/systemtray/core/task.h +++ applets/systemtray/core/task.h @@ -0,0 +1,129 @@ +/*************************************************************************** + * task.h * + * * + * Copyright (C) 2008 Jason Stubbs <jasonbstubbs@gmail.com> * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#ifndef SYSTEMTRAYTASK_H +#define SYSTEMTRAYTASK_H + +#include <QtCore/QObject> + +#include <QtGui/QIcon> + +class QGraphicsWidget; + +namespace Plasma +{ + class Applet; +} // namespace Plasma + +namespace SystemTray +{ + +/** + * @short System tray task base class + * + * To support a new system tray protocol, Protocol and this class should + * be subclassed. + **/ +class Task : public QObject +{ + Q_OBJECT + +public: + virtual ~Task(); + + /** + * Creates a new graphics widget for this task + * + * isEmbeddable() should be checked before creating a new widget. + **/ + QGraphicsWidget* widget(Plasma::Applet *host); + + /** + * Returns the current list of graphics widgets that have been created + * for this task and have not yet been deleted + **/ + QList<QGraphicsWidget*> associatedWidgets() const; + + /** + * Returns whether this task can be embeddable + * + * Depending on the protocol, there may be circumstances under which + * a new widget can not be created. isEmbeddable() will return false + * under these circumstances. + **/ + virtual bool isEmbeddable() const = 0; + + /** + * Returns the name of this task that should be presented to the user + **/ + virtual QString name() const = 0; + + /** + * Returns a unique identifier for this task + * + * The identifier is valid between restarts and so is safe to save + **/ + virtual QString typeId() const = 0; + + /** + * Returns an icon that can be associated with this task + * + * The icon returned is not necessarily the same icon that appears + * in the tray icon itself. + **/ + virtual QIcon icon() const = 0; + +signals: + /** + * Emitted when something about the task has changed + **/ + void changed(SystemTray::Task *task = 0); + + /** + * Emitted when the task is about to be destroyed + **/ + void destroyed(SystemTray::Task *task = 0); + +protected: + Task(); + + /** + * Called when a new widget is required + * + * Subclasses should implement this to return a graphics widget that + * handles all user interaction with the task. Ownership of the + * created widget is handled automatically so subclasses should not + * delete the created widget. + **/ + virtual QGraphicsWidget* createWidget(Plasma::Applet *host) = 0; + +private slots: + void widgetDeleted(); + +private: + class Private; + Private* const d; +}; + +} + + +#endif --- applets/systemtray/core/taskprotocol.h +++ applets/systemtray/core/taskprotocol.h @@ -0,0 +1,61 @@ +/*************************************************************************** + * taskprotocol.h * + * * + * Copyright (C) 2008 Jason Stubbs <jasonbstubbs@gmail.com> * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#ifndef SYSTEMTRAYTASKPROTOCOL_H +#define SYSTEMTRAYTASKPROTOCOL_H + +#include <QtCore/QObject> + +namespace SystemTray +{ + class Task; +} + + +namespace SystemTray +{ + +/** + * @short System tray protocol base class + * + * To support a new system tray protocol, this class and Task should be + * subclassed and the subclass of this class registered with the global + * Manager. The Protocol subclass should emit taskCreated() for each new + * task created. + **/ +class TaskProtocol : public QObject +{ + Q_OBJECT +public: + explicit TaskProtocol(QObject *parent = 0); + virtual void init() = 0; + +signals: + /** + * Signals that a new task has been created + **/ + void taskCreated(SystemTray::Task *task); +}; + +} + + +#endif --- applets/systemtray/core/manager.cpp +++ applets/systemtray/core/manager.cpp @@ -0,0 +1,117 @@ +/*************************************************************************** + * manager.cpp * + * * + * Copyright (C) 2008 Jason Stubbs <jasonbstubbs@gmail.com> * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#include "manager.h" + +#include <KGlobal> + +#include <plasma/applet.h> + +#include "task.h" +#include "taskprotocol.h" + +#include "../protocols/fdo/fdotaskprotocol.h" +#include "../protocols/plasmoid/plasmoidtaskprotocol.h" + +namespace SystemTray +{ + + +class Manager::Singleton +{ +public: + Manager instance; +}; + +K_GLOBAL_STATIC(Manager::Singleton, singleton) + + +class Manager::Private +{ +public: + Private(Manager *manager) + : q(manager) + { + registerTaskProtocol(new Plasmoid::TaskProtocol(q)); + registerTaskProtocol(new FDO::TaskProtocol(q)); + } + + void registerTaskProtocol(TaskProtocol *protocol); + + Manager *q; + QList<Task*> tasks; +}; + + +Manager* Manager::self() +{ + return &singleton->instance; +} + +Manager::Manager() + : d(new Private(this)) +{ +} + +Manager::~Manager() +{ + delete d; +} + + +QList<Task*> Manager::tasks() const +{ + return d->tasks; +} + + +void Manager::Private::registerTaskProtocol(TaskProtocol *protocol) +{ + connect(protocol, SIGNAL(taskCreated(SystemTray::Task*)), + q, SLOT(addTask(SystemTray::Task*))); + protocol->init(); +} + + +void Manager::addTask(Task *task) +{ + connect(task, SIGNAL(destroyed(SystemTray::Task*)), + this, SLOT(removeTask(SystemTray::Task*))); + connect(task, SIGNAL(changed(SystemTray::Task*)), + this, SIGNAL(taskChanged(SystemTray::Task*))); + + kDebug() << task->name() << "(" << task->typeId() << ")"; + + d->tasks.append(task); + emit taskAdded(task); +} + + +void Manager::removeTask(Task *task) +{ + d->tasks.removeAll(task); + emit taskRemoved(task); +} + +} + + +#include "manager.moc" --- applets/systemtray/plasma-applet-systemtray.desktop +++ applets/systemtray/plasma-applet-systemtray.desktop @@ -1,8 +1,9 @@ [Desktop Entry] - Name=System Tray Name[af]=Stelsellaai +Name[ar]=صينية النظام Name[be]=Сістэмны трэй +Name[be@latin]=Systemny trej Name[bg]=Системен панел Name[bn]=সিস্টেম ট্রে Name[bn_IN]=সিস্টেম ট্রে @@ -35,6 +36,7 @@ Name[ka]=სისტემური პანელი Name[kk]=Жүйелік сөре Name[km]=ថាសប្រព័ន្ធ +Name[kn]=ವ್ಯವಸ್ಥಾ ಖಾನೆ (ಟ್ರೇ) Name[ko]=시스템 트레이 Name[lt]=Sistemos dėklas Name[lv]=Sistēmas ikonu josla @@ -70,6 +72,25 @@ Name[xh]=Itreyi Yendlela yokusebenza Name[zh_CN]=系统托盘 Name[zh_TW]=系統匣 +Comment=Access hidden applications minimized in the system tray +Comment[be@latin]=Dostup da schavanych u systemnym trei aplikacyjaŭ +Comment[el]=Πρόσβαση κρυφών εφαρμογών ελαχιστοποιημένων στο πλαίσιο συστήματος +Comment[et]=Süsteemsesse salve minimeeritud peidetud rakenduste kasutamine +Comment[gl]=Acede a programa ocultos minimizados na bandexa do sistema +Comment[kk]=Жүйелік сөреге түйілген жасырын қолданбаларға қатынау +Comment[km]=ចូលដំណើរការកម្មវិធីដែលលាក់ដែលបានបង្រួមនៅក្នុងថាសប្រព័ន្ធ +Comment[kn]=ವ್ಯವಸ್ಥಾ ಖಾನೆಯಲ್ಲಿ (ಟ್ರೇ) ಕನಿಷ್ಠೀಕರಿಸಲಾದ ಅಡಗಿಸಲಾದ ಅನ್ವಯಗಳನ್ನು ನಿಲುಕಿಸಿಕೋ +Comment[nb]=Få tilgang til skjulte programmer som er minimert i systemkurven +Comment[nds]=Togriep op op versteken Programmen in den Systeemafsnitt +Comment[pt]=Aceder às aplicações escondidas e minimizadas na bandeja do sistema +Comment[pt_BR]=Aceder às aplicações escondidas e minimizadas na bandeja do sistema +Comment[sl]=Dostopajte do skritih programov, pomanjšanih v sistemsko vrstico +Comment[sv]=Kom åt dolda program minimerade i systembrickan +Comment[tr]=Sistem çekmecesine küçültülen uygulamalara erişin +Comment[uk]=Доступ до прихованих програму, мінімізованих до системного лотка +Comment[x-test]=xxAccess hidden applications minimized in the system trayxx +Comment[zh_TW]=存取最小化在系統匣內的隱藏應用程式 +# Icon=systemtray //TODO: fix icon Type=Service X-KDE-ServiceTypes=Plasma/Applet @@ -78,9 +99,8 @@ X-KDE-PluginInfo-Email=rodin.alexander@gmail.com X-KDE-PluginInfo-Name=systemtray X-KDE-PluginInfo-Version=pre0.1 -X-KDE-PluginInfo-Website=http://plasma.kde.org +X-KDE-PluginInfo-Website=http://plasma.kde.org/ X-KDE-PluginInfo-Category=Windows and Tasks X-KDE-PluginInfo-Depends= X-KDE-PluginInfo-License=GPL v2+ X-KDE-PluginInfo-EnabledByDefault=true - --- applets/systemtray/CMakeLists.txt +++ applets/systemtray/CMakeLists.txt @@ -1,13 +1,31 @@ project(plasma-systemtray) set(systemtray_SRCS - systemtray.cpp - systemtraycontainer.cpp - systemtraywidget.cpp) + core/manager.cpp + core/taskprotocol.cpp + core/task.cpp + + protocols/fdo/fdotaskprotocol.cpp + protocols/fdo/fdotask.cpp + protocols/fdo/fdographicswidget.cpp + protocols/fdo/fdoselectionmanager.cpp + protocols/fdo/x11embedcontainer.cpp + protocols/fdo/x11embeddelegate.cpp + + protocols/plasmoid/plasmoidtaskprotocol.cpp + protocols/plasmoid/plasmoidtask.cpp + + ui/applet.cpp + ui/compactlayout.cpp + ui/taskarea.cpp + + ) + kde4_add_plugin(plasma_applet_systemtray ${systemtray_SRCS}) -target_link_libraries(plasma_applet_systemtray ${KDE4_KDEUI_LIBS} plasma ${X11_LIBRARIES}) +include_directories(${CMAKE_SOURCE_DIR}) +target_link_libraries(plasma_applet_systemtray ${KDE4_KDEUI_LIBS} plasma ${X11_LIBRARIES} ${X11_Xrender_LIB} + ${X11_Xfixes_LIB} ${X11_Xdamage_LIB} ${X11_Xcomposite_LIB}) install(TARGETS plasma_applet_systemtray DESTINATION ${PLUGIN_INSTALL_DIR}) install(FILES plasma-applet-systemtray.desktop DESTINATION ${SERVICES_INSTALL_DIR}) - --- applets/systemtray/ui/taskarea.h +++ applets/systemtray/ui/taskarea.h @@ -0,0 +1,64 @@ +/*************************************************************************** + * taskarea.h * + * * + * Copyright (C) 2008 Jason Stubbs <jasonbstubbs@gmail.com> * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#ifndef TASKAREA_H +#define TASKAREA_H + +#include <QGraphicsWidget> + +namespace Plasma +{ + class Applet; +} // namespace Plasma + +namespace SystemTray +{ + +class Task; + +class TaskArea : public QGraphicsWidget +{ + Q_OBJECT + +public: + TaskArea(Plasma::Applet *parent); + ~TaskArea(); + + void setHiddenTypes(const QStringList &hiddenTypes); + bool isHiddenType(const QString &typeId) const; + void syncTasks(const QList<SystemTray::Task*> &tasks); + +public slots: + void addTask(SystemTray::Task *task); + void removeTask(SystemTray::Task *task); + +signals: + void sizeHintChanged(Qt::SizeHint which); + +private: + class Private; + Private* const d; +}; + +} + + +#endif --- applets/systemtray/ui/compactlayout.cpp +++ applets/systemtray/ui/compactlayout.cpp @@ -0,0 +1,347 @@ +/*************************************************************************** + * compactlayout.cpp * + * * + * Copyright (C) 2008 Jason Stubbs <jasonbstubbs@gmail.com> * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#include "compactlayout.h" + +#include <QtCore/QHash> + +#include <QtGui/QGraphicsWidget> + + +namespace SystemTray +{ + + +class CompactLayout::Private +{ +public: + Private(CompactLayout *q) + : q(q), + spacing(4.0) + { + } + + QHash<QGraphicsLayoutItem*, QRectF> calculateGeometries(Qt::SizeHint which, + const QSizeF &constraint) const; + void addPadding(QHash<QGraphicsLayoutItem*, QRectF> &geometries, + const QSizeF &constraint); + QSizeF hackedConstraint(const QSizeF &constraint) const; + void updateParentWidget(QGraphicsWidget *item); + QRectF boundingRect(const QList<QRectF> &rects) const; + + CompactLayout *q; + qreal spacing; + QList<QGraphicsLayoutItem*> items; +}; + + +CompactLayout::CompactLayout(QGraphicsLayoutItem *parent) + : QGraphicsLayout(parent), + d(new Private(this)) +{ +} + + +CompactLayout::~CompactLayout() +{ + delete d; +} + + +qreal CompactLayout::spacing() const +{ + return d->spacing; +} + + +void CompactLayout::setSpacing(qreal spacing) +{ + d->spacing = spacing; +} + + +void CompactLayout::addItem(QGraphicsLayout *item) +{ + item->setParentLayoutItem(this); + d->items.append(item); + + updateGeometry(); + activate(); +} + + +void CompactLayout::addItem(QGraphicsWidget *item) +{ + item->setParentLayoutItem(this); + d->updateParentWidget(item); + + d->items.append(item); + + updateGeometry(); + activate(); +} + + +void CompactLayout::Private::updateParentWidget(QGraphicsWidget *item) +{ + QGraphicsLayoutItem *parentItem = q->parentLayoutItem(); + while (parentItem && parentItem->isLayout()) { + parentItem = parentItem->parentLayoutItem(); + } + + if (parentItem) { + item->setParentItem(static_cast<QGraphicsWidget*>(parentItem)); + } +} + + +void CompactLayout::removeItem(QGraphicsLayoutItem *item) +{ + d->items.removeAll(item); + + updateGeometry(); + activate(); +} + + +bool CompactLayout::containsItem(QGraphicsLayoutItem *item) const +{ + return d->items.contains(item); +} + + +int CompactLayout::count() const +{ + return d->items.count(); +} + + +void CompactLayout::setGeometry(const QRectF &rect) +{ + QHash<QGraphicsLayoutItem*, QRectF> geometries; + geometries = d->calculateGeometries(Qt::PreferredSize, rect.size()); + d->addPadding(geometries, rect.size()); + + QHashIterator<QGraphicsLayoutItem*, QRectF> i(geometries); + while (i.hasNext()) { + i.next(); + QGraphicsLayoutItem *item = i.key(); + item->setGeometry(i.value()); + } +} + + +void CompactLayout::Private::addPadding(QHash<QGraphicsLayoutItem*, QRectF> &geometries, const QSizeF &constraint) +{ + QSizeF size = boundingRect(geometries.values()).size(); + + qreal xAdjustment = (constraint.width() - size.width()) / 2.0; + qreal yAdjustment = (constraint.height() - size.height()) / 2.0; + + if (xAdjustment || yAdjustment) { + foreach (QGraphicsLayoutItem *item, items) { + geometries[item].moveLeft(geometries[item].left() + xAdjustment); + geometries[item].moveTop(geometries[item].top() + yAdjustment); + } + } +} + + +QGraphicsLayoutItem* CompactLayout::itemAt(int index) const +{ + return d->items.at(index); +} + + +void CompactLayout::removeAt(int index) +{ + d->items.removeAt(index); +} + + +QSizeF CompactLayout::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const +{ + if (which != Qt::PreferredSize) { + return QSizeF(); + } + + QHash<QGraphicsLayoutItem*, QRectF> geometries = + d->calculateGeometries(which, d->hackedConstraint(constraint)); + + return d->boundingRect(geometries.values()).size(); +} + + +QRectF CompactLayout::Private::boundingRect(const QList<QRectF> &rects) const +{ + QRectF boundingRect; + + foreach (const QRectF &rect, rects) { + if (boundingRect.isNull()) { + boundingRect = rect; + } else { + boundingRect = boundingRect.united(rect); + } + } + + return boundingRect; +} + + +QHash<QGraphicsLayoutItem*, QRectF> CompactLayout::Private::calculateGeometries(Qt::SizeHint which, const QSizeF &constraint) const +{ + QSizePolicy sizePolicy = q->parentLayoutItem()->sizePolicy(); + + QHash<QGraphicsLayoutItem*, QRectF> geometries; + QList<qreal> xPositions; + QList<qreal> yPositions; + + xPositions << 0.0; + yPositions << 0.0; + + foreach (QGraphicsLayoutItem *item, items) { + QRectF rect; + rect.setSize(item->effectiveSizeHint(which)); + + // Strictly speaking, this should check the item's minimum width/height + // but in practice, doing so will lead to a worse visual result. + rect.setWidth(qMin(rect.width(), constraint.width())); + rect.setHeight(qMin(rect.height(), constraint.height())); + + // Try to find an empty space for the item within the bounds + // of the already positioned out items + foreach (qreal x, xPositions) { + rect.moveLeft(x); + if (rect.right() >= xPositions.last()) { + continue; + } + + foreach (qreal y, yPositions) { + rect.moveTop(y); + if (rect.bottom() >= yPositions.last()) { + continue; + } + + bool overlapping = false; + foreach (const QRectF &existingRect, geometries) { + if (existingRect.intersects(rect)) { + overlapping = true; + } + } + + if (!overlapping) { + goto positioning_done; + } + } + } + + // It didn't fit anywhere, so the current bounds will need to + // be extended. + Qt::Orientation direction; + + // Extend based on constraints + if (yPositions.last() + rect.height() > constraint.height()) { + direction = Qt::Horizontal; + } else if (xPositions.last() + rect.width() > constraint.width()) { + direction = Qt::Vertical; + // Then extend based on expanding policy + } else if (sizePolicy.horizontalPolicy() & QSizePolicy::ExpandFlag) { + direction = Qt::Horizontal; + } else if (sizePolicy.verticalPolicy() & QSizePolicy::ExpandFlag) { + direction = Qt::Vertical; + // Otherwise try to keep the shape of a square + } else if (yPositions.last() >= xPositions.last()) { + direction = Qt::Horizontal; + } else { + direction = Qt::Vertical; + } + + if (direction == Qt::Horizontal) { + rect.moveTop(yPositions.first()); + rect.moveLeft(xPositions.last()); + } else { + rect.moveLeft(xPositions.first()); + rect.moveTop(yPositions.last()); + } + + positioning_done: + if (!xPositions.contains(rect.right() + spacing)) { + xPositions.append(rect.right() + spacing); + qSort(xPositions); + } + + if (!yPositions.contains(rect.bottom() + spacing)) { + yPositions.append(rect.bottom() + spacing); + qSort(yPositions); + } + + geometries[item] = rect; + } + + return geometries; +} + + +QSizeF CompactLayout::Private::hackedConstraint(const QSizeF &constraint) const +{ + // Qt doesn't seem to ever specify constraints to sizeHint() + // but the layout needs to know what the constraints are. + // This function returns a new constraint with the size of + // the containing view when Qt hasn't passed a constraint. + + if (constraint.width() != -1 || constraint.height() != -1) { + return constraint; + } + + const QGraphicsWidget *widget = 0; + const QGraphicsLayoutItem *item = q; + + while (item && !widget) { + item = item->parentLayoutItem(); + if (!item->isLayout()) { + widget = static_cast<const QGraphicsWidget*>(item); + } + } + + if (!widget) { + return constraint; + } + + QSizeF parentSize; + qreal xMargins = 0.0, yMargins = 0.0; + + while (widget->parentWidget()) { + widget = widget->parentWidget(); + parentSize = widget->size(); + + if (widget->layout()) { + qreal left, top, right, bottom; + widget->layout()->getContentsMargins(&left, &top, &right, &bottom); + xMargins += left + right; + yMargins += top + bottom; + } + } + + return parentSize - QSizeF(xMargins, yMargins); +} + + +} --- applets/systemtray/ui/applet.cpp +++ applets/systemtray/ui/applet.cpp @@ -0,0 +1,290 @@ +/*************************************************************************** + * applet.cpp * + * * + * Copyright (C) 2008 Jason Stubbs <jasonbstubbs@gmail.com> * + * Copyright (C) 2008 Sebastian Sauer * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#include "applet.h" +#include "taskarea.h" + +#include <QtGui/QGraphicsLayout> +#include <QtGui/QIcon> +#include <QtGui/QListWidget> + +#include <KActionSelector> +#include <KConfigDialog> + +#include <plasma/panelsvg.h> +#include <plasma/theme.h> + +#include "../core/manager.h" +#include "../core/task.h" + + +namespace SystemTray +{ + +K_EXPORT_PLASMA_APPLET(systemtray, Applet) + + +class Applet::Private +{ +public: + Private(Applet *q) + : q(q), + taskArea(0), + configInterface(0), + background(0), + backgroundEnabled(false) + { + } + + void setTaskAreaGeometry(); + + Applet *q; + + TaskArea *taskArea; + QPointer<KActionSelector> configInterface; + + Plasma::PanelSvg *background; + bool backgroundEnabled; +}; + + +Applet::Applet(QObject *parent, const QVariantList &arguments) + : Plasma::Applet(parent, arguments), + d(new Private(this)) +{ + d->background = new Plasma::PanelSvg(this); + d->background->setImagePath("widgets/systemtray"); + + setAspectRatioMode(Plasma::KeepAspectRatio); + + setHasConfigurationInterface(true); +} + +Applet::~Applet() +{ + delete d; +} + +void Applet::init() +{ + KConfigGroup cg = config(); + QStringList hiddenTypes = cg.readEntry("hidden", QStringList()); + + d->taskArea = new TaskArea(this); + d->setTaskAreaGeometry(); + connect(Manager::self(), SIGNAL(taskAdded(SystemTray::Task*)), + d->taskArea, SLOT(addTask(SystemTray::Task*))); + connect(Manager::self(), SIGNAL(taskChanged(SystemTray::Task*)), + d->taskArea, SLOT(addTask(SystemTray::Task*))); + connect(Manager::self(), SIGNAL(taskRemoved(SystemTray::Task*)), + d->taskArea, SLOT(removeTask(SystemTray::Task*))); + + d->taskArea->setHiddenTypes(hiddenTypes); + connect(d->taskArea, SIGNAL(sizeHintChanged(Qt::SizeHint)), + this, SLOT(propogateSizeHintChange(Qt::SizeHint))); + + connect(Plasma::Theme::defaultTheme(), SIGNAL(themeChanged()), + this, SLOT(checkSizes())); + checkSizes(); + + d->taskArea->syncTasks(Manager::self()->tasks()); + +} + + +void Applet::constraintsEvent(Plasma::Constraints constraints) +{ + if (constraints & Plasma::FormFactorConstraint) { + QSizePolicy policy(QSizePolicy::Minimum, QSizePolicy::Minimum); + policy.setHeightForWidth(true); + + if (formFactor() == Plasma::Horizontal) { + policy.setVerticalPolicy(QSizePolicy::Expanding); + } else if (formFactor() == Plasma::Vertical) { + policy.setHorizontalPolicy(QSizePolicy::Expanding); + } + + setSizePolicy(policy); + d->taskArea->setSizePolicy(policy); + } + + if (constraints & Plasma::SizeConstraint) { + checkSizes(); + } +} + + +void Applet::setGeometry(const QRectF &rect) +{ + Plasma::Applet::setGeometry(rect); + + if (d->taskArea) { + d->setTaskAreaGeometry(); + } +} + + +void Applet::checkSizes() +{ + d->taskArea->layout()->updateGeometry(); + + QSizeF preferredSize = d->taskArea->effectiveSizeHint(Qt::PreferredSize); + QSizeF actualSize = size(); + + qreal leftMargin, topMargin, rightMargin, bottomMargin; + d->background->getMargins(leftMargin, topMargin, rightMargin, bottomMargin); + + bool backgroundEnabled; + switch (formFactor()) { + case Plasma::Horizontal: + backgroundEnabled = actualSize.height() >= (preferredSize.height() + topMargin + bottomMargin); + break; + default: + backgroundEnabled = true; + } + + if (backgroundEnabled) { + setContentsMargins(leftMargin, topMargin, rightMargin, bottomMargin); + } else { + setContentsMargins(0, 0, 0, 0); + leftMargin = topMargin = rightMargin = bottomMargin = 0; + } + + preferredSize.setWidth(preferredSize.width() + leftMargin + rightMargin); + preferredSize.setHeight(preferredSize.height() + topMargin + bottomMargin); + setPreferredSize(preferredSize); + + if (formFactor() == Plasma::Planar && (actualSize.width() < preferredSize.width() || + actualSize.height() < preferredSize.height())) { + + QSizeF constraint; + if (actualSize.width() > actualSize.height()) { + constraint = QSize(actualSize.width() - leftMargin - rightMargin, -1); + } else { + constraint = QSize(-1, actualSize.height() - topMargin - bottomMargin); + } + + preferredSize = d->taskArea->effectiveSizeHint(Qt::PreferredSize, constraint); + preferredSize.setWidth(qMax(actualSize.width(), preferredSize.width())); + preferredSize.setHeight(qMax(actualSize.height(), preferredSize.height())); + + resize(preferredSize); + return; + } + + if (backgroundEnabled != d->backgroundEnabled) { + d->backgroundEnabled = backgroundEnabled; + update(); + } +} + + +void Applet::Private::setTaskAreaGeometry() +{ + qreal leftMargin, topMargin, rightMargin, bottomMargin; + q->getContentsMargins(&leftMargin, &topMargin, &rightMargin, &bottomMargin); + + QRectF taskAreaRect(q->rect()); + taskAreaRect.moveLeft(leftMargin); + taskAreaRect.moveTop(topMargin); + taskAreaRect.setWidth(taskAreaRect.width() - leftMargin - rightMargin); + taskAreaRect.setHeight(taskAreaRect.height() - topMargin - bottomMargin); + + taskArea->setGeometry(taskAreaRect); +} + + +void Applet::paintInterface(QPainter *painter, const QStyleOptionGraphicsItem *option, const QRect &contentsRect) +{ + Q_UNUSED(option) + Q_UNUSED(contentsRect); + + if (d->backgroundEnabled) { + d->background->resizePanel(size()); + d->background->paintPanel(painter); + } +} + + +void Applet::propogateSizeHintChange(Qt::SizeHint which) +{ + checkSizes(); + emit sizeHintChanged(which); +} + + +void Applet::createConfigurationInterface(KConfigDialog *parent) +{ + if (!d->configInterface) { + d->configInterface = new KActionSelector(); + d->configInterface->setAvailableLabel(i18n("Visible icons:")); + d->configInterface->setSelectedLabel(i18n("Hidden icons:")); + d->configInterface->setShowUpDownButtons(false); + + connect(parent, SIGNAL(applyClicked()), this, SLOT(configAccepted())); + connect(parent, SIGNAL(okClicked()), this, SLOT(configAccepted())); + + parent->setMainWidget(d->configInterface); + } + + QListWidget *visibleList = d->configInterface->availableListWidget(); + QListWidget *hiddenList = d->configInterface->selectedListWidget(); + + visibleList->clear(); + hiddenList->clear(); + + foreach (Task *task, Manager::self()->tasks()) { + QListWidgetItem *listItem = new QListWidgetItem(); + listItem->setText(task->name()); + listItem->setIcon(task->icon()); + listItem->setData(Qt::UserRole, task->typeId()); + + if (d->taskArea->isHiddenType(task->typeId())) { + hiddenList->addItem(listItem); + } else { + visibleList->addItem(listItem); + } + } +} + + +void Applet::configAccepted() +{ + QStringList hiddenTypes; + + QListWidget *hiddenList = d->configInterface->selectedListWidget(); + for (int i = 0; i < hiddenList->count(); ++i) { + hiddenTypes << hiddenList->item(i)->data(Qt::UserRole).toString(); + } + + d->taskArea->setHiddenTypes(hiddenTypes); + d->taskArea->syncTasks(Manager::self()->tasks()); + + KConfigGroup cg = config(); + cg.writeEntry("hidden", hiddenTypes); + emit configNeedsSaving(); +} + + +} + +#include "applet.moc" --- applets/systemtray/ui/compactlayout.h +++ applets/systemtray/ui/compactlayout.h @@ -0,0 +1,61 @@ +/*************************************************************************** + * compactlayout.h * + * * + * Copyright (C) 2008 Jason Stubbs <jasonbstubbs@gmail.com> * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#ifndef COMPACTLAYOUT_H +#define COMPACTLAYOUT_H + +#include <QGraphicsLayout> + + +namespace SystemTray +{ + +class CompactLayout : public QGraphicsLayout +{ +public: + CompactLayout(QGraphicsLayoutItem *parent = 0); + ~CompactLayout(); + + qreal spacing() const; + void setSpacing(qreal spacing); + + void addItem(QGraphicsLayout *item); + void addItem(QGraphicsWidget *item); + void removeItem(QGraphicsLayoutItem *item); + bool containsItem(QGraphicsLayoutItem *item) const; + + int count() const; + void setGeometry(const QRectF &rect); + QGraphicsLayoutItem* itemAt(int i) const; + void removeAt(int index); + +protected: + QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint = QSizeF()) const; + +private: + class Private; + Private* const d; +}; + +} + + +#endif --- applets/systemtray/ui/applet.h +++ applets/systemtray/ui/applet.h @@ -0,0 +1,68 @@ +/*************************************************************************** + * applet.h * + * * + * Copyright (C) 2008 Jason Stubbs <jasonbstubbs@gmail.com> * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#ifndef APPLET_H +#define APPLET_H + +#include <plasma/applet.h> + +namespace SystemTray +{ +} + + +namespace SystemTray +{ + +class Applet : public Plasma::Applet +{ + Q_OBJECT + +public: + explicit Applet(QObject *parent, const QVariantList &arguments = QVariantList()); + ~Applet(); + + void init(); + void constraintsEvent(Plasma::Constraints constraints); + void setGeometry(const QRectF &rect); + +protected: + void paintInterface(QPainter *painter, const QStyleOptionGraphicsItem *option, const QRect &contentsRect); + void createConfigurationInterface(KConfigDialog *parent); +// void initExtenderItem(Plasma::ExtenderItem *extenderItem); + + void hoverEnterEvent(QGraphicsSceneHoverEvent *event) { Q_UNUSED(event); } + void hoverLeaveEvent(QGraphicsSceneHoverEvent *event) { Q_UNUSED(event); } + +private slots: + void configAccepted(); + void propogateSizeHintChange(Qt::SizeHint which); + void checkSizes(); + +private: + class Private; + Private* const d; +}; + +} + + +#endif --- applets/systemtray/ui/taskarea.cpp +++ applets/systemtray/ui/taskarea.cpp @@ -0,0 +1,130 @@ +/*************************************************************************** + * taskarea.cpp * + * * + * Copyright (C) 2008 Jason Stubbs <jasonbstubbs@gmail.com> * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#include "taskarea.h" + +#include <QtCore/QSet> + +#include <plasma/applet.h> + +#include "../core/task.h" +#include "compactlayout.h" + + +namespace SystemTray +{ + + +class TaskArea::Private +{ +public: + Private(Plasma::Applet *h) + : host(h), + layout(new CompactLayout()) + { + } + + QGraphicsWidget* findWidget(Task *task); + + Plasma::Applet *host; + CompactLayout *layout; + QSet<QString> hiddenTypes; +}; + + +TaskArea::TaskArea(Plasma::Applet *parent) + : QGraphicsWidget(parent), + d(new Private(parent)) +{ + setLayout(d->layout); +} + + +TaskArea::~TaskArea() +{ + delete d; +} + + +void TaskArea::setHiddenTypes(const QStringList &hiddenTypes) +{ + d->hiddenTypes = QSet<QString>::fromList(hiddenTypes); +} + + +bool TaskArea::isHiddenType(const QString &typeId) const +{ + return d->hiddenTypes.contains(typeId); +} + + +void TaskArea::syncTasks(const QList<SystemTray::Task*> &tasks) +{ + foreach (Task *task, tasks) { + if (isHiddenType(task->typeId())) { + QGraphicsWidget *widget = d->findWidget(task); + if (widget) { + d->layout->removeItem(widget); + delete widget; + } + } else { + addTask(task); + } + } +} + + +void TaskArea::addTask(Task *task) +{ + if (task->isEmbeddable() && !isHiddenType(task->typeId()) && !d->findWidget(task)) { + d->layout->addItem(task->widget(d->host)); + emit sizeHintChanged(Qt::PreferredSize); + } +} + + +void TaskArea::removeTask(Task *task) +{ + foreach (QGraphicsWidget *widget, task->associatedWidgets()) { + if (d->layout->containsItem(widget)) { + d->layout->removeItem(widget); + emit sizeHintChanged(Qt::PreferredSize); + break; + } + } +} + + +QGraphicsWidget* TaskArea::Private::findWidget(Task *task) +{ + foreach (QGraphicsWidget *widget, task->associatedWidgets()) { + if (layout->containsItem(widget)) { + return widget; + } + } + + return 0; +} + + +} + +#include "taskarea.moc" --- applets/tasks/windowtaskitem.h +++ applets/tasks/windowtaskitem.h @@ -55,8 +55,11 @@ public: /** Constructs a new representation for a window task. */ - WindowTaskItem(Tasks *parent, const bool showTooltip); + WindowTaskItem(Tasks *parent, bool showTooltip); + /**Destruct the representation of the window task */ + ~WindowTaskItem(); + /** Sets the starting task represented by this item. */ void setStartupTask(TaskManager::StartupPtr task); @@ -124,6 +127,8 @@ public slots: virtual void activate(); + void toolTipAboutToShow(); + void toolTipHidden(); protected: virtual void contextMenuEvent(QGraphicsSceneContextMenuEvent *event); @@ -169,9 +174,10 @@ */ void drawTextLayout(QPainter *painter, const QTextLayout &layout, const QRect &rect) const; + void updateToolTip(); private slots: - void updateTask(); + void updateTask(::TaskManager::TaskChanges changes); void animationUpdate(qreal progress); private: @@ -180,6 +186,7 @@ QTimer* m_activateTimer; bool m_showTooltip; + bool m_showingTooltip; // area of item occupied by task's icon QRectF iconRect(const QRectF &bounds) const; // area of item occupied by task's text --- applets/tasks/tasks.cpp +++ applets/tasks/tasks.cpp @@ -92,11 +92,9 @@ setLayout(m_layout); KConfigGroup cg = config(); -#ifdef TOOLTIP_MANAGER - m_showTooltip = cg.readEntry("showTooltip", true); -#endif m_showOnlyCurrentDesktop = cg.readEntry("showOnlyCurrentDesktop", false); m_showOnlyCurrentScreen = cg.readEntry("showOnlyCurrentScreen", false); + m_showTooltip = cg.readEntry("showTooltip", true); // listen for addition and removal of window tasks connect(TaskManager::TaskManager::self(), SIGNAL(taskAdded(TaskPtr)), @@ -130,6 +128,7 @@ item->deleteLater(); } + updatePreferredSize(); adjustStretch(); } @@ -138,12 +137,18 @@ TaskManager::TaskManager *manager = TaskManager::TaskManager::self(); TaskManager::TaskDict tasks = manager->tasks(); - QMapIterator<WId,TaskPtr> iter(tasks); + QHashIterator<WId,TaskPtr> iter(tasks); while (iter.hasNext()) { iter.next(); + if ((!iter.value()->isOnCurrentDesktop() && m_showOnlyCurrentDesktop) || + (!isOnMyScreen(iter.value()) && m_showOnlyCurrentScreen)) { + connect(iter.value().data(), SIGNAL(changed(::TaskManager::TaskChanges)), + this, SLOT(addAttentionTask(::TaskManager::TaskChanges))); + } addWindowTask(iter.value()); } + updatePreferredSize(); } void Tasks::addWindowTask(TaskPtr task) @@ -152,11 +157,11 @@ return; } - if (m_showOnlyCurrentDesktop && !task->isOnCurrentDesktop()) { + if (m_showOnlyCurrentDesktop && !task->isOnCurrentDesktop() && !task->demandsAttention()) { return; } - if (m_showOnlyCurrentScreen && !isOnMyScreen(task)) { + if (m_showOnlyCurrentScreen && !isOnMyScreen(task) && !task->demandsAttention()) { return; } @@ -208,31 +213,33 @@ void Tasks::removeWindowTask(TaskPtr task) { - if (m_windowTaskItems.contains(task)) { - WindowTaskItem *item = m_windowTaskItems.take(task); + WindowTaskItem *item = m_windowTaskItems.take(task); + if (item) { m_layout->removeItem(item); scene()->removeItem(item); item->deleteLater(); m_activeTask = m_windowTaskItems.end(); + updatePreferredSize(); + adjustStretch(); } - - adjustStretch(); } void Tasks::removeAllWindowTasks() { - QHash<TaskPtr,WindowTaskItem*>::iterator it = m_windowTaskItems.begin(); + QHashIterator<TaskPtr,WindowTaskItem*> iter (m_windowTaskItems); - while (it != m_windowTaskItems.end()) { - WindowTaskItem *item = it.value(); + while (iter.hasNext()) { + iter.next(); + WindowTaskItem *item = iter.value(); m_layout->removeItem(item); scene()->removeItem(item); item->deleteLater(); - ++it; } - - m_windowTaskItems.clear(); - m_activeTask = m_windowTaskItems.end(); + if (m_windowTaskItems.count() > 0) { + m_windowTaskItems.clear(); + m_activeTask = m_windowTaskItems.end(); + updatePreferredSize(); + } } void Tasks::constraintsEvent(Plasma::Constraints constraints) @@ -371,7 +378,7 @@ return; } - if (!task->isOnCurrentDesktop()) { + if (!task->isOnCurrentDesktop() && !task->demandsAttention()) { removeWindowTask(task); } else if (!m_windowTaskItems.contains(task)) { addWindowTask(task); @@ -392,7 +399,7 @@ void Tasks::checkScreenChange() { foreach (const TaskPtr &task, m_geometryTasks) { - if (!isOnMyScreen(task)) { + if (!isOnMyScreen(task) && !task->demandsAttention()) { removeWindowTask(task); } else if (!m_windowTaskItems.contains(task)) { addWindowTask(task); @@ -446,6 +453,27 @@ } +void Tasks::updatePreferredSize() +{ + if (m_layout->count() > 0) { + QGraphicsLayoutItem *item = m_layout->itemAt(0); + + if (formFactor() == Plasma::Horizontal) { + setPreferredSize(item->preferredSize().width()*m_layout->count(), preferredSize().height()); + } else if (formFactor() == Plasma::Vertical) { + setPreferredSize(preferredSize().width(), item->preferredSize().height()*m_layout->count()); + } + //Empty taskbar, arbitrary small value + } else { + if (formFactor() == Plasma::Horizontal) { + setPreferredSize(10, preferredSize().height()); + } else if (formFactor() == Plasma::Vertical) { + setPreferredSize(preferredSize().width(), 10); + } + } + emit sizeHintChanged(Qt::PreferredSize); +} + bool Tasks::isOnMyScreen(TaskPtr task) { Plasma::Containment* appletContainment = containment(); @@ -463,18 +491,14 @@ void Tasks::createConfigurationInterface(KConfigDialog *parent) { - QWidget *widget = new QWidget; - m_ui.setupUi(widget); - parent->setButtons(KDialog::Ok | KDialog::Cancel | KDialog::Apply); - connect(parent, SIGNAL(applyClicked()), this, SLOT(configAccepted())); - connect(parent, SIGNAL(okClicked()), this, SLOT(configAccepted())); - parent->addPage(widget, parent->windowTitle(), icon()); + QWidget *widget = new QWidget; + m_ui.setupUi(widget); + parent->setButtons(KDialog::Ok | KDialog::Cancel | KDialog::Apply); + connect(parent, SIGNAL(applyClicked()), this, SLOT(configAccepted())); + connect(parent, SIGNAL(okClicked()), this, SLOT(configAccepted())); + parent->addPage(widget, parent->windowTitle(), icon()); -#ifdef TOOLTIP_MANAGER m_ui.showTooltip->setChecked(m_showTooltip); -#else - m_ui.showTooltip->hide(); -#endif m_ui.showOnlyCurrentDesktop->setChecked(m_showOnlyCurrentDesktop); m_ui.showOnlyCurrentScreen->setChecked(m_showOnlyCurrentScreen); } @@ -495,25 +519,17 @@ cg.writeEntry("showOnlyCurrentScreen", m_showOnlyCurrentScreen); changed = true; } - - if (changed) { - reconnect(); - } -#ifdef TOOLTIP_MANAGER - if (m_showTooltip != (m_ui.showTooltip->checkState() == Qt::Checked)) { + if (m_showTooltip != (m_ui.showTooltip->isChecked())) { m_showTooltip = !m_showTooltip; - foreach (AbstractTaskItem *taskItem, m_windowTaskItems) { - WindowTaskItem *windowTaskItem = dynamic_cast<WindowTaskItem *>(taskItem); - if (windowTaskItem) { - windowTaskItem->setShowTooltip(m_showTooltip); - } - } KConfigGroup cg = config(); cg.writeEntry("showTooltip", m_showTooltip); changed = true; } -#endif + if (changed) { + reconnect(); + } + if (changed) { update(); emit configNeedsSaving(); } @@ -559,6 +575,21 @@ } } +/** Adds a windowTaskItem that is demanding attention to the taskbar if it is not currently shown and is not on the current desktop. +*This funtion applies when the m_showOnlyCurrentDesktop or m_showOnlyCurrentScreen switch set. */ +void Tasks::addAttentionTask(::TaskManager::TaskChanges changes) +{ + if (!(changes & TaskManager::StateChanged)) { + return; + } + + TaskPtr task; + task.attach(qobject_cast<TaskManager::Task*>(sender())); + if (task->demandsAttention() && !m_windowTaskItems.contains(task)) { + addWindowTask(task); + } +} + K_EXPORT_PLASMA_APPLET(tasks, Tasks) #include "tasks.moc" --- applets/tasks/windowtaskitem.cpp +++ applets/tasks/windowtaskitem.cpp @@ -41,13 +41,15 @@ #include "plasma/theme.h" #include "plasma/paintutils.h" #include "plasma/panelsvg.h" +#include "plasma/tooltipmanager.h" #include "tasks.h" -WindowTaskItem::WindowTaskItem(Tasks *parent, const bool showTooltip) +WindowTaskItem::WindowTaskItem(Tasks *parent, bool showTooltip) : QGraphicsWidget(parent), m_applet(parent), m_activateTimer(0), + m_showingTooltip(false), m_flags(0), m_animId(0), m_alpha(1), @@ -56,17 +58,27 @@ m_attentionTimerId(0), m_attentionTicks(0) { - m_showTooltip = showTooltip; + setShowTooltip(showTooltip); setSizePolicy(QSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding)); setAcceptsHoverEvents(true); setAcceptDrops(true); + if (m_showTooltip) { + Plasma::ToolTipManager::self()->registerWidget(this); + } else { + Plasma::ToolTipManager::self()->unregisterWidget(this); + } + QFontMetrics fm(KGlobalSettings::taskbarFont()); QSize mSize = fm.size(0, "M"); setPreferredSize(QSize(mSize.width()*15 + m_applet->itemLeftMargin() + m_applet->itemRightMargin() + IconSize(KIconLoader::Panel), mSize.height()*3 + m_applet->itemTopMargin() + m_applet->itemBottomMargin())); } +WindowTaskItem::~WindowTaskItem() +{ +} + void WindowTaskItem::activate() { // the Task class has a method called activateRaiseOrIconify() which @@ -87,6 +99,19 @@ } } +void WindowTaskItem::toolTipAboutToShow() +{ + m_showingTooltip = true; + updateToolTip(); +} + +void WindowTaskItem::toolTipHidden() +{ + m_showingTooltip = false; + Plasma::ToolTipManager::ToolTipContent data; + Plasma::ToolTipManager::self()->setToolTipContent(this, data); +} + void WindowTaskItem::close() { if (m_task) { @@ -97,7 +122,11 @@ void WindowTaskItem::setShowTooltip(const bool showit) { m_showTooltip = showit; - updateTask(); + if (showit) { + Plasma::ToolTipManager::self()->registerWidget(this); + } else { + Plasma::ToolTipManager::self()->unregisterWidget(this); + } } void WindowTaskItem::setText(const QString &text) @@ -518,7 +547,7 @@ painter->drawPixmap(rect.topLeft(), pixmap); } -void WindowTaskItem::updateTask() +void WindowTaskItem::updateTask(::TaskManager::TaskChanges changes) { Q_ASSERT(m_task); @@ -545,32 +574,41 @@ setTaskFlags(flags); - // basic title and icon - QIcon taskIcon; - taskIcon.addPixmap(m_task->icon(KIconLoader::SizeSmall, KIconLoader::SizeSmall, false)); - taskIcon.addPixmap(m_task->icon(KIconLoader::SizeSmallMedium, KIconLoader::SizeSmallMedium, false)); - taskIcon.addPixmap(m_task->icon(KIconLoader::SizeMedium, KIconLoader::SizeMedium, false)); - taskIcon.addPixmap(m_task->icon(KIconLoader::SizeLarge, KIconLoader::SizeLarge, false)); + if (changes & TaskManager::IconChanged) { + setIcon(m_task->icon()); + } -#ifdef TOOLTIP_MANAGER - if (m_showTooltip) { - Plasma::ToolTipData data; - data.mainText = m_task->visibleName(); - data.subText = i18nc("Which virtual desktop a window is currently on", "On %1", KWindowSystem::desktopName(m_task->desktop())); - data.image = iconPixmap; - data.windowToPreview = m_task->window(); - setToolTip(data); - } else { - Plasma::ToolTipData data; - setToolTip(data); // Clear + if (changes & TaskManager::NameChanged) { + setText(m_task->visibleName()); } -#endif - setIcon(taskIcon); - setText(m_task->visibleName()); + + if (m_showingTooltip && + (changes & TaskManager::IconChanged || + changes & TaskManager::NameChanged || + changes & TaskManager::DesktopChanged)) { + updateToolTip(); + } + //redraw queueUpdate(); } +void WindowTaskItem::updateToolTip() +{ + if (!m_task) { + return; + } + + Plasma::ToolTipManager::ToolTipContent data; + data.mainText = m_task->visibleName(); + data.subText = i18nc("Which virtual desktop a window is currently on", "On %1", + KWindowSystem::desktopName(m_task->desktop())); + data.image = m_task->icon(KIconLoader::SizeSmall, KIconLoader::SizeSmall, false); + data.windowToPreview = m_task->window(); + + Plasma::ToolTipManager::self()->setToolTipContent(this, data); +} + void WindowTaskItem::animationUpdate(qreal progress) { if (progress == 1) { @@ -606,12 +644,10 @@ m_task = task; - connect(task.constData(), SIGNAL(changed()), - this, SLOT(updateTask())); - connect(task.constData(), SIGNAL(iconChanged()), - this, SLOT(updateTask())); + connect(task.constData(), SIGNAL(changed(::TaskManager::TaskChanges)), + this, SLOT(updateTask(::TaskManager::TaskChanges))); - updateTask(); + updateTask(TaskManager::EverythingChanged); publishIconGeometry(); //kDebug() << "Task added, isActive = " << task->isActive(); --- applets/tasks/tasks.h +++ applets/tasks/tasks.h @@ -101,6 +101,7 @@ void taskMovedDesktop(TaskPtr task); void windowChangedGeometry(TaskPtr task); void checkScreenChange(); + void addAttentionTask(::TaskManager::TaskChanges changes); private: // creates task representations for existing windows @@ -113,6 +114,7 @@ void insertItemBeforeSpacer(QGraphicsWidget * item); void adjustStretch(); + void updatePreferredSize(); bool isOnMyScreen(TaskPtr task); void reconnect(); --- applets/icon/icon.cpp +++ applets/icon/icon.cpp @@ -44,6 +44,7 @@ #include <plasma/theme.h> #include <plasma/widgets/icon.h> #include <plasma/containment.h> +#include <plasma/tooltipmanager.h> IconApplet::IconApplet(QObject *parent, const QVariantList &args) : Plasma::Applet(parent, args), @@ -80,6 +81,7 @@ setDisplayLines(2); registerAsDragHandle(m_icon); + Plasma::ToolTipManager::self()->registerWidget(m_icon); setAspectRatioMode(Plasma::ConstrainedSquare); @@ -157,12 +159,11 @@ //in the panel the icon behaves like a button connect(m_icon, SIGNAL(clicked()), this, SLOT(openUrl())); m_icon->setText(QString()); - //FIXME PORT TO TOOL TIP MANAGER - /*Plasma::ToolTipData data; + Plasma::ToolTipManager::ToolTipContent data; data.mainText = m_text; data.subText = m_genericName; data.image = m_icon->icon().pixmap(IconSize(KIconLoader::Desktop)); - m_icon->setToolTip(data);*/ + Plasma::ToolTipManager::self()->setToolTipContent(m_icon, data); m_icon->setDrawBackground(false); } } --- applets/analog-clock/plasma-applet-analogclock.desktop +++ applets/analog-clock/plasma-applet-analogclock.desktop @@ -101,7 +101,7 @@ Comment[nds]=En Klock mit SVG-Mustern Comment[ne]=एउटा एसभीजी थेमेबल घडी Comment[nl]=Een klok met SVG-themamogelijkheden -Comment[nn]=Ei SVG-basert klokke med fleire tema +Comment[nn]=SVG-basert klokke med fleire tema Comment[pa]=ਇੱਕ SVG ਥੀਮ-ਯੋਗ ਕਲਾਕ Comment[pl]=Zegar z motywami SVG Comment[pt]=Um relógio com temas em SVG @@ -123,7 +123,7 @@ Comment[zh_TW]=SVG 可調整外觀時鐘 Icon=chronometer Type=Service -X-KDE-ServiceTypes=Plasma/Applet,Plasma/Containment +X-KDE-ServiceTypes=Plasma/Applet X-KDE-Library=plasma_applet_clock X-KDE-PluginInfo-Author=The Plasma Team --- applets/battery/battery.svg +++ applets/battery/battery.svg @@ -1,682 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="no"?> -<!-- Created with Inkscape (http://www.inkscape.org/) --> -<svg - xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/" - xmlns:svg="http://www.w3.org/2000/svg" - xmlns="http://www.w3.org/2000/svg" - xmlns:xlink="http://www.w3.org/1999/xlink" - version="1.0" - width="22.000275" - height="22.000181" - viewBox="0 0 22 12" - id="svg2065" - xml:space="preserve"><rect - width="8" - height="10" - x="13" - y="1" - style="fill:url(#linearGradient10105);fill-opacity:1" - id="rect9410" /><defs - id="defs2113"><linearGradient - id="linearGradient4870"><stop - style="stop-color:#ffdd00;stop-opacity:1" - offset="0" - id="stop4872" /><stop - style="stop-color:#ffdd00;stop-opacity:0" - offset="1" - id="stop4874" /></linearGradient><linearGradient - x1="11.9995" - y1="2.2495" - x2="11.9995" - y2="9.7489996" - id="linearGradient6729" - gradientUnits="userSpaceOnUse"> - <stop - style="stop-color:#ffbf80;stop-opacity:1" - offset="0" - id="stop6731" /> - <stop - style="stop-color:#ff7e00;stop-opacity:1" - offset="1" - id="stop6733" /> - <a:midPointStop - offset="0" - style="stop-color:#99DCC6" /> - <a:midPointStop - offset="0.5" - style="stop-color:#99DCC6" /> - <a:midPointStop - offset="1" - style="stop-color:#00734D" /> - </linearGradient><linearGradient - x1="11.9995" - y1="2.2495" - x2="11.9995" - y2="9.7489996" - id="linearGradient5838" - gradientUnits="userSpaceOnUse"> - <stop - style="stop-color:#ff8080;stop-opacity:1" - offset="0" - id="stop5840" /> - <stop - style="stop-color:#cd0000;stop-opacity:1" - offset="1" - id="stop5842" /> - <a:midPointStop - offset="0" - style="stop-color:#99DCC6" /> - <a:midPointStop - offset="0.5" - style="stop-color:#99DCC6" /> - <a:midPointStop - offset="1" - style="stop-color:#00734D" /> - </linearGradient><linearGradient - id="linearGradient3291"><stop - style="stop-color:#000000;stop-opacity:1" - offset="0" - id="stop3293" /><stop - style="stop-color:#000000;stop-opacity:0" - offset="1" - id="stop3295" /></linearGradient><linearGradient - x1="11.9995" - y1="2.2495" - x2="11.9995" - y2="9.7489996" - id="linearGradient3311" - gradientUnits="userSpaceOnUse"> - <stop - style="stop-color:#3cff3c;stop-opacity:1" - offset="0" - id="stop3313" /> - <stop - style="stop-color:#008c00;stop-opacity:1" - offset="1" - id="stop3315" /> - <a:midPointStop - style="stop-color:#99DCC6" - offset="0" /> - <a:midPointStop - style="stop-color:#99DCC6" - offset="0.5" /> - <a:midPointStop - style="stop-color:#00734D" - offset="1" /> - </linearGradient><linearGradient - id="linearGradient3043"><stop - style="stop-color:#ffffff;stop-opacity:0.5029586" - offset="0" - id="stop3045" /><stop - style="stop-color:#ffffff;stop-opacity:0" - offset="1" - id="stop3047" /></linearGradient><linearGradient - x1="12" - y1="11" - x2="12" - y2="1" - id="XMLID_8_" - gradientUnits="userSpaceOnUse"> - <stop - style="stop-color:#454545;stop-opacity:1" - offset="0" - id="stop2078" /> - <stop - style="stop-color:#000000;stop-opacity:1" - offset="1" - id="stop2080" /> - <a:midPointStop - offset="0" - style="stop-color:#454545" /> - <a:midPointStop - offset="0.5" - style="stop-color:#454545" /> - <a:midPointStop - offset="1" - style="stop-color:#000000" /> - </linearGradient><linearGradient - x1="12" - y1="9.0010004" - x2="12" - y2="1.001" - id="XMLID_9_" - gradientUnits="userSpaceOnUse"> - <stop - style="stop-color:#aeaeae;stop-opacity:1" - offset="0" - id="stop2085" /><stop - style="stop-color:#696969;stop-opacity:1" - offset="0.25714287" - id="stop3403" /> - <stop - style="stop-color:#3a3a3a;stop-opacity:1" - offset="1" - id="stop2087" /> - <a:midPointStop - offset="0" - style="stop-color:#FFFFFF" /> - <a:midPointStop - offset="0.5" - style="stop-color:#FFFFFF" /> - <a:midPointStop - offset="1" - style="stop-color:#000000" /> - </linearGradient><radialGradient - cx="96.8349" - cy="78.852486" - r="26.26219" - fx="96.8349" - fy="78.852486" - id="radialGradient7893" - xlink:href="#linearGradient4870" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(0.194405,0,0,0.355618,-6.03865,-20.42761)" /><linearGradient - x1="13.633333" - y1="1.5664186" - x2="13.633333" - y2="6" - id="linearGradient8047" - xlink:href="#linearGradient3311" - gradientUnits="userSpaceOnUse" /><linearGradient - x1="12" - y1="9.0010004" - x2="12" - y2="1.001" - id="linearGradient8049" - xlink:href="#XMLID_9_" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1,0,0,1.25,0,-0.25)" /><linearGradient - x1="12" - y1="11" - x2="12" - y2="1" - id="linearGradient8051" - xlink:href="#XMLID_8_" - gradientUnits="userSpaceOnUse" /><linearGradient - x1="1" - y1="11" - x2="1" - y2="1" - id="linearGradient8053" - xlink:href="#XMLID_8_" - gradientUnits="userSpaceOnUse" /><linearGradient - x1="12" - y1="11" - x2="12" - y2="1" - id="linearGradient4791" - xlink:href="#XMLID_8_" - gradientUnits="userSpaceOnUse" /><linearGradient - x1="13.633333" - y1="1.5664186" - x2="13.633333" - y2="6" - id="linearGradient4787" - xlink:href="#linearGradient6729" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(0.222223,0,0,1,16.33333,0)" /><linearGradient - x1="13.633333" - y1="1.5664186" - x2="13.633333" - y2="6" - id="linearGradient7749" - xlink:href="#linearGradient3311" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(0.333334,0,0,1,14,0)" /><linearGradient - x1="6.8666668" - y1="11.006487" - x2="6.8666668" - y2="9.6329269" - id="linearGradient7751" - xlink:href="#linearGradient3043" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(0.333334,0,0,1.463415,14,-5.0976)" /><linearGradient - x1="13.633333" - y1="1.5664186" - x2="13.633333" - y2="6" - id="linearGradient9844" - xlink:href="#linearGradient3311" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(0.555556,0,0,1,9.33333,0)" /><linearGradient - x1="6.8666668" - y1="11.006487" - x2="6.8666668" - y2="9.6329269" - id="linearGradient9840" - xlink:href="#linearGradient3043" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(0.555556,0,0,1.463415,9.33333,-5.0976)" /><linearGradient - x1="13.633333" - y1="1.5664186" - x2="13.633333" - y2="6" - id="linearGradient10117" - xlink:href="#linearGradient3311" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(0.666667,0,0,1,7,0)" /><linearGradient - x1="6.8666668" - y1="11.006487" - x2="6.8666668" - y2="9.6329269" - id="linearGradient10113" - xlink:href="#linearGradient3043" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(0.666667,0,0,1.463415,7,-5.0976)" /><radialGradient - cx="63.912209" - cy="115.70919" - r="63.912209" - fx="63.912209" - fy="115.7093" - id="radialGradient10059" - xlink:href="#linearGradient3291" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1,0,0,0.197802,0,92.82166)" /><linearGradient - x1="13.633333" - y1="1.5664186" - x2="13.633333" - y2="6" - id="linearGradient6655" - xlink:href="#linearGradient3311" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(0.777778,0,0,1,4.66667,0)" /><linearGradient - x1="6.8666668" - y1="11.006487" - x2="6.8666668" - y2="9.6329269" - id="linearGradient6651" - xlink:href="#linearGradient3043" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(0.777778,0,0,1.463415,4.66667,-5.0976)" /><linearGradient - x1="6.8666668" - y1="11.006487" - x2="6.8666668" - y2="9.6329269" - id="linearGradient68886" - xlink:href="#linearGradient3043" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(0.9991321,0,0,1.463415,3.4277715e-3,-5.1057075)" /><linearGradient - x1="6.8666668" - y1="11.006487" - x2="6.8666668" - y2="9.6329269" - id="linearGradient76332" - xlink:href="#linearGradient3043" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(0.222222,0,0,1.463415,16.33334,-5.0976)" /><linearGradient - x1="1.5" - y1="4.0419998" - x2="1.5" - y2="8" - id="linearGradient76336" - xlink:href="#linearGradient3311" - gradientUnits="userSpaceOnUse" /><linearGradient - x1="6.8666668" - y1="11.006487" - x2="6.8666668" - y2="9.6329269" - id="linearGradient83062" - xlink:href="#linearGradient3043" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.0002516,0,0,1.463415,-5.2735133e-3,-5.0976)" /><linearGradient - x1="13.633333" - y1="1.5664186" - x2="13.633333" - y2="6" - id="linearGradient83064" - xlink:href="#linearGradient3311" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.0002516,0,0,1,-5.2735133e-3,0)" /><linearGradient - x1="13.633333" - y1="1.5664186" - x2="13.633333" - y2="6" - id="linearGradient83066" - xlink:href="#linearGradient3311" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(0.8882738,0,0,1,2.3462594,0)" /><linearGradient - x1="6.8666668" - y1="11.006487" - x2="6.8666668" - y2="9.6329269" - id="linearGradient83068" - xlink:href="#linearGradient3043" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(0.8882738,0,0,1.463415,2.3462594,-5.0976)" /><linearGradient - x1="13.633333" - y1="1.5664186" - x2="13.633333" - y2="6" - id="linearGradient16304" - xlink:href="#linearGradient3311" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(0.555556,0,0,1,9.33333,0)" /><linearGradient - x1="6.8666668" - y1="11.006487" - x2="6.8666668" - y2="9.6329269" - id="linearGradient16306" - xlink:href="#linearGradient3043" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(0.555556,0,0,1.463415,9.33333,-5.0976)" /><linearGradient - x1="13.633333" - y1="1.5664186" - x2="13.633333" - y2="6" - id="linearGradient17814" - xlink:href="#linearGradient5838" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(0.111111,0,0,1,18.66667,0)" /><linearGradient - x1="6.8666668" - y1="11.006487" - x2="6.8666668" - y2="9.6329269" - id="linearGradient17816" - xlink:href="#linearGradient3043" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(0.111111,0,0,1.463415,18.66667,-5.0976)" /></defs> - - - <g - transform="translate(1.3686299e-4,4.672975e-5)" - style="display:inline" - id="Battery"><rect - width="22" - height="22" - x="0" - y="-5" - style="fill:none" - id="rect68833" /><g - id="g32977"><rect - width="2" - height="6" - x="0" - y="3" - style="fill:url(#linearGradient8053);fill-opacity:1" - id="rect9324" /><rect - width="20" - height="12" - rx="1" - ry="1" - x="2" - y="0" - style="fill:url(#linearGradient8051)" - id="rect9326" /><rect - width="18" - height="10" - x="3" - y="1" - style="fill:url(#linearGradient8049)" - id="rect9328" /><rect - width="1" - height="4" - x="2" - y="4" - style="opacity:0.1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1" - id="rect9336" /></g></g><g - transform="translate(1.3686299e-4,4.672975e-5)" - style="display:inline" - id="Fill100"><rect - width="1" - height="3.9579999" - x="1" - y="4.0419922" - style="fill:url(#linearGradient76336);fill-opacity:1" - id="rect32905" /><rect - width="18" - height="10" - x="3" - y="1" - style="fill:url(#linearGradient8047);fill-opacity:1" - id="rect32971" /><rect - width="17.984375" - height="2" - x="3.0008278" - y="8.9918919" - style="fill:url(#linearGradient68886);fill-opacity:1;display:inline;overflow:visible" - id="rect68884" /><rect - width="21.990196" - height="21.991766" - x="0.003928124" - y="-4.9961619" - style="fill:none" - id="rect83029" /></g><g - transform="translate(1.3686299e-4,4.672975e-5)" - style="display:inline" - id="Fill90"><g - transform="translate(4.3492649e-3,-6.9736349e-3)" - style="overflow:visible" - id="g83044"><rect - width="21.990196" - height="21.991766" - x="0.003928124" - y="-4.9961619" - style="fill:none" - id="rect83046" /><rect - width="18.004524" - height="10" - x="2.9954765" - y="1" - style="fill:url(#linearGradient83064);fill-opacity:1" - id="rect83048" /><rect - width="18.004524" - height="2" - x="2.9954765" - y="9" - style="fill:url(#linearGradient83062);fill-opacity:1" - id="rect83050" /></g></g><g - transform="translate(1.3686299e-4,4.672975e-5)" - style="display:inline" - id="Fill80"><g - transform="translate(4.3492649e-3,-6.9736349e-3)" - style="overflow:visible" - id="g83032"><rect - width="21.990196" - height="21.991766" - x="0.003928124" - y="-4.9961619" - style="fill:none" - id="rect83034" /><rect - width="15.988924" - height="10" - x="5.0110765" - y="1" - style="fill:url(#linearGradient83066);fill-opacity:1" - id="rect83036" /><rect - width="15.988924" - height="2" - x="5.0110765" - y="9" - style="fill:url(#linearGradient83068);fill-opacity:1" - id="rect83038" /></g></g><g - transform="translate(1.3686299e-4,4.672975e-5)" - style="display:inline" - id="Fill70"><g - transform="translate(4.3492649e-3,-6.9736349e-3)" - style="overflow:visible" - id="g32987"><rect - width="21.990196" - height="21.991766" - x="0.003928124" - y="-4.9961619" - style="fill:none" - id="rect83173" /><rect - width="14" - height="10" - x="7" - y="1" - style="fill:url(#linearGradient6655);fill-opacity:1" - id="rect5296" /><rect - width="14" - height="2" - x="7" - y="9" - style="fill:url(#linearGradient6651);fill-opacity:1" - id="rect5300" /></g></g><g - transform="translate(1.3686299e-4,4.672975e-5)" - style="display:inline" - id="Fill60"><g - transform="translate(-1.3686299e-4,-8.0465899e-4)" - style="overflow:visible" - id="g32990"><rect - width="12" - height="10" - x="9" - y="1" - style="fill:url(#linearGradient10117);fill-opacity:1" - id="rect9378" /><rect - width="12" - height="2" - x="9" - y="9" - style="fill:url(#linearGradient10113);fill-opacity:1" - id="rect9382" /></g><rect - width="21.990196" - height="21.991766" - x="0.003928124" - y="-4.9961619" - style="fill:none" - id="brect" /></g><g - transform="translate(1.3686299e-4,4.672975e-5)" - style="display:inline" - id="Fill50"><rect - width="21.990196" - height="21.991766" - x="0.003928124" - y="-4.9961619" - style="fill:none" - id="rect83163" /><g - transform="translate(3.2523847e-4,-9.9243469e-4)" - style="overflow:visible" - id="g32992"><rect - width="10" - height="10" - x="11" - y="1" - style="fill:url(#linearGradient9844);fill-opacity:1" - id="rect9394" /><rect - width="10" - height="2" - x="11" - y="9" - style="fill:url(#linearGradient9840);fill-opacity:1" - id="rect9398" /></g></g><g - style="display:inline" - id="Fill40"><g - transform="matrix(0.7985304,0,0,1,4.2311874,-9.9243469e-4)" - style="overflow:visible" - id="g16292"><rect - width="10" - height="10" - x="11" - y="1" - style="fill:url(#linearGradient16304);fill-opacity:1" - id="rect16294" /><rect - width="10" - height="2" - x="11" - y="9" - style="fill:url(#linearGradient16306);fill-opacity:1" - id="rect16296" /></g><rect - width="21.990196" - height="21.991766" - x="0.003928124" - y="-4.9961619" - style="fill:none" - id="rect16308" /></g><g - transform="translate(1.3686299e-4,4.672975e-5)" - style="display:inline" - id="Fill30"><g - transform="translate(0,1.1800146e-4)" - style="overflow:visible" - id="g33048"><rect - width="6" - height="10" - x="15" - y="1" - style="fill:url(#linearGradient7749);fill-opacity:1" - id="rect9426" /><rect - width="6" - height="2" - x="15" - y="9" - style="fill:url(#linearGradient7751);fill-opacity:1" - id="rect9430" /></g><rect - width="21.990196" - height="21.991766" - x="0.003928124" - y="-4.9961619" - style="fill:none" - id="rect17969" /></g><g - transform="translate(1.3686299e-4,4.672975e-5)" - style="display:inline" - id="Fill20"><rect - width="21.990196" - height="21.991766" - x="0.003928124" - y="-4.9961619" - style="fill:none" - id="boundrect" /><rect - width="4" - height="10" - x="17" - y="1" - style="fill:url(#linearGradient4787);fill-opacity:1" - id="rect33050" /></g><g - transform="translate(1.3686299e-4,4.672975e-5)" - style="display:inline" - id="Fill10"><g - transform="translate(-8.1659365e-3,-2.0281456e-2)" - style="overflow:visible" - id="g17775"><rect - width="2" - height="10" - x="19" - y="1" - style="fill:url(#linearGradient17814);fill-opacity:1" - id="rect17780" /><rect - width="2" - height="2" - x="19" - y="9" - style="fill:url(#linearGradient17816);fill-opacity:1" - id="rect17783" /></g><rect - width="21.990196" - height="21.991766" - x="0.003928124" - y="-4.9961619" - style="fill:none" - id="rect17818" /></g><g - style="display:inline" - id="AcAdapter"><g - transform="translate(1.3686299e-4,4.672975e-5)" - id="g81881"><path - d="M 16.121693,-4.8283693 C 13.684604,-3.5801574 9.63517,2.6825902 7,5.9943844 L 11.225525,6.397576 C 10.580558,9.2005486 9.762696,14.475723 8.570824,15.263474 C 11.030937,15.020018 15.63969,7.1348077 18.39671,3.5658063 L 13.62714,3.1633147 C 14.371019,0.63350016 15.038711,-3.2486895 16.121693,-4.8283693 z " - style="opacity:0.41803278;fill:#cf4913;fill-opacity:0.75;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - id="path9470" /><path - d="M 15.586715,-4.188275 C 13.41255,-2.5785363 10.316234,2.4353018 7.681064,5.7470959 L 11.561494,6.0845553 C 10.916527,8.8875278 10.37803,13.291754 9.613414,14.490327 C 11.153278,13.556682 15.135063,7.3647272 17.892084,3.7957258 L 13.355089,3.4011686 C 14.098964,0.87135406 14.503729,-2.6085952 15.586715,-4.188275 z " - style="fill:#e3ad00;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - id="path9472" /><path - d="M 15.586715,-4.188275 C 13.41255,-2.5785363 10.316234,2.4353018 7.681064,5.7470959 L 11.561494,6.0845553 C 10.916527,8.8875278 10.37803,13.291754 9.613414,14.490327 C 11.153278,13.556682 15.135063,7.3647272 17.892084,3.7957258 L 13.355089,3.4011686 C 14.098964,0.87135406 14.503729,-2.6085952 15.586715,-4.188275 z " - style="fill:url(#radialGradient7893);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - id="path9474" /><rect - width="21.997829" - height="21.996096" - ry="0" - x="0" - y="-4.9961433" - style="opacity:1;fill:none;fill-opacity:0.68235294" - id="rect81883" /></g></g><g - style="display:inline" - id="Shadow"><path - d="M 127.82442 115.70919 A 63.912209 12.641975 0 1 1 0,115.70919 A 63.912209 12.641975 0 1 1 127.82442 115.70919 z" - transform="matrix(0.172079,0,0,-8.975362e-2,0,26.2507)" - style="opacity:0.38139535;fill:url(#radialGradient10059);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" - id="path9618" /><rect - width="21.997829" - height="21.996096" - ry="0" - x="0" - y="-4.9961433" - style="opacity:1;fill:none;fill-opacity:0.68235294" - id="rect81886" /></g></svg> \ No newline at end of file Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream --- applets/battery/battery.h +++ applets/battery/battery.h @@ -28,6 +28,7 @@ #include <plasma/applet.h> #include <plasma/animator.h> #include <plasma/dataengine.h> +#include <plasma/dialog.h> #include "ui_batteryConfig.h" namespace Plasma @@ -35,6 +36,10 @@ class Svg; } + class QLabel; + class QComboBox; + class QSlider; + class Battery : public Plasma::Applet { Q_OBJECT @@ -46,15 +51,14 @@ void paintInterface(QPainter *painter, const QStyleOptionGraphicsItem *option, const QRect &contents); void setPath(const QString&); - QSizeF contentSizeHint() const; Qt::Orientations expandingDirections() const; - void constraintsEvent(Plasma::Constraints constraints); public slots: void dataUpdated(const QString &name, const Plasma::DataEngine::Data &data); protected Q_SLOTS: + virtual void mousePressEvent(QGraphicsSceneMouseEvent *event); virtual void hoverEnterEvent(QGraphicsSceneHoverEvent *event); virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent *event); void configAccepted(); @@ -62,6 +66,7 @@ protected: void createConfigurationInterface(KConfigDialog *parent); + void setEmbedded(const bool embedded); private slots: void animationUpdate(qreal progress); @@ -69,16 +74,32 @@ void batteryAnimationUpdate(qreal progress); void sourceAdded(const QString &source); void sourceRemoved(const QString &source); + void brightnessChanged(const int brightness); + void updateSlider(const float brightness); + void setFullBrightness(); + void openConfig(); + void setProfile(const QString &profile); + void suspend(); + void hibernate(); private: - Q_ENUMS( m_batteryStyle ) - enum ClockStyle { - // Keep the order of styles the same order as the items in the configdialog! - OxygenBattery, ClassicBattery - }; void connectSources(); void disconnectSources(); - int m_batteryStyle; + void initWidget(QWidget *widget); + void updateStatus(); + + /* Prevent creating infinite loops by embedding applets inside applets */ + bool m_isEmbedded; + QWidget *m_widget; + bool m_extenderVisible; + QString m_svgFile; + QLabel *m_statusLabel; + QLabel *m_batteryLabel; + QLabel *m_profileLabel; + QComboBox *m_profileCombo; + QSlider *m_brightnessSlider; + int m_inhibitCookie; + /* Paint battery with proper charge level */ void paintBattery(QPainter *p, const QRect &contentsRect, const int batteryPercent, const bool plugState); /* Paint a label on top of the battery */ @@ -100,6 +121,10 @@ Plasma::Svg* m_theme; bool m_acadapter_plugged; + QStringList m_availableProfiles; + QString m_currentProfile; + QStringList m_suspendMethods; + // Configuration dialog Ui::batteryConfig ui; @@ -120,6 +145,7 @@ QHash<QString, QHash<QString, QVariant> > m_batteries_data; QFont m_font; bool m_isHovered; + bool m_firstRun; QColor m_boxColor; QColor m_textColor; QRectF m_textRect; --- applets/battery/battery.cpp +++ applets/battery/battery.cpp @@ -1,7 +1,7 @@ /*************************************************************************** - * Copyright (C) 2007-2008 by Riccardo Iaconelli <riccardo@kde.org> * - * Copyright (C) 2007-2008 by Sebastian Kuegler <sebas@kde.org> * - * Copyright (C) 2007 by Luka Renko <lure@kubuntu.org> * + * Copyright 2007-2008 by Riccardo Iaconelli <riccardo@kde.org> * + * Copyright 2007-2008 by Sebastian Kuegler <sebas@kde.org> * + * Copyright 2007 by Luka Renko <lure@kubuntu.org> * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * @@ -22,28 +22,58 @@ #include "battery.h" #include <QApplication> +#include <QDBusConnection> +#include <QDBusInterface> #include <QPainter> #include <QStyleOptionGraphicsItem> #include <QFont> #include <QGraphicsSceneHoverEvent> +#include <QGraphicsGridLayout> +#include <QGraphicsLinearLayout> +#include <QTimer> +#include <QX11Info> #include <KDebug> #include <KIcon> #include <KLocalizedString> #include <KSharedConfig> +#include <KToolInvocation> #include <KDialog> #include <KColorScheme> #include <KConfigDialog> #include <KGlobalSettings> +#include <KPushButton> +#include <kworkspace/kworkspace.h> + +#include <solid/control/powermanager.h> +#include <solid/powermanagement.h> + #include <plasma/svg.h> #include <plasma/theme.h> #include <plasma/animator.h> +#include <QLabel> +#include <QSlider> +#include <QPushButton> +#include <QToolButton> +#include <QCheckBox> +#include <QComboBox> +#include <X11/Xlib.h> + Battery::Battery(QObject *parent, const QVariantList &args) : Plasma::Applet(parent, args), - m_batteryStyle(0), + m_isEmbedded(false), + m_widget(0), + m_extenderVisible(false), + m_svgFile(0), + m_statusLabel(0), + m_batteryLabel(0), + m_profileLabel(0), + m_profileCombo(0), m_theme(0), + m_availableProfiles(QStringList()), + m_currentProfile(0), m_animId(-1), m_alpha(1), m_fadeIn(false), @@ -54,33 +84,34 @@ m_batteryAlpha(1), m_batteryFadeIn(true), m_isHovered(false), + m_firstRun(true), m_numOfBattery(0) { kDebug() << "Loading applet battery"; setAcceptsHoverEvents(true); setHasConfigurationInterface(true); resize(128, 128); - //setAspectRatioMode(Plasma::ConstrainedSquare ); - m_textRect = QRect(); + setAspectRatioMode(Plasma::ConstrainedSquare ); + m_textRect = QRectF(); } void Battery::init() { KConfigGroup cg = config(); m_showBatteryString = cg.readEntry("showBatteryString", false); - m_showMultipleBatteries = cg.readEntry("showMultipleBatteries", true); + m_showMultipleBatteries = cg.readEntry("showMultipleBatteries", !m_isEmbedded); - QString svgFile = QString(); - if (cg.readEntry("style", 0) == 0) { - m_batteryStyle = OxygenBattery; - svgFile = "widgets/battery-oxygen"; - } else { - m_batteryStyle = ClassicBattery; - svgFile = "widgets/battery"; - } + m_svgFile = QString(); + + showBattery(false);; m_theme = new Plasma::Svg(this); - m_theme->setImagePath(svgFile); + m_theme->setImagePath("widgets/battery-oxygen"); m_theme->setContainsMultipleImages(false); + m_theme->resize(contentsRect().size()); + if (m_acadapter_plugged) { + showAcAdapter(true); + } + showBattery(true); m_theme->resize(contentsRect().size()); m_font = QApplication::font(); @@ -92,31 +123,56 @@ readColors(); connect(Plasma::Theme::defaultTheme(), SIGNAL(themeChanged()), SLOT(readColors())); - const QStringList& battery_sources = dataEngine("powermanagement")->query(I18N_NOOP("Battery"))[I18N_NOOP("sources")].toStringList(); + const QStringList& battery_sources = dataEngine("powermanagement")->query("Battery")["sources"].toStringList(); //connect sources connectSources(); foreach (const QString &battery_source, battery_sources) { - kDebug() << "BatterySource:" << battery_source; + //kDebug() << "BatterySource:" << battery_source; dataUpdated(battery_source, dataEngine("powermanagement")->query(battery_source)); } - dataUpdated(I18N_NOOP("AC Adapter"), dataEngine("powermanagement")->query(I18N_NOOP("AC Adapter"))); m_numOfBattery = battery_sources.size(); - kDebug() << battery_sources.size(); + + dataUpdated("AC Adapter", dataEngine("powermanagement")->query("AC Adapter")); + + if (!m_isEmbedded) { + m_widget = new QWidget(); + initWidget(m_widget); + m_widget->setWindowFlags(Qt::Popup); + } } void Battery::constraintsEvent(Plasma::Constraints constraints) { + //kDebug() << "ConstraintsEvent, Dude." << contentsRect(); if (constraints & (Plasma::FormFactorConstraint | Plasma::SizeConstraint)) { if (formFactor() == Plasma::Vertical) { - setMaximumSize(QWIDGETSIZE_MAX, qMax(m_textRect.height(), contentsRect().width())); + if (!m_showMultipleBatteries) { + setMinimumHeight(qMax(m_textRect.height(), size().width())); + } else { + setMinimumHeight(qMax(m_textRect.height(), size().width()*m_numOfBattery)); + } + setMinimumWidth(0); //kDebug() << "Vertical FormFactor"; } else if (formFactor() == Plasma::Horizontal) { - setMaximumSize(qMax(m_textRect.width(), contentsRect().height()), QWIDGETSIZE_MAX); + if (!m_showMultipleBatteries) { + setMinimumWidth(qMax(m_textRect.width(), size().height())); + } else { + setMinimumWidth(qMax(m_textRect.width(), size().height()*m_numOfBattery)); + } + setMinimumHeight(0); //kDebug() << "Horizontal FormFactor" << m_textRect.width() << contentsRect().height(); + } else { + setMaximumSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); + setMinimumSize(KIconLoader::SizeSmall, KIconLoader::SizeSmall); } } + if (!m_showMultipleBatteries || m_numOfBattery < 2) { + setAspectRatioMode(Plasma::Square); + } else { + setAspectRatioMode(Plasma::KeepAspectRatio); + } if (constraints & (Plasma::SizeConstraint | Plasma::FormFactorConstraint) && m_theme) { m_theme->resize(contentsRect().size().toSize()); @@ -127,26 +183,30 @@ void Battery::dataUpdated(const QString& source, const Plasma::DataEngine::Data &data) { - if (source.startsWith(I18N_NOOP("Battery"))) { + if (source.startsWith("Battery")) { m_batteries_data[source] = data; - } else if (source == I18N_NOOP("AC Adapter")) { - m_acadapter_plugged = data[I18N_NOOP("Plugged in")].toBool(); + } else if (source == "AC Adapter") { + m_acadapter_plugged = data["Plugged in"].toBool(); showAcAdapter(m_acadapter_plugged); + } else if (source == "PowerDevil") { + m_availableProfiles = data["availableProfiles"].toStringList(); + m_currentProfile = data["currentProfile"].toString(); + //kDebug() << "PowerDevil profiles:" << m_availableProfiles << "[" << m_currentProfile << "]"; } else { kDebug() << "Applet::Dunno what to do with " << source; } + updateStatus(); update(); } void Battery::createConfigurationInterface(KConfigDialog *parent) { - QWidget *widget = new QWidget(); + QWidget *widget = new QWidget(parent); ui.setupUi(widget); parent->setButtons( KDialog::Ok | KDialog::Cancel | KDialog::Apply ); - parent->addPage(widget, parent->windowTitle(), icon()); + parent->addPage(widget, parent->windowTitle(), Applet::icon()); connect(parent, SIGNAL(applyClicked()), this, SLOT(configAccepted())); connect(parent, SIGNAL(okClicked()), this, SLOT(configAccepted())); - ui.styleGroup->setSelected(m_batteryStyle); ui.showBatteryStringCheckBox->setChecked(m_showBatteryString ? Qt::Checked : Qt::Unchecked); ui.showMultipleBatteriesCheckBox->setChecked(m_showMultipleBatteries ? Qt::Checked : Qt::Unchecked); } @@ -165,32 +225,9 @@ m_showMultipleBatteries = !m_showMultipleBatteries; cg.writeEntry("showMultipleBatteries", m_showMultipleBatteries); kDebug() << "Show multiple battery changed: " << m_showMultipleBatteries; + emit sizeHintChanged(Qt::PreferredSize); } - if (ui.styleGroup->selected() != m_batteryStyle) { - QString svgFile = QString(); - if (ui.styleGroup->selected() == OxygenBattery) { - svgFile = "widgets/battery-oxygen"; - } else { - svgFile = "widgets/battery"; - } - if (m_acadapter_plugged) { - showAcAdapter(false); - } - showBattery(false); - m_batteryStyle = ui.styleGroup->selected(); - delete m_theme; - m_theme = new Plasma::Svg(this); - m_theme->setImagePath(svgFile); - kDebug() << "Changing theme to " << svgFile; - cg.writeEntry("style", m_batteryStyle); - m_theme->resize(contentsRect().size()); - if (m_acadapter_plugged) { - showAcAdapter(true); - } - showBattery(true); - } - //reconnect sources disconnectSources(); connectSources(); @@ -227,8 +264,290 @@ Battery::~Battery() { + delete m_widget; } +void Battery::suspend() +{ + XUngrabKeyboard( QX11Info::display(), QX11Info::appTime()); + XUngrabPointer( QX11Info::display(), QX11Info::appTime()); + XSync( QX11Info::display(), False ); + QDBusConnection dbus( QDBusConnection::sessionBus() ); + QDBusInterface iface( "org.kde.kded", "/modules/powerdevil", "org.kde.PowerDevil", dbus ); + iface.call( "suspend", Solid::Control::PowerManager::ToRam ); +} + +void Battery::hibernate() +{ + XUngrabKeyboard( QX11Info::display(), QX11Info::appTime()); + XUngrabPointer( QX11Info::display(), QX11Info::appTime()); + XSync( QX11Info::display(), False ); + QDBusConnection dbus( QDBusConnection::sessionBus() ); + QDBusInterface iface( "org.kde.kded", "/modules/powerdevil", "org.kde.PowerDevil", dbus ); + iface.call( "suspend", Solid::Control::PowerManager::ToDisk ); +} + +void Battery::brightnessChanged(const int brightness) +{ + Solid::Control::PowerManager::setBrightness(brightness); +} + +void Battery::updateSlider(const float brightness) +{ + m_brightnessSlider->setValue((int) brightness); +} + +void Battery::setFullBrightness() +{ + brightnessChanged(100); + updateSlider(100); +} + +void Battery::setEmbedded(const bool embedded) +{ + m_isEmbedded = embedded; +} + +void Battery::initWidget(QWidget *controls) +{ + // We only show the extender for applets that are not embedded, as + // that would create infinitve loops, you really don't want an applet + // extender when the applet is embedded into another applet, such + // as the battery applet is also embedded into the battery's extender. + if (!m_isEmbedded) { + int row = 0; + int rowHeight = 20; + int columnWidth = 80; + + QGridLayout *controlsLayout = new QGridLayout(controls); + controls->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + + QLabel *headerLabel = new QLabel(controls); + headerLabel->setText(i18n("Power Management")); + QFont font = headerLabel->font(); + font.setBold(true); + headerLabel->setFont(font); + headerLabel->setWordWrap(false); + QGridLayout *headerLayout = new QGridLayout(controls); + headerLayout->setColumnMinimumWidth(0, columnWidth/2); + headerLayout->addWidget(headerLabel, 0, 1, Qt::AlignLeft); + controlsLayout->addItem(headerLayout, row, 1, 1, 2); + row++; + + controlsLayout->setColumnMinimumWidth(0, rowHeight); + controlsLayout->setColumnMinimumWidth(1, 2*columnWidth); + controlsLayout->setColumnMinimumWidth(2, rowHeight); + controlsLayout->setHorizontalSpacing(0); + QGridLayout *batteryLayout = new QGridLayout(controls); + batteryLayout->setColumnMinimumWidth(0, 100); + batteryLayout->setColumnMinimumWidth(1, columnWidth); + batteryLayout->setRowMinimumHeight(row, 20); + m_batteryLabel = new QLabel(controls); + m_batteryLabel->setMinimumSize(160, 60); + m_batteryLabel->setWordWrap(false); + m_batteryLabel->setAlignment(Qt::AlignTop); + + batteryLayout->addWidget(m_batteryLabel, 0, 0, 1, 1, Qt::AlignLeft); + controlsLayout->addItem(batteryLayout, row, 0, 1, 3); + row++; + + QLabel *brightnessLabel = new QLabel(controls); + brightnessLabel->setText(i18n("Screen Brightness")); + brightnessLabel->setWordWrap(false); + controlsLayout->addWidget(brightnessLabel, row, 0, 1, 3); + brightnessLabel->setWordWrap(false); + row++; + + m_brightnessSlider = new QSlider(controls); + m_brightnessSlider->setRange(0, 100); + m_brightnessSlider->setValue(Solid::Control::PowerManager::brightness()); + m_brightnessSlider->setTickInterval(10); + m_brightnessSlider->setOrientation(Qt::Horizontal); + connect(m_brightnessSlider, SIGNAL(valueChanged(int)), + this, SLOT(brightnessChanged(int))); + + Solid::Control::PowerManager::Notifier *notifier = Solid::Control::PowerManager::notifier(); + + connect(notifier, SIGNAL(brightnessChanged(float)), + this, SLOT(updateSlider(float))); + controlsLayout->addWidget(m_brightnessSlider, row, 1, 1, 1); + + QToolButton *brightnessIcon = new QToolButton(controls); + brightnessIcon->setIcon(KIcon("ktip")); + connect(brightnessIcon, SIGNAL(clicked()), + this, SLOT(setFullBrightness())); + brightnessIcon->setMinimumSize(rowHeight, rowHeight); + controlsLayout->addWidget(brightnessIcon, row, 2, 1, 1); + controlsLayout->setSpacing(10); + row++; + + m_profileLabel = new QLabel(controls); + m_profileLabel->setText(i18n("Power Profile")); + controlsLayout->addWidget(m_profileLabel, row, 0, 1, 3); + row++; + + m_profileCombo = new QComboBox(controls); + connect(m_profileCombo, SIGNAL(activated(QString)), + this, SLOT(setProfile(QString))); + + controlsLayout->addWidget(m_profileCombo, row, 1, 1, 2); + row++; + + QLabel *actionsLabel = new QLabel(controls); + actionsLabel->setText(i18n("Actions")); + actionsLabel->setWordWrap(false); + controlsLayout->addWidget(actionsLabel, row, 0, 1, 3); + row++; + + QGridLayout *actionsLayout = new QGridLayout(controls); + + // Sleep and Hibernate buttons + QSet<Solid::PowerManagement::SleepState> sleepstates = Solid::PowerManagement::supportedSleepStates(); + foreach (const Solid::PowerManagement::SleepState &sleepstate, sleepstates) { + if (sleepstate == Solid::PowerManagement::StandbyState) { + // Not interesting at this point ... + + } else if (sleepstate == Solid::PowerManagement::SuspendState) { + QToolButton *suspendButton = new QToolButton(controls); + suspendButton->setIcon(KIcon("system-suspend")); + suspendButton->setText(i18n("Sleep")); + suspendButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); + suspendButton->setMaximumHeight(36); + actionsLayout->addWidget(suspendButton, 0, 0); + connect(suspendButton, SIGNAL(clicked()), this, SLOT(suspend())); + } else if (sleepstate == Solid::PowerManagement::HibernateState) { + QToolButton *hibernateButton = new QToolButton(controls); + hibernateButton->setIcon(KIcon("system-suspend-hibernate")); + hibernateButton->setText(i18n("Hibernate")); + hibernateButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); + hibernateButton->setMaximumHeight(36); + actionsLayout->addWidget(hibernateButton, 0, 1); + connect(hibernateButton, SIGNAL(clicked()), this, SLOT(hibernate())); + } + } + controlsLayout->addItem(actionsLayout, row, 1, 1, 2); + row++; + + // More settings button + QToolButton *configButton = new QToolButton(controls); + configButton->setText(i18n("Configure...")); + configButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); + configButton->setMaximumHeight(36); + configButton->setIcon(KIcon("preferences-system-power-management")); + configButton->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); + connect(configButton, SIGNAL(clicked()), this, SLOT(openConfig())); + + QGridLayout *moreLayout = new QGridLayout(controls); + moreLayout->setColumnMinimumWidth(0, columnWidth); + moreLayout->addWidget(configButton, 0, 1, Qt::AlignLeft); + + controlsLayout->addItem(moreLayout, row, 1, 1, 2); + + controls->setLayout(controlsLayout); + } +} + +void Battery::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + if (event->buttons() == Qt::LeftButton) { + if (m_widget->isVisible()) { + m_widget->hide(); + m_extenderVisible = false; + } else { + m_widget->move(popupPosition(m_widget->sizeHint())); + m_widget->show(); + m_extenderVisible = true; + updateStatus(); + } + } + Applet::mousePressEvent(event); +} + +void Battery::updateStatus() +{ + if (!m_extenderVisible) { + return; + } + + if (m_numOfBattery && m_batteryLabel) { + QHashIterator<QString, QHash<QString, QVariant > > battery_data(m_batteries_data); + QString batteryLabelText = QString("<br />"); + int bnum = 0; + while (battery_data.hasNext()) { + bnum++; + battery_data.next(); + QString state = battery_data.value()["State"].toString(); + if (m_numOfBattery == 1) { + if (battery_data.value()["Plugged in"].toBool()) { + if (state == "NoCharge") { + batteryLabelText.append(i18n("<b>Battery:</b> %1% (fully charged)", battery_data.value()["Percent"].toString())); + } else if (state == "Discharging") { + batteryLabelText.append(i18n("<b>Battery:</b> %1% (discharging)", battery_data.value()["Percent"].toString())); + } else { + batteryLabelText.append(i18n("<b>Battery:</b> %1% (charging)", battery_data.value()["Percent"].toString())); + } + } else { + batteryLabelText.append(i18nc("Battery is not plugged in", "<b>Battery:</b> not present")); + } + } else { + if (state == "NoCharge") { + batteryLabelText.append(i18n("<b>Battery %1:</b> %2% (fully charged)", bnum, battery_data.value()["Percent"].toString())); + } else if (state == "Discharging") { + batteryLabelText.append(i18n("<b>Battery %1:</b> %2% (discharging)", bnum, battery_data.value()["Percent"].toString())); + } else { + batteryLabelText.append(i18n("<b>Battery %1:</b> %2% (charging)", bnum, battery_data.value()["Percent"].toString())); + } + } + + if (m_acadapter_plugged) { + batteryLabelText.append(i18n("<br /><b>AC Adapter:</b> Plugged in")); + } else { + batteryLabelText.append(i18n("<br /><b>AC Adapter:</b> Not plugged in")); + } + } + m_batteryLabel->setText(batteryLabelText); + } + + if (!m_availableProfiles.empty() && m_profileCombo) { + m_profileCombo->clear(); + m_profileCombo->addItem(m_currentProfile); + foreach (const QString &p, m_availableProfiles) { + if (m_currentProfile != p) { + m_profileCombo->addItem(p); + } + } + } + + if (m_profileLabel && m_profileCombo) { + if (m_availableProfiles.empty()) { + m_profileCombo->hide(); + m_profileLabel->hide(); + } else { + m_profileCombo->show(); + m_profileLabel->show(); + } + } +} + +void Battery::openConfig() +{ + kDebug() << "opening powermanagement configuration dialog"; + QStringList args; + args << "powerdevilconfig"; + KToolInvocation::kdeinitExec("kcmshell4", args); +} + +void Battery::setProfile(const QString &profile) +{ + if (m_currentProfile != profile) { + kDebug() << "Changing power profile to " << profile; + QDBusConnection dbus( QDBusConnection::sessionBus() ); + QDBusInterface iface( "org.kde.kded", "/modules/powerdevil", "org.kde.PowerDevil", dbus ); + iface.call( "refreshStatus" ); + iface.call( "setProfile", profile ); + } +} + void Battery::showLabel(bool show) { if (m_fadeIn == show) { @@ -245,7 +564,8 @@ "animationUpdate"); } -QRectF Battery::scaleRectF(const qreal progress, QRectF rect) { +QRectF Battery::scaleRectF(const qreal progress, QRectF rect) +{ if (progress == 1) { return rect; } @@ -269,7 +589,7 @@ return; } m_acFadeIn = show; - const int FadeInDuration = 300; + const int FadeInDuration = 600; // As long as the animation is running, we fake it's still plugged in so it gets // painted in paintInterface() m_acadapter_plugged = true; @@ -323,6 +643,7 @@ // now the animation has ended, we _really_ set it to not show the adapter if (!m_acFadeIn && (progress == 1)) { m_acadapter_plugged = false; + updateStatus(); } update(); } @@ -368,12 +689,19 @@ } p->setFont(m_font); - // Let's find a good position for painting the background + // Let's find a good position for painting the percentage on top of the battery m_textRect = QRectF(qMax(qreal(0.0), contentsRect.left() + (contentsRect.width() - text_width) / 2), contentsRect.top() + ((contentsRect.height() - (int)fm.height()) / 2 * 0.9), qMin(contentsRect.width(), (int)text_width), fm.height() * 1.2 ); + //kDebug() << contentsRect << m_textRect; + //p->setBrush(QColor("green")); + //p->drawRect(m_textRect); + if (m_firstRun) { + m_firstRun = false; + return; + } // Poor man's highlighting m_boxColor.setAlphaF(m_alpha); p->setPen(m_boxColor); @@ -402,41 +730,17 @@ if (plugState && m_theme->hasElement("Battery")) { m_theme->paint(p, scaleRectF(m_batteryAlpha, contentsRect), "Battery"); - if (m_batteryStyle == OxygenBattery) { - if (batteryPercent > 95) { - fill_element = "Fill100"; - } else if (batteryPercent > 80) { - fill_element = "Fill80"; - } else if (batteryPercent > 50) { - fill_element = "Fill60"; - } else if (batteryPercent > 20) { - fill_element = "Fill40"; - } else if (batteryPercent > 10) { - fill_element = "Fill20"; - } // Don't show a fillbar below 11% charged - } else { // OxyenStyle - if (batteryPercent > 95) { - fill_element = "Fill100"; - } else if (batteryPercent > 90) { - fill_element = "Fill90"; - } else if (batteryPercent > 80) { - fill_element = "Fill80"; - } else if (batteryPercent > 70) { - fill_element = "Fill70"; - } else if (batteryPercent > 55) { - fill_element = "Fill60"; - } else if (batteryPercent > 40) { - fill_element = "Fill50"; - } else if (batteryPercent > 30) { - fill_element = "Fill40"; - } else if (batteryPercent > 20) { - fill_element = "Fill30"; - } else if (batteryPercent > 10) { - fill_element = "Fill20"; - } else if (batteryPercent >= 5) { - fill_element = "Fill10"; - } // Lower than 5%? Show no fillbar. - } + if (batteryPercent > 95) { + fill_element = "Fill100"; + } else if (batteryPercent > 80) { + fill_element = "Fill80"; + } else if (batteryPercent > 50) { + fill_element = "Fill60"; + } else if (batteryPercent > 20) { + fill_element = "Fill40"; + } else if (batteryPercent > 10) { + fill_element = "Fill20"; + } // Don't show a fillbar below 11% charged } //kDebug() << "plugState:" << plugState; @@ -479,11 +783,11 @@ m_theme->paint(p, ac_contentsRect, "AcAdapter"); } // Show that there's no battery - paintLabel(p, contentsRect, I18N_NOOP("n/a")); + paintLabel(p, contentsRect, "n/a"); return; } - if (m_showMultipleBatteries) { + if (m_isEmbedded || m_showMultipleBatteries || m_firstRun) { // paint each battery with own charge level int battery_num = 0; int width = contentsRect.width()/m_numOfBattery; @@ -495,16 +799,16 @@ width, contentsRect.height()); // paint battery with appropriate charge level - paintBattery(p, corect, battery_data.value()[I18N_NOOP("Percent")].toInt(), battery_data.value()[I18N_NOOP("Plugged in")].toBool()); + paintBattery(p, corect, battery_data.value()["Percent"].toInt(), battery_data.value()["Plugged in"].toBool()); - if (m_showBatteryString || m_isHovered) { + if (m_showBatteryString || m_isHovered || m_firstRun) { // Show the charge percentage with a box on top of the battery QString batteryLabel; - if (battery_data.value()[I18N_NOOP("Plugged in")].toBool()) { - batteryLabel = battery_data.value()[I18N_NOOP("Percent")].toString(); + if (battery_data.value()["Plugged in"].toBool()) { + batteryLabel = battery_data.value()["Percent"].toString(); batteryLabel.append("%"); } else { - batteryLabel = I18N_NOOP("n/a"); + batteryLabel = "n/a"; } paintLabel(p, corect, batteryLabel); } @@ -518,8 +822,8 @@ QHashIterator<QString, QHash<QString, QVariant > > battery_data(m_batteries_data); while (battery_data.hasNext()) { battery_data.next(); - if (battery_data.value()[I18N_NOOP("Plugged in")].toBool()) { - battery_charge += battery_data.value()[I18N_NOOP("Percent")].toInt(); + if (battery_data.value()["Plugged in"].toBool()) { + battery_charge += battery_data.value()["Percent"].toInt(); has_battery = true; ++battery_num; } @@ -529,28 +833,30 @@ } // paint battery with appropriate charge level paintBattery(p, contentsRect, battery_charge, has_battery); - if (m_showBatteryString || m_isHovered) { + if (m_isEmbedded || m_showBatteryString || m_isHovered) { // Show the charge percentage with a box on top of the battery QString batteryLabel; - if(has_battery) { + if (has_battery) { batteryLabel = QString::number(battery_charge); batteryLabel.append("%"); } else { - batteryLabel = I18N_NOOP("n/a"); + batteryLabel = "n/a"; } paintLabel(p, contentsRect, batteryLabel); } } } -void Battery::connectSources() { - const QStringList& battery_sources = dataEngine("powermanagement")->query(I18N_NOOP("Battery"))[I18N_NOOP("sources")].toStringList(); +void Battery::connectSources() +{ + const QStringList& battery_sources = dataEngine("powermanagement")->query("Battery")["sources"].toStringList(); foreach (const QString &battery_source, battery_sources) { dataEngine("powermanagement")->connectSource(battery_source, this); } - dataEngine("powermanagement")->connectSource(I18N_NOOP("AC Adapter"), this); + dataEngine("powermanagement")->connectSource("AC Adapter", this); + dataEngine("powermanagement")->connectSource("PowerDevil", this); connect(dataEngine("powermanagement"), SIGNAL(sourceAdded(QString)), this, SLOT(sourceAdded(QString))); @@ -560,13 +866,14 @@ void Battery::disconnectSources() { - const QStringList& battery_sources = dataEngine("powermanagement")->query(I18N_NOOP("Battery"))[I18N_NOOP("sources")].toStringList(); + const QStringList& battery_sources = dataEngine("powermanagement")->query("Battery")["sources"].toStringList(); foreach (const QString &battery_source ,battery_sources) { dataEngine("powermanagement")->disconnectSource(battery_source, this); } - dataEngine("powermanagement")->disconnectSource(I18N_NOOP("AC Adapter"), this); + dataEngine("powermanagement")->disconnectSource("AC Adapter", this); + dataEngine("powermanagement")->disconnectSource("PowerDevil", this); disconnect(SLOT(sourceAdded(QString))); disconnect(SLOT(sourceRemoved(QString))); @@ -578,15 +885,20 @@ dataEngine("powermanagement")->connectSource(source, this); m_numOfBattery++; } + if (source == "PowerDevil") { + dataEngine("powermanagement")->connectSource(source, this); + } } void Battery::sourceRemoved(const QString& source) { - if (m_batteries_data.contains(source)) { - m_batteries_data.remove(source); + if (m_batteries_data.remove(source)) { m_numOfBattery--; update(); } + if (source == "PowerDevil") { + dataEngine("powermanagement")->disconnectSource(source, this); + } } #include "battery.moc" --- applets/battery/batteryConfig.ui +++ applets/battery/batteryConfig.ui @@ -6,7 +6,7 @@ <x>0</x> <y>0</y> <width>363</width> - <height>134</height> + <height>80</height> </rect> </property> <property name="windowTitle" > @@ -15,7 +15,7 @@ <property name="accessibleName" > <string>Configure Battery Monitor</string> </property> - <layout class="QVBoxLayout" > + <layout class="QVBoxLayout" name="verticalLayout" > <item> <widget class="QCheckBox" name="showBatteryStringCheckBox" > <property name="toolTip" > @@ -37,38 +37,20 @@ </widget> </item> <item> - <widget class="KButtonGroup" name="styleGroup" > - <layout class="QVBoxLayout" > - <item> - <widget class="QRadioButton" name="oxygenBattery" > - <property name="text" > - <string>Oxygen theme</string> - </property> - <property name="checked" > - <bool>true</bool> - </property> - </widget> - </item> - <item> - <widget class="QRadioButton" name="classicBattery" > - <property name="text" > - <string>Classic theme</string> - </property> - </widget> - </item> - </layout> - </widget> + <spacer name="verticalSpacer" > + <property name="orientation" > + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0" > + <size> + <width>20</width> + <height>15</height> + </size> + </property> + </spacer> </item> </layout> </widget> - <customwidgets> - <customwidget> - <class>KButtonGroup</class> - <extends>QGroupBox</extends> - <header>kbuttongroup.h</header> - <container>1</container> - </customwidget> - </customwidgets> <resources/> <connections/> </ui> --- applets/battery/CMakeLists.txt +++ applets/battery/CMakeLists.txt @@ -5,13 +5,12 @@ kde4_add_ui_files(battery_SRCS batteryConfig.ui ) kde4_add_plugin(plasma_applet_battery ${battery_SRCS}) -target_link_libraries(plasma_applet_battery plasma ${KDE4_KIO_LIBS}) +target_link_libraries(plasma_applet_battery plasma ${KDE4_KIO_LIBS} ${KDE4_SOLID_LIBS} solidcontrol) install(TARGETS plasma_applet_battery DESTINATION ${PLUGIN_INSTALL_DIR}) install(FILES plasma-battery-default.desktop DESTINATION ${SERVICES_INSTALL_DIR}) install(FILES - battery.svg battery-oxygen.svg DESTINATION ${DATA_INSTALL_DIR}/desktoptheme/default/widgets/) --- applets/kickoff/simpleapplet/menuview.cpp +++ applets/kickoff/simpleapplet/menuview.cpp @@ -143,7 +143,7 @@ action->setText(name); } else { // seems we have a perfect desktop-file (likely a KDE one, heh) and name+description are clear separated if (d->formattype == NameDescription) { - action->setText(QString("%1 %2").arg(name).arg(text)); + action->setText(QString("%1 (%2)").arg(name).arg(text)); } else { action->setText(QString("%1 (%2)").arg(text).arg(name)); } --- applets/kickoff/simpleapplet/simpleapplet.cpp +++ applets/kickoff/simpleapplet/simpleapplet.cpp @@ -31,6 +31,7 @@ #include <QMetaEnum> #include <QPointer> #include <QGraphicsLinearLayout> +#include <QFile> // KDE #include <KIcon> @@ -133,7 +134,10 @@ QString viewIcon() { switch( viewtype ) { case Combined: - return "start-here-kde"; + if (QFile::exists("/usr/share/icons/oxygen/scalable/places/start-here-branding.svg")) + return "start-here-branding"; + else + return "start-here-kde"; case Favorites: return "bookmarks"; case Applications: @@ -274,7 +278,7 @@ formatLabel->setBuddy(d->formatComboBox); d->addItem(d->formatComboBox, i18nc("@item:inlistbox Format:", "Name Only"), MenuLauncherApplet::Name); d->addItem(d->formatComboBox, i18nc("@item:inlistbox Format:", "Description Only"), MenuLauncherApplet::Description); - d->addItem(d->formatComboBox, i18nc("@item:inlistbox Format:", "Name Description"), MenuLauncherApplet::NameDescription); + d->addItem(d->formatComboBox, i18nc("@item:inlistbox Format:", "Name (Description)"), MenuLauncherApplet::NameDescription); d->addItem(d->formatComboBox, i18nc("@item:inlistbox Format:", "Description (Name)"), MenuLauncherApplet::DescriptionName); l->addWidget(d->formatComboBox, 1, 1); --- applets/kickoff/applet/applet.cpp +++ applets/kickoff/applet/applet.cpp @@ -29,6 +29,7 @@ #include <QVBoxLayout> #include <QLabel> #include <QGraphicsLinearLayout> +#include <QFile> // KDE #include <KIcon> @@ -41,6 +42,7 @@ #include <plasma/widgets/icon.h> #include <plasma/containment.h> #include <plasma/view.h> +#include <plasma/tooltipmanager.h> // Local #include "ui/launcher.h" @@ -55,10 +57,12 @@ KIntNumInput *visibleCountEdit; QList<QAction*> actions; QAction* switcher; + LauncherApplet *q; - Private() : launcher(0), switcher(0) {} + Private(LauncherApplet *lApplet) : launcher(0), switcher(0), q(lApplet) {} ~Private() { delete launcher; } void createLauncher(LauncherApplet *q); + void initToolTip(); }; void LauncherApplet::Private::createLauncher(LauncherApplet *q) @@ -71,15 +75,28 @@ QObject::connect(launcher, SIGNAL(configNeedsSaving()), q, SIGNAL(configNeedsSaving())); } + +void LauncherApplet::Private::initToolTip() +{ + Plasma::ToolTipManager::ToolTipContent data; + data.mainText = i18n("Application Launcher"); + data.subText = i18n("Favorites, applications, computer places, recently used items and desktop sessions"); + data.image = KIcon(q->icon()).pixmap(IconSize(KIconLoader::Desktop)); + Plasma::ToolTipManager::self()->setToolTipContent(q, data); +} + LauncherApplet::LauncherApplet(QObject *parent, const QVariantList &args) : Plasma::Applet(parent,args), - d(new Private) + d(new Private(this)) { KGlobal::locale()->insertCatalog("plasma_applet_launcher"); setHasConfigurationInterface(true); setBackgroundHints(NoBackground); - d->icon = new Plasma::Icon(KIcon("start-here-kde"), QString(), this); + if (QFile::exists("/usr/share/icons/oxygen/scalable/places/start-here-branding.svg")) + d->icon = new Plasma::Icon(KIcon("start-here-branding"), QString(), this); + else + d->icon = new Plasma::Icon(KIcon("start-here-kde"), QString(), this); d->icon->setFlag(ItemIsMovable, false); connect(d->icon, SIGNAL(pressed(bool)), this, SLOT(toggleMenu(bool))); connect(this, SIGNAL(activate()), this, SLOT(toggleMenu())); @@ -113,6 +130,8 @@ connect(d->switcher, SIGNAL(triggered(bool)), this, SLOT(switchMenuStyle())); resize(IconSize(KIconLoader::Desktop),IconSize(KIconLoader::Desktop)); d->icon->resize(contentsRect().size()); + + Plasma::ToolTipManager::self()->registerWidget(this); } void LauncherApplet::constraintsEvent(Plasma::Constraints constraints) @@ -170,6 +189,15 @@ d->switchOnHoverCheckBox->setChecked(d->launcher->switchTabsOnHover()); } +void LauncherApplet::toolTipAboutToShow() +{ + if (d->launcher && d->launcher->isVisible()) { + Plasma::ToolTipManager::self()->clearToolTipContent(this); + } else { + d->initToolTip(); + } +} + void LauncherApplet::configAccepted() { bool switchTabsOnHover = d->switchOnHoverCheckBox->isChecked(); @@ -197,6 +225,7 @@ void LauncherApplet::toggleMenu() { if (!d->launcher) { + Plasma::ToolTipManager::self()->clearToolTipContent(this); d->createLauncher(this); } --- applets/kickoff/applet/plasma-applet-launcher.desktop +++ applets/kickoff/applet/plasma-applet-launcher.desktop @@ -96,7 +96,7 @@ Comment[nds]=Röppt Programmen op Comment[ne]=अनुप्रयोग सुरुआत गर्न सुरुआतकर्ता Comment[nl]=Applet voor het starten van programma's -Comment[nn]=Start program +Comment[nn]=Moderne programstartar Comment[pa]=ਐਪਲੀਕੇਸ਼ਨ ਚਲਾਉਣ ਲਈ ਲਾਂਚਰ Comment[pl]=Uruchamianie programów Comment[pt]=Lançador para iniciar aplicações --- applets/kickoff/applet/applet.h +++ applets/kickoff/applet/applet.h @@ -53,6 +53,7 @@ public slots: void switchMenuStyle(); void startMenuEditor(); + void toolTipAboutToShow(); protected slots: void configAccepted(); --- applets/kickoff/core/systemmodel.cpp +++ applets/kickoff/core/systemmodel.cpp @@ -87,7 +87,7 @@ connect(placesModel, SIGNAL(rowsRemoved(QModelIndex,int,int)), q, SLOT(sourceRowsRemoved(QModelIndex,int,int))); - topLevelSections << i18n("Applications") + topLevelSections << i18n("Administration") << i18n("Places") << i18n("Removable Storage") << i18n("Storage"); @@ -248,17 +248,32 @@ KService::Ptr service = d->appsList[index.row()]; - switch(role) { - case Qt::DisplayRole: - return service->name(); - case Qt::DecorationRole: - return KIcon(service->icon()); - case SubTitleRole: - return service->genericName(); - case UrlRole: - return service->entryPath(); - default: - return QVariant(); + if (service->name()=="sysinfo") { + switch(role) { + case Qt::DisplayRole: + return i18n("System Information"); + case Qt::DecorationRole: + return KIcon("hwinfo"); + case SubTitleRole: + return "sysinfo:/"; + case UrlRole: + return "sysinfo:/"; + default: + return QVariant(); + } + } else { + switch(role) { + case Qt::DisplayRole: + return service->name(); + case Qt::DecorationRole: + return KIcon(service->icon()); + case SubTitleRole: + return service->genericName(); + case UrlRole: + return service->entryPath(); + default: + return QVariant(); + } } } --- applets/kickoff/core/leavemodel.cpp +++ applets/kickoff/core/leavemodel.cpp @@ -27,6 +27,8 @@ #include <KLocalizedString> #include <KIcon> #include <solid/powermanagement.h> +#include <solid/control/powermanager.h> +#include <KConfigGroup> // Local #include "core/models.h" @@ -42,7 +44,7 @@ //Q_ASSERT(KUrl(url).scheme() == "leave"); QStandardItem *item = new QStandardItem(); const QString basename = QFileInfo(url).baseName(); - if (basename == "logout") { + if (basename == "logoutonly") { item->setText(i18n("Logout")); item->setIcon(KIcon("system-log-out")); item->setData(i18n("End session"),Kickoff::SubTitleRole); @@ -60,12 +62,12 @@ else if (basename == "sleep") { item->setText(i18n("Sleep")); item->setIcon(KIcon("system-suspend")); - item->setData(url,Kickoff::SubTitleRole); + item->setData(i18n("Suspend to RAM"),Kickoff::SubTitleRole); } else if (basename == "hibernate") { item->setText(i18n("Hibernate")); item->setIcon(KIcon("system-suspend-hibernate")); - item->setData(url,Kickoff::SubTitleRole); + item->setData(i18n("Suspend to Disk"),Kickoff::SubTitleRole); } else if (basename == "shutdown") { item->setText(i18n("Shutdown")); @@ -77,6 +79,26 @@ item->setIcon(KIcon("system-restart")); item->setData(i18n("Restart the computer"),Kickoff::SubTitleRole); } + else if (basename == "savesession") { + item->setText(i18n("Save Session")); + item->setIcon(KIcon("document-save")); + item->setData(i18n("Save current session for next login"),Kickoff::SubTitleRole); + } + else if (basename == "standby") { + item->setText(i18n("Standby")); + item->setIcon(KIcon("system-suspend")); + item->setData(i18n("Pause without logging out"),Kickoff::SubTitleRole); + } + else if (basename == "suspenddisk") { + item->setText(i18n("Suspend to Disk")); + item->setIcon(KIcon("system-suspend-hibernate")); + item->setData(i18n("Pause without logging out"),Kickoff::SubTitleRole); + } + else if (basename == "suspendram") { + item->setText(i18n("Suspend to RAM")); + item->setIcon(KIcon("system-suspend-hibernate")); + item->setData(i18n("Pause without logging out"),Kickoff::SubTitleRole); + } else { item->setText(basename); item->setData(url,Kickoff::SubTitleRole); @@ -89,17 +111,30 @@ : QStandardItemModel(parent) , d(0) { +} + +void LeaveModel::updateModel() +{ + clear(); + // Session Options QStandardItem *sessionOptions = new QStandardItem(i18n("Session")); // Logout - QStandardItem *logoutOption = createStandardItem("leave:/logout"); + QStandardItem *logoutOption = createStandardItem("leave:/logoutonly"); sessionOptions->appendRow(logoutOption); // Lock QStandardItem *lockOption = createStandardItem("leave:/lock"); sessionOptions->appendRow(lockOption); + // Save Session + KConfigGroup c(KSharedConfig::openConfig("ksmserverrc", KConfig::NoGlobals), "General"); + if (c.readEntry( "loginMode") == "restoreSavedSession") { + QStandardItem *saveSessionOption = createStandardItem("leave:/savesession"); + sessionOptions->appendRow(saveSessionOption); + } + // Switch User QStandardItem *switchUserOption = createStandardItem("leave:/switch"); sessionOptions->appendRow(switchUserOption); @@ -122,6 +157,24 @@ systemOptions->appendRow(hibernateOption); } + Solid::Control::PowerManager::SuspendMethods spdMethods = Solid::Control::PowerManager::supportedSuspendMethods(); + if( spdMethods & Solid::Control::PowerManager::Standby ) { + QStandardItem *standbyOption = createStandardItem("leave:/standby"); + systemOptions->appendRow(standbyOption); + } + +#if 0 + if( spdMethods & Solid::Control::PowerManager::ToRam ) { + QStandardItem *suspendramOption = createStandardItem("leave:/suspendram"); + systemOptions->appendRow(suspendramOption); + } + + if( spdMethods & Solid::Control::PowerManager::ToDisk ) { + QStandardItem *suspenddiskOption = createStandardItem("leave:/suspenddisk"); + systemOptions->appendRow(suspenddiskOption); + } +#endif + // Shutdown QStandardItem *shutDownOption = createStandardItem("leave:/shutdown"); systemOptions->appendRow(shutDownOption); --- applets/kickoff/core/itemhandlers.cpp +++ applets/kickoff/core/itemhandlers.cpp @@ -29,6 +29,8 @@ #include <KToolInvocation> #include <KUrl> #include <solid/powermanagement.h> +#include <solid/control/powermanager.h> +#include <kjob.h> // KDE Base #include <kworkspace/kworkspace.h> @@ -39,6 +41,7 @@ // DBus #include "krunner_interface.h" #include "screensaver_interface.h" +#include "ksmserver_interface.h" using namespace Kickoff; @@ -78,11 +81,27 @@ // decouple dbus call, otherwise we'll run into a dead-lock QTimer::singleShot(0, this, SLOT(switchUser())); return true; - } else if (m_logoutAction == "logout" || + } else if (m_logoutAction == "logout" || m_logoutAction == "logoutonly" || m_logoutAction == "restart" || m_logoutAction == "shutdown" ) { // decouple dbus call, otherwise we'll run into a dead-lock QTimer::singleShot(0, this, SLOT(logout())); return true; + } else if (m_logoutAction == "savesession") { + // decouple dbus call, otherwise we'll run into a dead-lock + QTimer::singleShot(0, this, SLOT(saveSession())); + return true; + } else if (m_logoutAction == "standby") { + // decouple dbus call, otherwise we'll run into a dead-lock + QTimer::singleShot(0, this, SLOT(standby())); + return true; + } else if (m_logoutAction == "suspendram") { + // decouple dbus call, otherwise we'll run into a dead-lock + QTimer::singleShot(0, this, SLOT(suspendRAM())); + return true; + } else if (m_logoutAction == "suspenddisk") { + // decouple dbus call, otherwise we'll run into a dead-lock + QTimer::singleShot(0, this, SLOT(suspendDisk())); + return true; } return false; @@ -95,6 +114,8 @@ if (m_logoutAction == "logout") { type = KWorkSpace::ShutdownTypeNone; + } else if (m_logoutAction == "logoutonly") { + type = KWorkSpace::ShutdownTypeLogout; } else if (m_logoutAction == "lock") { kDebug() << "Locking screen"; } else if (m_logoutAction == "switch") { @@ -130,3 +151,38 @@ krunner.switchUser(); } } + +void LeaveItemHandler::saveSession() +{ + QString interface("org.kde.ksmserver"); + + org::kde::KSMServerInterface ksmserver(interface, "/KSMServer", + QDBusConnection::sessionBus()); + if (ksmserver.isValid()) { + ksmserver.saveCurrentSession(); + } +} + +void LeaveItemHandler::standby() +{ + Solid::Control::PowerManager::SuspendMethod spdMethod = Solid::Control::PowerManager::Standby; + KJob *job = Solid::Control::PowerManager::suspend( spdMethod ); + if (job != 0) + job->start(); +} + +void LeaveItemHandler::suspendRAM() +{ + Solid::Control::PowerManager::SuspendMethod spdMethod = Solid::Control::PowerManager::ToRam; + KJob *job = Solid::Control::PowerManager::suspend( spdMethod ); + if (job != 0) + job->start(); +} + +void LeaveItemHandler::suspendDisk() +{ + Solid::Control::PowerManager::SuspendMethod spdMethod = Solid::Control::PowerManager::ToDisk; + KJob *job = Solid::Control::PowerManager::suspend( spdMethod ); + if (job != 0) + job->start(); +} --- applets/kickoff/core/leavemodel.h +++ applets/kickoff/core/leavemodel.h @@ -36,6 +36,8 @@ static QStandardItem* createStandardItem(const QString& url); + void updateModel(); + private: class Private; Private * const d; --- applets/kickoff/core/favoritesmodel.cpp +++ applets/kickoff/core/favoritesmodel.cpp @@ -138,6 +138,11 @@ } void FavoritesModel::add(const QString& url) { + KService::Ptr service = KService::serviceByStorageId(url); + if (!service) { + return; + } + Private::globalFavoriteList << url; Private::globalFavoriteSet << url; --- applets/kickoff/core/models.cpp +++ applets/kickoff/core/models.cpp @@ -155,7 +155,19 @@ { KConfigGroup appsGroup = componentData().config()->group("SystemApplications"); QStringList apps; - apps << "systemsettings"; + + if (QFile::exists("/usr/share/applications/YaST.desktop")) + apps << "YaST.desktop"; + + if (QFile::exists("/usr/share/applications/package-manager.desktop")) + apps << "package-manager.desktop"; + + if (KService::serviceByStorageId("YaST2/live-installer.desktop")) + apps << "YaST2/live-installer.desktop"; + + if (QFile::exists("/usr/share/kde4/services/sysinfo.protocol")) + apps << "/usr/share/kde4/services/sysinfo.protocol"; + apps = appsGroup.readEntry("DesktopFiles", apps); return apps; } --- applets/kickoff/core/itemhandlers.h +++ applets/kickoff/core/itemhandlers.h @@ -42,6 +42,10 @@ void logout(); void lock(); void switchUser(); + void saveSession(); + void standby(); + void suspendRAM(); + void suspendDisk(); private: QString m_logoutAction; --- applets/kickoff/core/applicationmodel.cpp +++ applets/kickoff/core/applicationmodel.cpp @@ -110,6 +110,8 @@ static bool AppNodeLessThan(AppNode *n1, AppNode *n2); void fillNode(const QString &relPath, AppNode *node); + void addAppNode(const QString &icon, const QString &appName, const QString &genericName, + const QString& relPath, const QString &desktopEntry, bool isDir, AppNode *parent); static QHash<QString,QString> iconNameMap(); ApplicationModel *q; @@ -118,6 +120,9 @@ Qt::SortOrder sortOrder; int sortColumn; QStringList systemApplications; + + QStringList newInstalledPrograms, seenPrograms; + QString currentDate; }; bool ApplicationModelPrivate::AppNodeLessThan(AppNode *n1, AppNode *n2) @@ -134,78 +139,150 @@ void ApplicationModelPrivate::fillNode(const QString &_relPath, AppNode *node) { + if (_relPath=="new/") { + for (QStringList::ConstIterator it = newInstalledPrograms.begin(); it != newInstalledPrograms.end(); ++it) { + KService::Ptr p = KService::serviceByStorageId((*it)); + + if (p->noDisplay()) { + continue; + } + + AppNode *newnode = new AppNode(); + newnode->icon = KIcon(p->icon()); + newnode->appName = p->name(); + newnode->genericName = p->genericName(); + newnode->relPath = QString(); + newnode->desktopEntry = p->entryPath(); + newnode->isDir = false; + newnode->parent = node; + node->children.append(newnode); + } + return; + } + KServiceGroup::Ptr root = KServiceGroup::group(_relPath); if (!root || !root->isValid()) return; KServiceGroup::List list = root->entries(); - // application name <-> service map for detecting duplicate entries - QHash<QString,KService::Ptr> existingServices; + KSortableList<KSharedPtr<KSycocaEntry>,QByteArray> slist; + KSortableList<KSharedPtr<KSycocaEntry>,QByteArray> glist; + QMap<QString,QString> specialTitle; + QMap<QString,QString> categoryIcon; + QMap<QString,QString> shortenedMenuPath; + for (KServiceGroup::List::ConstIterator it = list.begin(); it != list.end(); ++it) { - QString icon; - QString appName; - QString genericName; - QString relPath = _relPath; - QString desktopEntry; - bool isDir = false; const KSycocaEntry::Ptr p = (*it); if (p->isType(KST_KService)) { const KService::Ptr service = KService::Ptr::staticCast(p); + slist.insert( service->name().toLocal8Bit(), p); + } + else if (p->isType(KST_KServiceGroup)) + { + KServiceGroup::Ptr serviceGroup = KServiceGroup::Ptr::staticCast(p); + if ( serviceGroup->SuSEshortMenu() ){ + KServiceGroup::List l = serviceGroup->entries(true, true /*excludeNoDisplay_*/, false ); + if ( l.count() == 1 ) { + // the special case, we want to short the menu. + // TOFIX? : this works only for one level + KServiceGroup::List::ConstIterator _it=l.begin(); + const KSycocaEntry::Ptr _e = (*_it); + if (_e->isType(KST_KService)) { + const KService::Ptr s = KService::Ptr::staticCast(_e); + QString key; + if ( serviceGroup->SuSEgeneralDescription() ) + key = s->name(); + else { + // we use the normal menu description + key = s->name(); + if( !s->genericName().isEmpty() && serviceGroup->caption()!=s->genericName()) + key = serviceGroup->caption() + " (" + s->name() + ")"; + } + specialTitle.insert( _e->name(), key ); + categoryIcon.insert( _e->name(), serviceGroup->icon() ); + slist.insert( key.toLocal8Bit(), _e ); + shortenedMenuPath.insert( _e->name(), serviceGroup->relPath() ); + // and escape from here + continue; + } + } + } + glist.insert( serviceGroup->caption().toLocal8Bit(), p ); + } + else + slist.insert( p->name().toLocal8Bit(), p); + } + + list = root->SuSEsortEntries( slist, glist, true /*excludeNoDisplay_*/, false ); + + for( KServiceGroup::List::ConstIterator it = list.begin(); + it != list.end(); ++it) + { + const KSycocaEntry::Ptr p = (*it); + if (p->isType(KST_KService)) + { + const KService::Ptr service = KService::Ptr::staticCast(p); + if (service->noDisplay()) continue; - icon = service->icon(); - appName = service->name(); - genericName = service->genericName(); - desktopEntry = service->entryPath(); - - // check for duplicates (eg. KDE 3 and KDE 4 versions of application - // both present) - if (duplicatePolicy == ApplicationModel::ShowLatestOnlyPolicy && - existingServices.contains(appName) - ) { - if (Kickoff::isLaterVersion(existingServices[appName],service)) { - continue; - } else { - // find and remove the existing entry with the same name - for (int i = 0 ; i < node->children.count() ; i++) { - if ( node->children[i]->appName == appName ) { - delete node->children.takeAt(i); - } - } - } - } // don't duplicate applications that are configured to appear in the System tab // in the Applications tab if ( systemApplications.contains( service->desktopEntryName() ) ) { continue; } - existingServices[appName] = service; + QString menuPath; + if (shortenedMenuPath[service->name()].isEmpty()) + menuPath=_relPath+service->menuId(); + else + menuPath=shortenedMenuPath[service->name()]+service->menuId(); + + QString icon = categoryIcon[service->name()]; + if (icon.isEmpty()) + icon = service->icon(); + + QString name = specialTitle[service->name()]; + if (name.isEmpty()) + name = service->name(); + + QString genericName = service->genericName(); + if (genericName.isEmpty()) { + genericName = name; + name = QString::null; + } + + if (name==genericName) + name = QString::null; + + addAppNode(icon, name, genericName, _relPath, service->entryPath(), false, node); } else if (p->isType(KST_KServiceGroup)) { - const KServiceGroup::Ptr serviceGroup = KServiceGroup::Ptr::staticCast(p); + KServiceGroup::Ptr serviceGroup = KServiceGroup::Ptr::staticCast(p); + if ( serviceGroup->SuSEshortMenu() ){ + KServiceGroup::List l = serviceGroup->entries(true, true /*excludeNoDisplay_*/ ); + if ( l.count() == 1 ) + continue; + } + // standard sub menu + if (serviceGroup->noDisplay() || serviceGroup->childCount() == 0) continue; kDebug(250) << "Service group" << serviceGroup->entryPath() << serviceGroup->icon() << serviceGroup->relPath() << serviceGroup->directoryEntryPath(); - icon = serviceGroup->icon(); - if (iconNameMap().contains(icon)) { + QString icon = serviceGroup->icon(); + if (iconNameMap().contains(icon)) icon = iconNameMap().value(icon); - } - genericName = serviceGroup->caption(); - relPath = serviceGroup->relPath(); - appName = serviceGroup->comment(); - isDir = true; + addAppNode(icon, serviceGroup->comment(), serviceGroup->caption(), serviceGroup->relPath(), QString::null, true, node); } else { @@ -213,18 +290,35 @@ continue; } + } + + qStableSort(node->children.begin(), node->children.end(), ApplicationModelPrivate::AppNodeLessThan); + + if (_relPath.isEmpty() && newInstalledPrograms.count()) { AppNode *newnode = new AppNode(); - newnode->icon = KIcon(icon); - newnode->appName = appName; - newnode->genericName = genericName; - newnode->relPath = relPath; - newnode->desktopEntry = desktopEntry; - newnode->isDir = isDir; + newnode->icon = KIcon("chronometer"); + newnode->appName = QString(); + newnode->genericName = i18n("Recently Installed"); + newnode->relPath = "new/"; + newnode->desktopEntry = QString(); + newnode->isDir = true; newnode->parent = node; - node->children.append(newnode); + node->children.prepend(newnode); } +} - qStableSort(node->children.begin(), node->children.end(), ApplicationModelPrivate::AppNodeLessThan); +void ApplicationModelPrivate::addAppNode(const QString &icon, const QString &appName, const QString &genericName, + const QString& relPath, const QString &desktopEntry, bool isDir, AppNode *parent ) +{ + AppNode *newnode = new AppNode(); + newnode->icon = KIcon(icon); + newnode->appName = appName; + newnode->genericName = genericName; + newnode->relPath = relPath; + newnode->desktopEntry = desktopEntry; + newnode->isDir = isDir; + newnode->parent = parent; + parent->children.append(newnode); } ApplicationModel::ApplicationModel(QObject *parent) @@ -236,6 +330,7 @@ dbus.connect(QString(), "/kickoff", "org.kde.plasma", "reloadMenu", this, SLOT(slotReloadMenu())); connect(KSycoca::self(), SIGNAL(databaseChanged()), this, SLOT(checkSycocaChange())); d->fillNode(QString(), d->root); + createNewProgramList(); } ApplicationModel::~ApplicationModel() @@ -384,6 +479,7 @@ d->root = new AppNode(); d->fillNode(QString(), d->root); reset(); + createNewProgramList(); } void ApplicationModel::checkSycocaChange() @@ -398,6 +494,100 @@ return d->duplicatePolicy; } +void ApplicationModel::createNewProgramList() +{ + KConfigGroup kickoffrc = Kickoff::componentData().config()->group("Applications"); + d->seenPrograms = kickoffrc.readEntry("FirstSeen", QStringList()); + d->newInstalledPrograms.clear(); + + d->currentDate = QDate::currentDate().toString(Qt::ISODate); + + bool initialize = (d->seenPrograms.count() == 0); + + bool seenProgramsChanged = createNewProgramList(QString::null); + + if (initialize) { + for (QStringList::Iterator it = d->seenPrograms.begin(); it != d->seenPrograms.end(); ++it) { + *(++it) = "-"; + } + + d->newInstalledPrograms.clear(); + } + + if (seenProgramsChanged) { + kickoffrc.writeEntry("FirstSeen", d->seenPrograms); + kickoffrc.sync(); + } +} + +bool ApplicationModel::createNewProgramList(QString relPath) +{ + bool seenProgramsChanged = false; + + KServiceGroup::Ptr group = KServiceGroup::group(relPath); + if (!group || !group->isValid()) { + return false; + } + + KServiceGroup::List list = group->entries(); + if (list.isEmpty()) { + return false; + } + + KServiceGroup::List::ConstIterator it = list.begin(); + for (; it != list.end(); ++it) { + KSycocaEntry::Ptr e = (*it); + + if (e) { + if (e->isType(KST_KServiceGroup)) { + KServiceGroup::Ptr g(KServiceGroup::Ptr::staticCast(e)); + if(!g->noDisplay()) { + seenProgramsChanged |= createNewProgramList(g->relPath()); + } + } else if (e->isType(KST_KService)) { + KService::Ptr s(KService::Ptr::staticCast(e)); + if (s->isApplication() && !s->noDisplay() ) { + QString shortStorageId = s->storageId().replace(".desktop", QString::null); + QStringList::Iterator it_find = d->seenPrograms.begin(); + QStringList::Iterator it_end = d->seenPrograms.end(); + bool found = false; + for (; it_find != it_end; ++it_find) { + if (*(it_find)==shortStorageId) { + found = true; + break; + } + ++it_find; + } + if (!found) { + seenProgramsChanged = true; + d->seenPrograms += shortStorageId; + d->seenPrograms += d->currentDate; + if (d->newInstalledPrograms.indexOf(s->storageId())==-1) { + d->newInstalledPrograms += s->storageId(); + } + } + else { + ++it_find; + if (*(it_find)!="-") { + QDate date = QDate::fromString(*(it_find), Qt::ISODate); + if (date.daysTo(QDate::currentDate())<3) { + if (d->newInstalledPrograms.indexOf(s->storageId())==-1) { + d->newInstalledPrograms += s->storageId(); + } + } + else { + seenProgramsChanged=true; + (*it_find)="-"; + } + } + } + } + } + } + } + return seenProgramsChanged; +} + /** * FIXME This is a temporary workaround to map the icon names found * in the desktop directory files (from /usr/share/desktop-directories) --- applets/kickoff/core/applicationmodel.h +++ applets/kickoff/core/applicationmodel.h @@ -86,10 +86,15 @@ void slotReloadMenu(); void checkSycocaChange(); + protected slots: + void createNewProgramList(); + private: friend class ApplicationModelPrivate; ApplicationModelPrivate *const d; + bool createNewProgramList(QString relPath); + Q_DISABLE_COPY(ApplicationModel) }; --- applets/kickoff/CMakeLists.txt +++ applets/kickoff/CMakeLists.txt @@ -33,6 +33,10 @@ QT4_ADD_DBUS_INTERFACE(Kickoff_SRCS ${screensaver_xml} screensaver_interface) set(krunner_xml ${KDEBASE_WORKSPACE_SOURCE_DIR}/krunner/org.kde.krunner.Interface.xml) QT4_ADD_DBUS_INTERFACE(Kickoff_SRCS ${krunner_xml} krunner_interface) + +set(ksmserver_xml ${KDEBASE_WORKSPACE_SOURCE_DIR}/ksmserver/org.kde.KSMServerInterface.xml) +QT4_ADD_DBUS_INTERFACE(Kickoff_SRCS ${ksmserver_xml} ksmserver_interface) + if(NOT WIN32) set ( Kickoff_LIBS ${KDE4_KIO_LIBS} @@ -63,13 +67,13 @@ # Kickoff Plasma Applet set ( Applet_SRCS ${Kickoff_SRCS} applet/applet.cpp ) kde4_add_plugin(plasma_applet_launcher ${Applet_SRCS}) -target_link_libraries(plasma_applet_launcher plasma ${Kickoff_LIBS}) +target_link_libraries(plasma_applet_launcher plasma solidcontrol ${Kickoff_LIBS}) install(TARGETS plasma_applet_launcher DESTINATION ${PLUGIN_INSTALL_DIR}) install(FILES applet/plasma-applet-launcher.desktop DESTINATION ${SERVICES_INSTALL_DIR}) # Simple KMenu Plasma Applet set ( SimpleApplet_SRCS ${Kickoff_SRCS} simpleapplet/menuview.cpp simpleapplet/simpleapplet.cpp ) kde4_add_plugin(plasma_applet_simplelauncher ${SimpleApplet_SRCS}) -target_link_libraries(plasma_applet_simplelauncher plasma ${Kickoff_LIBS}) +target_link_libraries(plasma_applet_simplelauncher plasma solidcontrol ${Kickoff_LIBS}) install(TARGETS plasma_applet_simplelauncher DESTINATION ${PLUGIN_INSTALL_DIR}) install(FILES simpleapplet/plasma-applet-simplelauncher.desktop DESTINATION ${SERVICES_INSTALL_DIR}) --- applets/kickoff/ui/launcher.cpp +++ applets/kickoff/ui/launcher.cpp @@ -80,6 +80,7 @@ , urlLauncher(new UrlItemLauncher(launcher)) , resizeHandle(0) , searchModel(0) + , leaveModel(0) , searchBar(0) , footer(0) , contentArea(0) @@ -152,14 +153,14 @@ void setupLeaveView() { - LeaveModel *model = new LeaveModel(q); + leaveModel = new LeaveModel(q); UrlItemView *view = new UrlItemView; ItemDelegate *delegate = new ItemDelegate(q); delegate->setRoleMapping(Plasma::Delegate::SubTitleRole, SubTitleRole); delegate->setRoleMapping(Plasma::Delegate::SubTitleMandatoryRole, SubTitleMandatoryRole); view->setItemDelegate(delegate); view->setItemStateProvider(delegate); - addView(i18n("Leave"), KIcon("system-shutdown"), model, view); + addView(i18n("Leave"), KIcon("system-shutdown"), leaveModel, view); } void setupFavoritesView() @@ -420,6 +421,7 @@ FlipScrollView *applicationView; QAbstractItemView *searchView; QAbstractItemView *favoritesView; + LeaveModel *leaveModel; ContextMenuFactory *contextMenuFactory; bool autoHide; int visibleItemCount; @@ -697,6 +699,7 @@ d->contentArea->setCurrentWidget(d->favoritesView); d->searchBar->clear(); d->applicationView->viewRoot(); + d->leaveModel->updateModel(); } Launcher::~Launcher() @@ -868,7 +871,9 @@ void Launcher::openHomepage() { hide(); - KToolInvocation::invokeBrowser("http://www.kde.org/"); + KConfig config("kickoffrc"); + KConfigGroup group = config.group("Branding"); + KToolInvocation::invokeBrowser(group.readEntry("Homepage", "http://www.kde.org/")); } void Launcher::resultsAvailable() --- applets/pager/plasma-pager-default.desktop +++ applets/pager/plasma-pager-default.desktop @@ -1,5 +1,6 @@ [Desktop Entry] Name=Pager +Name[ar]=جهاز النداء Name[bg]=Пейджър Name[bn_IN]=পেজার Name[ca]=Paginador @@ -47,6 +48,7 @@ Name[x-test]=xxPagerxx Name[zh_CN]=分页器 Name[zh_TW]=呼叫器 +Comment=Switch between virtual desktops Type=Service X-KDE-ServiceTypes=Plasma/Applet --- wallpapers/image/Messages.sh +++ wallpapers/image/Messages.sh @@ -0,0 +1,2 @@ +#! /usr/bin/env bash +$XGETTEXT *.cpp -o $podir/plasma_wallpaper_image.pot Property changes on: wallpapers/image/Messages.sh ___________________________________________________________________ Added: svn:executable + * --- wallpapers/image/backgroundpackage.h +++ wallpapers/image/backgroundpackage.h @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2007 Paolo Capriotti <p.capriotti@gmail.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, + * or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef BACKGROUNDPACKAGE_H +#define BACKGROUNDPACKAGE_H + +#include <memory> +#include <QImage> +#include <QPersistentModelIndex> +#include <QPixmap> +#include <QSize> +#include <QThread> +#include <QVariant> +#include <ThreadWeaver/Job> +#include <plasma/package.h> + +namespace Plasma { class PackageMetadata; } + +class DummyObject : public QObject +{ +Q_OBJECT +signals: + void done(ThreadWeaver::Job *); +}; + +class Background : public QObject +{ +Q_OBJECT +public: + enum ResizeMethod { + Scale, + Center, + ScaleCrop, + Tiled, + CenterTiled, + Maxpect + }; + + static const int SCREENSHOT_HEIGHT = 60; + + virtual ~Background(); + + virtual QString path() const = 0; + virtual QString findBackground(const QSize &resolution, + ResizeMethod method) const = 0; + virtual QPixmap screenshot() const = 0; + virtual bool screenshotGenerationStarted() const = 0; + virtual void generateScreenshot(QPersistentModelIndex index) const = 0; + virtual QString title() const = 0; + virtual QString author() const = 0; + virtual QString email() const = 0; + virtual QString license() const = 0; + + virtual bool isValid() const = 0; + +protected: + static QImage defaultScreenshot(); + static QImage createScreenshot(const QString &path, float ratio); + friend class ResizeThread; +}; + +class BackgroundPackage : public Background, + public Plasma::Package +{ +Q_OBJECT +public: + BackgroundPackage(const QString &path, float ratio); + + virtual QString path() const; + virtual QString findBackground(const QSize &resolution, + ResizeMethod method) const; + virtual QPixmap screenshot() const; + virtual bool screenshotGenerationStarted() const; + virtual void generateScreenshot(QPersistentModelIndex index) const; + virtual QString author() const; + virtual QString title() const; + virtual QString email() const; + virtual QString license() const; + virtual bool isValid() const; +private: + QString resString(const QSize &size) const; + QSize resSize(const QString &res) const; + + float distance(const QSize &size, + const QSize &desired, + ResizeMethod method) const; + + QString m_path; + float m_ratio; + mutable QPixmap m_screenshot; +}; + +class BackgroundFile : public Background +{ +Q_OBJECT +public: + BackgroundFile(const QString &file, float ratio); + virtual ~BackgroundFile(); + + virtual QString path() const; + virtual QString findBackground(const QSize &resolution, + ResizeMethod method) const; + virtual bool screenshotGenerationStarted() const; + virtual void generateScreenshot(QPersistentModelIndex index) const; + virtual QPixmap screenshot() const; + virtual QString author() const; + virtual QString title() const; + virtual QString email() const; + virtual QString license() const; + virtual bool isValid() const; +private: + QString m_file, m_author, m_title; + float m_ratio; + + mutable bool m_resizer_started; + mutable QPixmap m_screenshot; +private slots: + void updateScreenshot(ThreadWeaver::Job *); +signals: + void screenshotDone(QPersistentModelIndex index); +}; + +#endif // BACKGROUNDPACKAGE_H --- wallpapers/image/backgroundlistmodel.h +++ wallpapers/image/backgroundlistmodel.h @@ -0,0 +1,52 @@ +/* + Copyright (c) 2007 Paolo Capriotti <p.capriotti@gmail.com> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. +*/ + +#ifndef BACKGROUNDLISTMODEL_H +#define BACKGROUNDLISTMODEL_H + +#include <QAbstractListModel> +#include <KDirWatch> + +class Background; + +class BackgroundContainer +{ +public: + virtual ~BackgroundContainer() {}; + virtual bool contains(const QString &path) const = 0; +}; + +class BackgroundListModel : public QAbstractListModel, public BackgroundContainer +{ +public: + BackgroundListModel(float ratio, QObject *listener); + virtual ~BackgroundListModel(); + + virtual int rowCount(const QModelIndex &parent = QModelIndex()) const; + virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; + Background* package(int index) const; + + void reload(); + void reload(const QStringList &selected); + void addBackground(const QString &path); + int indexOf(const QString &path) const; + void removeBackground(const QString &path); + virtual bool contains(const QString &bg) const; + + static QList<Background *> findAllBackgrounds(const BackgroundContainer *container, + const QString &path, float ratio); + +private: + QObject *m_listener; + QList<Background*> m_packages; + float m_ratio; + KDirWatch m_dirwatch; +}; + +#endif // BACKGROUNDLISTMODEL_H --- wallpapers/image/imageconfig.ui +++ wallpapers/image/imageconfig.ui @@ -0,0 +1,279 @@ +<ui version="4.0" > + <class>ImageConfig</class> + <widget class="QWidget" name="ImageConfig" > + <property name="geometry" > + <rect> + <x>0</x> + <y>0</y> + <width>605</width> + <height>230</height> + </rect> + </property> + <layout class="QGridLayout" name="gridLayout_2" > + <item row="0" column="0" > + <widget class="QLabel" name="label" > + <property name="minimumSize" > + <size> + <width>75</width> + <height>0</height> + </size> + </property> + <property name="text" > + <string>&Picture:</string> + </property> + <property name="alignment" > + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + <property name="buddy" > + <cstring>m_view</cstring> + </property> + </widget> + </item> + <item row="0" column="1" > + <widget class="QComboBox" name="m_view" > + <property name="sizePolicy" > + <sizepolicy vsizetype="Fixed" hsizetype="Preferred" > + <horstretch>1</horstretch> + <verstretch>1</verstretch> + </sizepolicy> + </property> + </widget> + </item> + <item row="0" column="2" > + <widget class="QToolButton" name="m_pictureUrlButton" > + <property name="toolTip" > + <string>Browse</string> + </property> + <property name="text" > + <string>...</string> + </property> + </widget> + </item> + <item row="1" column="1" colspan="2" > + <layout class="QGridLayout" name="gridLayout" > + <item row="0" column="0" > + <widget class="QLabel" name="m_authorLabel" > + <property name="text" > + <string>Author:</string> + </property> + <property name="alignment" > + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + </widget> + </item> + <item row="0" column="1" > + <widget class="QLabel" name="m_authorLine" > + <property name="sizePolicy" > + <sizepolicy vsizetype="Fixed" hsizetype="Preferred" > + <horstretch>1</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text" > + <string/> + </property> + </widget> + </item> + <item row="1" column="0" > + <widget class="QLabel" name="m_emailLabel" > + <property name="text" > + <string>Email:</string> + </property> + <property name="alignment" > + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + </widget> + </item> + <item row="1" column="1" > + <widget class="QLabel" name="m_emailLine" > + <property name="sizePolicy" > + <sizepolicy vsizetype="Fixed" hsizetype="Preferred" > + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text" > + <string/> + </property> + </widget> + </item> + <item row="2" column="0" > + <widget class="QLabel" name="m_licenseLabel" > + <property name="text" > + <string>License:</string> + </property> + <property name="alignment" > + <set>Qt::AlignRight|Qt::AlignTop|Qt::AlignTrailing</set> + </property> + </widget> + </item> + <item row="2" column="1" > + <widget class="QLabel" name="m_licenseLine" > + <property name="sizePolicy" > + <sizepolicy vsizetype="Fixed" hsizetype="Preferred" > + <horstretch>1</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text" > + <string/> + </property> + <property name="alignment" > + <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set> + </property> + </widget> + </item> + </layout> + </item> + <item row="2" column="0" > + <widget class="QLabel" name="label_4" > + <property name="minimumSize" > + <size> + <width>125</width> + <height>0</height> + </size> + </property> + <property name="text" > + <string>P&ositioning:</string> + </property> + <property name="alignment" > + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + <property name="buddy" > + <cstring>m_resizeMethod</cstring> + </property> + </widget> + </item> + <item row="2" column="1" colspan="2" > + <layout class="QHBoxLayout" name="horizontalLayout" > + <item> + <widget class="QComboBox" name="m_resizeMethod" > + <property name="sizePolicy" > + <sizepolicy vsizetype="Fixed" hsizetype="Preferred" > + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + </widget> + </item> + <item> + <spacer name="spacer_2" > + <property name="orientation" > + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0" > + <size> + <width>187</width> + <height>17</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + <item row="3" column="0" > + <widget class="QLabel" name="label_5" > + <property name="text" > + <string>&Color:</string> + </property> + <property name="alignment" > + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + <property name="buddy" > + <cstring>m_color</cstring> + </property> + </widget> + </item> + <item row="3" column="1" colspan="2" > + <layout class="QHBoxLayout" name="horizontalLayout_2" > + <item> + <widget class="KColorButton" name="m_color" > + <property name="sizePolicy" > + <sizepolicy vsizetype="Fixed" hsizetype="Minimum" > + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="color" > + <color> + <red>70</red> + <green>90</green> + <blue>130</blue> + </color> + </property> + <property name="defaultColor" > + <color> + <red>70</red> + <green>90</green> + <blue>130</blue> + </color> + </property> + </widget> + </item> + <item> + <spacer name="spacer" > + <property name="orientation" > + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0" > + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + <item row="4" column="1" colspan="2" > + <layout class="QHBoxLayout" name="horizontalLayout_3" > + <item> + <spacer name="horizontalSpacer" > + <property name="orientation" > + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0" > + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QPushButton" name="m_newStuff" > + <property name="toolTip" > + <string>Download new wallpapers</string> + </property> + <property name="text" > + <string>Get New Wallpapers...</string> + </property> + </widget> + </item> + </layout> + </item> + <item row="5" column="1" > + <spacer name="verticalSpacer_2" > + <property name="orientation" > + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0" > + <size> + <width>13</width> + <height>5</height> + </size> + </property> + </spacer> + </item> + </layout> + </widget> + <customwidgets> + <customwidget> + <class>KColorButton</class> + <extends>QPushButton</extends> + <header>kcolorbutton.h</header> + </customwidget> + </customwidgets> + <resources/> + <connections/> +</ui> --- wallpapers/image/renderthread.cpp +++ wallpapers/image/renderthread.cpp @@ -0,0 +1,257 @@ +/* + Copyright (c) 2007 Paolo Capriotti <p.capriotti@gmail.com> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. +*/ + +#include "renderthread.h" + +#include <QPainter> +#include <QFile> +#include <KDebug> +#include <KSvgRenderer> + +RenderThread::RenderThread() +: m_current_token(-1) +, m_size(0, 0) +, m_ratio(1.0) +{ + m_abort = false; + m_restart = false; +} + +RenderThread::~RenderThread() +{ + { + // abort computation + QMutexLocker lock(&m_mutex); + m_abort = true; + m_condition.wakeOne(); + } + + wait(); +} + +void RenderThread::setSize(const QSize& size) +{ + QMutexLocker lock(&m_mutex); + m_size = size; +} + +void RenderThread::setRatio(float ratio) +{ + QMutexLocker lock(&m_mutex); + m_ratio = ratio; +} + +int RenderThread::render(const QString &file, + const QColor &color, + Background::ResizeMethod method, + Qt::TransformationMode mode) +{ + int token; + { + QMutexLocker lock(&m_mutex); + m_file = file; + m_color = color; + m_method = method; + m_mode = mode; + m_restart = true; + token = ++m_current_token; + } + + if (!isRunning()) { + start(); + } + else { + m_condition.wakeOne(); + } + + return token; +} + +void RenderThread::run() +{ + QString file; + QColor color; + QSize size; + float ratio; + Background::ResizeMethod method; + Qt::TransformationMode mode; + int token; + + forever { + { + QMutexLocker lock(&m_mutex); + while (!m_restart && !m_abort) { + m_condition.wait(&m_mutex); + } + if (m_abort) { + return; + } + m_restart = false; + + // load all parameters in nonshared variables + token = m_current_token; + file = m_file; + color = m_color; + size = m_size; + ratio = m_ratio; + method = m_method; + mode = m_mode; + } + + QImage result(size, QImage::Format_ARGB32_Premultiplied); + result.fill(color.rgba()); + + if (file.isEmpty() || !QFile::exists(file)) { + emit done(token, result); + continue; + } + + QPoint pos(0, 0); + bool tiled = false; + bool scalable = file.endsWith("svg") || file.endsWith("svgz"); + QSize scaledSize; + QImage img; + + // load nonscalable image + if (!scalable) { + img = QImage(file); + } + + // set image size + QSize imgSize; + if (scalable) { + // scalable: image can be of any size + imgSize = size; + } + else { + // otherwise, use the natural size of the loaded image + imgSize = img.size(); + } + imgSize *= ratio; + + // if any of them is zero we may run into a div-by-zero below. + if (imgSize.width() == 0) { + imgSize.setWidth(1); + } + if (imgSize.height() == 0) { + imgSize.setHeight(1); + } + + // set render parameters according to resize mode + switch (method) + { + case Background::Scale: + scaledSize = size; + break; + case Background::Center: + scaledSize = imgSize; + pos = QPoint((size.width() - scaledSize.width()) / 2, + (size.height() - scaledSize.height()) / 2); + + //If the picture is bigger than the screen, shrink it + if( size.width() < imgSize.width() && imgSize.width() > imgSize.height() ) + { + int width = size.width(); + int height = width * scaledSize.height() / imgSize.width(); + scaledSize = QSize(width, height); + pos = QPoint((size.width() - scaledSize.width()) / 2, + (size.height() - scaledSize.height()) / 2); + } + else if( size.height() < imgSize.height() ) + { + int height = size.height(); + int width = height * imgSize.width() / imgSize.height(); + scaledSize = QSize(width, height); + pos = QPoint((size.width() - scaledSize.width()) / 2, + (size.height() - scaledSize.height()) / 2); + } + + break; + case Background::Maxpect: { + float xratio = (float) size.width() / imgSize.width(); + float yratio = (float) size.height() / imgSize.height(); + if (xratio > yratio) { + int height = size.height(); + int width = height * imgSize.width() / imgSize.height(); + scaledSize = QSize(width, height); + } else { + int width = size.width(); + int height = width * imgSize.height() / imgSize.width(); + scaledSize = QSize(width, height); + } + pos = QPoint((size.width() - scaledSize.width()) / 2, + (size.height() - scaledSize.height()) / 2); + break; + } + case Background::ScaleCrop: { + float xratio = (float) size.width() / imgSize.width(); + float yratio = (float) size.height() / imgSize.height(); + if (xratio > yratio) { + int width = size.width(); + int height = width * imgSize.height() / imgSize.width(); + scaledSize = QSize(width, height); + } else { + int height = size.height(); + int width = height * imgSize.width() / imgSize.height(); + scaledSize = QSize(width, height); + } + pos = QPoint((size.width() - scaledSize.width()) / 2, + (size.height() - scaledSize.height()) / 2); + break; + } + case Background::Tiled: + scaledSize = imgSize; + tiled = true; + break; + case Background::CenterTiled: + scaledSize = imgSize; + pos = QPoint( + -scaledSize.width() + + ((size.width() - scaledSize.width()) / 2) % scaledSize.width(), + -scaledSize.height() + + ((size.height() - scaledSize.height()) / 2) % scaledSize.height()); + tiled = true; + break; + } + + QPainter p(&result); + if (scalable) { + // tiling is ignored for scalable wallpapers + KSvgRenderer svg(file); + if (m_restart) { + continue; + } + svg.render(&p); + } + else { + QImage scaled = img.scaled(scaledSize, Qt::IgnoreAspectRatio, mode); + if (m_restart) { + continue; + } + if (tiled) { + for (int x = pos.x(); x < size.width(); x += scaledSize.width()) { + for (int y = pos.y(); y < size.height(); y += scaledSize.height()) { + p.drawImage(QPoint(x, y), scaled); + if (m_restart) { + goto endLoop; + } + } + } + } + else { + p.drawImage(pos, scaled); + } + } + + // signal we're done + emit done(token, result); + + endLoop: continue; + } +} --- wallpapers/image/plasma-wallpaper-image.desktop +++ wallpapers/image/plasma-wallpaper-image.desktop @@ -0,0 +1,73 @@ +[Desktop Entry] +Type=Service +Name=Image +Name[be@latin]=Vyjava +Name[el]=Εικόνα +Name[et]=Pilt +Name[ga]=Íomhá +Name[gl]=Imaxe +Name[gu]=ચિત્ર +Name[km]=រូបភាព +Name[nds]=Bild +Name[pt]=Imagem +Name[pt_BR]=Imagem +Name[sl]=Slika +Name[sv]=Bild +Name[tr]=Resim +Name[uk]=Зображення +Name[zh_TW]=影像 +Icon=image-jpeg +ServiceTypes=Plasma/Wallpaper +Actions=SingleImage;Slideshow; + +X-KDE-Library=plasma_wallpaper_image +X-KDE-PluginInfo-Author=Petri Damstén +X-KDE-PluginInfo-Email=damu@iki.fi +X-KDE-PluginInfo-Name=image +X-KDE-PluginInfo-Version=pre0.1 +X-KDE-PluginInfo-Website=http://plasma.kde.org/ +X-KDE-PluginInfo-Depends= +X-KDE-PluginInfo-License=GPL +X-KDE-PluginInfo-EnabledByDefault=true + +[Desktop Action SingleImage] +Name=Image +Name[be@latin]=Vyjava +Name[el]=Εικόνα +Name[et]=Pilt +Name[ga]=Íomhá +Name[gl]=Imaxe +Name[gu]=ચિત્ર +Name[km]=រូបភាព +Name[nds]=Bild +Name[pt]=Imagem +Name[pt_BR]=Imagem +Name[sl]=Slika +Name[sv]=Bild +Name[tr]=Resim +Name[uk]=Зображення +Name[zh_TW]=影像 +Icon=image-jpeg +# Dummy +Exec=plasma + +[Desktop Action Slideshow] +Name=Slideshow +Name[be@latin]=Słajdy +Name[el]=Προβολή σλάιντ +Name[et]=Slaidiseanss +Name[ga]=Taispeántas Sleamhnán +Name[gl]=Presentación +Name[gu]=સ્લાઇડશો +Name[km]=បញ្ចាំងស្លាយ +Name[nds]=Diaschau +Name[pt]=Apresentação +Name[pt_BR]=Apresentação +Name[sl]=Menjanje slik +Name[sv]=Bildspel +Name[tr]=Slayt Gösterisi +Name[uk]=Показ слайдів +Name[zh_TW]=投影播放 +Icon=folder-image +# Dummy +Exec=plasma --- wallpapers/image/backgrounddelegate.cpp +++ wallpapers/image/backgrounddelegate.cpp @@ -0,0 +1,88 @@ +/* + Copyright (c) 2007 Paolo Capriotti <p.capriotti@gmail.com> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. +*/ + +#include "backgrounddelegate.h" + +#include <KGlobalSettings> +#include <QPen> +#include <QPainter> +#include "backgroundpackage.h" + +BackgroundDelegate::BackgroundDelegate(QObject *listener, + float ratio, QObject *parent) +: QAbstractItemDelegate(parent) +, m_listener(listener) +, m_ratio(ratio) +{ +} + +void BackgroundDelegate::paint(QPainter *painter, + const QStyleOptionViewItem &option, + const QModelIndex &index) const +{ + QString title = index.model()->data(index, Qt::DisplayRole).toString(); + QString author = index.model()->data(index, AuthorRole).toString(); + QPixmap pix = index.model()->data(index, ScreenshotRole).value<QPixmap>(); + + // draw selection outline + if (option.state & QStyle::State_Selected) { + QPen oldPen = painter->pen(); + painter->setPen(option.palette.color(QPalette::Highlight)); + painter->drawRect(option.rect.adjusted(2, 2, -2, -2)); + painter->setPen(oldPen); + } + + // draw pixmap + int maxheight = Background::SCREENSHOT_HEIGHT; + int maxwidth = int(maxheight * m_ratio); + if (!pix.isNull()) { + QSize sz = pix.size(); + int x = MARGIN + (maxwidth - pix.width()) / 2; + int y = MARGIN + (maxheight - pix.height()) / 2; + QRect imgRect = QRect(option.rect.topLeft(), pix.size()).translated(x, y); + painter->drawPixmap(imgRect, pix); + } + + // draw text + painter->save(); + QFont font = painter->font(); + font.setWeight(QFont::Bold); + painter->setFont(font); + int x = option.rect.left() + MARGIN * 5 + maxwidth; + + QRect textRect(x, + option.rect.top() + MARGIN, + option.rect.width() - x - MARGIN * 2, + maxheight); + QString text = title; + QString authorCaption; + if (!author.isEmpty()) { + authorCaption = i18nc("Caption to wallpaper preview, %1 author name", + "by %1", author); + text += '\n' + authorCaption; + } + QRect boundingRect = painter->boundingRect( + textRect, Qt::AlignVCenter | Qt::TextWordWrap, text); + painter->drawText(boundingRect, Qt::TextWordWrap, title); + if (!author.isEmpty()) { + QRect titleRect = painter->boundingRect(boundingRect, Qt::TextWordWrap, title); + QRect authorRect(titleRect.bottomLeft(), textRect.size()); + painter->setFont(KGlobalSettings::smallestReadableFont()); + painter->drawText(authorRect, Qt::TextWordWrap, authorCaption); + } + + painter->restore(); +} + +QSize BackgroundDelegate::sizeHint(const QStyleOptionViewItem &, + const QModelIndex &) const +{ + return QSize(100, Background::SCREENSHOT_HEIGHT + MARGIN * 2); +} + --- wallpapers/image/renderthread.h +++ wallpapers/image/renderthread.h @@ -0,0 +1,58 @@ +/* + Copyright (c) 2007 Paolo Capriotti <p.capriotti@gmail.com> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. +*/ + +#ifndef RENDERTHREAD_H +#define RENDERTHREAD_H + +#include "backgroundpackage.h" +#include <QColor> +#include <QImage> +#include <QMutex> +#include <QThread> +#include <QWaitCondition> + +class RenderThread : public QThread +{ +Q_OBJECT +public: + RenderThread(); + virtual ~RenderThread(); + + int render(const QString &file, + const QColor &color, + Background::ResizeMethod method, + Qt::TransformationMode mode); + + void setSize(const QSize &size); + void setRatio(float ratio); + +protected: + virtual void run(); + +private: + QMutex m_mutex; // to protect parameters + QWaitCondition m_condition; + + // protected by mutex + int m_current_token; + QString m_file; + QColor m_color; + QSize m_size; + float m_ratio; + Background::ResizeMethod m_method; + Qt::TransformationMode m_mode; + + bool m_abort; + bool m_restart; + +signals: + void done(int token, const QImage &pixmap); +}; + +#endif // RENDERTHREAD_H --- wallpapers/image/backgrounddelegate.h +++ wallpapers/image/backgrounddelegate.h @@ -0,0 +1,38 @@ +/* + Copyright (c) 2007 Paolo Capriotti <p.capriotti@gmail.com> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. +*/ + +#ifndef BACKGROUNDDELEGATE_H +#define BACKGROUNDDELEGATE_H + +#include <QAbstractItemDelegate> + +class BackgroundDelegate : public QAbstractItemDelegate +{ +public: + enum { + AuthorRole = Qt::UserRole, + ScreenshotRole + }; + + BackgroundDelegate(QObject *listener, + float ratio, QObject *parent = 0); + + virtual void paint(QPainter *painter, + const QStyleOptionViewItem &option, + const QModelIndex &index) const; + virtual QSize sizeHint(const QStyleOptionViewItem &option, + const QModelIndex &index) const; + +private: + static const int MARGIN = 5; + QObject *m_listener; + float m_ratio; +}; + +#endif // BACKGROUNDDELEGATEL_H --- wallpapers/image/image.cpp +++ wallpapers/image/image.cpp @@ -0,0 +1,494 @@ +/* + Copyright (c) 2007 by Paolo Capriotti <p.capriotti@gmail.com> + Copyright (c) 2007 by Aaron Seigo <aseigo@kde.org> + Copyright (c) 2008 by Alexis Ménard <darktears31@gmail.com> + Copyright (c) 2008 by Petri Damsten <damu@iki.fi> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. +*/ + +#include "image.h" + +#include <QPainter> +#include <QFile> +#include <KDirSelectDialog> +#include <KStandardDirs> +#include <KDirWatch> +#include <KGlobalSettings> +#include <KFileDialog> +#include <KImageFilePreview> +#include <KNS/Engine> +#include <plasma/theme.h> +#include "backgroundlistmodel.h" +#include "backgrounddelegate.h" +#include "ksmserver_interface.h" + + +Image::Image(QObject *parent, const QVariantList &args) +: Plasma::Wallpaper(parent, args) +, m_dialog(0) +, m_rendererToken(-1) +{ + qRegisterMetaType<QImage>("QImage"); + connect(&m_renderer, SIGNAL(done(int, QImage)), this, SLOT(updateBackground(int, QImage))); + connect(&m_timer, SIGNAL(timeout()), this, SLOT(nextSlide())); +} + +Image::~Image() +{ + qDeleteAll(m_slideshowBackgrounds); + delete m_dialog; +} + +void Image::init(const KConfigGroup &config) +{ + m_timer.stop(); + m_mode = renderingMode().name(); + calculateGeometry(); + + m_delay = config.readEntry("slideTimer", 60); + m_resizeMethod = (Background::ResizeMethod)config.readEntry("wallpaperposition", + (int)Background::Scale); + m_wallpaper = config.readEntry("wallpaper", QString()); + if (m_wallpaper.isEmpty()) { + m_wallpaper = Plasma::Theme::defaultTheme()->wallpaperPath(); + int index = m_wallpaper.indexOf("/contents/images/"); + if (index > -1) { // We have file from package -> get path to package + m_wallpaper = m_wallpaper.left(index); + } + } + m_color = config.readEntry("wallpapercolor", QColor(56, 111, 150)); + m_usersWallpapers = config.readEntry("userswallpapers", QStringList()); + m_dirs = config.readEntry("slidepaths", QStringList()); + if (m_dirs.isEmpty()) { + m_dirs << KStandardDirs::installPath("wallpaper"); + } + + if (m_mode == "SingleImage") { + setSingleImage(); + } else { + startSlideshow(); + } +} + +void Image::save(KConfigGroup &config) +{ + config.writeEntry("slideTimer", m_delay); + config.writeEntry("wallpaperposition", (int)m_resizeMethod); + config.writeEntry("slidepaths", m_dirs); + config.writeEntry("wallpaper", m_wallpaper); + config.writeEntry("wallpapercolor", m_color); + config.writeEntry("userswallpapers", m_usersWallpapers); +} + +QWidget* Image::createConfigurationInterface(QWidget* parent) +{ + m_widget = new QWidget(parent); + + if (m_mode == "SingleImage") { + m_uiImage.setupUi(m_widget); + + m_model = new BackgroundListModel(m_ratio, this); + m_uiImage.m_view->setModel(m_model); + m_uiImage.m_view->setItemDelegate(new BackgroundDelegate(m_uiImage.m_view->view(), + m_ratio, this)); + m_uiImage.m_view->view()->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel); + m_model->reload(m_usersWallpapers); + int index = m_model->indexOf(m_wallpaper); + if (index != -1) { + m_uiImage.m_view->setCurrentIndex(index); + Background *b = m_model->package(index); + if (b) { + fillMetaInfo(b); + } + } + connect(m_uiImage.m_view, SIGNAL(currentIndexChanged(int)), this, SLOT(pictureChanged(int))); + + m_uiImage.m_pictureUrlButton->setIcon(KIcon("document-open")); + connect(m_uiImage.m_pictureUrlButton, SIGNAL(clicked()), this, SLOT(showFileDialog())); + + m_uiImage.m_emailLine->setTextInteractionFlags(Qt::TextSelectableByMouse); + + m_uiImage.m_resizeMethod->addItem(i18n("Scaled & Cropped"), Background::ScaleCrop); + m_uiImage.m_resizeMethod->addItem(i18n("Scaled"), Background::Scale); + m_uiImage.m_resizeMethod->addItem(i18n("Maxpect"), Background::Maxpect); + m_uiImage.m_resizeMethod->addItem(i18n("Centered"), Background::Center); + m_uiImage.m_resizeMethod->addItem(i18n("Tiled"), Background::Tiled); + m_uiImage.m_resizeMethod->addItem(i18n("Center Tiled"), Background::CenterTiled); + for (int i = 0; i < m_uiImage.m_resizeMethod->count(); ++i) { + if (m_resizeMethod == m_uiImage.m_resizeMethod->itemData(i).value<int>()) { + m_uiImage.m_resizeMethod->setCurrentIndex(i); + break; + } + } + connect(m_uiImage.m_resizeMethod, SIGNAL(currentIndexChanged(int)), + this, SLOT(positioningChanged(int))); + + m_uiImage.m_color->setColor(m_color); + connect(m_uiImage.m_color, SIGNAL(changed(const QColor&)), this, SLOT(colorChanged(const QColor&))); + + connect(m_uiImage.m_newStuff, SIGNAL(clicked()), this, SLOT(getNewWallpaper())); + } else { + m_uiSlideshow.setupUi(m_widget); + + m_uiSlideshow.m_dirlist->clear(); + foreach (const QString &dir, m_dirs) { + m_uiSlideshow.m_dirlist->addItem(dir); + } + m_uiSlideshow.m_dirlist->setCurrentRow(0); + updateDirs(); + m_uiSlideshow.m_addDir->setIcon(KIcon("list-add")); + connect(m_uiSlideshow.m_addDir, SIGNAL(clicked()), this, SLOT(slotAddDir())); + m_uiSlideshow.m_removeDir->setIcon(KIcon("list-remove")); + connect(m_uiSlideshow.m_removeDir, SIGNAL(clicked()), this, SLOT(slotRemoveDir())); + + QTime time(0, 0, 0); + time = time.addSecs(m_delay); + m_uiSlideshow.m_slideshowDelay->setTime(time); + m_uiSlideshow.m_slideshowDelay->setMinimumTime(QTime(0, 0, 30)); + connect(m_uiSlideshow.m_slideshowDelay, SIGNAL(timeChanged(const QTime&)), + this, SLOT(timeChanged(const QTime&))); + + m_uiSlideshow.m_resizeMethod->addItem(i18n("Scaled & Cropped"), Background::ScaleCrop); + m_uiSlideshow.m_resizeMethod->addItem(i18n("Scaled"), Background::Scale); + m_uiSlideshow.m_resizeMethod->addItem(i18n("Maxpect"), Background::Maxpect); + m_uiSlideshow.m_resizeMethod->addItem(i18n("Centered"), Background::Center); + m_uiSlideshow.m_resizeMethod->addItem(i18n("Tiled"), Background::Tiled); + m_uiSlideshow.m_resizeMethod->addItem(i18n("Center Tiled"), Background::CenterTiled); + for (int i = 0; i < m_uiSlideshow.m_resizeMethod->count(); ++i) { + if (m_resizeMethod == m_uiSlideshow.m_resizeMethod->itemData(i).value<int>()) { + m_uiSlideshow.m_resizeMethod->setCurrentIndex(i); + break; + } + } + connect(m_uiSlideshow.m_resizeMethod, SIGNAL(currentIndexChanged(int)), + this, SLOT(positioningChanged(int))); + + m_uiSlideshow.m_color->setColor(m_color); + connect(m_uiSlideshow.m_color, SIGNAL(changed(const QColor&)), this, SLOT(colorChanged(const QColor&))); + } + + return m_widget; +} + +void Image::calculateGeometry() +{ + m_size = boundingRect().size().toSize(); + m_renderer.setSize(m_size); + m_ratio = boundingRect().width() / boundingRect().height(); + m_renderer.setRatio(m_ratio); +} + +void Image::paint(QPainter *painter, const QRectF& exposedRect) +{ + // Check if geometry changed + //kDebug() << m_size << boundingRect().size().toSize(); + if (m_size != boundingRect().size().toSize()) { + calculateGeometry(); + if (!m_img.isEmpty()) { // We have previous image + render(); + //kDebug() << "re-rendering"; + return; + } + } + if (m_pixmap.isNull()) { + painter->fillRect(exposedRect, QBrush(m_color)); + //kDebug() << "pixmap null"; + return; + } + painter->save(); + + if (painter->worldMatrix() == QMatrix()) { + // draw the background untransformed when possible;(saves lots of per-pixel-math) + painter->resetTransform(); + } + + // blit the background (saves all the per-pixel-products that blending does) + painter->setCompositionMode(QPainter::CompositionMode_Source); + + // for pixmaps we draw only the exposed part (untransformed since the + // bitmapBackground already has the size of the viewport) + painter->drawPixmap(exposedRect, m_pixmap, exposedRect); + + // restore transformation and composition mode + painter->restore(); +} + +void Image::timeChanged(const QTime& time) +{ + m_delay = QTime(0, 0, 0).secsTo(time); + if (!m_slideshowBackgrounds.isEmpty()) { + m_timer.start(m_delay * 1000); + } +} + +void Image::slotAddDir() +{ + KUrl empty; + KDirSelectDialog dialog(empty, true, m_widget); + if (dialog.exec()) { + m_uiSlideshow.m_dirlist->addItem(dialog.url().path()); + updateDirs(); + startSlideshow(); + } +} + +void Image::slotRemoveDir() +{ + int row = m_uiSlideshow.m_dirlist->currentRow(); + if (row != -1) { + m_uiSlideshow.m_dirlist->takeItem(row); + updateDirs(); + startSlideshow(); + } +} + +void Image::updateDirs() +{ + m_dirs.clear(); + for (int i = 0; i < m_uiSlideshow.m_dirlist->count(); i++) { + m_dirs.append(m_uiSlideshow.m_dirlist->item(i)->text()); + } + + if (m_uiSlideshow.m_dirlist->count() == 0) { + m_uiSlideshow.m_dirlist->hide(); + } else { + const int itemHeight = m_uiSlideshow.m_dirlist->visualItemRect(m_uiSlideshow.m_dirlist->item(0)).height(); + const int vMargin = m_uiSlideshow.m_dirlist->height() - m_uiSlideshow.m_dirlist->viewport()->height(); + + if (m_uiSlideshow.m_dirlist->count() <= 6) { + m_uiSlideshow.m_dirlist->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); + m_uiSlideshow.m_dirlist->setFixedHeight(itemHeight * m_uiSlideshow.m_dirlist->count() + vMargin); + } else { + m_uiSlideshow.m_dirlist->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + } + + if (!m_uiSlideshow.m_dirlist->isVisible()) { + m_uiSlideshow.m_dirlist->setCurrentRow(0); + } + + m_uiSlideshow.m_dirlist->show(); + m_uiSlideshow.gridLayout->invalidate(); + } + + m_uiSlideshow.m_removeDir->setEnabled(m_uiSlideshow.m_dirlist->currentRow() != -1); +} + +void Image::setSingleImage() +{ + QString img; + BackgroundPackage b(m_wallpaper, m_ratio); + + img = b.findBackground(m_size, m_resizeMethod); // isValid() returns true for jpg? + kDebug() << img << m_wallpaper; + if (img.isEmpty()) { + img = m_wallpaper; + } + render(img); +} + +void Image::startSlideshow() +{ + // populate background list + m_timer.stop(); + qDeleteAll(m_slideshowBackgrounds); + m_slideshowBackgrounds.clear(); + foreach (const QString& dir, m_dirs) { + m_slideshowBackgrounds += BackgroundListModel::findAllBackgrounds(0, dir, m_ratio); + } + + // start slideshow + if (m_slideshowBackgrounds.isEmpty()) { + m_pixmap = QPixmap(); + emit update(boundingRect()); + } else { + m_currentSlide = -1; + nextSlide(); + m_timer.start(m_delay * 1000); + } +} + +void Image::getNewWallpaper() +{ + KNS::Engine engine(0); + if (engine.init("wallpaper.knsrc")) { + KNS::Entry::List entries = engine.downloadDialogModal(m_widget); + + if (entries.size() > 0) { + m_model->reload(); + } + } +} + +void Image::colorChanged(const QColor& color) +{ + m_color = color; + setSingleImage(); +} + +void Image::pictureChanged(int index) +{ + if (index == -1) { + return; + } + Background *b = m_model->package(index); + if (!b) { + return; + } + fillMetaInfo(b); + m_wallpaper = b->path(); + setSingleImage(); +} + +void Image::positioningChanged(int index) +{ + if (m_mode == "SingleImage") { + m_resizeMethod = + (Background::ResizeMethod)m_uiImage.m_resizeMethod->itemData(index).value<int>(); + setSingleImage(); + } else { + m_resizeMethod = + (Background::ResizeMethod)m_uiSlideshow.m_resizeMethod->itemData(index).value<int>(); + startSlideshow(); + } +} + +void Image::fillMetaInfo(Background *b) +{ + // Prepare more user-friendly forms of some pieces of data. + // - license by config is more a of a key value, + // try to get the proper name if one of known licenses. + QString license = b->license(); + KAboutLicense knownLicense = KAboutLicense::byKeyword(license); + if (knownLicense.key() != KAboutData::License_Custom) { + license = knownLicense.name(KAboutData::ShortName); + } + // - last ditch attempt to localize author's name, if not such by config + // (translators can "hook" names from outside if resolute enough). + QString author = i18nc("Wallpaper info, author name", "%1", b->author()); + + setMetadata(m_uiImage.m_authorLine, author); + setMetadata(m_uiImage.m_licenseLine, license); + setMetadata(m_uiImage.m_emailLine, b->email()); +} + +bool Image::setMetadata(QLabel *label, const QString &text) +{ + if (text.isEmpty()) { + label->hide(); + return false; + } + else { + label->show(); + label->setText(text); + return true; + } +} + +void Image::showFileDialog() +{ + if (!m_dialog) { + m_dialog = new KFileDialog(KUrl(), "*.png *.jpeg *.jpg *.svg *.svgz", m_widget); + KImageFilePreview *previewWidget = new KImageFilePreview(m_dialog); + m_dialog->setPreviewWidget(previewWidget); + m_dialog->setOperationMode(KFileDialog::Opening); + m_dialog->setCaption(i18n("Select Wallpaper Image File")); + m_dialog->setModal(false); + } + m_dialog->show(); + m_dialog->raise(); + m_dialog->activateWindow(); + + connect(m_dialog, SIGNAL(okClicked()), this, SLOT(browse())); +} + +void Image::browse() +{ + QString wallpaper = m_dialog->selectedFile(); + disconnect(m_dialog, SIGNAL(okClicked()), this, SLOT(browse())); + + if (wallpaper.isEmpty()) { + return; + } + + // add background to the model + m_model->addBackground(wallpaper); + + // select it + int index = m_model->indexOf(wallpaper); + if (index != -1) { + m_uiImage.m_view->setCurrentIndex(index); + } + // save it + m_usersWallpapers << wallpaper; +} + +void Image::nextSlide() +{ + QString previous; + if (m_currentSlide >= 0 && m_currentSlide < m_slideshowBackgrounds.size()) { + previous = m_slideshowBackgrounds[m_currentSlide]->path(); + } + if (++m_currentSlide >= m_slideshowBackgrounds.size()) { + m_currentSlide = 0; + } + + if (m_slideshowBackgrounds.size() > 0) { + // do not change to the same background if we have a choice + // if there is only one background, it may be changed by someone else + if (m_slideshowBackgrounds.size() > 1 && + m_slideshowBackgrounds[m_currentSlide]->path() == previous) { + // try next one, they can't be the same (at least the same path) + if (++m_currentSlide >= m_slideshowBackgrounds.size()) { + m_currentSlide = 0; + } + } + render(m_slideshowBackgrounds[m_currentSlide]->findBackground(m_size, m_resizeMethod)); + } +} + +void Image::render(const QString& image) +{ + if (!image.isEmpty()) { + m_img = image; + } + // else re-render previous image + m_rendererToken = m_renderer.render(m_img, m_color, m_resizeMethod, + Qt::SmoothTransformation); + suspendStartup(true); // during KDE startup, make ksmserver until the wallpaper is ready +} + +void Image::updateBackground(int token, const QImage &img) +{ + if (m_rendererToken == token) { + m_pixmap = QPixmap::fromImage(img); + emit update(boundingRect()); + suspendStartup(false); + } +} + +void Image::suspendStartup(bool suspend) +{ + org::kde::KSMServerInterface ksmserver("org.kde.ksmserver", "/KSMServer", QDBusConnection::sessionBus()); + const QString startupID("desktop wallaper"); + if (suspend) { + ksmserver.suspendStartup(startupID); + } else { + ksmserver.resumeStartup(startupID); + } +} + +void Image::updateScreenshot(QPersistentModelIndex index) +{ + m_uiImage.m_view->view()->update(index); +} + +void Image::removeBackground(const QString &path) +{ + m_model->removeBackground(path); +} + +#include "image.moc" --- wallpapers/image/slideshowconfig.ui +++ wallpapers/image/slideshowconfig.ui @@ -0,0 +1,278 @@ +<ui version="4.0" > + <class>SlideshowConfig</class> + <widget class="QWidget" name="SlideshowConfig" > + <property name="geometry" > + <rect> + <x>0</x> + <y>0</y> + <width>468</width> + <height>347</height> + </rect> + </property> + <property name="sizePolicy" > + <sizepolicy vsizetype="Fixed" hsizetype="Preferred" > + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <layout class="QGridLayout" name="gridLayout" > + <item row="0" column="0" > + <widget class="QLabel" name="label" > + <property name="minimumSize" > + <size> + <width>75</width> + <height>0</height> + </size> + </property> + <property name="text" > + <string>Folders:</string> + </property> + <property name="alignment" > + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + <property name="buddy" > + <cstring>m_addDir</cstring> + </property> + </widget> + </item> + <item row="0" column="1" > + <widget class="KPushButton" name="m_addDir" > + <property name="sizePolicy" > + <sizepolicy vsizetype="Fixed" hsizetype="Expanding" > + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text" > + <string>&Add Folder...</string> + </property> + </widget> + </item> + <item row="0" column="2" > + <widget class="KPushButton" name="m_removeDir" > + <property name="sizePolicy" > + <sizepolicy vsizetype="Fixed" hsizetype="Expanding" > + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text" > + <string>&Remove Folder</string> + </property> + </widget> + </item> + <item row="0" column="3" > + <spacer name="horizontalSpacer" > + <property name="orientation" > + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0" > + <size> + <width>105</width> + <height>23</height> + </size> + </property> + </spacer> + </item> + <item row="1" column="1" colspan="3" > + <widget class="KListWidget" name="m_dirlist" > + <property name="sizePolicy" > + <sizepolicy vsizetype="Maximum" hsizetype="Expanding" > + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + </widget> + </item> + <item row="2" column="0" > + <widget class="QLabel" name="label_2" > + <property name="minimumSize" > + <size> + <width>125</width> + <height>0</height> + </size> + </property> + <property name="text" > + <string>&Change images every:</string> + </property> + <property name="alignment" > + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + <property name="buddy" > + <cstring>m_slideshowDelay</cstring> + </property> + </widget> + </item> + <item row="2" column="1" colspan="3" > + <layout class="QHBoxLayout" name="horizontalLayout_3" > + <item> + <widget class="QTimeEdit" name="m_slideshowDelay" > + <property name="dateTime" > + <datetime> + <hour>0</hour> + <minute>0</minute> + <second>0</second> + <year>2000</year> + <month>1</month> + <day>1</day> + </datetime> + </property> + <property name="currentSection" > + <enum>QDateTimeEdit::HourSection</enum> + </property> + <property name="displayFormat" > + <string comment="(qtdt-format) Please do not change the quotes (') and translate only the content of the quotes." >hh 'Hours' mm 'Mins' ss 'Secs'</string> + </property> + <property name="time" > + <time> + <hour>0</hour> + <minute>0</minute> + <second>0</second> + </time> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_2" > + <property name="orientation" > + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0" > + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + <item row="3" column="0" > + <widget class="QLabel" name="label_4" > + <property name="minimumSize" > + <size> + <width>75</width> + <height>0</height> + </size> + </property> + <property name="text" > + <string>P&ositioning:</string> + </property> + <property name="alignment" > + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + <property name="buddy" > + <cstring>m_resizeMethod</cstring> + </property> + </widget> + </item> + <item row="3" column="1" colspan="3" > + <layout class="QHBoxLayout" name="horizontalLayout_2" > + <item> + <widget class="QComboBox" name="m_resizeMethod" > + <property name="sizePolicy" > + <sizepolicy vsizetype="Fixed" hsizetype="Preferred" > + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_3" > + <property name="orientation" > + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0" > + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + <item row="4" column="0" > + <widget class="QLabel" name="label_5" > + <property name="text" > + <string>Color:</string> + </property> + <property name="alignment" > + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + <property name="buddy" > + <cstring>m_color</cstring> + </property> + </widget> + </item> + <item row="4" column="1" colspan="3" > + <layout class="QHBoxLayout" name="horizontalLayout" > + <item> + <widget class="KColorButton" name="m_color" > + <property name="color" > + <color> + <red>70</red> + <green>90</green> + <blue>130</blue> + </color> + </property> + <property name="defaultColor" > + <color> + <red>70</red> + <green>90</green> + <blue>130</blue> + </color> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_4" > + <property name="orientation" > + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0" > + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + <item row="5" column="1" colspan="2" > + <spacer name="verticalSpacer" > + <property name="orientation" > + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0" > + <size> + <width>105</width> + <height>5</height> + </size> + </property> + </spacer> + </item> + </layout> + </widget> + <customwidgets> + <customwidget> + <class>KColorButton</class> + <extends>QPushButton</extends> + <header>kcolorbutton.h</header> + </customwidget> + <customwidget> + <class>KListWidget</class> + <extends>QListWidget</extends> + <header>klistwidget.h</header> + </customwidget> + <customwidget> + <class>KPushButton</class> + <extends>QPushButton</extends> + <header>kpushbutton.h</header> + </customwidget> + </customwidgets> + <resources/> + <connections/> +</ui> --- wallpapers/image/wallpaper.knsrc +++ wallpapers/image/wallpaper.knsrc @@ -0,0 +1,4 @@ +[KNewStuff2] +ProvidersUrl=http://download.kde.org/khotnewstuff/wallpaper-providers.xml +StandardResource=wallpaper +CachePolicy=resident --- wallpapers/image/image.h +++ wallpapers/image/image.h @@ -0,0 +1,91 @@ +/* + Copyright (c) 2007 Paolo Capriotti <p.capriotti@gmail.com> + Copyright (c) 2008 by Petri Damsten <damu@iki.fi> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. +*/ + +#ifndef IMAGE_HEADER +#define IMAGE_HEADER + +#include <QTimer> +#include <QPixmap> +#include <QStringList> +#include <plasma/wallpaper.h> +#include "backgroundpackage.h" +#include "renderthread.h" +#include "ui_imageconfig.h" +#include "ui_slideshowconfig.h" + +class KFileDialog; +class BackgroundContainer; +class BackgroundListModel; + +class Image : public Plasma::Wallpaper +{ + Q_OBJECT + public: + Image(QObject* parent, const QVariantList& args); + ~Image(); + + virtual void save(KConfigGroup &config); + virtual void paint(QPainter* painter, const QRectF& exposedRect); + virtual QWidget* createConfigurationInterface(QWidget* parent); + + protected slots: + void timeChanged(const QTime& time); + void positioningChanged(int index); + void slotAddDir(); + void slotRemoveDir(); + void getNewWallpaper(); + void colorChanged(const QColor& color); + void pictureChanged(int index); + void browse(); + void nextSlide(); + void updateBackground(int token, const QImage &img); + void showFileDialog(); + void updateScreenshot(QPersistentModelIndex index); + void removeBackground(const QString &path); + + protected: + void init(const KConfigGroup &config); + void updateDirs(); + void startSlideshow(); + void fillMetaInfo(Background* b); + bool setMetadata(QLabel *label, const QString &text); + void render(const QString& image = QString()); + void suspendStartup(bool suspend); // for ksmserver + void calculateGeometry(); + void setSingleImage(); + + private: + int m_delay; + Background::ResizeMethod m_resizeMethod; + QStringList m_dirs; + QString m_wallpaper; + QColor m_color; + QStringList m_usersWallpapers; + + QWidget* m_widget; + Ui::ImageConfig m_uiImage; + Ui::SlideshowConfig m_uiSlideshow; + QString m_mode; + QList<Background *> m_slideshowBackgrounds; + QTimer m_timer; + QPixmap m_pixmap; + int m_currentSlide; + qreal m_ratio; + BackgroundListModel *m_model; + KFileDialog *m_dialog; + RenderThread m_renderer; + int m_rendererToken; + QSize m_size; + QString m_img; +}; + +K_EXPORT_PLASMA_WALLPAPER(image, Image) + +#endif --- wallpapers/image/backgroundpackage.cpp +++ wallpapers/image/backgroundpackage.cpp @@ -0,0 +1,405 @@ +/* + * Copyright (c) 2007 Paolo Capriotti <p.capriotti@gmail.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, + * or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "backgroundpackage.h" +#include <cmath> +// <cmath> does not define fabs (by the standard, even if it does with gcc) +#include <math.h> +#include <float.h> // FLT_MAX + +#include <QFileInfo> +#include <QPainter> +#include <KDebug> +#include <KLocalizedString> +#include <KStandardDirs> +#include <KDesktopFile> +#include <KConfigGroup> +#include <KSvgRenderer> +#include <plasma/packagestructure.h> +#include <plasma/packagemetadata.h> +#include <ThreadWeaver/Weaver> + +using namespace Plasma; + +class ResizeThread : public ThreadWeaver::Job +{ +public: + ResizeThread(const QString &path, float ratio, QObject *parent = 0); + virtual ~ResizeThread(); + + virtual void start(QPersistentModelIndex index); + virtual void run(); + + QImage result() const; + QPersistentModelIndex index() const; + bool isInitialized() const; +private: + QString m_path; + QImage m_result; + float m_ratio; + QPersistentModelIndex m_index; +}; + +ResizeThread::ResizeThread(const QString &path, float ratio, QObject *parent) +: ThreadWeaver::Job(parent) +, m_path(path) +, m_ratio(ratio) +{ +} + +ResizeThread::~ResizeThread() { +} + +void ResizeThread::start(QPersistentModelIndex index) +{ + m_index = index; + ThreadWeaver::Weaver::instance()->enqueue(this); +} + +bool ResizeThread::isInitialized() const +{ + return m_index.isValid(); +} + +void ResizeThread::run() +{ + m_result = Background::createScreenshot(m_path, m_ratio); +} + +QImage ResizeThread::result() const +{ + if (isFinished()) { + return m_result; + } + else { + return QImage(); + } +} + +QPersistentModelIndex ResizeThread::index() const +{ + return m_index; +} + +Background::~Background() +{ +} + +QImage Background::createScreenshot(const QString &path, float ratio) +{ + if (path.endsWith("svg") || path.endsWith("svgz")) { + KSvgRenderer renderer(path); + QImage img(QSize(int(SCREENSHOT_HEIGHT * ratio), SCREENSHOT_HEIGHT), + QImage::Format_ARGB32_Premultiplied); + img.fill(0); + QPainter p(&img); + renderer.render(&p); + return img; + } + else { + QImage img(path); + if (!img.isNull()) { + return img.scaled(int(SCREENSHOT_HEIGHT * ratio), + SCREENSHOT_HEIGHT, + Qt::KeepAspectRatio); + } + else { + return defaultScreenshot(); + } + } + +} + +QImage Background::defaultScreenshot() +{ + static QImage defaultScreenshotImage; + + if (defaultScreenshotImage.isNull()) { + QImage img(QSize(SCREENSHOT_HEIGHT, SCREENSHOT_HEIGHT), QImage::Format_ARGB32_Premultiplied); + img.fill(Qt::white); + QPainter p(&img); + p.drawText(QRect(0, 0, SCREENSHOT_HEIGHT, SCREENSHOT_HEIGHT), + Qt::AlignHCenter | Qt::AlignVCenter, + "Preview\nnot\navailable"); + defaultScreenshotImage = img; + } + return defaultScreenshotImage; +} + + +class BackgroundPackageStructure : public PackageStructure +{ +public: + static const PackageStructure::Ptr self(); +private: + BackgroundPackageStructure(); // should be used as a singleton + void addResolution(const char *res); +}; + +BackgroundPackageStructure::BackgroundPackageStructure() +: PackageStructure(0, "Background") +{ + QStringList mimetypes; + mimetypes << "image/svg" << "image/png" << "image/jpeg" << "image/jpg"; + setDefaultMimetypes(mimetypes); + + addDirectoryDefinition("images", "images", i18n("Images")); + addFileDefinition("screenshot", "screenshot.png", i18n("Screenshot")); +} + + +const PackageStructure::Ptr BackgroundPackageStructure::self() +{ + static BackgroundPackageStructure::Ptr instance(0); + + if (!instance) { + instance = new BackgroundPackageStructure; + } + + return instance; +} + + + +BackgroundPackage::BackgroundPackage(const QString &path, float ratio) +: Package(path, BackgroundPackageStructure::self()) +, m_path(path) +, m_ratio(ratio) +{ +} + +QString BackgroundPackage::resString(const QSize &size) const +{ + return QString::number(size.width()) + 'x' + QString::number(size.height()); +} + +QSize BackgroundPackage::resSize(const QString &str) const +{ + int index = str.indexOf('x'); + if (index != -1) { + return QSize(str.left(index).toInt(), + str.mid(index + 1).toInt()); + } + else { + return QSize(); + } +} + +QString BackgroundPackage::findBackground(const QSize &size, + ResizeMethod method) const +{ + QStringList images = entryList("images"); + if (images.empty()) { + return QString(); + } + + // choose the nearest resolution + float best = FLT_MAX; + QString bestImage; + foreach (const QString &entry, images) { + QSize candidate = resSize(QFileInfo(entry).baseName()); + if (candidate == QSize()) { + continue; + } + + double dist = distance(candidate, size, method); + //kDebug() << "candidate" << candidate << "distance" << dist; + if (bestImage.isNull() || dist < best) { + bestImage = filePath("images", entry); + best = dist; + //kDebug() << "best" << bestImage; + if (dist == 0) { + break; + } + } + } + + //kDebug() << "best image" << bestImage; + return bestImage; +} + +float BackgroundPackage::distance(const QSize& size, + const QSize& desired, + ResizeMethod method) const +{ + // compute difference of areas + float delta = size.width() * size.height() - + desired.width() * desired.height(); + // scale down to about 1.0 + delta /= 1000000.0; + + switch (method) { + case Scale: { + // Consider first the difference in aspect ratio, + // then in areas. Prefer scaling down. + float deltaRatio = 1.0; + if (size.height() > 0 && desired.height() > 0) { + deltaRatio = size.width() / size.height() - + desired.width() / desired.height(); + } + return fabs(deltaRatio) * 3.0 + (delta >= 0.0 ? delta : -delta + 5.0); + } + case ScaleCrop: + // Difference of areas, slight preference to scale down + return delta >= 0.0 ? delta : -delta + 2.0; + case Center: + default: + // Difference in areas + return fabs(delta); + } +} + +QPixmap BackgroundPackage::screenshot() const +{ + if (m_screenshot.isNull()) { + QString screenshotPath = filePath("screenshot"); + if (!screenshotPath.isEmpty()) { + QImage img = createScreenshot(screenshotPath, m_ratio); + m_screenshot = QPixmap::fromImage(img); + } + } + + return m_screenshot; +} + +bool BackgroundPackage::screenshotGenerationStarted() const +{ + return true; +} + +void BackgroundPackage::generateScreenshot(QPersistentModelIndex) const +{ +} + +QString BackgroundPackage::title() const +{ + QString title = metadata()->name(); + if (title.isEmpty()) { + title = metadata()->pluginName(); + title.replace("_", " "); + } + return title; +} + +QString BackgroundPackage::author() const +{ + return metadata()->author(); +} + +QString BackgroundPackage::email() const +{ + return metadata()->email(); +} + +QString BackgroundPackage::license() const +{ + return metadata()->license(); +} + +bool BackgroundPackage::isValid() const +{ + return Package::isValid(); +} + +QString BackgroundPackage::path() const +{ + return m_path; +} + + +BackgroundFile::BackgroundFile(const QString &file, float ratio) +: m_file(file) +, m_author(QString()) +, m_title(QFileInfo(m_file).baseName()) +, m_ratio(ratio) +, m_resizer_started(false) +{ + if (QFile::exists(m_file+".desktop")) { + KDesktopFile config(m_file+".desktop"); + KConfigGroup cg = config.group("Wallpaper"); + m_title = cg.readEntry("Name", m_title); + m_author = cg.readEntry("Author", QString()); + } +} + +BackgroundFile::~BackgroundFile() +{ +} + +QString BackgroundFile::findBackground(const QSize &, + ResizeMethod) const +{ + return m_file; +} + +QPixmap BackgroundFile::screenshot() const +{ + return m_screenshot; +} + +bool BackgroundFile::screenshotGenerationStarted() const +{ + return m_resizer_started; +} + +void BackgroundFile::generateScreenshot(QPersistentModelIndex index) const +{ + ResizeThread *resizer = new ResizeThread(m_file, m_ratio); + connect(resizer, SIGNAL(done(ThreadWeaver::Job *)), + this, SLOT(updateScreenshot(ThreadWeaver::Job *))); + m_resizer_started = true; + resizer->start(index); +} + +void BackgroundFile::updateScreenshot(ThreadWeaver::Job *job) +{ + ResizeThread *resizer = static_cast<ResizeThread *>(job); + m_screenshot = QPixmap::fromImage(resizer->result()); + emit screenshotDone(resizer->index()); + resizer->deleteLater(); +} + +QString BackgroundFile::author() const +{ + return m_author; +} + +QString BackgroundFile::title() const +{ + return m_title; +} + +QString BackgroundFile::email() const +{ + return QString(); +} + +QString BackgroundFile::license() const +{ + return QString(); +} + +bool BackgroundFile::isValid() const +{ + return true; +} + +QString BackgroundFile::path() const +{ + return m_file; +} --- wallpapers/image/CMakeLists.txt +++ wallpapers/image/CMakeLists.txt @@ -0,0 +1,21 @@ +project(plasma-wallpaper-image) + +set(image_SRCS + image.cpp + backgroundpackage.cpp + renderthread.cpp + backgrounddelegate.cpp + backgroundlistmodel.cpp +) +kde4_add_ui_files(image_SRCS imageconfig.ui slideshowconfig.ui) + +set(ksmserver_xml ${KDEBASE_WORKSPACE_SOURCE_DIR}/ksmserver/org.kde.KSMServerInterface.xml) +qt4_add_dbus_interface(image_SRCS ${ksmserver_xml} ksmserver_interface) + +kde4_add_plugin(plasma_wallpaper_image ${image_SRCS}) +target_link_libraries(plasma_wallpaper_image plasma ${KDE4_KIO_LIBS} ${KDE4_KFILE_LIBS} ${KDE4_KNEWSTUFF2_LIBS} ${KDE4_THREADWEAVER_LIBRARY}) + +install(TARGETS plasma_wallpaper_image DESTINATION ${PLUGIN_INSTALL_DIR}) +install(FILES plasma-wallpaper-image.desktop DESTINATION ${SERVICES_INSTALL_DIR}) + +install(FILES wallpaper.knsrc DESTINATION ${CONFIG_INSTALL_DIR}) --- wallpapers/image/backgroundlistmodel.cpp +++ wallpapers/image/backgroundlistmodel.cpp @@ -0,0 +1,187 @@ +/* + Copyright (c) 2007 Paolo Capriotti <p.capriotti@gmail.com> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. +*/ + +#include "backgroundlistmodel.h" + +#include <QFile> +#include <QDir> +#include <KGlobal> +#include <KStandardDirs> +#include <KDesktopFile> +#include <KConfigGroup> +#include "backgroundpackage.h" +#include "backgrounddelegate.h" + +BackgroundListModel::BackgroundListModel(float ratio, QObject *listener) +: m_listener(listener) +, m_ratio(ratio) +{ + connect(&m_dirwatch, SIGNAL(deleted(QString)), listener, SLOT(removeBackground(QString))); +} + +void BackgroundListModel::removeBackground(const QString &path) +{ + int index; + while ((index = indexOf(path)) != -1) { + beginRemoveRows(QModelIndex(), index, index); + m_packages.removeAt(index); + endRemoveRows(); + } +} + +void BackgroundListModel::reload() +{ + reload(QStringList()); +} + +void BackgroundListModel::reload(const QStringList& selected) +{ + QStringList dirs = KGlobal::dirs()->findDirs("wallpaper", ""); + QList<Background *> tmp; + foreach (const QString &file, selected) { + if (!contains(file) && QFile::exists(file)) { + tmp << new BackgroundFile(file, m_ratio); + } + } + foreach (const QString &dir, dirs) { + tmp += findAllBackgrounds(this, dir, m_ratio); + } + + // add new files to dirwatch + foreach (Background *b, tmp) { + if (!m_dirwatch.contains(b->path())) { + m_dirwatch.addFile(b->path()); + } + } + + if (!tmp.isEmpty()) { + beginInsertRows(QModelIndex(), 0, tmp.size() - 1); + m_packages = tmp + m_packages; + endInsertRows(); + } +} + +void BackgroundListModel::addBackground(const QString& path) { + if (!contains(path)) { + if (!m_dirwatch.contains(path)) { + m_dirwatch.addFile(path); + } + beginInsertRows(QModelIndex(), 0, 0); + m_packages.prepend(new BackgroundFile(path, m_ratio)); + endInsertRows(); + } +} + +int BackgroundListModel::indexOf(const QString &path) const +{ + for (int i = 0; i < m_packages.size(); i++) { + if (path.startsWith(m_packages[i]->path())) { + return i; + } + } + return -1; +} + +bool BackgroundListModel::contains(const QString &path) const +{ + return indexOf(path) != -1; +} + +BackgroundListModel::~BackgroundListModel() +{ + foreach (Background* pkg, m_packages) { + delete pkg; + } +} + +int BackgroundListModel::rowCount(const QModelIndex &) const +{ + return m_packages.size(); +} + +QVariant BackgroundListModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid()) { + return QVariant(); + } + + if (index.row() >= m_packages.size()) { + return QVariant(); + } + + Background *b = package(index.row()); + if (!b) { + return QVariant(); + } + + switch (role) { + case Qt::DisplayRole: + return b->title(); + case BackgroundDelegate::ScreenshotRole: { + QPixmap pix = b->screenshot(); + if (pix.isNull() && !b->screenshotGenerationStarted()) { + connect(b, SIGNAL(screenshotDone(QPersistentModelIndex)), + m_listener, SLOT(updateScreenshot(QPersistentModelIndex)), + Qt::QueuedConnection); + b->generateScreenshot(index); + } + return pix; + } + case BackgroundDelegate::AuthorRole: + return b->author(); + default: + return QVariant(); + } +} + +Background* BackgroundListModel::package(int index) const +{ + return m_packages.at(index); +} + +QList<Background *> BackgroundListModel::findAllBackgrounds(const BackgroundContainer *container, + const QString &path, float ratio) +{ + QList<Background *> res; + + // get all packages in this directory + QStringList packages = Plasma::Package::listInstalled(path); + foreach (const QString &packagePath, packages) + { + kDebug() << packagePath; + std::auto_ptr<Background> pkg(new BackgroundPackage(path+packagePath, ratio)); + if (pkg->isValid() && + (!container || !container->contains(pkg->path()))) { + res.append(pkg.release()); + } + } + + // search normal wallpapers + QDir dir(path); + QStringList filters; + filters << "*.png" << "*.jpeg" << "*.jpg" << "*.svg" << "*.svgz"; + dir.setNameFilters(filters); + dir.setFilter(QDir::Files | QDir::Hidden); + QFileInfoList files = dir.entryInfoList(); + foreach (const QFileInfo &wp, files) + { + bool hidden = false; + if (QFile::exists(wp.filePath()+".desktop")) { + KDesktopFile config(wp.filePath()+".desktop"); + KConfigGroup cg = config.group("Wallpaper"); + hidden = cg.readEntry("Hidden", false); + } + if (!hidden && (!container || !container->contains(wp.filePath()))) { + res.append(new BackgroundFile(wp.filePath(), ratio)); + } + } + return res; +} + + --- wallpapers/CMakeLists.txt +++ wallpapers/CMakeLists.txt @@ -0,0 +1,2 @@ +add_subdirectory(color) +add_subdirectory(image) --- wallpapers/color/color.cpp +++ wallpapers/color/color.cpp @@ -0,0 +1,61 @@ +/* + * Copyright 2008 by Petri Damsten <damu@iki.fi> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "color.h" + +#include <QPainter> +#include <KDebug> + +Color::Color(QObject *parent, const QVariantList &args) + : Plasma::Wallpaper(parent, args), m_color(Qt::gray) +{ +} + +void Color::paint(QPainter *painter, const QRectF& exposedRect) +{ + painter->fillRect(exposedRect, QBrush(m_color)); +} + +void Color::init(const KConfigGroup &config) +{ + m_color = config.readEntry("wallpapercolor", QColor(Qt::gray)); +} + +QWidget* Color::createConfigurationInterface(QWidget* parent) +{ + QWidget *widget = new QWidget(parent); + m_ui.setupUi(widget); + + m_ui.m_color->setColor(m_color); + connect(m_ui.m_color, SIGNAL(changed(const QColor&)), this, SLOT(setColor(const QColor&))); + return widget; +} + +void Color::setColor(const QColor& color) +{ + m_color = color; + emit update(boundingRect()); +} + +void Color::save(KConfigGroup &config) +{ + config.writeEntry("wallpapercolor", m_color); +} + +#include "color.moc" --- wallpapers/color/Messages.sh +++ wallpapers/color/Messages.sh @@ -0,0 +1,2 @@ +#! /usr/bin/env bash +$XGETTEXT *.cpp -o $podir/plasma_wallpaper_color.pot Property changes on: wallpapers/color/Messages.sh ___________________________________________________________________ Added: svn:executable + * --- wallpapers/color/config.ui +++ wallpapers/color/config.ui @@ -0,0 +1,96 @@ +<ui version="4.0" > + <class>Config</class> + <widget class="QWidget" name="Config" > + <property name="geometry" > + <rect> + <x>0</x> + <y>0</y> + <width>381</width> + <height>145</height> + </rect> + </property> + <property name="windowTitle" > + <string>Color</string> + </property> + <layout class="QGridLayout" name="gridLayout" > + <item row="0" column="0" > + <widget class="QLabel" name="label_5" > + <property name="minimumSize" > + <size> + <width>125</width> + <height>0</height> + </size> + </property> + <property name="text" > + <string>&Color:</string> + </property> + <property name="alignment" > + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + <property name="buddy" > + <cstring>m_color</cstring> + </property> + </widget> + </item> + <item row="0" column="1" > + <widget class="KColorButton" name="m_color" > + <property name="sizePolicy" > + <sizepolicy vsizetype="Fixed" hsizetype="Minimum" > + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="color" > + <color> + <red>70</red> + <green>90</green> + <blue>130</blue> + </color> + </property> + <property name="defaultColor" > + <color> + <red>70</red> + <green>90</green> + <blue>130</blue> + </color> + </property> + </widget> + </item> + <item row="0" column="2" > + <spacer name="spacer" > + <property name="orientation" > + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0" > + <size> + <width>87</width> + <height>27</height> + </size> + </property> + </spacer> + </item> + <item row="1" column="0" colspan="3" > + <spacer name="verticalSpacer_2" > + <property name="orientation" > + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0" > + <size> + <width>338</width> + <height>30</height> + </size> + </property> + </spacer> + </item> + </layout> + </widget> + <customwidgets> + <customwidget> + <class>KColorButton</class> + <extends>QPushButton</extends> + <header>kcolorbutton.h</header> + </customwidget> + </customwidgets> + <resources/> + <connections/> +</ui> --- wallpapers/color/color.h +++ wallpapers/color/color.h @@ -0,0 +1,50 @@ +/* + * Copyright 2008 by Petri Damsten <damu@iki.fi> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef COLOR_HEADER +#define COLOR_HEADER + +#include <QColor> +#include <plasma/wallpaper.h> +#include "ui_config.h" + +class Color : public Plasma::Wallpaper +{ + Q_OBJECT + public: + Color(QObject* parent, const QVariantList& args); + + virtual void save(KConfigGroup &config); + virtual void paint(QPainter* painter, const QRectF& exposedRect); + virtual QWidget* createConfigurationInterface(QWidget* parent); + + protected: + virtual void init(const KConfigGroup &config); + + protected slots: + void setColor(const QColor& color); + + private: + Ui::Config m_ui; + QColor m_color; +}; + +K_EXPORT_PLASMA_WALLPAPER(color, Color) + +#endif --- wallpapers/color/plasma-wallpaper-color.desktop +++ wallpapers/color/plasma-wallpaper-color.desktop @@ -0,0 +1,35 @@ +[Desktop Entry] +Name=Color +Name[be@latin]=Koler +Name[el]=Χρώμα +Name[et]=Värv +Name[ga]=Dath +Name[gl]=Cor +Name[gu]=રંગ +Name[ja]=色 +Name[km]=ពណ៌ +Name[nb]=Farge +Name[nds]=Klöör +Name[nn]=Farge +Name[pt]=Cor +Name[pt_BR]=Cor +Name[sl]=Barva +Name[sv]=Färg +Name[te]=రంగు +Name[tr]=Renk +Name[uk]=Колір +Name[zh_TW]=顏色 +Type=Service +Icon=preferences-desktop-color +ServiceTypes=Plasma/Wallpaper + +X-KDE-Library=plasma_wallpaper_color +X-KDE-PluginInfo-Author=Petri Damstén +X-KDE-PluginInfo-Email=damu@iki.fi +X-KDE-PluginInfo-Name=color +X-KDE-PluginInfo-Version=pre0.1 +X-KDE-PluginInfo-Website=http://plasma.kde.org/ +X-KDE-PluginInfo-Depends= +X-KDE-PluginInfo-License=GPL +X-KDE-PluginInfo-EnabledByDefault=true + --- wallpapers/color/CMakeLists.txt +++ wallpapers/color/CMakeLists.txt @@ -0,0 +1,12 @@ +project(plasma-wallpaper-color) + +set(color_SRCS + color.cpp +) +kde4_add_ui_files(color_SRCS config.ui) + +kde4_add_plugin(plasma_wallpaper_color ${color_SRCS}) +target_link_libraries(plasma_wallpaper_color plasma ${KDE4_KIO_LIBS}) + +install(TARGETS plasma_wallpaper_color DESTINATION ${PLUGIN_INSTALL_DIR}) +install(FILES plasma-wallpaper-color.desktop DESTINATION ${SERVICES_INSTALL_DIR}) --- CMakeLists.txt +++ CMakeLists.txt @@ -9,3 +9,4 @@ add_subdirectory(tools) add_subdirectory(containments) add_subdirectory(plasma) +add_subdirectory(wallpapers) --- plasma/wallpaperpreview.h +++ plasma/wallpaperpreview.h @@ -0,0 +1,49 @@ +/* + * Copyright 2008 Petri Damsten <damu@iki.fi> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef WALLPAPER_PREVIEW_HEADER +#define WALLPAPER_PREVIEW_HEADER + +#include <QWidget> + +namespace Plasma{ + class Wallpaper; + class Svg; +} + +class WallpaperPreview : public QWidget +{ + Q_OBJECT +public: + WallpaperPreview(QWidget *parent = 0); + virtual ~WallpaperPreview(); + + void setWallpaper(Plasma::Wallpaper* wallpaper); + +protected: + virtual void paintEvent(QPaintEvent* event); + virtual void resizeEvent(QResizeEvent* event); + +protected slots: + void updateRect(const QRectF& rect); + +private: + Plasma::Wallpaper* m_wallpaper; + Plasma::Svg* m_wallpaperOverlay; +}; + +#endif // WALLPAPER_PREVIEW --- plasma/plasma-themes.knsrc +++ plasma/plasma-themes.knsrc @@ -0,0 +1,4 @@ +[KNewStuff2] +ProvidersUrl=http://download.kde.org/khotnewstuff/plasmathemes-providers.xml +TargetDir=desktoptheme +Uncompress=true --- plasma/panelview.h +++ plasma/panelview.h @@ -27,12 +27,17 @@ #include <plasma/plasma.h> #include <plasma/view.h> +#ifdef Q_WS_X11 +#include <X11/Xlib.h> +#include <fixx11h.h> +#endif + #ifdef Q_WS_WIN #include <windows.h> -#include <shellapi.h> #endif class QWidget; +class QTimeLine; namespace Plasma { @@ -42,6 +47,7 @@ } class PanelController; + class PanelAppletOverlay; class PanelView : public Plasma::View @@ -49,6 +55,12 @@ Q_OBJECT public: + enum PanelMode { + NormalPanel = 0, + AutoHide, + LetWindowsCover + }; + /** * Constructs a new panelview. * @arg parent the QWidget this panel is parented to @@ -62,11 +74,16 @@ Plasma::Location location() const; /** + * @return panel behaviour + */ + PanelMode panelMode() const; + + /** * @return the Corona (scene) associated with this panel. */ Plasma::Corona *corona() const; - /** + /* * @return the offset of the panel from the left screen edge */ int offset() const; @@ -80,6 +97,16 @@ * Pinches the min/max sizes of the containment to the current screen resolution */ void pinchContainment(const QRect &screenGeometry); +#ifdef Q_WS_X11 + /** + * @return the unhide trigger window id, None if there is none + */ + Window unhideTrigger() { return m_unhideTrigger; } +#endif + /** + * unhides the panel if it is hidden + */ + void unhide(); public Q_SLOTS: /** @@ -106,15 +133,44 @@ */ void setLocation(Plasma::Location location); + /** + * Sets the panel behaviour + * @param mode + */ + void setPanelMode(PanelView::PanelMode mode); + protected: void updateStruts(); void moveEvent(QMoveEvent *event); void resizeEvent(QResizeEvent *event); + void leaveEvent(QEvent *event); + void drawBackground(QPainter * painter, const QRectF & rect); + void paintEvent(QPaintEvent *event); + bool event(QEvent *event); +private: + void createUnhideTrigger(); + void destroyUnhideTrigger(); + Qt::Alignment alignmentFilter(Qt::Alignment align) const; + bool isHorizontal() const; + QTimeLine *timeLine(); + +#ifdef Q_WS_WIN + bool registerAccessBar(HWND hwndAccessBar, bool fRegister); + void appBarQuerySetPos(uint uEdge, LPRECT lprc, PAPPBARDATA pabd); + void appBarCallback(MSG *message, long *result); + void appBarPosChanged(PAPPBARDATA pabd); + bool winEvent(MSG *message, long *result); + bool m_barRegistered; +#endif + private Q_SLOTS: + void checkForActivation(); void showAppletBrowser(); void togglePanelController(); void edittingComplete(); + void animateHide(qreal); + void panelDeleted(); /** * Updates the panel's position according to the screen and containment @@ -123,28 +179,25 @@ void updatePanelGeometry(); private: - Qt::Alignment alignmentFilter(Qt::Alignment align) const; - bool isHorizontal() const; -#ifdef Q_WS_WIN - bool registerAccessBar(HWND hwndAccessBar, bool fRegister); - void appBarQuerySetPos(uint uEdge, LPRECT lprc, PAPPBARDATA pabd); - void appBarCallback(MSG *message, long *result); - void appBarPosChanged(PAPPBARDATA pabd); - bool winEvent(MSG *message, long *result); - bool m_barRegistered; -#endif - Plasma::Svg *m_background; PanelController *m_panelController; QList<PanelAppletOverlay*> m_moveOverlays; + QTimeLine *m_timeLine; int m_offset; Qt::Alignment m_alignment; +#ifdef Q_WS_X11 + Window m_unhideTrigger; +#endif + QSizeF m_lastMin; QSizeF m_lastMax; + PanelMode m_panelMode; int m_lastSeenSize; - bool m_lastHorizontal; - bool m_editting; + bool m_lastHorizontal : 1; + + bool m_editting : 1; + bool m_firstPaint : 1; }; #endif --- plasma/backgrounddialog.cpp +++ plasma/backgrounddialog.cpp @@ -0,0 +1,586 @@ +/* + Copyright (c) 2007 Paolo Capriotti <p.capriotti@gmail.com> + Copyright (C) 2007 Ivan Cukic <ivan.cukic+kde@gmail.com> + Copyright (c) 2008 by Petri Damsten <damu@iki.fi> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. +*/ + +#include "backgrounddialog.h" + +#include <QPainter> +#include <QFile> +#include <QAbstractItemView> +#include <QStandardItemModel> + +#include <KStandardDirs> +#include <KDesktopFile> +#include <KColorScheme> +#include <KNS/Engine> + +#include <plasma/containment.h> +#include <plasma/panelsvg.h> +#include <plasma/theme.h> +#include <plasma/wallpaper.h> +#include <plasma/view.h> +#include <plasma/corona.h> + +#include "wallpaperpreview.h" + +typedef QPair<QString, QString> WallpaperInfo; +Q_DECLARE_METATYPE(WallpaperInfo) + +class ThemeInfo +{ +public: + QString package; + Plasma::PanelSvg *svg; +}; + +class ThemeModel : public QAbstractListModel +{ +public: + enum { PackageNameRole = Qt::UserRole, + SvgRole = Qt::UserRole + 1 + }; + + ThemeModel(QObject *parent = 0); + virtual ~ThemeModel(); + + virtual int rowCount(const QModelIndex &parent = QModelIndex()) const; + virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; + int indexOf(const QString &path) const; + void reload(); +private: + QMap<QString, ThemeInfo> m_themes; +}; + +ThemeModel::ThemeModel( QObject *parent ) +: QAbstractListModel( parent ) +{ + reload(); +} + +ThemeModel::~ThemeModel() +{ +} + +void ThemeModel::reload() +{ + reset(); + foreach (const QString& key, m_themes.keys()) { + delete m_themes[key].svg; + } + m_themes.clear(); + + // get all desktop themes + KStandardDirs dirs; + QStringList themes = dirs.findAllResources("data", "desktoptheme/*/metadata.desktop", + KStandardDirs::NoDuplicates); + foreach (const QString &theme, themes) { + kDebug() << theme; + int themeSepIndex = theme.lastIndexOf('/', -1); + QString themeRoot = theme.left(themeSepIndex); + int themeNameSepIndex = themeRoot.lastIndexOf('/', -1); + QString packageName = themeRoot.right(themeRoot.length() - themeNameSepIndex - 1); + + KDesktopFile df(theme); + QString name = df.readName(); + if (name.isEmpty()) { + name = packageName; + } + + Plasma::PanelSvg *svg = new Plasma::PanelSvg(this); + QString svgFile = themeRoot + "/widgets/background.svg"; + if (QFile::exists(svgFile)) { + svg->setImagePath(svgFile); + } else { + svg->setImagePath(svgFile + "z"); + } + svg->setEnabledBorders(Plasma::PanelSvg::AllBorders); + ThemeInfo info; + info.package = packageName; + info.svg = svg; + m_themes[name] = info; + } + + beginInsertRows(QModelIndex(), 0, m_themes.size()); + endInsertRows(); +} + +int ThemeModel::rowCount(const QModelIndex &) const +{ + return m_themes.size(); +} + +QVariant ThemeModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid()) { + return QVariant(); + } + + if (index.row() >= m_themes.size()) { + return QVariant(); + } + + QMap<QString, ThemeInfo>::const_iterator it = m_themes.constBegin(); + for (int i = 0; i < index.row(); ++i) { + ++it; + } + + switch (role) { + case Qt::DisplayRole: + return it.key(); + case PackageNameRole: + return (*it).package; + case SvgRole: + return qVariantFromValue((void*)(*it).svg); + default: + return QVariant(); + } +} + +int ThemeModel::indexOf(const QString &name) const +{ + QMapIterator<QString, ThemeInfo> it(m_themes); + int i = -1; + while (it.hasNext()) { + ++i; + if (it.next().value().package == name) { + return i; + } + } + + return -1; +} + + +class ThemeDelegate : public QAbstractItemDelegate +{ +public: + ThemeDelegate(QObject * parent = 0); + + virtual void paint(QPainter *painter, + const QStyleOptionViewItem &option, + const QModelIndex &index) const; + virtual QSize sizeHint(const QStyleOptionViewItem &option, + const QModelIndex &index) const; +private: + static const int MARGIN = 5; +}; + +ThemeDelegate::ThemeDelegate(QObject* parent) +: QAbstractItemDelegate(parent) +{ +} + +void ThemeDelegate::paint(QPainter *painter, + const QStyleOptionViewItem &option, + const QModelIndex &index) const +{ + QString title = index.model()->data(index, Qt::DisplayRole).toString(); + QString package = index.model()->data(index, ThemeModel::PackageNameRole).toString(); + + // highlight selected item + painter->save(); + if (option.state & QStyle::State_Selected) { + painter->setBrush(option.palette.color(QPalette::Highlight)); + } else { + painter->setBrush(Qt::gray); + } + painter->drawRect(option.rect); + painter->restore(); + + // draw image + Plasma::PanelSvg *svg = static_cast<Plasma::PanelSvg *>( + index.model()->data(index, ThemeModel::SvgRole).value<void *>()); + svg->resizePanel(QSize(option.rect.width() - (2 * MARGIN), 100 - (2 * MARGIN))); + QRect imgRect = QRect(option.rect.topLeft(), + QSize(option.rect.width() - (2 * MARGIN), 100 - (2 * MARGIN))) + .translated(MARGIN, MARGIN); + svg->paintPanel( painter, imgRect, QPoint(option.rect.left() + MARGIN, option.rect.top() + MARGIN) ); + + // draw text + painter->save(); + QFont font = painter->font(); + font.setWeight(QFont::Bold); + QString colorFile = KStandardDirs::locate("data", "desktoptheme/" + package + "/colors"); + if (!colorFile.isEmpty()) { + KSharedConfigPtr colors = KSharedConfig::openConfig(colorFile); + KColorScheme colorScheme(QPalette::Active, KColorScheme::Window, colors); + painter->setPen(colorScheme.foreground(KColorScheme::NormalText).color()); + } + painter->setFont(font); + painter->drawText(option.rect, Qt::AlignCenter | Qt::TextWordWrap, title); + painter->restore(); +} + +QSize ThemeDelegate::sizeHint(const QStyleOptionViewItem &, const QModelIndex &) const +{ + return QSize(200, 100); +} + +// From kcategorizeditemsviewdelegate by Ivan Cukic +#define EMBLEM_ICON_SIZE 16 +#define UNIVERSAL_PADDING 6 +#define FADE_LENGTH 32 +#define MAIN_ICON_SIZE 48 + +class AppletDelegate : public QAbstractItemDelegate +{ +public: + enum { DescriptionRole = Qt::UserRole + 1, PluginNameRole }; + + AppletDelegate(QObject * parent = 0); + + virtual void paint(QPainter* painter, const QStyleOptionViewItem& option, + const QModelIndex& index) const; + virtual QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const; + int calcItemHeight(const QStyleOptionViewItem& option) const; +}; + +AppletDelegate::AppletDelegate(QObject* parent) +: QAbstractItemDelegate(parent) +{ +} + +void AppletDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, + const QModelIndex& index) const +{ + QStyleOptionViewItemV4 opt(option); + QStyle *style = opt.widget ? opt.widget->style() : QApplication::style(); + style->drawPrimitive(QStyle::PE_PanelItemViewItem, &opt, painter, opt.widget); + + const int left = option.rect.left(); + const int top = option.rect.top(); + const int width = option.rect.width(); + const int height = calcItemHeight(option); + + bool leftToRight = (painter->layoutDirection() == Qt::LeftToRight); + QIcon::Mode iconMode = QIcon::Normal; + + QColor foregroundColor = (option.state.testFlag(QStyle::State_Selected)) ? + option.palette.color(QPalette::HighlightedText) : option.palette.color(QPalette::Text); + + // Painting main column + QFont titleFont = option.font; + titleFont.setBold(true); + titleFont.setPointSize(titleFont.pointSize() + 2); + + QPixmap pixmap(width, height); + pixmap.fill(Qt::transparent); + QPainter p(&pixmap); + p.translate(-option.rect.topLeft()); + + QLinearGradient gradient; + + QString title = index.model()->data(index, Qt::DisplayRole).toString(); + QString description = index.model()->data(index, AppletDelegate::DescriptionRole).toString(); + + // Painting + + // Text + int textInner = 2 * UNIVERSAL_PADDING + MAIN_ICON_SIZE; + + p.setPen(foregroundColor); + p.setFont(titleFont); + p.drawText(left + (leftToRight ? textInner : 0), + top, width - textInner, height / 2, + Qt::AlignBottom | Qt::AlignLeft, title); + p.setFont(option.font); + p.drawText(left + (leftToRight ? textInner : 0), + top + height / 2, + width - textInner, height / 2, + Qt::AlignTop | Qt::AlignLeft, description); + + // Main icon + const QIcon& icon = qVariantValue<QIcon>(index.model()->data(index, Qt::DecorationRole)); + icon.paint(&p, + leftToRight ? left + UNIVERSAL_PADDING : left + width - UNIVERSAL_PADDING - MAIN_ICON_SIZE, + top + UNIVERSAL_PADDING, MAIN_ICON_SIZE, MAIN_ICON_SIZE, Qt::AlignCenter, iconMode); + + // Gradient part of the background - fading of the text at the end + if (leftToRight) { + gradient = QLinearGradient(left + width - UNIVERSAL_PADDING - FADE_LENGTH, 0, + left + width - UNIVERSAL_PADDING, 0); + gradient.setColorAt(0, Qt::white); + gradient.setColorAt(1, Qt::transparent); + } else { + gradient = QLinearGradient(left + UNIVERSAL_PADDING, 0, + left + UNIVERSAL_PADDING + FADE_LENGTH, 0); + gradient.setColorAt(0, Qt::transparent); + gradient.setColorAt(1, Qt::white); + } + + QRect paintRect = option.rect; + p.setCompositionMode(QPainter::CompositionMode_DestinationIn); + p.fillRect(paintRect, gradient); + + if (leftToRight) { + gradient.setStart(left + width - FADE_LENGTH, 0); + gradient.setFinalStop(left + width, 0); + } else { + gradient.setStart(left + UNIVERSAL_PADDING, 0); + gradient.setFinalStop(left + UNIVERSAL_PADDING + FADE_LENGTH, 0); + } + paintRect.setHeight(UNIVERSAL_PADDING + MAIN_ICON_SIZE / 2); + p.fillRect(paintRect, gradient); + p.end(); + + painter->drawPixmap(option.rect.topLeft(), pixmap); +} + +int AppletDelegate::calcItemHeight(const QStyleOptionViewItem& option) const +{ + // Painting main column + QFont titleFont = option.font; + titleFont.setBold(true); + titleFont.setPointSize(titleFont.pointSize() + 2); + + int textHeight = QFontInfo(titleFont).pixelSize() + QFontInfo(option.font).pixelSize(); + //kDebug() << textHeight << qMax(textHeight, MAIN_ICON_SIZE) + 2 * UNIVERSAL_PADDING; + return qMax(textHeight, MAIN_ICON_SIZE) + 2 * UNIVERSAL_PADDING; +} + +QSize AppletDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const +{ + Q_UNUSED(index) + return QSize(200, calcItemHeight(option)); +} + +BackgroundDialog::BackgroundDialog(const QSize& res, Plasma::View* view, QWidget* parent) + : KDialog(parent), + m_themeModel(0), + m_containmentModel(0), + m_wallpaper(0), + m_view(view), + m_containment(m_view->containment()), + m_preview(0) +{ + setWindowIcon(KIcon("preferences-desktop-wallpaper")); + setCaption(i18n("Desktop Settings")); + showButtonSeparator(true); + setButtons(Ok | Cancel | Apply); + + QWidget * main = new QWidget(this); + setupUi(main); + + // Size of monitor image: 200x186 + // Geometry of "display" part of monitor image: (23,14)-[151x115] + qreal previewRatio = (qreal)res.height() / (qreal)res.width(); + QSize monitorSize(200, int(200 * previewRatio)); + + Plasma::PanelSvg *svg = new Plasma::PanelSvg(this); + svg->setImagePath("widgets/monitor"); + svg->resizePanel(monitorSize); + QPixmap monitorPix(monitorSize + QSize(0, svg->elementSize("base").height() - svg->marginSize(Plasma::BottomMargin))); + monitorPix.fill(Qt::transparent); + + QPainter painter(&monitorPix); + QPoint standPosizion(monitorSize.width()/2 - svg->elementSize("base").width()/2, svg->contentsRect().bottom()); + svg->paint(&painter, standPosizion, "base"); + svg->paintPanel(&painter, monitorPix.rect()); + painter.end(); + + m_monitor->setPixmap(monitorPix); + m_monitor->setWhatsThis(i18n( + "This picture of a monitor contains a preview of " + "what the current settings will look like on your desktop.")); + m_preview = new WallpaperPreview(m_monitor); + m_preview->setGeometry(svg->contentsRect().toRect()); + + connect(m_newThemeButton, SIGNAL(clicked()), this, SLOT(getNewThemes())); + + connect(this, SIGNAL(finished(int)), this, SLOT(cleanup())); + connect(this, SIGNAL(okClicked()), this, SLOT(saveConfig())); + connect(this, SIGNAL(applyClicked()), this, SLOT(saveConfig())); + + m_themeModel = new ThemeModel(this); + m_theme->setModel(m_themeModel); + m_theme->setItemDelegate(new ThemeDelegate(m_theme->view())); + m_theme->view()->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel); + + m_containmentModel = new QStandardItemModel(this); + m_containmentComboBox->setModel(m_containmentModel); + m_containmentComboBox->setItemDelegate(new AppletDelegate()); + + setMainWidget(main); + reloadConfig(); + adjustSize(); +} + +BackgroundDialog::~BackgroundDialog() +{ + cleanup(); +} + +void BackgroundDialog::cleanup() +{ + delete m_wallpaper; + m_wallpaper = 0; +} + +void BackgroundDialog::getNewThemes() +{ + KNS::Engine engine(0); + if (engine.init("plasma-themes.knsrc")) { + KNS::Entry::List entries = engine.downloadDialogModal(this); + + if (entries.size() > 0) { + m_themeModel->reload(); + m_theme->setCurrentIndex(m_themeModel->indexOf( + Plasma::Theme::defaultTheme()->themeName())); + } + } +} + +void BackgroundDialog::reloadConfig() +{ + disconnect(m_wallpaperMode, SIGNAL(currentIndexChanged(int)), this, SLOT(changeBackgroundMode(int))); + m_containment = m_view->containment(); + int containmentIndex = 0; + int wallpaperIndex = 0; + + // Containment + KPluginInfo::List plugins = Plasma::Containment::listContainments(); + m_containmentModel->clear(); + int i = 0; + foreach (KPluginInfo info, plugins) { + QStandardItem* item = new QStandardItem(KIcon(info.icon()), info.name()); + item->setData(info.comment(), AppletDelegate::DescriptionRole); + item->setData(info.pluginName(), AppletDelegate::PluginNameRole); + m_containmentModel->appendRow(item); + if (info.pluginName() == m_containment->pluginName()) { + containmentIndex = i; + } + ++i; + } + m_containmentComboBox->setCurrentIndex(containmentIndex); + + // Wallpaper + bool doWallpaper = m_containment->drawWallpaper(); + m_wallpaperLabel->setVisible(doWallpaper); + m_wallpaperGroup->setVisible(doWallpaper); + if (doWallpaper) { + // Load wallpaper plugins + QString currentPlugin; + QString currentMode; + + Plasma::Wallpaper *currentWallpaper = m_containment->wallpaper(); + if (currentWallpaper) { + currentPlugin = currentWallpaper->pluginName(); + currentMode = currentWallpaper->renderingMode().name(); + } + + plugins = Plasma::Wallpaper::listWallpaperInfo(); + m_wallpaperMode->clear(); + i = 0; + foreach (KPluginInfo info, plugins) { + bool matches = info.pluginName() == currentPlugin; + const QList<KServiceAction>& modes = info.service()->actions(); + if (modes.count() > 0) { + foreach (const KServiceAction& mode, modes) { + m_wallpaperMode->addItem(KIcon(mode.icon()), mode.text(), + QVariant::fromValue(WallpaperInfo(info.pluginName(), mode.name()))); + if (matches && mode.name() == currentMode) { + wallpaperIndex = i; + } + ++i; + } + } else { + m_wallpaperMode->addItem(KIcon(info.icon()), info.name(), + QVariant::fromValue(WallpaperInfo(info.pluginName(), QString()))); + if (matches) { + wallpaperIndex = i; + } + ++i; + } + } + m_wallpaperMode->setCurrentIndex(wallpaperIndex); + changeBackgroundMode(wallpaperIndex); + } + + // Theme + m_theme->setCurrentIndex(m_themeModel->indexOf(Plasma::Theme::defaultTheme()->themeName())); + + connect(m_wallpaperMode, SIGNAL(currentIndexChanged(int)), this, SLOT(changeBackgroundMode(int))); +} + +void BackgroundDialog::changeBackgroundMode(int mode) +{ + kDebug(); + QWidget* w = 0; + WallpaperInfo wallpaperInfo = m_wallpaperMode->itemData(mode).value<WallpaperInfo>(); + + if (m_wallpaperGroup->layout()->count() > 1) { + delete dynamic_cast<QWidgetItem*>(m_wallpaperGroup->layout()->takeAt(1))->widget(); + } + + if (m_wallpaper && m_wallpaper->pluginName() != wallpaperInfo.first) { + delete m_wallpaper; + m_wallpaper = 0; + } + + if (!m_wallpaper) { + m_wallpaper = Plasma::Wallpaper::load(wallpaperInfo.first); + m_preview->setWallpaper(m_wallpaper); + } + + if (m_wallpaper) { + KConfigGroup cfg = wallpaperConfig(wallpaperInfo.first); + kDebug() << "making a" << wallpaperInfo.first << "in mode" << wallpaperInfo.second; + m_wallpaper->restore(cfg, wallpaperInfo.second); + w = m_wallpaper->createConfigurationInterface(m_wallpaperGroup); + } + + if (!w) { + w = new QWidget(m_wallpaperGroup); + } + + m_wallpaperGroup->layout()->addWidget(w); +} + +KConfigGroup BackgroundDialog::wallpaperConfig(const QString &plugin) +{ + Q_ASSERT(m_containment); + + //FIXME: we have details about the structure of the containment config duplicated here! + KConfigGroup cfg = m_containment->config(); + cfg = KConfigGroup(&cfg, "Wallpaper"); + return KConfigGroup(&cfg, plugin); +} + +void BackgroundDialog::saveConfig() +{ + QString theme = m_theme->itemData(m_theme->currentIndex(), + ThemeModel::PackageNameRole).toString(); + QString wallpaperPlugin = m_wallpaperMode->itemData(m_wallpaperMode->currentIndex()).value<WallpaperInfo>().first; + QString wallpaperMode = m_wallpaperMode->itemData(m_wallpaperMode->currentIndex()).value<WallpaperInfo>().second; + QString containment = m_containmentComboBox->itemData(m_containmentComboBox->currentIndex(), + AppletDelegate::PluginNameRole).toString(); + + // Containment + if (m_containment->pluginName() != containment) { + m_containment = m_view->swapContainment(containment); + } + + // Wallpaper + Plasma::Wallpaper *currentWallpaper = m_containment->wallpaper(); + if (currentWallpaper) { + KConfigGroup cfg = wallpaperConfig(currentWallpaper->pluginName()); + currentWallpaper->save(cfg); + } + + if (m_wallpaper) { + KConfigGroup cfg = wallpaperConfig(m_wallpaper->pluginName()); + m_wallpaper->save(cfg); + } + + m_containment->setWallpaper(wallpaperPlugin, wallpaperMode); + + // Plasma Theme + Plasma::Theme::defaultTheme()->setThemeName(theme); +} --- plasma/panelcontroller.cpp +++ plasma/panelcontroller.cpp @@ -1,4 +1,4 @@ - /* +/* * Copyright 2008 Marco Martin <notmart@gmail.com> * * This program is free software; you can redistribute it and/or modify @@ -22,13 +22,16 @@ #include <QAction> #include <QApplication> #include <QBoxLayout> +#include <QVBoxLayout> #include <QDesktopWidget> #include <QFrame> +#include <QLabel> #include <QMouseEvent> #include <QPainter> #include <QToolButton> #include <KColorUtils> +#include <KIconLoader> #include <KIcon> #include <KWindowSystem> @@ -36,6 +39,8 @@ #include <plasma/corona.h> #include <plasma/paintutils.h> #include <plasma/theme.h> +#include <plasma/svg.h> +#include <plasma/dialog.h> #include "plasmaapp.h" #include "positioningruler.h" @@ -83,89 +88,7 @@ } }; -class PanelController::ResizeHandle: public QWidget -{ -public: - ResizeHandle(QWidget *parent) - : QWidget(parent), - m_mouseOver(false) - { - setCursor(Qt::SizeVerCursor); - } - QSize sizeHint() const - { - return QSize(4, 4); - } - - void paintEvent(QPaintEvent *event) - { - QPainter painter(this); - QColor backColor = Plasma::Theme::defaultTheme()->color(Plasma::Theme::TextColor); - - if (m_mouseOver) { - backColor.setAlphaF(0.50); - } else { - backColor.setAlphaF(0.30); - } - - painter.fillRect(event->rect(), backColor); - - // draw 3 dots to resemble other resize handles - int diameter = qMin(width(), height()); - QRect dotRect(QPoint(0,0), QSize(diameter, diameter)); - dotRect.moveCenter(mapFromParent(geometry().center())); - - painter.setRenderHint(QPainter::Antialiasing, true); - - paintDot(&painter, dotRect); - - //other two dots - if (size().width() > size().height()) { - dotRect.translate(-diameter*2, 0); - paintDot(&painter, dotRect); - dotRect.translate(diameter*4, 0); - paintDot(&painter, dotRect); - } else { - dotRect.translate(0, -diameter*2); - paintDot(&painter, dotRect); - dotRect.translate(0, diameter*4); - paintDot(&painter, dotRect); - } - } - -protected: - void enterEvent(QEvent * event) - { - m_mouseOver = true; - update(); - } - - void leaveEvent(QEvent * event) - { - m_mouseOver = false; - update(); - } - -private: - void paintDot(QPainter *painter, QRect dotRect) - { - QLinearGradient gradient(dotRect.left(), dotRect.top(), dotRect.left(), dotRect.bottom()); - QColor firstColor = Plasma::Theme::defaultTheme()->color(Plasma::Theme::BackgroundColor); - firstColor.setAlphaF(0.6); - QColor secondColor = Plasma::Theme::defaultTheme()->color(Plasma::Theme::TextColor); - secondColor.setAlphaF(0.6); - gradient.setColorAt(0, firstColor); - gradient.setColorAt(1, secondColor); - - painter->setBrush(gradient); - painter->setPen(Qt::NoPen); - painter->drawEllipse(dotRect); - } - - bool m_mouseOver; -}; - class PanelController::Private { public: @@ -180,7 +103,8 @@ startDragPos(0,0), leftAlignTool(0), centerAlignTool(0), - rightAlignTool(0) + rightAlignTool(0), + drawMoveHint(false) { } @@ -242,7 +166,7 @@ return; } - QSize preferredSize(containment->size().toSize()); + QSize preferredSize(containment->preferredSize().toSize()); switch (location) { case Plasma::LeftEdge: @@ -284,9 +208,94 @@ ruler->setOffset(0); } + void panelModeChanged(bool toggle) + { + if (!toggle) { + return; + } + + if (q->sender() == normalPanelTool) { + emit q->panelModeChanged(PanelView::NormalPanel); + } else if (q->sender() == autoHideTool) { + emit q->panelModeChanged(PanelView::AutoHide); + } else if (q->sender() == underWindowsTool) { + emit q->panelModeChanged(PanelView::LetWindowsCover); + } + } + + void settingsPopup() + { + if (optionsDialog->isVisible()) { + optionsDialog->hide(); + } else { + KWindowSystem::setState(optionsDialog->winId(), NET::SkipTaskbar | NET::SkipPager | NET::Sticky); + QPoint pos = q->mapToGlobal(settingsTool->pos()); + optionsDialog->layout()->activate(); + optionsDialog->resize(optionsDialog->sizeHint()); + QSize s = optionsDialog->size(); + + switch (location) { + case Plasma::BottomEdge: + pos = QPoint(pos.x(), pos.y() - s.height()); + break; + case Plasma::TopEdge: + pos = QPoint(pos.x(), pos.y() + settingsTool->size().height()); + break; + case Plasma::LeftEdge: + pos = QPoint(pos.x() + settingsTool->size().width(), pos.y()); + break; + case Plasma::RightEdge: + pos = QPoint(pos.x() - s.width(), pos.y()); + break; + default: + if (pos.y() - s.height() > 0) { + pos = QPoint(pos.x(), pos.y() - s.height()); + } else { + pos = QPoint(pos.x(), pos.y() + settingsTool->size().height()); + } + } + + QRect screenRect = QApplication::desktop()->screenGeometry(containment->screen()); + + if (pos.rx() + s.width() > screenRect.right()) { + pos.rx() -= ((pos.rx() + s.width()) - screenRect.right()); + } + + if (pos.ry() + s.height() > screenRect.bottom()) { + pos.ry() -= ((pos.ry() + s.height()) - screenRect.bottom()); + } + + pos.rx() = qMax(0, pos.rx()); + optionsDialog->move(pos); + optionsDialog->show(); + } + } + + void syncRuler() + { + QRect screenGeom = + QApplication::desktop()->screenGeometry(containment->screen()); + + switch (location) { + case Plasma::LeftEdge: + case Plasma::RightEdge: + ruler->setAvailableLength(screenGeom.height()); + ruler->setMaxLength(qMin((int)containment->maximumSize().height(), screenGeom.height())); + ruler->setMinLength(containment->minimumSize().height()); + break; + case Plasma::TopEdge: + case Plasma::BottomEdge: + default: + ruler->setAvailableLength(screenGeom.width()); + ruler->setMaxLength(qMin((int)containment->maximumSize().width(), screenGeom.width())); + ruler->setMinLength(containment->minimumSize().width()); + break; + } + } + enum DragElement { NoElement = 0, - ResizeHandleElement, - PanelControllerElement + ResizeButtonElement, + MoveButtonElement }; PanelController *q; @@ -295,21 +304,35 @@ Plasma::Location location; QBoxLayout *extLayout; QBoxLayout *layout; - QBoxLayout *alignLayout; + QLabel *alignLabel; + QLabel *modeLabel; DragElement dragging; QPoint startDragPos; + Plasma::Svg *svg; + Plasma::Dialog *optionsDialog; + QBoxLayout *optDialogLayout; + ToolButton *settingsTool; + ToolButton *moveTool; + ToolButton *sizeTool; + //Alignment buttons ToolButton *leftAlignTool; ToolButton *centerAlignTool; ToolButton *rightAlignTool; + //Panel mode buttons + ToolButton *normalPanelTool; + ToolButton *autoHideTool; + ToolButton *underWindowsTool; + //Widgets for actions QList<QWidget *> actionWidgets; - ResizeHandle *panelHeightHandle; PositioningRuler *ruler; + bool drawMoveHint; + static const int minimumHeight = 10; }; @@ -317,19 +340,26 @@ : QWidget(0), d(new Private(this)) { + Q_UNUSED(parent) + + QPalette pal = palette(); + pal.setBrush(backgroundRole(), Qt::transparent); + QWidget::setPalette(pal); + + d->svg = new Plasma::Svg(this); + d->svg->setImagePath("widgets/containment-controls"); + d->svg->setContainsMultipleImages(true); + //setWindowFlags(Qt::Popup); setWindowFlags(Qt::FramelessWindowHint); KWindowSystem::setState(winId(), NET::SkipTaskbar | NET::SkipPager | NET::Sticky); setAttribute(Qt::WA_DeleteOnClose); setFocus(Qt::ActiveWindowFocusReason); - //Resize handles - d->panelHeightHandle = new ResizeHandle(this); //layout setup d->extLayout = new QBoxLayout(QBoxLayout::TopToBottom, this); d->extLayout->setContentsMargins(0, 1, 0, 0); setLayout(d->extLayout); - d->extLayout->addWidget(d->panelHeightHandle); d->layout = new QBoxLayout(QBoxLayout::LeftToRight); d->layout->setContentsMargins(4, 4, 4, 4); @@ -339,6 +369,7 @@ d->layout->setDirection(QBoxLayout::LeftToRight); } d->layout->setSpacing(4); + d->layout->addStretch(); d->extLayout->addLayout(d->layout); @@ -347,34 +378,91 @@ //alignment //first the container QFrame *alignFrame = new ButtonGroup(this); - d->alignLayout = new QBoxLayout(d->layout->direction(), alignFrame); - alignFrame->setLayout(d->alignLayout); - d->layout->addWidget(alignFrame); - - d->leftAlignTool = d->addTool("format-justify-left", i18n("Align panel to left"), alignFrame, Qt::ToolButtonIconOnly, true); - d->alignLayout->addWidget(d->leftAlignTool); + QVBoxLayout *alignLayout = new QVBoxLayout(alignFrame); + + + d->alignLabel = new QLabel(i18n("Panel Alignment"), this); + alignLayout->addWidget(d->alignLabel); + + d->leftAlignTool = d->addTool("format-justify-left", i18n("Left"), alignFrame, Qt::ToolButtonTextBesideIcon, true); + d->leftAlignTool->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); + alignLayout->addWidget(d->leftAlignTool); d->leftAlignTool->setChecked(true); connect(d->leftAlignTool, SIGNAL(toggled(bool)), this, SLOT(alignToggled(bool))); - d->centerAlignTool = d->addTool("format-justify-center", i18n("Align panel to center"), alignFrame, Qt::ToolButtonIconOnly, true); - d->alignLayout->addWidget(d->centerAlignTool); + d->centerAlignTool = d->addTool("format-justify-center", i18n("Center"), alignFrame, Qt::ToolButtonTextBesideIcon, true); + d->centerAlignTool->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); + alignLayout->addWidget(d->centerAlignTool); connect(d->centerAlignTool, SIGNAL(clicked(bool)), this, SLOT(alignToggled(bool))); - d->rightAlignTool = d->addTool("format-justify-right", i18n("Align panel to right"), alignFrame, Qt::ToolButtonIconOnly, true); - d->alignLayout->addWidget(d->rightAlignTool); + d->rightAlignTool = d->addTool("format-justify-right", i18n("Right"), alignFrame, Qt::ToolButtonTextBesideIcon, true); + d->rightAlignTool->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); + alignLayout->addWidget(d->rightAlignTool); connect(d->rightAlignTool, SIGNAL(clicked(bool)), this, SLOT(alignToggled(bool))); + + //Panel mode + //first the container + QFrame *modeFrame = new ButtonGroup(this); + QVBoxLayout *modeLayout = new QVBoxLayout(modeFrame); + + d->modeLabel = new QLabel(i18n("Visibility"), this); + modeLayout->addWidget(d->modeLabel); + + d->normalPanelTool = d->addTool("checkmark", i18n("Always visible"), modeFrame, Qt::ToolButtonTextBesideIcon, true); + d->normalPanelTool->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); + modeLayout->addWidget(d->normalPanelTool); + connect(d->normalPanelTool, SIGNAL(toggled(bool)), this, SLOT(panelModeChanged(bool))); + + d->autoHideTool = d->addTool("video-display", i18n("Auto hide"), modeFrame, Qt::ToolButtonTextBesideIcon, true); + d->autoHideTool->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); + modeLayout->addWidget(d->autoHideTool); + connect(d->autoHideTool, SIGNAL(toggled(bool)), this, SLOT(panelModeChanged(bool))); + + d->underWindowsTool = d->addTool("view-fullscreen", i18n("Windows can cover"), modeFrame, Qt::ToolButtonTextBesideIcon, true); + d->underWindowsTool->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); + modeLayout->addWidget(d->underWindowsTool); + connect(d->underWindowsTool, SIGNAL(toggled(bool)), this, SLOT(panelModeChanged(bool))); + + d->layout->addStretch(); + d->moveTool = d->addTool("transform-move", i18n("Screen Edge"), this); + d->moveTool->installEventFilter(this); + d->moveTool->setCursor(Qt::SizeAllCursor); + d->layout->addWidget(d->moveTool); + d->sizeTool = d->addTool("transform-scale", i18n("Height"), this); + d->sizeTool->installEventFilter(this); + d->sizeTool->setCursor(Qt::SizeVerCursor); + d->layout->addWidget(d->sizeTool); + d->layout->addStretch(); + //other buttons d->layout->addSpacing(20); + + //Settings popup menu + d->settingsTool = d->addTool("configure", i18n("More Settings"), this); + d->layout->addWidget(d->settingsTool); + connect(d->settingsTool, SIGNAL(pressed()), this, SLOT(settingsPopup())); + d->optionsDialog = new Plasma::Dialog(0); // don't pass in a parent; breaks with some lesser WMs + d->optionsDialog->installEventFilter(this); + KWindowSystem::setState(d->optionsDialog->winId(), NET::SkipTaskbar | NET::SkipPager | NET::Sticky); + d->optDialogLayout = new QVBoxLayout(d->optionsDialog); + d->optDialogLayout->setMargin(0); + d->optDialogLayout->addWidget(alignFrame); + d->optDialogLayout->addWidget(modeFrame); + + ToolButton *closeControllerTool = d->addTool("window-close", i18n("Close this configuration window"), this, Qt::ToolButtonIconOnly, false); d->layout->addWidget(closeControllerTool); - connect(closeControllerTool, SIGNAL(clicked()), this, SLOT(hideController())); + connect(closeControllerTool, SIGNAL(clicked()), this, SLOT(hide())); d->ruler = new PositioningRuler(this); connect(d->ruler, SIGNAL(rulersMoved(int, int, int)), this, SLOT(rulersMoved(int, int, int))); d->extLayout->addWidget(d->ruler); + + connect(Plasma::Theme::defaultTheme(), SIGNAL(themeChanged()), SLOT(setPalette())); + setPalette(); } PanelController::~PanelController() @@ -382,6 +470,8 @@ //TODO: should we try and only call this when something has actually been // altered that we care about? PlasmaApp::self()->corona()->requestConfigSync(); + delete d->optionsDialog; + d->optionsDialog = 0; delete d; } @@ -396,7 +486,9 @@ QWidget *child; while (!d->actionWidgets.isEmpty()) { child = d->actionWidgets.first(); + //try to remove from both layouts d->layout->removeWidget(child); + d->optDialogLayout->removeWidget(child); d->actionWidgets.removeFirst(); child->deleteLater(); } @@ -408,7 +500,7 @@ ToolButton *addWidgetTool = d->addTool(action, this); d->layout->insertWidget(insertIndex, addWidgetTool); ++insertIndex; - connect(addWidgetTool, SIGNAL(clicked()), this, SLOT(hideController())); + connect(addWidgetTool, SIGNAL(clicked()), this, SLOT(hide())); } action = containment->action("lock widgets"); @@ -416,34 +508,18 @@ ToolButton *lockWidgetsTool = d->addTool(action, this); d->layout->insertWidget(insertIndex, lockWidgetsTool); ++insertIndex; - connect(lockWidgetsTool, SIGNAL(clicked()), this, SLOT(hideController())); + connect(lockWidgetsTool, SIGNAL(clicked()), this, SLOT(hide())); } action = containment->action("remove"); if (action) { ToolButton *removePanelTool = d->addTool(action, this); - d->layout->insertWidget(insertIndex, removePanelTool); - ++insertIndex; - connect(removePanelTool, SIGNAL(clicked()), this, SLOT(hideController())); + removePanelTool->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); + d->optDialogLayout->insertWidget(insertIndex, removePanelTool); + connect(removePanelTool, SIGNAL(clicked()), this, SLOT(hide())); } - QRect screenGeom = QApplication::desktop()->screenGeometry(d->containment->screen()); - - switch (d->location) { - case Plasma::LeftEdge: - case Plasma::RightEdge: - d->ruler->setAvailableLength(screenGeom.height()); - d->ruler->setMaxLength(qMin((int)containment->maximumSize().height(), screenGeom.height())); - d->ruler->setMinLength(containment->minimumSize().height()); - break; - case Plasma::TopEdge: - case Plasma::BottomEdge: - default: - d->ruler->setAvailableLength(screenGeom.width()); - d->ruler->setMaxLength(qMin((int)containment->maximumSize().width(), screenGeom.width())); - d->ruler->setMinLength(containment->minimumSize().width()); - break; - } + d->syncRuler(); } QSize PanelController::sizeHint() const @@ -508,8 +584,10 @@ d->extLayout->setDirection(QBoxLayout::RightToLeft); } d->extLayout->setContentsMargins(1, 0, 0, 0); - d->panelHeightHandle->setCursor(Qt::SizeHorCursor); - d->panelHeightHandle->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding); + d->sizeTool->setCursor(Qt::SizeHorCursor); + d->sizeTool->setText(i18n("Width")); + d->leftAlignTool->setText(i18n("Top")); + d->rightAlignTool->setText(i18n("Bottom")); d->ruler->setAvailableLength(screenGeom.height()); break; @@ -521,8 +599,10 @@ d->extLayout->setDirection(QBoxLayout::LeftToRight); } d->extLayout->setContentsMargins(1, 0, 0, 0); - d->panelHeightHandle->setCursor(Qt::SizeHorCursor); - d->panelHeightHandle->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding); + d->sizeTool->setCursor(Qt::SizeHorCursor); + d->sizeTool->setText(i18n("Width")); + d->leftAlignTool->setText(i18n("Top")); + d->rightAlignTool->setText(i18n("Bottom")); d->ruler->setAvailableLength(screenGeom.height()); break; @@ -534,8 +614,10 @@ } d->extLayout->setDirection(QBoxLayout::BottomToTop); d->extLayout->setContentsMargins(0, 0, 0, 1); - d->panelHeightHandle->setCursor(Qt::SizeVerCursor); - d->panelHeightHandle->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); + d->sizeTool->setCursor(Qt::SizeVerCursor); + d->sizeTool->setText(i18n("Height")); + d->leftAlignTool->setText(i18n("Left")); + d->rightAlignTool->setText(i18n("Right")); d->ruler->setAvailableLength(screenGeom.width()); break; @@ -548,19 +630,18 @@ } d->extLayout->setDirection(QBoxLayout::TopToBottom); d->extLayout->setContentsMargins(0, 1, 0, 0); - d->panelHeightHandle->setCursor(Qt::SizeVerCursor); - d->panelHeightHandle->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); + d->sizeTool->setCursor(Qt::SizeVerCursor); + d->sizeTool->setText(i18n("Height")); + d->leftAlignTool->setText(i18n("Left")); + d->rightAlignTool->setText(i18n("Right")); d->ruler->setAvailableLength(screenGeom.width()); break; } - d->alignLayout->setDirection(d->layout->direction()); - if (d->alignLayout->parentWidget()) { - d->alignLayout->parentWidget()->setMaximumSize(d->alignLayout->sizeHint()); - } + d->ruler->setMaximumSize(d->ruler->sizeHint()); - d->ruler->setMaximumSize(d->ruler->sizeHint()); + d->syncRuler(); } Plasma::Location PanelController::location() const @@ -575,7 +656,7 @@ } } -int PanelController::offset() +int PanelController::offset() const { return d->ruler->offset(); } @@ -595,67 +676,143 @@ } } -int PanelController::alignment() +Qt::Alignment PanelController::alignment() const { return d->ruler->alignment(); } -void PanelController::hideController() +void PanelController::setPanelMode(PanelView::PanelMode mode) { - hide(); + switch (mode) { + case PanelView::AutoHide: + d->autoHideTool->setChecked(true); + break; + case PanelView::LetWindowsCover: + d->underWindowsTool->setChecked(true); + break; + case PanelView::NormalPanel: + default: + d->normalPanelTool->setChecked(true); + break; + } } + + +PanelView::PanelMode PanelController::panelMode() const +{ + if (d->underWindowsTool->isChecked()) { + return PanelView::LetWindowsCover; + } else if (d->autoHideTool->isChecked()) { + return PanelView::AutoHide; + } else { + return PanelView::NormalPanel; + } +} + +void PanelController::setPalette() +{ + QColor color = Plasma::Theme::defaultTheme()->color(Plasma::Theme::TextColor); + QPalette p = d->alignLabel->palette(); + p.setColor(QPalette::Normal, QPalette::WindowText, color); + p.setColor(QPalette::Inactive, QPalette::WindowText, color); + d->alignLabel->setPalette(p); + d->modeLabel->setPalette(p); +} + void PanelController::paintEvent(QPaintEvent *event) { QPainter painter(this); painter.setCompositionMode(QPainter::CompositionMode_Source ); - QColor backColor = Plasma::Theme::defaultTheme()->color(Plasma::Theme::BackgroundColor); + QColor backColor = Plasma::Theme::defaultTheme() ->color(Plasma::Theme::BackgroundColor); backColor.setAlphaF(0.75); painter.fillRect(event->rect(), backColor); -} -void PanelController::mousePressEvent(QMouseEvent *event) -{ - if (d->panelHeightHandle->geometry().contains(event->pos()) ) { - d->startDragPos = event->pos(); - d->dragging = Private::ResizeHandleElement; - } else if (QRect(QPoint(0, 0), size()).contains(event->pos()) && !d->ruler->geometry().contains(event->pos()) ) { - d->dragging = Private::PanelControllerElement; - setCursor(Qt::SizeAllCursor); + QRect borderRect; + QString element; + switch (d->location) { + case Plasma::LeftEdge: + element = "west-right"; + borderRect = QRect(QPoint(0,0), d->svg->elementSize(element)); + borderRect.setHeight(height()); + borderRect.moveRight(geometry().width()); + break; + case Plasma::RightEdge: + element = "east-left"; + borderRect = QRect(QPoint(0,0), d->svg->elementSize(element)); + borderRect.setHeight(height()); + break; + case Plasma::TopEdge: + element = "north-bottom"; + borderRect = QRect(QPoint(0,0), d->svg->elementSize(element)); + borderRect.setWidth(width()); + borderRect.moveBottom(geometry().height()); + break; + case Plasma::BottomEdge: + default: + element = "south-top"; + borderRect = QRect(QPoint(0, 0), d->svg->elementSize(element)); + borderRect.setWidth(width()); + break; } - QWidget::mousePressEvent(event); + d->svg->paint(&painter, borderRect, element); } -void PanelController::mouseReleaseEvent(QMouseEvent *event) +bool PanelController::eventFilter(QObject *watched, QEvent *event) { - Q_UNUSED(event) + if (watched == d->optionsDialog && event->type() == QEvent::WindowDeactivate) { + if (!d->settingsTool->underMouse()) { + d->optionsDialog->hide(); + } + if (!isActiveWindow()) { + close(); + } + return true; + } else if (watched == d->moveTool) { + if (event->type() == QEvent::MouseButtonPress) { + d->dragging = Private::MoveButtonElement; + } else if (event->type() == QEvent::MouseButtonRelease) { + d->dragging = Private::NoElement; + } + } else if (watched == d->sizeTool) { + if (event->type() == QEvent::MouseButtonPress) { + QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event); + d->startDragPos = mouseEvent->pos(); + d->dragging = Private::ResizeButtonElement; + } else if (event->type() == QEvent::MouseButtonRelease) { + //FIXME: for now resizes here instead of on mouse move, for a serious performance problem, maybe in Qt + QRect screenGeom = + QApplication::desktop()->screenGeometry(d->containment->screen()); + if (d->dragging == Private::ResizeButtonElement) { + switch (location()) { + case Plasma::LeftEdge: + d->resizePanelHeight(geometry().left() - screenGeom.left()); + break; + case Plasma::RightEdge: + d->resizePanelHeight(screenGeom.right() - geometry().right()); + break; + case Plasma::TopEdge: + d->resizePanelHeight(geometry().top() - screenGeom.top()); + break; + case Plasma::BottomEdge: + default: + d->resizePanelHeight(screenGeom.bottom() - geometry().bottom()); + break; + } + } - //FIXME: for now resizes here instead of on mouse move, for a serious performance problem, maybe in Qt - QRect screenGeom = - QApplication::desktop()->screenGeometry(d->containment->screen()); - if (d->dragging == Private::ResizeHandleElement) { - switch (location()) { - case Plasma::LeftEdge: - d->resizePanelHeight(geometry().left() - screenGeom.left()); - break; - case Plasma::RightEdge: - d->resizePanelHeight(screenGeom.right() - geometry().right()); - break; - case Plasma::TopEdge: - d->resizePanelHeight(geometry().top() - screenGeom.top()); - break; - case Plasma::BottomEdge: - default: - d->resizePanelHeight(screenGeom.bottom() - geometry().bottom()); - break; + //resets properties saved during the drag + d->startDragPos = QPoint(0, 0); + d->dragging = Private::NoElement; + setCursor(Qt::ArrowCursor); + } else if (event->type() == QEvent::MouseMove) { + QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event); + mouseMoveEvent(mouseEvent); } } - //resets properties saved during the drag - d->startDragPos = QPoint(0, 0); - d->dragging = Private::NoElement; - setCursor(Qt::ArrowCursor); + return false; } void PanelController::mouseMoveEvent(QMouseEvent *event) @@ -667,7 +824,7 @@ QDesktopWidget *desktop = QApplication::desktop(); QRect screenGeom = desktop->screenGeometry(d->containment->screen()); - if (d->dragging == Private::PanelControllerElement) { + if (d->dragging == Private::MoveButtonElement) { //only move when the mouse cursor is out of the controller to avoid an endless reposition cycle if (geometry().contains(event->globalPos())) { return; @@ -740,6 +897,7 @@ d->startDragPos.x() - d->minimumHeight > screenGeom.left()) { move(mapToGlobal(event->pos()).x() - d->startDragPos.x(), pos().y()); + d->sizeTool->setText(i18n("Width: %1", screenGeom.left() + (mapToGlobal(event->pos()).x() - d->startDragPos.x()))); //FIXME: Panel resize deferred, should be here } break; @@ -748,6 +906,7 @@ d->startDragPos.x() + width() + d->minimumHeight < screenGeom.right()) { move(mapToGlobal(event->pos()).x() - d->startDragPos.x(), pos().y()); + d->sizeTool->setText(i18n("Width: %1", screenGeom.right() - (mapToGlobal(event->pos()).x() - d->startDragPos.x()) - width() + 1)); } break; case Plasma::TopEdge: @@ -755,6 +914,7 @@ d->startDragPos.y() - d->minimumHeight > screenGeom.top()) { move(pos().x(), mapToGlobal(event->pos()).y() - d->startDragPos.y()); + d->sizeTool->setText(i18n("Height: %1", screenGeom.top() + (mapToGlobal(event->pos()).y() - d->startDragPos.y()))); } break; case Plasma::BottomEdge: @@ -763,6 +923,7 @@ d->startDragPos.y() + height() + d->minimumHeight < screenGeom.bottom()) { move(pos().x(), mapToGlobal(event->pos()).y() - d->startDragPos.y()); + d->sizeTool->setText(i18n("Height: %1", screenGeom.bottom() - (mapToGlobal(event->pos()).y() - d->startDragPos.y()) - height() + 1)); } break; } @@ -771,7 +932,10 @@ void PanelController::focusOutEvent(QFocusEvent * event) { Q_UNUSED(event) - close(); + if (!d->optionsDialog->isActiveWindow()) { + d->optionsDialog->hide(); + close(); + } } #include "panelcontroller.moc" --- plasma/backgrounddialog.h +++ plasma/backgrounddialog.h @@ -0,0 +1,55 @@ +/* + Copyright (c) 2007 Paolo Capriotti <p.capriotti@gmail.com> + Copyright (c) 2008 by Petri Damsten <damu@iki.fi> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. +*/ + +#ifndef BACKGROUNDDIALOG_H +#define BACKGROUNDDIALOG_H + +#include <KDialog> +#include "ui_BackgroundDialog.h" + +namespace Plasma { + class Wallpaper; + class Containment; + class View; +} +class ThemeModel; +class WallpaperPreview; +class QStandardItemModel; + +class BackgroundDialog : public KDialog, public Ui::BackgroundDialog +{ + Q_OBJECT +public: + BackgroundDialog(const QSize& res, Plasma::View* view, QWidget* parent = 0); + ~BackgroundDialog(); + + void reloadConfig(); + +public slots: + void saveConfig(); + +private: + KConfigGroup wallpaperConfig(const QString &plugin); + +private slots: + void getNewThemes(); + void changeBackgroundMode(int mode); + void cleanup(); + +private: + ThemeModel* m_themeModel; + QStandardItemModel* m_containmentModel; + Plasma::Wallpaper* m_wallpaper; + Plasma::View* m_view; + Plasma::Containment* m_containment; + WallpaperPreview* m_preview; +}; + +#endif // BACKGROUNDDIALOG_H --- plasma/desktopview.cpp +++ plasma/desktopview.cpp @@ -35,10 +35,14 @@ #include "plasma/corona.h" #include "plasma/containment.h" #include "plasma/svg.h" +#include "plasma/wallpaper.h" +#include "plasma/theme.h" #include "dashboardview.h" #include "plasmaapp.h" +#include "backgrounddialog.h" + #ifdef Q_WS_WIN #include "windows.h" #include "windef.h" @@ -50,6 +54,7 @@ : Plasma::View(containment, id, parent), m_zoomLevel(Plasma::DesktopZoom), m_dashboard(0), + m_configDialog(0), m_dashboardFollowsDesktop(true) { setFocusPolicy(Qt::NoFocus); @@ -86,6 +91,7 @@ DesktopView::~DesktopView() { + delete m_configDialog; delete m_dashboard; } @@ -97,6 +103,7 @@ connect(containment, SIGNAL(showAddWidgetsInterface(QPointF)), this, SLOT(showAppletBrowser())); connect(containment, SIGNAL(addSiblingContainment(Plasma::Containment *)), this, SLOT(addContainment(Plasma::Containment *))); connect(containment, SIGNAL(focusRequested(Plasma::Containment *)), this, SLOT(setContainment(Plasma::Containment *))); + connect(containment, SIGNAL(configureRequested()), this, SLOT(configureContainment())); } } @@ -113,7 +120,7 @@ int containmentId = cg.readEntry("DashboardContainment", 0); if (containmentId > 0) { foreach (Plasma::Containment *c, containment()->corona()->containments()) { - if (c->id() == containmentId) { + if ((int)c->id() == containmentId) { dc = c; m_dashboardFollowsDesktop = false; break; @@ -162,7 +169,7 @@ setWindowFlags(windowFlags() & ~Qt::FramelessWindowHint); KWindowSystem::setOnAllDesktops(winId(), false); - KWindowSystem::setType(winId(), NET::Normal); + KWindowSystem::setType(winId(), NET::Normal); } } @@ -222,6 +229,22 @@ } } +void DesktopView::configureContainment() +{ + if (m_configDialog == 0) { + const QSize resolution = + QApplication::desktop()->screenGeometry(screen()).size(); + m_configDialog = new BackgroundDialog(resolution, this); + } + else { + m_configDialog->reloadConfig(); + } + + m_configDialog->show(); + KWindowSystem::setOnDesktop(m_configDialog->winId(), KWindowSystem::currentDesktop()); + KWindowSystem::activateWindow(m_configDialog->winId()); +} + void DesktopView::zoom(Plasma::Containment *containment, Plasma::ZoomDirection direction) { if (direction == Plasma::ZoomIn) { --- plasma/panelappletoverlay.cpp +++ plasma/panelappletoverlay.cpp @@ -19,6 +19,7 @@ #include "panelappletoverlay.h" +#include <QApplication> #include <QGraphicsLinearLayout> #include <QPainter> #include <QTimer> @@ -30,6 +31,7 @@ #include <plasma/containment.h> #include <plasma/paintutils.h> #include <plasma/theme.h> +#include <plasma/view.h> class AppletMoveSpacer : public QGraphicsWidget { @@ -141,6 +143,17 @@ return; } + if (event->button() != Qt::LeftButton) { + kDebug() << "sending even to" << (QWidget*)parent(); + Plasma::View *view = dynamic_cast<Plasma::View*>(parent()); + + if (view && view->containment()) { + view->containment()->showContextMenu(mapToParent(event->pos()), event->globalPos()); + } + + return; + } + m_clickDrag = false; if (!m_spacer) { m_spacer = new AppletMoveSpacer(m_applet); @@ -167,6 +180,10 @@ { Q_UNUSED(event) + if (!m_spacer) { + return; + } + QPoint p = mapToParent(event->pos()); QRect g = geometry(); @@ -199,6 +216,11 @@ { Q_UNUSED(event) + releaseMouse(); + if (!m_spacer) { + return; + } + if (!m_origin.isNull()) { //kDebug() << m_clickDrag << m_origin << mapToParent(event->pos()); if (m_orientation == Qt::Horizontal) { @@ -221,7 +243,6 @@ m_spacer = 0; m_layout->insertItem(m_index, m_applet); m_applet->setZValue(m_applet->zValue() - 1); - releaseMouse(); } void PanelAppletOverlay::enterEvent(QEvent *event) --- plasma/panelcontroller.h +++ plasma/panelcontroller.h @@ -24,8 +24,10 @@ #include <plasma/plasma.h> +#include "panelview.h" + namespace Plasma { class Containment; @@ -35,6 +37,7 @@ { Q_OBJECT public: + PanelController(QWidget* parent = 0); ~PanelController(); @@ -48,18 +51,20 @@ Plasma::Location location() const; void setOffset(int newOffset); - int offset(); + int offset() const; void setAlignment(const Qt::Alignment &newAlignment); - int alignment(); + Qt::Alignment alignment() const; + void setPanelMode(PanelView::PanelMode); + PanelView::PanelMode panelMode() const; + public Q_SLOTS: - void hideController(); + void setPalette(); protected: void paintEvent(QPaintEvent *event); - void mousePressEvent(QMouseEvent *event); - void mouseReleaseEvent(QMouseEvent *event); + bool eventFilter(QObject *watched, QEvent *event); void mouseMoveEvent(QMouseEvent *event); void focusOutEvent(QFocusEvent * event); @@ -70,10 +75,13 @@ void offsetChanged(int offset); void alignmentChanged(Qt::Alignment); void locationChanged(Plasma::Location); + void panelModeChanged(PanelView::PanelMode mode); private: Q_PRIVATE_SLOT(d, void rulersMoved(int offset, int minLength, int minLength)) Q_PRIVATE_SLOT(d, void alignToggled(bool toggle)) + Q_PRIVATE_SLOT(d, void panelModeChanged(bool toggle)) + Q_PRIVATE_SLOT(d, void settingsPopup()) class ButtonGroup; class ResizeHandle; --- plasma/desktopview.h +++ plasma/desktopview.h @@ -29,6 +29,7 @@ } // namespace Plasma class DashboardView; +class BackgroundDialog; class DesktopView : public Plasma::View { @@ -52,7 +53,7 @@ */ void setIsDesktop(bool isDesktop); - /** + /** * Returns true if this widget is currently a desktop window. * See setAsDesktop() */ @@ -96,6 +97,13 @@ */ void setContainment(Plasma::Containment *containment); + /** + * Configure containment. + * + * @arg containment to configure + */ + void configureContainment(); + protected: void wheelEvent(QWheelEvent *event); void drawBackground(QPainter *painter, const QRectF &rect); @@ -103,6 +111,7 @@ private: Plasma::ZoomLevel m_zoomLevel; DashboardView *m_dashboard; + BackgroundDialog *m_configDialog; bool m_dashboardFollowsDesktop; }; --- plasma/desktopcorona.cpp +++ plasma/desktopcorona.cpp @@ -23,11 +23,13 @@ #include <QDesktopWidget> #include <QDir> #include <QGraphicsLayout> +#include <QFile> #include <KDebug> #include <KDialog> #include <KGlobalSettings> #include <KStandardDirs> +#include <KMessageBox> #include <plasma/containment.h> #include <plasma/dataenginemanager.h> @@ -52,7 +54,9 @@ for (int i = 0; i < numScreens; ++i) { if (!containmentForScreen(i)) { //TODO: should we look for containments that aren't asigned but already exist? - Plasma::Containment* c = addContainment("desktop"); + KSharedConfigPtr defaultconfig = KSharedConfig::openConfig("plasmarc"); + KConfigGroup group = KConfigGroup(defaultconfig, "Defaults"); + Plasma::Containment* c = addContainment(group.readEntry("containment", "desktop")); c->setScreen(i); c->setFormFactor(Plasma::Planar); c->flushPendingConstraintsEvents(); @@ -113,6 +117,7 @@ c->init(); c->setScreen(i); + c->setWallpaper("image", "SingleImage"); c->setFormFactor(Plasma::Planar); c->updateConstraints(Plasma::StartupCompletedConstraint); c->flushPendingConstraintsEvents(); @@ -150,17 +155,57 @@ panel->updateConstraints(Plasma::StartupCompletedConstraint); panel->flushPendingConstraintsEvents(); + loadDefaultApplets(panel); + + emit containmentAdded(panel); + requestConfigSync(); +} + +bool DesktopCorona::loadDefaultApplets(Plasma::Containment* panel, bool askType) +{ + if (askType) { + int answer = KMessageBox::questionYesNoCancel(0, i18n("Do you want a panel with the default widgets or an empty panel?"), i18n("Add Panel"), KGuiItem(i18n("Default Panel")), KGuiItem(i18n("Empty Panel"))); + if (answer==KMessageBox::Cancel) { + return false; + } else if (answer==KMessageBox::No) { + return true; + } + } + + // used to force a save into the config file + KConfigGroup invalidConfig; + // some default applets to get a usable UI Plasma::Applet *applet = loadDefaultApplet("launcher", panel); if (applet) { applet->setGlobalShortcut(KShortcut("Alt+F1")); } + if (QFile::exists("/usr/share/kde4/services/plasma-applet-showdashboard.desktop")) + panel->addApplet("showdashboard"); + + QVariantList args; + if (QFile::exists("/usr/share/applications/kde4/dolphin.desktop")) { + args << "/usr/share/applications/kde4/dolphin.desktop"; + QRectF rect; + panel->addApplet("icon", args, rect); + } + + args.clear(); + if (QFile::exists("/usr/share/applications/kde4/konqbrowser.desktop")) { + args << "/usr/share/applications/kde4/konqbrowser.desktop"; + QRectF rect; + panel->addApplet("icon", args, rect); + } + loadDefaultApplet("notifier", panel); loadDefaultApplet("pager", panel); loadDefaultApplet("tasks", panel); loadDefaultApplet("systemtray", panel); + if (QFile::exists("/usr/share/kde4/services/plasma-applet-networkmanagement.desktop")) + panel->addApplet("networkmanagement"); + Plasma::DataEngineManager *engines = Plasma::DataEngineManager::self(); Plasma::DataEngine *power = engines->loadEngine("powermanagement"); if (power) { @@ -173,6 +218,8 @@ loadDefaultApplet("digital-clock", panel); + panel->addApplet("lockout"); + foreach (Plasma::Applet* applet, panel->applets()) { applet->init(); applet->flushPendingConstraintsEvents(); @@ -180,17 +227,9 @@ } panel->save(invalidConfig); - emit containmentAdded(panel); + return true; +} - requestConfigSync(); - /* - foreach (Plasma::Containment *c, containments()) { - kDebug() << "letting the world know about" << (QObject*)c; - emit containmentAdded(c); - } - */ -} - Plasma::Applet *DesktopCorona::loadDefaultApplet(const QString &pluginName, Plasma::Containment *c) { QVariantList args; --- plasma/positioningruler.cpp +++ plasma/positioningruler.cpp @@ -70,10 +70,9 @@ } if (alignment == Qt::AlignCenter) { - const int newTop = offsetSliderRect.center().y() + (offsetSliderRect.center().y() - newPos.y()); - if (newTop < 0 || newTop > availableLength) { - return false; - } + int newTop = offsetSliderRect.center().y() + (offsetSliderRect.center().y() - newPos.y()); + newTop = qBound(0, newTop, availableLength); + symmetricSliderRect.moveCenter(QPoint(symmetricSliderRect.center().x(), newTop)); } sliderRect.moveCenter(QPoint(sliderRect.center().x(), newPos.y())); @@ -83,10 +82,9 @@ } if (alignment == Qt::AlignCenter) { - const int newLeft = offsetSliderRect.center().x() + (offsetSliderRect.center().x() - newPos.x()); - if (newLeft < 0 || newLeft > availableLength) { - return false; - } + int newLeft = offsetSliderRect.center().x() + (offsetSliderRect.center().x() - newPos.x()); + newLeft = qBound(0, newLeft, availableLength); + symmetricSliderRect.moveCenter(QPoint(newLeft, symmetricSliderRect.center().y())); } sliderRect.moveCenter(QPoint(newPos.x(), sliderRect.center().y())); @@ -135,11 +133,11 @@ break; } - leftMaxSliderRect.setSize(sliderGraphics->elementSize(elementPrefix + "maxslider")); - rightMaxSliderRect.setSize(leftMaxSliderRect.size()); - leftMinSliderRect.setSize(sliderGraphics->elementSize(elementPrefix + "minslider")); - rightMinSliderRect.setSize(leftMinSliderRect.size()); - offsetSliderRect.setSize(sliderGraphics->elementSize(elementPrefix + "offsetslider")); + leftMaxSliderRect.setSize(sliderGraphics->elementSize(elementPrefix + "left-limit-slider")); + leftMinSliderRect.setSize(sliderGraphics->elementSize(elementPrefix + "right-limit-slider")); + rightMaxSliderRect.setSize(leftMinSliderRect.size()); + rightMinSliderRect.setSize(leftMaxSliderRect.size()); + offsetSliderRect.setSize(sliderGraphics->elementSize(elementPrefix + "offset-slider")); } void setupSliders(const QSize &totalSize) @@ -164,67 +162,67 @@ //Here substracting one to everything because QRect.moveCenter(pos) moves the rect with //the width/2 th pixel at pos.x (and so for y) resulting in the painted image moved //one pixel to the right - rightMaxPos = offset + maxLength - 1; + rightMaxPos = offset + maxLength; leftMaxPos = 0; - rightMinPos = offset + minLength - 1; + rightMinPos = offset + minLength; leftMinPos = 0; - offsetPos = offset - 1; + offsetPos = offset; break; case Qt::AlignRight: - leftMaxPos = totalLength - offset - maxLength - 1; + leftMaxPos = totalLength - offset - maxLength; rightMaxPos = 0; - leftMinPos = totalLength - offset - minLength - 1; + leftMinPos = totalLength - offset - minLength; rightMinPos = 0; - offsetPos = totalLength - offset - 1; + offsetPos = totalLength - offset; break; case Qt::AlignCenter: default: - leftMaxPos = totalLength/2 + offset - maxLength/2 - 1; - rightMaxPos = totalLength/2 + offset + maxLength/2 - 1; + leftMaxPos = totalLength/2 + offset - maxLength/2; + rightMaxPos = totalLength/2 + offset + maxLength/2; - leftMinPos = totalLength/2 + offset - minLength/2 - 1; - rightMinPos = totalLength/2 + offset + minLength/2 - 1; + leftMinPos = totalLength/2 + offset - minLength/2; + rightMinPos = totalLength/2 + offset + minLength/2; - offsetPos = totalLength/2 + offset - 1; + offsetPos = totalLength/2 + offset; break; } - + switch (location) { case Plasma::LeftEdge: leftMaxSliderRect.moveCenter(QPoint(3*(totalSize.width()/4), leftMaxPos)); rightMaxSliderRect.moveCenter(QPoint(3*(totalSize.width()/4), rightMaxPos)); - + leftMinSliderRect.moveCenter(QPoint(totalSize.width()/4, leftMinPos)); rightMinSliderRect.moveCenter(QPoint(totalSize.width()/4, rightMinPos)); - + offsetSliderRect.moveCenter(QPoint(3*(totalSize.width()/4), offsetPos)); break; case Plasma::RightEdge: leftMaxSliderRect.moveCenter(QPoint(totalSize.width()/4, leftMaxPos)); rightMaxSliderRect.moveCenter(QPoint(totalSize.width()/4, rightMaxPos)); - + leftMinSliderRect.moveCenter(QPoint(3*(totalSize.width()/4), leftMinPos)); rightMinSliderRect.moveCenter(QPoint(3*(totalSize.width()/4), rightMinPos)); - + offsetSliderRect.moveCenter(QPoint(totalSize.width()/4, offsetPos)); break; case Plasma::TopEdge: leftMaxSliderRect.moveCenter(QPoint(leftMaxPos, 3*(totalSize.height()/4))); rightMaxSliderRect.moveCenter(QPoint(rightMaxPos, 3*(totalSize.height()/4))); - + leftMinSliderRect.moveCenter(QPoint(leftMinPos, totalSize.height()/4)); rightMinSliderRect.moveCenter(QPoint(rightMinPos, totalSize.height()/4)); - + offsetSliderRect.moveCenter(QPoint(offsetPos, 3*(totalSize.height()/4))); break; case Plasma::BottomEdge: default: leftMaxSliderRect.moveCenter(QPoint(leftMaxPos, totalSize.height()/4)); rightMaxSliderRect.moveCenter(QPoint(rightMaxPos, totalSize.height()/4)); - + leftMinSliderRect.moveCenter(QPoint(leftMinPos, 3*(totalSize.height()/4))); rightMinSliderRect.moveCenter(QPoint(rightMinPos, 3*(totalSize.height()/4))); - + offsetSliderRect.moveCenter(QPoint(offsetPos, totalSize.height()/4)); break; } @@ -480,8 +478,11 @@ //Draw center indicators if (d->alignment == Qt::AlignCenter && (d->location == Plasma::LeftEdge || d->location == Plasma::RightEdge)) { d->sliderGraphics->paint(&painter, QPoint(event->rect().left(), event->rect().center().y()), "vertical-centerindicator"); + //this because rect.moveCenter will cause a rect moved one pixel off respect where we need it + painter.translate(0, -1); } else if (d->alignment == Qt::AlignCenter) { d->sliderGraphics->paint(&painter, QPoint(event->rect().center().x(), event->rect().top()), "horizontal-centerindicator"); + painter.translate(-1, 0); } //Draw handles @@ -504,16 +505,16 @@ } if (d->alignment != Qt::AlignLeft) { - d->sliderGraphics->paint(&painter, d->leftMaxSliderRect, elementPrefix + "maxslider"); - d->sliderGraphics->paint(&painter, d->leftMinSliderRect, elementPrefix + "minslider"); + d->sliderGraphics->paint(&painter, d->leftMaxSliderRect, elementPrefix + "left-limit-slider"); + d->sliderGraphics->paint(&painter, d->leftMinSliderRect, elementPrefix + "right-limit-slider"); } if (d->alignment != Qt::AlignRight) { - d->sliderGraphics->paint(&painter, d->rightMaxSliderRect, elementPrefix + "maxslider"); - d->sliderGraphics->paint(&painter, d->rightMinSliderRect, elementPrefix + "minslider"); + d->sliderGraphics->paint(&painter, d->rightMaxSliderRect, elementPrefix + "right-limit-slider"); + d->sliderGraphics->paint(&painter, d->rightMinSliderRect, elementPrefix + "left-limit-slider"); } - d->sliderGraphics->paint(&painter, d->offsetSliderRect, elementPrefix + "offsetslider"); + d->sliderGraphics->paint(&painter, d->offsetSliderRect, elementPrefix + "offset-slider"); } void PositioningRuler::wheelEvent(QWheelEvent *event) @@ -633,7 +634,7 @@ newPos.setY(d->availableLength); } } - + switch (d->dragging) { case Private::LeftMaxSlider: //don't let the slider "cross" with the offset slider --- plasma/plasmaapp.cpp +++ plasma/plasmaapp.cpp @@ -17,12 +17,16 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -// plasma.loadEngine("hardware") -// LineGraph graph -// plasma.connect(graph, "hardware", "cpu"); - #include "plasmaapp.h" +#ifdef Q_WS_WIN +#ifdef _WIN32_WINNT +#undef _WIN32_WINNT +#endif +#define _WIN32_WINNT 0x0500 +#include <windows.h> +#endif + #include <unistd.h> #ifndef _SC_PHYS_PAGES @@ -127,7 +131,8 @@ : KUniqueApplication(), #endif m_corona(0), - m_appletBrowser(0) + m_appletBrowser(0), + m_panelHidden(0) { KGlobal::locale()->insertCatalog("libplasma"); @@ -197,7 +202,13 @@ memorySize /= 1024; #endif #ifdef Q_WS_WIN - size_t memorySize = 2000000000; //FIXME: get the right memorysize instead of hardcoding it + size_t memorySize; + + MEMORYSTATUSEX statex; + statex.dwLength = sizeof (statex); + GlobalMemoryStatusEx (&statex); + + memorySize = (statex.ullTotalPhys/1024) + (statex.ullTotalPageFile/1024); #endif // If you have no suitable sysconf() interface and are not FreeBSD, // then you are out of luck and get a compile error. @@ -297,13 +308,46 @@ view->toggleDashboard(); } +void PlasmaApp::panelHidden(bool hidden) +{ + if (hidden) { + ++m_panelHidden; + //kDebug() << "panel hidden" << m_panelHidden; + } else { + --m_panelHidden; + if (m_panelHidden < 0) { + kDebug() << "panelHidden(false) called too many times!"; + m_panelHidden = 0; + } + //kDebug() << "panel unhidden" << m_panelHidden; + } +} + +#ifdef Q_WS_X11 +bool PlasmaApp::x11EventFilter(XEvent *event) +{ + if (m_panelHidden && event->type == EnterNotify) { + //kDebug(); + foreach (PanelView *panel, m_panels) { + //kDebug() << panel->unhideTrigger() << event->xcrossing.window; + if (panel->unhideTrigger() == event->xcrossing.window) { + panel->unhide(); + return true; + } + } + } + + return KUniqueApplication::x11EventFilter(event); +} +#endif + void PlasmaApp::setIsDesktop(bool isDesktop) { m_isDesktop = isDesktop; foreach (DesktopView *view, m_desktops) { view->setIsDesktop(isDesktop); } - + if (isDesktop) { connect(QApplication::desktop(), SIGNAL(resized(int)), SLOT(adjustSize(int))); } else { @@ -318,7 +362,6 @@ void PlasmaApp::adjustSize(int screen) { - kDebug() << "adjust size for screen" << screen; QDesktopWidget *desktop = QApplication::desktop(); bool screenExists = screen < desktop->numScreens(); @@ -329,6 +372,8 @@ DesktopView *view = viewForScreen(screen); + kDebug() << "adjust size for screen" << screen << screenGeom << view; + if (view) { if (screenExists) { kDebug() << "here we go ... adjusting size"; @@ -346,15 +391,14 @@ // perhaps we should make one. } - foreach (PanelView *panel, m_panels) { - if (panel->screen() == screen) { - if (screenExists) { + //TODO: should we remove panels when the screen + // disappears? this would mean having some + // way of alerting that we have a new screen + // that appears + if (screenExists) { + foreach (PanelView *panel, m_panels) { + if (panel->screen() == screen) { panel->pinchContainment(screenGeom); - } else { - //TODO: should we remove panels when the screen - // disappears? this would mean having some - // way of alerting that we have a new screen - // that appears } } } --- plasma/desktopcorona.h +++ plasma/desktopcorona.h @@ -49,6 +49,11 @@ */ void checkScreens(); + /** + * SUSE-specific extension + **/ + bool loadDefaultApplets(Plasma::Containment* panel, bool askType=false); + protected Q_SLOTS: void screenResized(int); --- plasma/plasmaapp.h +++ plasma/plasmaapp.h @@ -75,11 +75,26 @@ */ void createDesktopView(Plasma::Containment *containment, int id = 0); + /** + * Should be called when a panel hides or unhides itself + */ + void panelHidden(bool hidden); + public Q_SLOTS: // DBUS interface. if you change these methods, you MUST run: // qdbuscpp2xml plasmaapp.h -o org.kde.plasma.App.xml void toggleDashboard(); +protected: +#ifdef Q_WS_X11 + bool x11EventFilter(XEvent *event); +#endif + +private: + PlasmaApp(Display* display, Qt::HANDLE visual, Qt::HANDLE colormap); + static void crashHandler(int signal); + DesktopView* viewForScreen(int screen) const; + private Q_SLOTS: void setCrashHandler(); void cleanup(); @@ -90,14 +105,11 @@ void adjustSize(int screen); private: - PlasmaApp(Display* display, Qt::HANDLE visual, Qt::HANDLE colormap); - static void crashHandler(int signal); - DesktopView* viewForScreen(int screen) const; - Plasma::Corona *m_corona; QList<PanelView*> m_panels; Plasma::AppletBrowser *m_appletBrowser; QList<DesktopView*> m_desktops; + int m_panelHidden; bool m_isDesktop; }; --- plasma/main.cpp +++ plasma/main.cpp @@ -27,7 +27,7 @@ #include "plasmaapp.h" static const char description[] = I18N_NOOP( "The KDE desktop, panels and widgets workspace application." ); -static const char version[] = "0.1"; +static const char version[] = "0.1-SUSE"; extern "C" #ifdef Q_WS_WIN --- plasma/wallpaperpreview.cpp +++ plasma/wallpaperpreview.cpp @@ -0,0 +1,67 @@ +/* + * Copyright 2008 Petri Damsten <damu@iki.fi> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "wallpaperpreview.h" +#include <QPainter> +#include <QPaintEvent> +#include <plasma/wallpaper.h> +#include <plasma/svg.h> + +WallpaperPreview::WallpaperPreview(QWidget *parent) : QWidget(parent), m_wallpaper(0) +{ + m_wallpaperOverlay = new Plasma::Svg(this); + m_wallpaperOverlay->setImagePath("widgets/monitor"); + m_wallpaperOverlay->setContainsMultipleImages(true); +} + +WallpaperPreview::~WallpaperPreview() +{ +} + +void WallpaperPreview::setWallpaper(Plasma::Wallpaper* wallpaper) +{ + m_wallpaper = wallpaper; + if (m_wallpaper) { + connect(m_wallpaper, SIGNAL(update(const QRectF &)), + this, SLOT(updateRect(const QRectF &))); + resizeEvent(0); + } +} + +void WallpaperPreview::resizeEvent(QResizeEvent* event) +{ + Q_UNUSED(event) + if (m_wallpaper) { + m_wallpaper->setBoundingRect(contentsRect()); + } +} + +void WallpaperPreview::updateRect(const QRectF& rect) +{ + update(rect.toRect()); +} + +void WallpaperPreview::paintEvent(QPaintEvent* event) +{ + QPainter painter(this); + if (m_wallpaper) { + m_wallpaper->paint(&painter, event->rect()); + m_wallpaperOverlay->paint(&painter, QRect(QPoint(0,0), size()), "glass"); + } +} + +#include "wallpaperpreview.moc" --- plasma/BackgroundDialog.ui +++ plasma/BackgroundDialog.ui @@ -0,0 +1,266 @@ +<ui version="4.0" > + <class>BackgroundDialog</class> + <widget class="QWidget" name="BackgroundDialog" > + <property name="geometry" > + <rect> + <x>0</x> + <y>0</y> + <width>478</width> + <height>290</height> + </rect> + </property> + <property name="sizePolicy" > + <sizepolicy vsizetype="Expanding" hsizetype="Expanding" > + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="baseSize" > + <size> + <width>200</width> + <height>700</height> + </size> + </property> + <layout class="QGridLayout" name="gridLayout" > + <item row="0" column="0" colspan="4" > + <widget class="QLabel" name="label_5" > + <property name="font" > + <font> + <weight>75</weight> + <bold>true</bold> + </font> + </property> + <property name="text" > + <string>Desktop Activity</string> + </property> + </widget> + </item> + <item row="1" column="0" > + <widget class="QLabel" name="label_4" > + <property name="text" > + <string>Type:</string> + </property> + <property name="alignment" > + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + <property name="buddy" > + <cstring>m_containmentComboBox</cstring> + </property> + </widget> + </item> + <item row="1" column="1" colspan="2" > + <layout class="QHBoxLayout" name="horizontalLayout_3" > + <item> + <widget class="QComboBox" name="m_containmentComboBox" > + <property name="sizePolicy" > + <sizepolicy vsizetype="Fixed" hsizetype="Expanding" > + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_2" > + <property name="orientation" > + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType" > + <enum>QSizePolicy::Preferred</enum> + </property> + <property name="sizeHint" stdset="0" > + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + <item rowspan="6" row="1" column="3" > + <layout class="QVBoxLayout" name="verticalLayout_2" > + <item> + <widget class="QLabel" name="m_monitor" > + <property name="sizePolicy" > + <sizepolicy vsizetype="Preferred" hsizetype="Preferred" > + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text" > + <string>Monitor</string> + </property> + <property name="alignment" > + <set>Qt::AlignCenter</set> + </property> + </widget> + </item> + <item> + <spacer name="verticalSpacer_2" > + <property name="orientation" > + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0" > + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + <item row="2" column="0" colspan="3" > + <widget class="QLabel" name="label_2" > + <property name="font" > + <font> + <weight>75</weight> + <bold>true</bold> + </font> + </property> + <property name="text" > + <string>Desktop Theme</string> + </property> + </widget> + </item> + <item row="3" column="0" > + <widget class="QLabel" name="label_3" > + <property name="minimumSize" > + <size> + <width>129</width> + <height>0</height> + </size> + </property> + <property name="text" > + <string>Theme:</string> + </property> + <property name="alignment" > + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + <property name="buddy" > + <cstring>m_theme</cstring> + </property> + </widget> + </item> + <item row="3" column="1" > + <widget class="QComboBox" name="m_theme" > + <property name="sizePolicy" > + <sizepolicy vsizetype="Fixed" hsizetype="Expanding" > + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + </widget> + </item> + <item row="3" column="2" > + <widget class="QPushButton" name="m_newThemeButton" > + <property name="enabled" > + <bool>true</bool> + </property> + <property name="text" > + <string>New Theme...</string> + </property> + </widget> + </item> + <item row="4" column="0" colspan="3" > + <widget class="QLabel" name="m_wallpaperLabel" > + <property name="sizePolicy" > + <sizepolicy vsizetype="Preferred" hsizetype="Expanding" > + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="font" > + <font> + <weight>75</weight> + <bold>true</bold> + </font> + </property> + <property name="text" > + <string>Wallpaper</string> + </property> + </widget> + </item> + <item row="5" column="0" colspan="3" > + <widget class="QWidget" native="1" name="m_wallpaperGroup" > + <layout class="QVBoxLayout" name="verticalLayout" > + <property name="leftMargin" > + <number>0</number> + </property> + <property name="topMargin" > + <number>0</number> + </property> + <property name="rightMargin" > + <number>0</number> + </property> + <item> + <layout class="QHBoxLayout" name="horizontalLayout" > + <item> + <widget class="QLabel" name="m_wallpaperTypeLabel" > + <property name="minimumSize" > + <size> + <width>129</width> + <height>0</height> + </size> + </property> + <property name="text" > + <string>Type:</string> + </property> + <property name="alignment" > + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + <property name="buddy" > + <cstring>m_wallpaperMode</cstring> + </property> + </widget> + </item> + <item> + <widget class="QComboBox" name="m_wallpaperMode" > + <property name="sizePolicy" > + <sizepolicy vsizetype="Fixed" hsizetype="Expanding" > + <horstretch>1</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize" > + <size> + <width>150</width> + <height>0</height> + </size> + </property> + </widget> + </item> + </layout> + </item> + <item> + <widget class="QWidget" native="1" name="m_wallpaperConfig" > + <property name="sizePolicy" > + <sizepolicy vsizetype="Expanding" hsizetype="Expanding" > + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item row="6" column="1" > + <spacer name="verticalSpacer" > + <property name="orientation" > + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0" > + <size> + <width>20</width> + <height>64</height> + </size> + </property> + </spacer> + </item> + </layout> + </widget> + <resources/> + <connections/> +</ui> --- plasma/panelview.cpp +++ plasma/panelview.cpp @@ -22,7 +22,11 @@ #include <QApplication> #include <QDesktopWidget> #include <QGraphicsLinearLayout> +#include <QTimeLine> #include <QTimer> +#ifdef Q_WS_X11 +#include <QX11Info> +#endif #include <KWindowSystem> #include <KDebug> @@ -40,15 +44,21 @@ PanelView::PanelView(Plasma::Containment *panel, int id, QWidget *parent) : Plasma::View(panel, id, parent), m_panelController(0), + m_timeLine(0), +#ifdef Q_WS_X11 + m_unhideTrigger(None), +#endif + m_panelMode(NormalPanel), m_lastHorizontal(true), - m_editting(false) + m_editting(false), + m_firstPaint(true) { Q_ASSERT(qobject_cast<Plasma::Corona*>(panel->scene())); - KConfigGroup viewConfig = config(); m_offset = viewConfig.readEntry("Offset", 0); m_alignment = alignmentFilter((Qt::Alignment)viewConfig.readEntry("Alignment", (int)Qt::AlignLeft)); + setPanelMode((PanelMode)viewConfig.readEntry("panelMode", (int)m_panelMode)); // pinchContainment calls updatePanelGeometry for us @@ -63,13 +73,14 @@ if (panel) { connect(panel, SIGNAL(showAddWidgetsInterface(QPointF)), this, SLOT(showAppletBrowser())); - connect(panel, SIGNAL(destroyed(QObject*)), this, SLOT(deleteLater())); + connect(panel, SIGNAL(destroyed(QObject*)), this, SLOT(panelDeleted())); connect(panel, SIGNAL(toolBoxToggled()), this, SLOT(togglePanelController())); + + kDebug() << "Panel geometry is" << panel->geometry(); } + connect(this, SIGNAL(sceneRectAboutToChange()), this, SLOT(updatePanelGeometry())); - kDebug() << "Panel geometry is" << panel->geometry(); - // Graphics view setup setFrameStyle(QFrame::NoFrame); //setAutoFillBackground(true); @@ -80,20 +91,25 @@ setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + QPalette pal = palette(); + pal.setBrush(backgroundRole(), Qt::transparent); + setPalette(pal); + // KWin setup - KWindowSystem::setType(winId(), NET::Dock); - KWindowSystem::setState(winId(), NET::Sticky); KWindowSystem::setOnAllDesktops(winId(), true); - + #ifdef Q_WS_WIN registerAccessBar(winId(), true); -#endif +#endif updateStruts(); } PanelView::~PanelView() { +#ifdef Q_WS_WIN + registerAccessBar(winId(), false); +#endif } void PanelView::setLocation(Plasma::Location location) @@ -165,6 +181,52 @@ return containment()->location(); } +void PanelView::checkForActivation() +{ + //kDebug() << "stacking order changed!" << KWindowSystem::self()->stackingOrder().last() << winId(); + if (KWindowSystem::self()->stackingOrder().last() == winId()) { + destroyUnhideTrigger(); + } else { + createUnhideTrigger(); + } +} + +void PanelView::setPanelMode(PanelView::PanelMode mode) +{ + unsigned long state = NET::Sticky; + + disconnect(KWindowSystem::self(), SIGNAL(stackingOrderChanged()), + this, SLOT(checkForActivation())); + + KWindowSystem::setType(winId(), NET::Dock); + if (mode == LetWindowsCover) { + createUnhideTrigger(); + connect(KWindowSystem::self(), SIGNAL(stackingOrderChanged()), + this, SLOT(checkForActivation())); + KWindowSystem::clearState(winId(), NET::StaysOnTop | NET::KeepAbove); + state |= NET::KeepBelow; + } else { + //kDebug() << "panel shouldn't let windows cover it!"; + state |= NET::StaysOnTop; + } + + if (mode == NormalPanel) { + // we need to kill the input window if it exists! + destroyUnhideTrigger(); + } + + //kDebug() << "panel state set to" << state << NET::Sticky; + KWindowSystem::setState(winId(), state); + + m_panelMode = mode; + config().writeEntry("panelMode", (int)mode); +} + +PanelView::PanelMode PanelView::panelMode() const +{ + return m_panelMode; +} + Plasma::Corona *PanelView::corona() const { return qobject_cast<Plasma::Corona*>(scene()); @@ -262,7 +324,7 @@ } else if (m_alignment == Qt::AlignRight) { geom.moveTopRight(QPoint(screenGeom.right() - m_offset, screenGeom.top())); } else if (m_alignment == Qt::AlignCenter) { - geom.moveCenter(QPoint(screenGeom.center().x() + m_offset, screenGeom.top() + geom.height()/2 - 1)); + geom.moveTopLeft(QPoint(screenGeom.center().x() - geom.width()/2 + 1 - geom.width()%2 + m_offset, screenGeom.top())); } //enable borders if needed @@ -275,7 +337,7 @@ } else if (m_alignment == Qt::AlignRight) { geom.moveBottomLeft(QPoint(screenGeom.left(), screenGeom.bottom() - m_offset)); } else if (m_alignment == Qt::AlignCenter) { - geom.moveCenter(QPoint(screenGeom.left()+size.width()/2 - 1, screenGeom.center().y() + m_offset -1)); + geom.moveTopLeft(QPoint(screenGeom.left(), screenGeom.center().y() - geom.height()/2 + 1 - geom.height()%2 + m_offset)); } //enable borders if needed @@ -284,11 +346,11 @@ case Plasma::RightEdge: if (m_alignment == Qt::AlignLeft) { - geom.moveTopLeft(QPoint(screenGeom.right() - size.width() + 1, m_offset)); + geom.moveTopRight(QPoint(screenGeom.right(), m_offset)); } else if (m_alignment == Qt::AlignRight) { - geom.moveBottomLeft(QPoint(screenGeom.right() - size.width() + 1, screenGeom.bottom() - m_offset)); + geom.moveBottomRight(QPoint(screenGeom.right(), screenGeom.bottom() - m_offset)); } else if (m_alignment == Qt::AlignCenter) { - geom.moveCenter(QPoint(screenGeom.right() - size.width()/2, screenGeom.center().y() + m_offset)); + geom.moveTopRight(QPoint(screenGeom.right(), screenGeom.center().y() - geom.height()/2 + 1 - geom.height()%2 + m_offset)); } //enable borders if needed @@ -298,11 +360,11 @@ case Plasma::BottomEdge: default: if (m_alignment == Qt::AlignLeft) { - geom.moveTopLeft(QPoint(m_offset, screenGeom.bottom() - size.height() + 1)); + geom.moveBottomLeft(QPoint(m_offset, screenGeom.bottom())); } else if (m_alignment == Qt::AlignRight) { - geom.moveTopRight(QPoint(screenGeom.right() - m_offset, screenGeom.bottom() - size.height() + 1)); + geom.moveBottomRight(QPoint(screenGeom.right() - m_offset, screenGeom.bottom())); } else if (m_alignment == Qt::AlignCenter) { - geom.moveCenter(QPoint(screenGeom.center().x() + m_offset, screenGeom.bottom() - size.height()/2)); + geom.moveBottomLeft(QPoint(screenGeom.center().x() - geom.width()/2 + 1 - geom.width()%2 + m_offset, screenGeom.bottom())); } //enable borders if needed @@ -456,7 +518,6 @@ if (m_panelController) { m_panelController->setContainment(c); - m_panelController->setOffset(m_offset); } } @@ -512,11 +573,13 @@ m_panelController->setLocation(containment()->location()); m_panelController->setAlignment(m_alignment); m_panelController->setOffset(m_offset); + m_panelController->setPanelMode(m_panelMode); connect(m_panelController, SIGNAL(destroyed(QObject*)), this, SLOT(edittingComplete())); connect(m_panelController, SIGNAL(offsetChanged(int)), this, SLOT(setOffset(int))); connect(m_panelController, SIGNAL(alignmentChanged(Qt::Alignment)), this, SLOT(setAlignment(Qt::Alignment))); connect(m_panelController, SIGNAL(locationChanged(Plasma::Location)), this, SLOT(setLocation(Plasma::Location))); + connect(m_panelController, SIGNAL(panelModeChanged(PanelView::PanelMode)), this, SLOT(setPanelMode(PanelView::PanelMode))); if (dynamic_cast<QGraphicsLinearLayout*>(containment()->layout())) { // we only support mouse over drags for panels with linear layouts @@ -549,6 +612,7 @@ m_panelController->show(); } else { m_panelController->close(); + updateStruts(); } } @@ -560,6 +624,12 @@ qDeleteAll(m_moveOverlays); m_moveOverlays.clear(); containment()->closeToolBox(); + updateStruts(); + m_firstPaint = true; // triggers autohide + + // not overly efficient since we may not have changed any settings, + // but ensures that if we have, a config sync will occur + PlasmaApp::self()->corona()->requestConfigSync(); } Qt::Alignment PanelView::alignmentFilter(Qt::Alignment align) const @@ -576,47 +646,49 @@ { NETExtendedStrut strut; - QRect thisScreen = QApplication::desktop()->screenGeometry(containment()->screen()); - QRect wholeScreen = QApplication::desktop()->geometry(); + if (m_panelMode == NormalPanel) { + QRect thisScreen = QApplication::desktop()->screenGeometry(containment()->screen()); + QRect wholeScreen = QApplication::desktop()->geometry(); - // extended struts are to the combined screen geoms, not the single screen - int leftOffset = wholeScreen.x() - thisScreen.x(); - int rightOffset = wholeScreen.right() - thisScreen.right(); - int bottomOffset = wholeScreen.bottom() - thisScreen.bottom(); - int topOffset = wholeScreen.top() - thisScreen.top(); - kDebug() << "screen l/r/b/t offsets are:" << leftOffset << rightOffset << bottomOffset << topOffset; + // extended struts are to the combined screen geoms, not the single screen + int leftOffset = wholeScreen.x() - thisScreen.x(); + int rightOffset = wholeScreen.right() - thisScreen.right(); + int bottomOffset = wholeScreen.bottom() - thisScreen.bottom(); + int topOffset = wholeScreen.top() - thisScreen.top(); + kDebug() << "screen l/r/b/t offsets are:" << leftOffset << rightOffset << bottomOffset << topOffset; - switch (location()) - { - case Plasma::TopEdge: - strut.top_width = height() + topOffset; - strut.top_start = x(); - strut.top_end = x() + width() - 1; - break; + switch (location()) + { + case Plasma::TopEdge: + strut.top_width = height() + topOffset; + strut.top_start = x(); + strut.top_end = x() + width() - 1; + break; - case Plasma::BottomEdge: - strut.bottom_width = height() + bottomOffset; - strut.bottom_start = x(); - strut.bottom_end = x() + width() - 1; - //kDebug() << "setting bottom edge to" << strut.bottom_width - // << strut.bottom_start << strut.bottom_end; - break; + case Plasma::BottomEdge: + strut.bottom_width = height() + bottomOffset; + strut.bottom_start = x(); + strut.bottom_end = x() + width() - 1; + //kDebug() << "setting bottom edge to" << strut.bottom_width + // << strut.bottom_start << strut.bottom_end; + break; - case Plasma::RightEdge: - strut.right_width = width() + rightOffset; - strut.right_start = y(); - strut.right_end = y() + height() - 1; - break; + case Plasma::RightEdge: + strut.right_width = width() + rightOffset; + strut.right_start = y(); + strut.right_end = y() + height() - 1; + break; - case Plasma::LeftEdge: - strut.left_width = width() + leftOffset; - strut.left_start = y(); - strut.left_end = y() + height() - 1; - break; + case Plasma::LeftEdge: + strut.left_width = width() + leftOffset; + strut.left_start = y(); + strut.left_end = y() + height() - 1; + break; - default: - //kDebug() << "where are we?"; + default: + //kDebug() << "where are we?"; break; + } } KWindowSystem::setExtendedStrut(winId(), strut.left_width, @@ -635,15 +707,256 @@ void PanelView::moveEvent(QMoveEvent *event) { + //kDebug(); QWidget::moveEvent(event); updateStruts(); } void PanelView::resizeEvent(QResizeEvent *event) { + //kDebug(); QWidget::resizeEvent(event); updateStruts(); } +QTimeLine *PanelView::timeLine() +{ + if (!m_timeLine) { + m_timeLine = new QTimeLine(200, this); + m_timeLine->setCurveShape(QTimeLine::EaseOutCurve); + m_timeLine->setUpdateInterval(10); + connect(m_timeLine, SIGNAL(valueChanged(qreal)), this, SLOT(animateHide(qreal))); + } + + return m_timeLine; +} + +void PanelView::unhide() +{ + //kDebug(); + destroyUnhideTrigger(); + + QTimeLine * tl = timeLine(); + tl->setDirection(QTimeLine::Backward); + // with composite, we can quite do some nice animations with transparent + // backgrounds; without it we can't so we just show/hide + if (PlasmaApp::hasComposite()) { + if (tl->state() == QTimeLine::NotRunning) { + tl->start(); + } + } + + show(); + KWindowSystem::setOnAllDesktops(winId(), true); + unsigned long state = NET::Sticky; + KWindowSystem::setState(winId(), state); + if (m_panelMode == LetWindowsCover) { + KWindowSystem::raiseWindow(winId()); + KWindowSystem::activateWindow(winId()); + } +} + +void PanelView::leaveEvent(QEvent *event) +{ + if (m_panelMode == AutoHide && !m_editting) { + // try not to hide if we have an associated popup or window about + bool havePopup = QApplication::activePopupWidget() != 0; + + if (!havePopup) { + QWidget *popup = QApplication::activeWindow(); + + if (popup) { + kDebug() << "got a popup!" << popup + << popup->window() << popup->window()->parentWidget() << popup->parentWidget() << this; + + + if (popup->window()->parentWidget() == this || + popup->parentWidget() == this || + (popup->parentWidget() && popup->parentWidget()->window() == this)) { + havePopup = true; + } + } /* else { + kDebug() << "no popup?!"; + } */ + } else { + kDebug() << "gota a popup widget"; + } + + if (!havePopup) { + QTimeLine * tl = timeLine(); + tl->setDirection(QTimeLine::Forward); + + // with composite, we can quite do some nice animations with transparent + // backgrounds; without it we can't so we just show/hide + if (PlasmaApp::hasComposite()) { + if (tl->state() == QTimeLine::NotRunning) { + tl->start(); + } + } else { + animateHide(1.0); + } + } + } + + Plasma::View::leaveEvent(event); +} + +void PanelView::drawBackground(QPainter *painter, const QRectF &rect) +{ + if (PlasmaApp::hasComposite()) { + painter->setCompositionMode(QPainter::CompositionMode_Source); + painter->fillRect(rect.toAlignedRect(), Qt::transparent); + } else { + Plasma::View::drawBackground(painter, rect); + } +} + +void PanelView::paintEvent(QPaintEvent *event) +{ + Plasma::View::paintEvent(event); + if (m_firstPaint) { + // set up our auothide system after we paint it visibly to the user + if (m_panelMode == AutoHide) { + QTimeLine * tl = timeLine(); + tl->setDirection(QTimeLine::Forward); + tl->start(); + } + + m_firstPaint = false; + } +} + +bool PanelView::event(QEvent *event) +{ + if (event->type() == QEvent::Paint) { + QPainter p(this); + p.setCompositionMode(QPainter::CompositionMode_Source); + p.fillRect(rect(), Qt::transparent); + } + return Plasma::View::event(event); +} + +void PanelView::animateHide(qreal progress) +{ + int margin = 0; + Plasma::Location loc = location(); + + if (loc == Plasma::TopEdge || loc == Plasma::BottomEdge) { + margin = progress * height(); + } else { + margin = progress * width(); + } + + int xtrans = 0; + int ytrans = 0; + + switch (loc) { + case Plasma::TopEdge: + ytrans = -margin; + break; + case Plasma::BottomEdge: + ytrans = margin; + break; + case Plasma::RightEdge: + xtrans = margin; + break; + case Plasma::LeftEdge: + xtrans = -margin; + break; + default: + // no hiding unless we're on an edge. + return; + break; + } + + //kDebug() << progress << xtrans << ytrans; + if (PlasmaApp::hasComposite()) { + viewport()->move(xtrans, ytrans); + } + + QTimeLine *tl = timeLine(); + if (qFuzzyCompare(qreal(1.0), progress) && tl->direction() == QTimeLine::Forward) { + //kDebug() << "**************** hide complete" << triggerPoint << triggerWidth << triggerHeight; + createUnhideTrigger(); + hide(); + }/* else if (qFuzzyCompare(qreal(0.0), progress) && tl->direction() == QTimeLine::Backward) { + kDebug() << "show complete"; + }*/ +} + +void PanelView::createUnhideTrigger() +{ +#ifdef Q_WS_X11 + if (m_unhideTrigger != None) { + return; + } + + int triggerWidth = 1; + int triggerHeight = 1; + QPoint triggerPoint = pos(); + + switch (location()) { + case Plasma::TopEdge: + triggerWidth = width(); + break; + case Plasma::BottomEdge: + triggerWidth = width(); + triggerPoint = geometry().bottomLeft(); + break; + case Plasma::RightEdge: + triggerHeight = height(); + triggerPoint = geometry().topRight(); + break; + case Plasma::LeftEdge: + triggerHeight = height(); + break; + default: + // no hiding unless we're on an edge. + return; + break; + } + + XSetWindowAttributes attributes; + attributes.override_redirect = True; + attributes.event_mask = EnterWindowMask; + unsigned long valuemask = CWOverrideRedirect | CWEventMask; + m_unhideTrigger = XCreateWindow(QX11Info::display(), QX11Info::appRootWindow(), + triggerPoint.x(), triggerPoint.y(), triggerWidth, triggerHeight, + 0, CopyFromParent, InputOnly, CopyFromParent, + valuemask, &attributes); + XMapWindow(QX11Info::display(), m_unhideTrigger); +// KWindowSystem::setState(m_unhideTrigger, NET::StaysOnTop); + +#endif + //kDebug() << m_unhideTrigger; + PlasmaApp::self()->panelHidden(true); +} + +void PanelView::destroyUnhideTrigger() +{ +#ifdef Q_WS_X11 + if (m_unhideTrigger == None) { + return; + } + + XDestroyWindow(QX11Info::display(), m_unhideTrigger); + m_unhideTrigger = None; +#endif + + //kDebug(); + PlasmaApp::self()->panelHidden(false); +} + +void PanelView::panelDeleted() +{ + if (!QApplication::closingDown()) { + // the panel was removed at runtime; clean up our configuration object as well + KConfigGroup c = config(); + c.deleteGroup(); + } + + deleteLater(); +} + #include "panelview.moc" --- plasma/CMakeLists.txt +++ plasma/CMakeLists.txt @@ -3,6 +3,7 @@ add_subdirectory(configupdates) set(plasma_SRCS + backgrounddialog.cpp dashboardview.cpp desktopcorona.cpp desktopview.cpp @@ -13,8 +14,11 @@ plasmaapp.cpp positioningruler.cpp toolbutton.cpp + wallpaperpreview.cpp ) +kde4_add_ui_files(plasma_SRCS BackgroundDialog.ui) + if(WIN32) set( plasma_SRCS ${plasma_SRCS} panelview_win.cpp ) endif(WIN32) @@ -30,7 +34,7 @@ if(WIN32) target_link_libraries(kdeinit_plasma_qgv plasma ${KDE4_KIO_LIBS}) else(WIN32) -target_link_libraries(kdeinit_plasma_qgv plasma kworkspace ${KDE4_KIO_LIBS} ${X11_LIBRARIES}) +target_link_libraries(kdeinit_plasma_qgv plasma kworkspace ${KDE4_KNEWSTUFF2_LIBS} ${KDE4_KIO_LIBS} ${X11_LIBRARIES}) endif(WIN32) if(X11_Xrender_FOUND) target_link_libraries(kdeinit_plasma_qgv ${X11_Xrender_LIB}) @@ -40,4 +44,6 @@ install(TARGETS kdeinit_plasma_qgv DESTINATION ${LIB_INSTALL_DIR}) install(TARGETS plasma_qgv ${INSTALL_TARGETS_DEFAULT_ARGS}) -install( FILES plasma.desktop DESTINATION ${AUTOSTART_INSTALL_DIR} ) +install(FILES plasma.desktop DESTINATION ${AUTOSTART_INSTALL_DIR}) + +install(FILES plasma-themes.knsrc DESTINATION ${CONFIG_INSTALL_DIR}) --- scriptengines/qscript/plasma-scriptengine-qscript.desktop +++ scriptengines/qscript/plasma-scriptengine-qscript.desktop @@ -36,8 +36,8 @@ Name[pt_BR]=Widget JavaScript Name[ro]=Miniaplicație JavaScript Name[sl]=Gradnik v JavaScriptu -Name[sr]=виџет јаваскрипта -Name[sr@latin]=vidžet JavaScripta +Name[sr]=јаваскриптни виџет +Name[sr@latin]=javascript vidžet Name[sv]=Grafisk Javascript-komponent Name[th]=วิดเจ็ตจาวาสคริปต์ Name[tr]=JavaScript Programcığı --- scriptengines/qscript/plasma-scriptengine-qscriptrunner.desktop +++ scriptengines/qscript/plasma-scriptengine-qscriptrunner.desktop @@ -29,15 +29,15 @@ Name[nb]=JavaScript-kjører Name[nds]=JavaScript-Dreger Name[nl]=JavaScript-runner -Name[nn]=JavaScript-køyrer +Name[nn]=JavaScript-køyrar Name[pa]=ਜਾਵਾ-ਸਕ੍ਰਿਪਟ ਰਨਰ Name[pl]=Silnik JavaScript Name[pt]=Execução de JavaScript Name[pt_BR]=Mecanismo JavaScript Name[ro]=Executor JavaScript Name[sl]=Zaganjalnik javascripta -Name[sr]=извођач јаваскрипта -Name[sr@latin]=izvođač JavaScripta +Name[sr]=јаваскриптни извођач +Name[sr@latin]=javascript izvođač Name[sv]=Kör Javascript Name[tg]=Иҷрогари JavaScript Name[th]=ตัวประมวลผลจาวาสคริปต์ @@ -76,15 +76,15 @@ Comment[nb]=JavaScript-kjører Comment[nds]=JavaScript-Dreger Comment[nl]=JavaScript-runner -Comment[nn]=JavaScript-køyrer +Comment[nn]=JavaScript-køyrar Comment[pa]=ਜਾਵਾ-ਸਕ੍ਰਿਪਟ ਰਨਰ Comment[pl]=Silnik JavaScript Comment[pt]=Execução de JavaScript Comment[pt_BR]=Mecanismo JavaScript Comment[ro]=Executor JavaScript Comment[sl]=Zaganjalnik javascripta -Comment[sr]=Извођач јаваскрипта -Comment[sr@latin]=Izvođač JavaScripta +Comment[sr]=Јаваскриптни извођач +Comment[sr@latin]=Javascript izvođač Comment[sv]=Kör Javascript Comment[tg]=Иҷрогари JavaScript Comment[th]=ตัวประมวลผลจาวาสคริปต์ --- scriptengines/webkit/plasma-packagestructure-dashboard.desktop +++ scriptengines/webkit/plasma-packagestructure-dashboard.desktop @@ -78,8 +78,8 @@ Comment[pt_BR]=Widget do painel do MacOS Comment[ru]=Виджет приборной доски MacOS Dashboard Comment[sl]=Gradnik za Mac OS Dashboard -Comment[sr]=Инструмент-табла као у МекОС‑у -Comment[sr@latin]=Instrument-tabla kao u MacOS‑u +Comment[sr]=Виџет инструмент-табле као у МекОС‑у +Comment[sr@latin]=Vidžet instrument-table kao u MacOS‑u Comment[sv]=Grafisk komponent för MacOS instrumentpanel Comment[th]=วิดเจ็ตของแดชบอร์ด MacOS Comment[tr]=MacOS kontrol paneli programcığı --- scriptengines/webkit/plasma-scriptengine-applet-web.desktop +++ scriptengines/webkit/plasma-scriptengine-applet-web.desktop @@ -36,7 +36,7 @@ Name[ru]=Веб-элемент Name[sl]=Spletni gradnik Name[sr]=веб виџет -Name[sr@latin]=web vidžet +Name[sr@latin]=veb vidžet Name[sv]=Webbkomponent Name[th]=วิดเจ็ตแบบเว็บ Name[tr]=Web Programcığı @@ -79,8 +79,8 @@ Comment[pt_BR]=Widget de página Web usando HTML e JavaScript Comment[ru]=Модуль, использующий HTML и JavaScript Comment[sl]=Spletni gradnik, ki uporablja HTML in JavaScript -Comment[sr]=Виџет веб стране са ХТМЛ‑ом и јаваскриптом -Comment[sr@latin]=Vidžet veb strane sa HTML‑om i JavaScriptom +Comment[sr]=Виџет веб странице са ХТМЛ‑ом и јаваскриптом +Comment[sr@latin]=Vidžet veb stranice sa HTML‑om i JavaScriptom Comment[sv]=Grafisk webbkomponent som använder HTML och Javascript Comment[th]=วิดเจ็ตหน้าเว็บที่ถูกเขียนด้วย HTML และจาวาสคริปต์ Comment[tr]=HTML ve JavaScript kullanan Web sayfası programcığı
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor