diff --git a/PowerDevilSettings.kcfg b/PowerDevilSettings.kcfg index a8fb76fc..b35bfb03 100644 --- a/PowerDevilSettings.kcfg +++ b/PowerDevilSettings.kcfg @@ -1,35 +1,38 @@ true 250 100 10 5 2 + + 10 + diff --git a/daemon/powerdevilcore.cpp b/daemon/powerdevilcore.cpp index 25244ebc..ab7c1d3f 100644 --- a/daemon/powerdevilcore.cpp +++ b/daemon/powerdevilcore.cpp @@ -1,760 +1,820 @@ /*************************************************************************** * Copyright (C) 2010 by Dario Freddi * * * * 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 "powerdevilcore.h" #include "PowerDevilSettings.h" #include "powerdevilaction.h" #include "powerdevilactionpool.h" #include "powerdevilbackendinterface.h" #include "powerdevilpolicyagent.h" #include "powerdevilprofilegenerator.h" #include "powerdevil_debug.h" #include "actions/bundled/suspendsession.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace PowerDevil { Core::Core(QObject* parent) : QObject(parent) , m_backend(nullptr) , m_notificationsWatcher(nullptr) , m_criticalBatteryTimer(new QTimer(this)) , m_activityConsumer(new KActivities::Consumer(this)) , m_pendingWakeupEvent(true) { } Core::~Core() { // Unload all actions before exiting, and clear the cache ActionPool::instance()->unloadAllActiveActions(); ActionPool::instance()->clearCache(); } void Core::loadCore(BackendInterface* backend) { if (!backend) { onBackendError(i18n("No valid Power Management backend plugins are available. " "A new installation might solve this problem.")); return; } m_backend = backend; // Async backend init - so that KDED gets a bit of a speed up qCDebug(POWERDEVIL) << "Core loaded, initializing backend"; connect(m_backend, SIGNAL(backendReady()), this, SLOT(onBackendReady())); connect(m_backend, SIGNAL(backendError(QString)), this, SLOT(onBackendError(QString))); m_backend->init(); } void Core::onBackendReady() { qCDebug(POWERDEVIL) << "Backend is ready, KDE Power Management system initialized"; m_profilesConfig = KSharedConfig::openConfig("powermanagementprofilesrc", KConfig::CascadeConfig); // Is it brand new? if (m_profilesConfig->groupList().isEmpty()) { // Generate defaults bool toRam = m_backend->supportedSuspendMethods() & PowerDevil::BackendInterface::ToRam; bool toDisk = m_backend->supportedSuspendMethods() & PowerDevil::BackendInterface::ToDisk; ProfileGenerator::generateProfiles(toRam, toDisk); m_profilesConfig->reparseConfiguration(); } // Get the battery devices ready { using namespace Solid; connect(DeviceNotifier::instance(), SIGNAL(deviceAdded(QString)), this, SLOT(onDeviceAdded(QString))); connect(DeviceNotifier::instance(), SIGNAL(deviceRemoved(QString)), this, SLOT(onDeviceRemoved(QString))); // Force the addition of already existent batteries Q_FOREACH (const Device &device, Device::listFromType(DeviceInterface::Battery, QString())) { onDeviceAdded(device.udi()); } } connect(m_backend, SIGNAL(acAdapterStateChanged(PowerDevil::BackendInterface::AcAdapterState)), this, SLOT(onAcAdapterStateChanged(PowerDevil::BackendInterface::AcAdapterState))); connect(m_backend, SIGNAL(batteryRemainingTimeChanged(qulonglong)), this, SLOT(onBatteryRemainingTimeChanged(qulonglong))); connect(m_backend, SIGNAL(lidClosedChanged(bool)), this, SLOT(onLidClosedChanged(bool))); connect(KIdleTime::instance(), SIGNAL(timeoutReached(int,int)), this, SLOT(onKIdleTimeoutReached(int,int))); connect(KIdleTime::instance(), SIGNAL(resumingFromIdle()), this, SLOT(onResumingFromIdle())); connect(m_activityConsumer, &KActivities::Consumer::currentActivityChanged, this, [this]() { loadProfile(); }); // Set up the policy agent PowerDevil::PolicyAgent::instance()->init(); // When inhibitions change, simulate user activity, see Bug 315438 connect(PowerDevil::PolicyAgent::instance(), &PowerDevil::PolicyAgent::unavailablePoliciesChanged, this, [](PowerDevil::PolicyAgent::RequiredPolicies newPolicies) { Q_UNUSED(newPolicies); KIdleTime::instance()->simulateUserActivity(); }); // Initialize the action pool, which will also load the needed startup actions. PowerDevil::ActionPool::instance()->init(this); // Set up the critical battery timer m_criticalBatteryTimer->setSingleShot(true); m_criticalBatteryTimer->setInterval(60000); connect(m_criticalBatteryTimer, SIGNAL(timeout()), this, SLOT(onCriticalBatteryTimerExpired())); // wait until the notification system is set up before firing notifications // to avoid them showing ontop of ksplash... if (QDBusConnection::sessionBus().interface()->isServiceRegistered("org.freedesktop.Notifications")) { onServiceRegistered(QString()); } else { m_notificationsWatcher = new QDBusServiceWatcher("org.freedesktop.Notifications", QDBusConnection::sessionBus(), QDBusServiceWatcher::WatchForRegistration, this); connect(m_notificationsWatcher, SIGNAL(serviceRegistered(QString)), this, SLOT(onServiceRegistered(QString))); // ...but fire them after 30s nonetheless to ensure they've been shown QTimer::singleShot(30000, this, SLOT(onNotificationTimeout())); } // All systems up Houston, let's go! Q_EMIT coreReady(); refreshStatus(); } bool Core::isActionSupported(const QString& actionName) { Action *action = ActionPool::instance()->loadAction(actionName, KConfigGroup(), this); if (!action) { return false; } else { return action->isSupported(); } } void Core::refreshStatus() { /* The configuration could have changed if this function was called, so * let's resync it. */ reparseConfiguration(); loadProfile(true); } void Core::reparseConfiguration() { PowerDevilSettings::self()->load(); m_profilesConfig->reparseConfiguration(); // Config reloaded Q_EMIT configurationReloaded(); } QString Core::currentProfile() const { return m_currentProfile; } void Core::loadProfile(bool force) { QString profileId; // Policy check if (PolicyAgent::instance()->requirePolicyCheck(PolicyAgent::ChangeProfile) != PolicyAgent::None) { qCDebug(POWERDEVIL) << "Policy Agent prevention: on"; return; } KConfigGroup config; // Check the activity in which we are in QString activity = m_activityConsumer->currentActivity(); qCDebug(POWERDEVIL) << "We are now into activity " << activity; KConfigGroup activitiesConfig(m_profilesConfig, "Activities"); qCDebug(POWERDEVIL) << activitiesConfig.groupList() << activitiesConfig.keyList(); // Are we mirroring an activity? if (activitiesConfig.group(activity).readEntry("mode", "None") == "ActLike" && activitiesConfig.group(activity).readEntry("actLike", QString()) != "AC" && activitiesConfig.group(activity).readEntry("actLike", QString()) != "Battery" && activitiesConfig.group(activity).readEntry("actLike", QString()) != "LowBattery") { // Yes, let's use that then activity = activitiesConfig.group(activity).readEntry("actLike", QString()); qCDebug(POWERDEVIL) << "Activity is a mirror"; } KConfigGroup activityConfig = activitiesConfig.group(activity); qCDebug(POWERDEVIL) << activityConfig.groupList() << activityConfig.keyList(); // See if this activity has priority if (activityConfig.readEntry("mode", "None") == "SeparateSettings") { // Prioritize this profile over anything config = activityConfig.group("SeparateSettings"); qCDebug(POWERDEVIL) << "Activity is enforcing a different profile"; profileId = activity; } else { // It doesn't, let's load the current state's profile - if (m_loadedBatteriesUdi.isEmpty()) { + if (m_batteriesPercent.isEmpty()) { qCDebug(POWERDEVIL) << "No batteries found, loading AC"; profileId = "AC"; } else if (activityConfig.readEntry("mode", "None") == "ActLike") { if (activityConfig.readEntry("actLike", QString()) == "AC" || activityConfig.readEntry("actLike", QString()) == "Battery" || activityConfig.readEntry("actLike", QString()) == "LowBattery") { // Same as above, but with an existing profile config = m_profilesConfig.data()->group(activityConfig.readEntry("actLike", QString())); profileId = activityConfig.readEntry("actLike", QString()); qCDebug(POWERDEVIL) << "Activity is mirroring a different profile"; } } else { // Compute the previous and current global percentage const int percent = currentChargePercent(); if (backend()->acAdapterState() == BackendInterface::Plugged) { profileId = "AC"; qCDebug(POWERDEVIL) << "Loading profile for plugged AC"; } else if (percent <= PowerDevilSettings::batteryLowLevel()) { profileId = "LowBattery"; qCDebug(POWERDEVIL) << "Loading profile for low battery"; } else { profileId = "Battery"; qCDebug(POWERDEVIL) << "Loading profile for unplugged AC"; } } config = m_profilesConfig.data()->group(profileId); qCDebug(POWERDEVIL) << "Activity is not forcing a profile"; } // Release any special inhibitions { QHash::iterator i = m_sessionActivityInhibit.begin(); while (i != m_sessionActivityInhibit.end()) { PolicyAgent::instance()->ReleaseInhibition(i.value()); i = m_sessionActivityInhibit.erase(i); } i = m_screenActivityInhibit.begin(); while (i != m_screenActivityInhibit.end()) { PolicyAgent::instance()->ReleaseInhibition(i.value()); i = m_screenActivityInhibit.erase(i); } } if (!config.isValid()) { emitNotification("powerdevilerror", i18n("The profile \"%1\" has been selected, " "but it does not exist.\nPlease check your PowerDevil configuration.", profileId)); return; } // Check: do we need to change profile at all? if (m_currentProfile == profileId && !force) { // No, let's leave things as they are qCDebug(POWERDEVIL) << "Skipping action reload routine as profile has not changed"; // Do we need to force a wakeup? if (m_pendingWakeupEvent) { // Fake activity at this stage, when no timeouts are registered onResumingFromIdle(); KIdleTime::instance()->simulateUserActivity(); m_pendingWakeupEvent = false; } } else { // First of all, let's clean the old actions. This will also call the onProfileUnload callback ActionPool::instance()->unloadAllActiveActions(); // Do we need to force a wakeup? if (m_pendingWakeupEvent) { // Fake activity at this stage, when no timeouts are registered onResumingFromIdle(); KIdleTime::instance()->simulateUserActivity(); m_pendingWakeupEvent = false; } // Cool, now let's load the needed actions Q_FOREACH (const QString &actionName, config.groupList()) { Action *action = ActionPool::instance()->loadAction(actionName, config.group(actionName), this); if (action) { action->onProfileLoad(); } else { // Ouch, error. But let's just warn and move on anyway //TODO Maybe Remove from the configuration if unsupported qCWarning(POWERDEVIL) << "The profile " << profileId << "tried to activate" << actionName << "a non-existent action. This is usually due to an installation problem," " or to a configuration problem, or simply the action is not supported"; } } // We are now on a different profile m_currentProfile = profileId; Q_EMIT profileChanged(m_currentProfile); } // Now... any special behaviors we'd like to consider? if (activityConfig.readEntry("mode", "None") == "SpecialBehavior") { qCDebug(POWERDEVIL) << "Activity has special behaviors"; KConfigGroup behaviorGroup = activityConfig.group("SpecialBehavior"); if (behaviorGroup.readEntry("performAction", false)) { // Let's override the configuration for this action at all times ActionPool::instance()->loadAction("SuspendSession", behaviorGroup.group("ActionConfig"), this); qCDebug(POWERDEVIL) << "Activity overrides suspend session action"; } if (behaviorGroup.readEntry("noSuspend", false)) { qCDebug(POWERDEVIL) << "Activity triggers a suspend inhibition"; // Trigger a special inhibition - if we don't have one yet if (!m_sessionActivityInhibit.contains(activity)) { int cookie = PolicyAgent::instance()->AddInhibition(PolicyAgent::InterruptSession, i18n("Activity Manager"), i18n("This activity's policies prevent the system from suspending")); m_sessionActivityInhibit.insert(activity, cookie); } } if (behaviorGroup.readEntry("noScreenManagement", false)) { qCDebug(POWERDEVIL) << "Activity triggers a screen management inhibition"; // Trigger a special inhibition - if we don't have one yet if (!m_screenActivityInhibit.contains(activity)) { int cookie = PolicyAgent::instance()->AddInhibition(PolicyAgent::ChangeScreenSettings, i18n("Activity Manager"), i18n("This activity's policies prevent screen power management")); m_screenActivityInhibit.insert(activity, cookie); } } } // If the lid is closed, retrigger the lid close signal if (m_backend->isLidClosed()) { Q_EMIT m_backend->buttonPressed(PowerDevil::BackendInterface::LidClose); } } -void Core::onDeviceAdded(const QString& udi) +void Core::onDeviceAdded(const QString &udi) { - if (m_loadedBatteriesUdi.contains(udi)) { + if (m_batteriesPercent.contains(udi) || m_peripheralBatteriesPercent.contains(udi)) { // We already know about this device return; } using namespace Solid; Device device(udi); - Battery *b = qobject_cast(device.asDeviceInterface(DeviceInterface::Battery)); + Battery *b = qobject_cast(device.asDeviceInterface(DeviceInterface::Battery)); if (!b) { - // Not interesting to us return; } - if (b->type() != Solid::Battery::PrimaryBattery && b->type() != Solid::Battery::UpsBattery) { - // Not interesting to us - return; - } - - if (!b->isPowerSupply()) { - // TODO: At some later point it would be really nice to handle those batteries too - // eg, show "your mouse is running low", but in the mean time, we don't care about those - return; - } - - if (!connect(b, SIGNAL(chargePercentChanged(int,QString)), - this, SLOT(onBatteryChargePercentChanged(int,QString))) || - !connect(b, SIGNAL(chargeStateChanged(int,QString)), - this, SLOT(onBatteryChargeStateChanged(int,QString)))) { + if (!connect(b, &Battery::chargePercentChanged, this, &Core::onBatteryChargePercentChanged) || + !connect(b, &Battery::chargeStateChanged, this, &Core::onBatteryChargeStateChanged)) { emitNotification("powerdevilerror", i18n("Could not connect to battery interface.\n" "Please check your system configuration")); } - qCDebug(POWERDEVIL) << "A new battery was detected"; - - m_batteriesPercent[udi] = b->chargePercent(); - m_batteriesCharged[udi] = (b->chargeState() == Solid::Battery::FullyCharged); - m_loadedBatteriesUdi.append(udi); + qCDebug(POWERDEVIL) << "Battery with UDI" << udi << "was detected"; - const int chargePercent = currentChargePercent(); + if (b->isPowerSupply()) { + m_batteriesPercent[udi] = b->chargePercent(); + m_batteriesCharged[udi] = (b->chargeState() == Solid::Battery::FullyCharged); + } else { // non-power supply batteries are treated separately + m_peripheralBatteriesPercent[udi] = b->chargePercent(); + } // If a new battery has been added, let's clear some pending suspend actions if the new global batteries percentage is // higher than the battery critical level. (See bug 329537) - if (m_criticalBatteryTimer->isActive() && chargePercent > PowerDevilSettings::batteryCriticalLevel()) { + if (m_criticalBatteryTimer->isActive() && currentChargePercent() > PowerDevilSettings::batteryCriticalLevel()) { m_criticalBatteryTimer->stop(); if (m_criticalBatteryNotification) { m_criticalBatteryNotification->close(); } emitRichNotification("pluggedin", i18n("Extra Battery Added"), - i18n("All pending suspend actions have been canceled.")); + i18n("All pending suspend actions have been canceled.")); // FIXME This wording is too technical } } -void Core::onDeviceRemoved(const QString& udi) +void Core::onDeviceRemoved(const QString &udi) { - if (!m_loadedBatteriesUdi.contains(udi)) { + if (!m_batteriesPercent.contains(udi) && !m_peripheralBatteriesPercent.contains(udi)) { // We don't know about this device return; } using namespace Solid; Device device(udi); - Battery *b = qobject_cast(device.asDeviceInterface(DeviceInterface::Battery)); + Battery *b = qobject_cast(device.asDeviceInterface(DeviceInterface::Battery)); - disconnect(b, SIGNAL(chargePercentChanged(int,QString)), - this, SLOT(onBatteryChargePercentChanged(int,QString))); - disconnect(b, SIGNAL(chargeStateChanged(int,QString)), - this, SLOT(onBatteryChargeStateChanged(int,QString))); + disconnect(b, &Battery::chargePercentChanged, this, &Core::onBatteryChargePercentChanged); + disconnect(b, &Battery::chargeStateChanged, this, &Core::onBatteryChargeStateChanged); - qCDebug(POWERDEVIL) << "An existing battery has been removed"; + qCDebug(POWERDEVIL) << "Battery with UDI" << udi << "has been removed"; m_batteriesPercent.remove(udi); + m_peripheralBatteriesPercent.remove(udi); m_batteriesCharged.remove(udi); - m_loadedBatteriesUdi.removeOne(udi); } void Core::emitNotification(const QString &evid, const QString &message, const QString &iconname) { if (!iconname.isEmpty()) { KNotification::event(evid, message, QIcon::fromTheme(iconname).pixmap(48,48), 0, KNotification::CloseOnTimeout, "powerdevil"); } else { KNotification::event(evid, message, QPixmap(), 0, KNotification::CloseOnTimeout, "powerdevil"); } } +void Core::emitNotification(const QString &eventId, const QString &title, const QString &message, const QString &iconName) +{ + KNotification::event(eventId, title, message, iconName, 0, KNotification::CloseOnTimeout, "powerdevil"); +} + void Core::emitRichNotification(const QString &evid, const QString &title, const QString &message) { KNotification::event(evid, title, message, QPixmap(), 0, KNotification::CloseOnTimeout, "powerdevil"); } -bool Core::emitBatteryChargePercentNotification(int currentPercent, int previousPercent) +bool Core::emitBatteryChargePercentNotification(int currentPercent, int previousPercent, const QString &udi) { + using namespace Solid; + Device device(udi); + Battery *b = qobject_cast(device.asDeviceInterface(DeviceInterface::Battery)); + + if (b && !b->isPowerSupply()) { + if (currentPercent <= PowerDevilSettings::peripheralBatteryLowLevel() && + previousPercent > PowerDevilSettings::peripheralBatteryLowLevel()) { + + QString name = device.product(); + if (!device.vendor().isEmpty()) { + name.prepend(QLatin1Char(' ')).prepend(device.vendor()); + } + + QString title = i18nc("battery of device with name %1 is low", "%1 Battery Low (%2% Remaining)", name, currentPercent); + + QString msg; + QString icon; + + switch(b->type()) { + case Battery::MouseBattery: + if (title.isEmpty()) { + title = i18n("Mouse Battery Low (%1% Remaining)", currentPercent); + } + + msg = i18n("The battery in your mouse is low, and the device may turn itself off at any time. " + "Please replace or charge the battery as soon as possible."); + icon = QStringLiteral("input-mouse"); + break; + case Battery::KeyboardBattery: + if (title.isEmpty()) { + title = i18n("Keyboard Battery Low (%1% Remaining)", currentPercent); + } + + msg = i18n("The battery in your keyboard is low, and the device may turn itself off at any time. " + "Please replace or charge the battery as soon as possible."); + icon = QStringLiteral("input-keyboard"); + break; + default: + if (title.isEmpty()) { + title = i18nc("The battery in an external device is low", "Device Battery Low (%1% Remaining)", currentPercent); + } + + msg = i18n("The battery in a connected device is low, and the device may turn itself off at any time. " + "Please replace or charge the battery as soon as possible."); + icon = QStringLiteral("battery-caution"); + break; + } + + emitNotification("lowperipheralbattery", title, msg, icon); + + return true; + } + + return false; + } + if (m_backend->acAdapterState() == BackendInterface::Plugged) { return false; } if (currentPercent <= PowerDevilSettings::batteryCriticalLevel() && previousPercent > PowerDevilSettings::batteryCriticalLevel()) { handleCriticalBattery(currentPercent); return true; } else if (currentPercent <= PowerDevilSettings::batteryLowLevel() && previousPercent > PowerDevilSettings::batteryLowLevel()) { emitRichNotification("lowbattery", i18n("Battery Low (%1% Remaining)", currentPercent), i18n("Your battery is low. If you need to continue using your computer, either plug in your computer, or shut it down and then change the battery.")); return true; } return false; } void Core::handleCriticalBattery(int percent) { // no parent, but it won't leak, since it will be closed both in case of timeout or direct action m_criticalBatteryNotification = new KNotification("criticalbattery", KNotification::Persistent, nullptr); m_criticalBatteryNotification->setComponentName(QStringLiteral("powerdevil")); m_criticalBatteryNotification->setTitle(i18n("Battery Critical (%1% Remaining)", percent)); const QStringList actions = {i18nc("Cancel timeout that will automatically suspend system because of low battery", "Cancel")}; connect(m_criticalBatteryNotification.data(), &KNotification::action1Activated, this, [this] { m_criticalBatteryTimer->stop(); m_criticalBatteryNotification->close(); }); switch (PowerDevilSettings::batteryCriticalAction()) { case PowerDevil::BundledActions::SuspendSession::ShutdownMode: m_criticalBatteryNotification->setText(i18n("Your battery level is critical, the computer will be halted in 60 seconds.")); m_criticalBatteryNotification->setActions(actions); m_criticalBatteryTimer->start(); break; case PowerDevil::BundledActions::SuspendSession::ToDiskMode: m_criticalBatteryNotification->setText(i18n("Your battery level is critical, the computer will be hibernated in 60 seconds.")); m_criticalBatteryNotification->setActions(actions); m_criticalBatteryTimer->start(); break; case PowerDevil::BundledActions::SuspendSession::ToRamMode: m_criticalBatteryNotification->setText(i18n("Your battery level is critical, the computer will be suspended in 60 seconds.")); m_criticalBatteryNotification->setActions(actions); m_criticalBatteryTimer->start(); break; default: m_criticalBatteryNotification->setText(i18n("Your battery level is critical, save your work as soon as possible.")); // no timer, no actions break; } m_criticalBatteryNotification->sendEvent(); } void Core::onAcAdapterStateChanged(PowerDevil::BackendInterface::AcAdapterState state) { qCDebug(POWERDEVIL); // Post request for faking an activity event - usually adapters don't plug themselves out :) m_pendingWakeupEvent = true; loadProfile(); if (state == BackendInterface::Plugged) { // If the AC Adaptor has been plugged in, let's clear some pending suspend actions if (m_criticalBatteryTimer->isActive()) { m_criticalBatteryTimer->stop(); if (m_criticalBatteryNotification) { m_criticalBatteryNotification->close(); } emitRichNotification("pluggedin", i18n("AC Adapter Plugged In"), i18n("All pending suspend actions have been canceled.")); } else { emitRichNotification("pluggedin", i18n("Running on AC power"), i18n("The power adaptor has been plugged in.")); } } else if (state == BackendInterface::Unplugged) { emitRichNotification("unplugged", i18n("Running on Battery Power"), i18n("The power adaptor has been unplugged.")); } } void Core::onBackendError(const QString& error) { emitNotification("powerdevilerror", i18n("KDE Power Management System could not be initialized. " "The backend reported the following error: %1\n" "Please check your system configuration", error)); } void Core::onBatteryChargePercentChanged(int percent, const QString &udi) { + if (m_peripheralBatteriesPercent.contains(udi)) { + const int previousPercent = m_peripheralBatteriesPercent.value(udi); + m_peripheralBatteriesPercent[udi] = percent; + + if (percent < previousPercent) { + emitBatteryChargePercentNotification(percent, previousPercent, udi); + } + return; + } + // Compute the previous and current global percentage const int previousPercent = currentChargePercent(); const int currentPercent = previousPercent - (m_batteriesPercent[udi] - percent); // Update the battery percentage m_batteriesPercent[udi] = percent; if (currentPercent < previousPercent) { - if (emitBatteryChargePercentNotification(currentPercent, previousPercent)) { + if (emitBatteryChargePercentNotification(currentPercent, previousPercent, udi)) { // Only refresh status if a notification has actually been emitted loadProfile(); } } } void Core::onBatteryChargeStateChanged(int state, const QString &udi) { + if (!m_batteriesCharged.contains(udi)) { + return; + } + bool previousCharged = true; for (auto i = m_batteriesCharged.constBegin(); i != m_batteriesCharged.constEnd(); ++i) { if (!i.value()) { previousCharged = false; break; } } m_batteriesCharged[udi] = (state == Solid::Battery::FullyCharged); if (m_backend->acAdapterState() != BackendInterface::Plugged) { return; } bool currentCharged = true; for (auto i = m_batteriesCharged.constBegin(); i != m_batteriesCharged.constEnd(); ++i) { if (!i.value()) { currentCharged = false; break; } } if (!previousCharged && currentCharged) { emitRichNotification("fullbattery", i18n("Charge Complete"), i18n("Your battery is now fully charged.")); loadProfile(); } } void Core::onCriticalBatteryTimerExpired() { if (m_criticalBatteryNotification) { m_criticalBatteryNotification->close(); } // Do that only if we're not on AC if (m_backend->acAdapterState() == BackendInterface::Unplugged) { // We consider this as a very special button PowerDevil::Action *helperAction = ActionPool::instance()->loadAction("HandleButtonEvents", KConfigGroup(), this); if (helperAction) { QVariantMap args; args["Button"] = 32; args["Type"] = QVariant::fromValue(PowerDevilSettings::batteryCriticalAction()); helperAction->trigger(args); } } } void Core::onBatteryRemainingTimeChanged(qulonglong time) { Q_EMIT batteryRemainingTimeChanged(time); } void Core::onKIdleTimeoutReached(int identifier, int msec) { // Find which action(s) requested this idle timeout for (QHash< Action*, QList< int > >::const_iterator i = m_registeredActionTimeouts.constBegin(); i != m_registeredActionTimeouts.constEnd(); ++i) { if (i.value().contains(identifier)) { i.key()->onIdleTimeout(msec); // And it will need to be awaken if (!m_pendingResumeFromIdleActions.contains(i.key())) { m_pendingResumeFromIdleActions.append(i.key()); } break; } } // Catch the next resume event if some actions require it if (!m_pendingResumeFromIdleActions.isEmpty()) { KIdleTime::instance()->catchNextResumeEvent(); } } void Core::onLidClosedChanged(bool closed) { Q_EMIT lidClosedChanged(closed); } void Core::registerActionTimeout(Action* action, int timeout) { // Register the timeout with KIdleTime int identifier = KIdleTime::instance()->addIdleTimeout(timeout); // Add the identifier to the action hash QList< int > timeouts = m_registeredActionTimeouts[action]; timeouts.append(identifier); m_registeredActionTimeouts[action] = timeouts; } void Core::unregisterActionTimeouts(Action* action) { // Clear all timeouts from the action QList< int > timeoutsToClean = m_registeredActionTimeouts[action]; Q_FOREACH (int id, timeoutsToClean) { KIdleTime::instance()->removeIdleTimeout(id); } m_registeredActionTimeouts.remove(action); } int Core::currentChargePercent() const { int chargePercent = 0; for (auto it = m_batteriesPercent.constBegin(); it != m_batteriesPercent.constEnd(); ++it) { chargePercent += it.value(); } return chargePercent; } void Core::onResumingFromIdle() { // Wake up the actions in which an idle action was triggered QList< Action* >::iterator i = m_pendingResumeFromIdleActions.begin(); while (i != m_pendingResumeFromIdleActions.end()) { (*i)->onWakeupFromIdle(); i = m_pendingResumeFromIdleActions.erase(i); } } void Core::onNotificationTimeout() { // cannot connect QTimer::singleShot directly to the other method onServiceRegistered(QString()); } void Core::onServiceRegistered(const QString &service) { Q_UNUSED(service); static bool notificationsReady = false; if (notificationsReady) { return; } // show warning about low batteries right on session startup, force it to show // by making sure the "old" percentage (that magic number) is always higher than the current one if (emitBatteryChargePercentNotification(currentChargePercent(), 1000)) { // need to refresh status to prevent the notification from showing again when charge percentage changes refreshStatus(); } notificationsReady = true; if (m_notificationsWatcher) { delete m_notificationsWatcher; m_notificationsWatcher = nullptr; } } BackendInterface* Core::backend() { return m_backend; } bool Core::isLidClosed() const { return m_backend->isLidClosed(); } bool Core::isLidPresent() const { return m_backend->isLidPresent(); } qulonglong Core::batteryRemainingTime() const { return m_backend->batteryRemainingTime(); } uint Core::backendCapabilities() { return m_backend->capabilities(); } } diff --git a/daemon/powerdevilcore.h b/daemon/powerdevilcore.h index 6ab94fb4..b81a5c07 100644 --- a/daemon/powerdevilcore.h +++ b/daemon/powerdevilcore.h @@ -1,153 +1,157 @@ /*************************************************************************** * Copyright (C) 2010 by Dario Freddi * * * * 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 POWERDEVILCORE_H #define POWERDEVILCORE_H #include "powerdevilbackendinterface.h" #include #include #include namespace KActivities { class Consumer; } // namespace KActivities class KDirWatch; class QDBusServiceWatcher; class QTimer; class KNotification; namespace Solid { class Battery; } namespace PowerDevil { class BackendInterface; class Action; class Q_DECL_EXPORT Core : public QObject { Q_OBJECT Q_DISABLE_COPY(Core) Q_CLASSINFO("D-Bus Interface", "org.kde.Solid.PowerManagement") public: explicit Core(QObject* parent); virtual ~Core(); void reloadProfile(int state); void emitNotification(const QString &evid, const QString &message = QString(), const QString &iconname = QString()); void emitRichNotification(const QString &evid, const QString &title, const QString &message = QString()); - bool emitBatteryChargePercentNotification(int currentPercent, int previousPercent); + + void emitNotification(const QString &eventId, const QString &title, const QString &message, const QString &iconName); + + bool emitBatteryChargePercentNotification(int currentPercent, int previousPercent, const QString &udi = QString()); BackendInterface *backend(); // More... public Q_SLOTS: void loadCore(PowerDevil::BackendInterface *backend); // Set of common action - useful for the DBus interface uint backendCapabilities(); void refreshStatus(); void reparseConfiguration(); QString currentProfile() const; void loadProfile(bool force = false); qulonglong batteryRemainingTime() const; bool isLidClosed() const; bool isLidPresent() const; bool isActionSupported(const QString &actionName); Q_SIGNALS: void coreReady(); void profileChanged(const QString &newProfile); void configurationReloaded(); void batteryRemainingTimeChanged(qulonglong time); void lidClosedChanged(bool closed); private: void registerActionTimeout(Action *action, int timeout); void unregisterActionTimeouts(Action *action); void handleCriticalBattery(int percent); /** * Computes the current global charge percentage. * Sum of all battery charges. */ int currentChargePercent() const; friend class Action; BackendInterface *m_backend; - QStringList m_loadedBatteriesUdi; + QStringList m_batteriesUdi; QDBusServiceWatcher *m_notificationsWatcher; KSharedConfigPtr m_profilesConfig; QString m_currentProfile; - QHash< QString, int > m_batteriesPercent; - QHash< QString, bool > m_batteriesCharged; + QHash m_batteriesPercent; + QHash m_peripheralBatteriesPercent; + QHash m_batteriesCharged; QTimer *m_criticalBatteryTimer; QPointer m_criticalBatteryNotification; KActivities::Consumer *m_activityConsumer; // Idle time management QHash< Action*, QList< int > > m_registeredActionTimeouts; QList< Action* > m_pendingResumeFromIdleActions; bool m_pendingWakeupEvent; // Activity inhibition management QHash< QString, int > m_sessionActivityInhibit; QHash< QString, int > m_screenActivityInhibit; private Q_SLOTS: void onBackendReady(); void onBackendError(const QString &error); void onAcAdapterStateChanged(PowerDevil::BackendInterface::AcAdapterState); void onBatteryChargePercentChanged(int,const QString&); void onBatteryChargeStateChanged(int,const QString&); void onBatteryRemainingTimeChanged(qulonglong); void onKIdleTimeoutReached(int,int); void onResumingFromIdle(); void onDeviceAdded(const QString &udi); void onDeviceRemoved(const QString &udi); void onCriticalBatteryTimerExpired(); void onNotificationTimeout(); void onServiceRegistered(const QString &service); void onLidClosedChanged(bool closed); }; } #endif // POWERDEVILCORE_H diff --git a/powerdevil.notifyrc b/powerdevil.notifyrc index 50c5deb7..e5649373 100644 --- a/powerdevil.notifyrc +++ b/powerdevil.notifyrc @@ -1,938 +1,946 @@ [Global] Name=KDE Power Management System Name[ar]=نظام إدارة طاقة كدي Name[ast]=Sistema de xestión d'enerxía KDE Name[bs]=KDE‑ov sistem za upravljanje napajanjem Name[ca]=Sistema de gestió d'energia del KDE Name[ca@valencia]=Sistema de gestió d'energia del KDE Name[cs]=Systém správy napájení KDE Name[da]=KDE's strømstyringssystem Name[de]=KDE-Energieverwaltungssystem Name[el]=Σύστημα διαχείρισης ενέργειας του KDE Name[en_GB]=KDE Power Management System Name[es]=Sistema de gestión de energía de KDE Name[et]=KDE toitehalduse süsteem Name[fi]=KDE:n virranhallintajärjestelmä Name[fr]=Système KDE de gestion de l'énergie Name[gl]=Sistema de xestión da enerxía de KDE Name[hu]=KDE energiakezelő rendszer Name[ia]=Systema de gestion de energia de KDE Name[id]=Sistem Manajemen Daya KDE Name[it]=Sistema di gestione energetica di KDE Name[ja]=KDE 電源管理 Name[ko]=KDE 전원 관리 시스템 Name[lt]=KDE energijos valdymo sistema Name[nb]=Et strømstyringsverktøy for KDE Name[nds]=Stroomkuntrullsysteem för KDE Name[nl]=KDE energiebeheersysteem Name[nn]=KDE-straumstyring Name[pa]=KDE ਪਾਵਰ ਪਰਬੰਧਕ ਸਿਸਟਮ Name[pl]=System zarządzania energią w KDE Name[pt]=Sistema de Gestão de Energia do KDE Name[pt_BR]=Sistema de Gerenciamento de Energia do KDE Name[ro]=Sistemul KDE de gestiune a alimentării Name[ru]=Система управления питанием KDE Name[sk]=Systém správy napájania KDE Name[sl]=KDE-jev sistem za upravljanje z energijo Name[sr]=КДЕ‑ов систем за управљање напајањем Name[sr@ijekavian]=КДЕ‑ов систем за управљање напајањем Name[sr@ijekavianlatin]=KDE‑ov sistem za upravljanje napajanjem Name[sr@latin]=KDE‑ov sistem za upravljanje napajanjem Name[sv]=KDE:s strömsparhanteringssystem Name[tr]=KDE Güç Yönetimi Sistemi Name[uk]=Система керування живленням KDE Name[x-test]=xxKDE Power Management Systemxx Name[zh_CN]=KDE 电源管理系统 Name[zh_TW]=KDE 電源管理系統 IconName=preferences-system-power-management Comment=Power Management System Comment[ar]=نظام إدارة الطاقة Comment[ast]=Sistema de xestión d'enerxía Comment[bs]=Sistem za upravljanje napajanjem Comment[ca]=Sistema de gestió d'energia Comment[ca@valencia]=Sistema de gestió d'energia Comment[cs]=Systém správy napájení Comment[da]=Strømstyringssystem Comment[de]=Energieverwaltungssystem Comment[el]=Σύστημα διαχείρισης ενέργειας Comment[en_GB]=Power Management System Comment[es]=Sistema de gestión de energía Comment[et]=Toitehalduse süsteem Comment[fi]=Virranhallintajärjestelmä Comment[fr]=Système de gestion de l'énergie Comment[gl]=Sistema de xestión da enerxía Comment[hu]=Energiakezelő rendszer Comment[ia]=Systema de gestion de energia Comment[id]=Sistem Manajemen Daya Comment[it]=Sistema di gestione energetica Comment[ko]=전원 관리 시스템 Comment[lt]=Energijos valdymo sistema Comment[nb]=Et strømstyringsverktøy Comment[nds]=Stroompleegsysteem Comment[nl]=Energiebeheersysteem Comment[nn]=Straumstyring Comment[pa]=ਪਾਵਰ ਪਰਬੰਧ ਸਿਸਟਮ Comment[pl]=System zarządzania energią Comment[pt]=Sistema de Gestão de Energia Comment[pt_BR]=Sistema de Gerenciamento de Energia Comment[ro]=Sistemul de gestiune a alimentării Comment[ru]=Система управления питанием Comment[sk]=Systém správy napájania Comment[sl]=Sistem za upravljanje z energijo Comment[sr]=Систем за управљање напајањем Comment[sr@ijekavian]=Систем за управљање напајањем Comment[sr@ijekavianlatin]=Sistem za upravljanje napajanjem Comment[sr@latin]=Sistem za upravljanje napajanjem Comment[sv]=Strömsparhanteringssystem Comment[tr]=Güç Yönetimi Sistemi Comment[uk]=Система керування живленням Comment[x-test]=xxPower Management Systemxx Comment[zh_CN]=电源管理系统 Comment[zh_TW]=電源管理系統 Version=2 [Context/warningnot] Name=Warning Name[ar]=تحذير Name[ast]=Avisu Name[bs]=Upozorenje Name[ca]=Avís Name[ca@valencia]=Avís Name[cs]=Varování Name[da]=Advarsel Name[de]=Warnung Name[el]=Προειδοποίηση Name[en_GB]=Warning Name[es]=Advertencia Name[et]=Hoiatus Name[fi]=Varoitus Name[fr]=Avertissement Name[gl]=Aviso Name[hu]=Figyelem Name[ia]=Aviso Name[id]=Peringatan Name[it]=Avviso Name[ja]=注意 Name[ko]=경고 Name[lt]=Perspėjimas Name[nb]=Advarsel Name[nds]=Wohrschoen Name[nl]=Waarschuwing Name[nn]=Åtvaring Name[pa]=ਚੇਤਾਵਨੀ Name[pl]=Ostrzeżenie Name[pt]=Aviso Name[pt_BR]=Aviso Name[ro]=Avertizare Name[ru]=Предупреждение Name[sk]=Upozornenie Name[sl]=Opozorilo Name[sr]=Упозорење Name[sr@ijekavian]=Упозорење Name[sr@ijekavianlatin]=Upozorenje Name[sr@latin]=Upozorenje Name[sv]=Varning Name[tr]=Uyarı Name[uk]=Попередження Name[x-test]=xxWarningxx Name[zh_CN]=警告 Name[zh_TW]=警告 Comment=Used for warning notifications Comment[ar]=يُتسخدَم لتنبيهات التحذير Comment[ast]=Úsase p'alvertencies Comment[bs]=Koristi se za obavještenja o upozorenjima Comment[ca]=S'usa per a les notificacions d'avís Comment[ca@valencia]=S'usa per a les notificacions d'avís Comment[cs]=Použito pro varování a upozornění Comment[da]=Bruges til advarselsbekendtgørelser Comment[de]=Verwendet für Warnmeldungen Comment[el]=Χρησιμοποιείται για τις προειδοποιήσεις Comment[en_GB]=Used for warning notifications Comment[es]=Usado para notificaciones de advertencia Comment[et]=Hoiatuste jaoks Comment[fi]=Käytetään varoitusilmoituksiin Comment[fr]=Utilisé pour les notifications d'avertissement Comment[gl]=Emprégase para as notificacións de aviso Comment[hu]=Kezelőprogram figyelmeztető üzenetekhez Comment[ia]=Usate pro notificationes de avisos Comment[id]=Digunakan untuk pemberitahuan peringatan Comment[it]=Usato per notifiche di avviso Comment[ko]=경고 알림에 사용됨 Comment[lt]=Naudojama perspėjimams Comment[nb]=Brukt til varselsmeldinger Comment[nds]=Bi Wohrschoen bruukt Comment[nl]=Wordt gebruikt voor waarschuwingsmeldingen Comment[nn]=Brukt til åtvaringsvarslingar Comment[pa]=ਚੇਤਾਵਨੀ ਨੋਟੀਫਿਕੇਸ਼ਨ ਲਈ ਵਰਤਿਆ ਜਾਂਦਾ ਹੈ Comment[pl]=Używane do powiadomień Comment[pt]=Usado para as notificações de aviso Comment[pt_BR]=Usado para as notificações de aviso Comment[ro]=Utilizat pentru notificări de avertizare Comment[ru]=Используется для системных уведомлений Comment[sk]=Používa sa pre varovné upozornenia Comment[sl]=Uporabljeno za obvestila z opozorili Comment[sr]=Користи се за позорна обавештења Comment[sr@ijekavian]=Користи се за позорна обавјештења Comment[sr@ijekavianlatin]=Koristi se za pozorna obavještenja Comment[sr@latin]=Koristi se za pozorna obaveštenja Comment[sv]=Används för varningsmeddelanden Comment[tr]=Uyarı bildirimleri için kullanılır Comment[uk]=Використовується для попереджень Comment[x-test]=xxUsed for warning notificationsxx Comment[zh_CN]=用于发出警告通知 Comment[zh_TW]=用於警告通知 [Context/stdnot] Name=Notification Name[ar]=تنبيه Name[ast]=Avisu Name[bs]=Obavještenje Name[ca]=Notificació Name[ca@valencia]=Notificació Name[cs]=Hlášení Name[da]=Bekendtgørelse Name[de]=Benachrichtigung Name[el]=Ειδοποίηση Name[en_GB]=Notification Name[es]=Notificación Name[et]=Märguanne Name[fi]=Ilmoitus Name[fr]=Notification Name[gl]=Notificación Name[hu]=Értesítés Name[ia]=Notification Name[id]=Pemberitahuan Name[it]=Notifica Name[ja]=通知 Name[ko]=알림 Name[lt]=Pranešimas Name[nb]=Varsling Name[nds]=Bescheed Name[nl]=Melding Name[nn]=Varsling Name[pa]=ਨੋਟੀਫਿਕੇਸ਼ਨ Name[pl]=Powiadomienie Name[pt]=Notificação Name[pt_BR]=Notificação Name[ro]=Notificare Name[ru]=Уведомление Name[se]=Dieđiheapmi Name[sk]=Oznámenie Name[sl]=Obvestilo Name[sr]=Обавештење Name[sr@ijekavian]=Обавјештење Name[sr@ijekavianlatin]=Obavještenje Name[sr@latin]=Obaveštenje Name[sv]=Underrättelse Name[tr]=Bildirim Name[uk]=Сповіщення Name[x-test]=xxNotificationxx Name[zh_CN]=通知 Name[zh_TW]=通知 Comment=Used for standard notifications Comment[ar]=يُستخدَم للتنبيهات الاعتيادية Comment[ast]=Úsase p'avisos estándar Comment[bs]=Koristi se za standardna obavještenja Comment[ca]=S'usa per a les notificacions estàndard Comment[ca@valencia]=S'usa per a les notificacions estàndard Comment[cs]=Použito pro běžná oznámení Comment[da]=Bruges til almindelige bekendtgørelser Comment[de]=Verwendet für Standard-Benachrichtigungen Comment[el]=Χρησιμοποιείται για τυπικές ειδοποιήσεις Comment[en_GB]=Used for standard notifications Comment[es]=Usado para notificaciones estándar Comment[et]=Tavaliste märguannete jaoks Comment[fi]=Käytetään normaaleihin ilmoituksiin Comment[fr]=Utilisé pour les notifications standards Comment[gl]=Emprégase para as notificacións estándar Comment[hu]=Kezelő értesítő üzenetekhez Comment[ia]=Usate pro notificationes standard Comment[id]=Digunakan untuk pemberitahuan standar Comment[it]=Usato per notifiche standard Comment[ja]=通常の通知に使用 Comment[ko]=표준 알림에 사용됨 Comment[lt]=Naudojamas standartiniams pranešimams Comment[nb]=Brukt til standardmeldinger Comment[nds]=Bi Standardbescheden bruukt Comment[nl]=Wordt gebruikt voor standaardmeldingen Comment[nn]=Er brukt til standardvarslingar Comment[pa]=ਸਟੈਂਡਰਡ ਨੋਟੀਫਿਕੇਸ਼ਨ ਲਈ ਵਰਤਿਆ ਜਾਂਦਾ ਹੈ Comment[pl]=Używane do zwykłych powiadomień Comment[pt]=Usado para as notificações normais Comment[pt_BR]=Usado para as notificações padrão Comment[ro]=Utilizat pentru notificări obișnuite Comment[ru]=Используется для уведомлений Comment[sk]=Používa sa pre bežné upozornenia Comment[sl]=Za običajna obvestila Comment[sr]=Користи се за стандардна обавештења Comment[sr@ijekavian]=Користи се за стандардна обавјештења Comment[sr@ijekavianlatin]=Koristi se za standardna obavještenja Comment[sr@latin]=Koristi se za standardna obaveštenja Comment[sv]=Används för standardmeddelanden Comment[tr]=Standart bildirimler için kullanılır Comment[uk]=Використовується для звичайних сповіщень Comment[x-test]=xxUsed for standard notificationsxx Comment[zh_CN]=用于标准通知 Comment[zh_TW]=用於標準通知 [Context/criticalnot] Name=Critical notification Name[ar]=تحذير حَرِج Name[ast]=Avisu críticu Name[bs]=Kritično obavještenje Name[ca]=Notificacions crítiques Name[ca@valencia]=Notificacions crítiques Name[cs]=Kritické hlášení Name[da]=Kritisk bekendtgørelse Name[de]=Kritische Benachrichtigung Name[el]=Κρίσιμη ειδοποίηση Name[en_GB]=Critical notification Name[es]=Notificación crítica Name[et]=Kriitiline märguanne Name[fi]=Kriittinen ilmoitus Name[fr]=Notification critique Name[gl]=Notificación crítica Name[hu]=Kritikus értesítés Name[ia]=Notification critic Name[id]=Pemberitahuan kritis Name[it]=Notifica critica Name[ja]=重大な通知 Name[ko]=치명적 알림 Name[lt]=Kritinis pranešimas Name[nb]=Kritisk varsling Name[nds]=Kritisch Bescheed Name[nl]=Kritieke melding Name[nn]=Viktig varsling Name[pa]=ਨਾਜ਼ੁਕ ਨੋਟੀਫਿਕੇਸ਼ਨ Name[pl]=Powiadomienie krytyczne Name[pt]=Notificação crítica Name[pt_BR]=Notificação crítica Name[ro]=Notificare critică Name[ru]=Критичное уведомление Name[sk]=Kritické upozornenie Name[sl]=Kritično obvestilo Name[sr]=Критично обавештење Name[sr@ijekavian]=Критично обавјештење Name[sr@ijekavianlatin]=Kritično obavještenje Name[sr@latin]=Kritično obaveštenje Name[sv]=Kritisk underrättelse Name[tr]=Kritik Bildirim Name[uk]=Сповіщення про критичні події Name[x-test]=xxCritical notificationxx Name[zh_CN]=危急通知 Name[zh_TW]=緊急通知 Comment=Notifies a critical event Comment[ar]=يُنبِّه عن حدث حَرِج Comment[ast]=Avisa d'un eventu críticu Comment[bs]=Obavještava o kritičnom događaju Comment[ca]=Notifiquen esdeveniments crítics Comment[ca@valencia]=Notifiquen esdeveniments crítics Comment[cs]=Upozorňuje na kritickou událost Comment[da]=Bekendtgør en kritisk begivenhed Comment[de]=Benachrichtigt über einen kritischen Zustand Comment[el]=Ειδοποίηση για κρίσιμο γεγονός Comment[en_GB]=Notifies a critical event Comment[es]=Notifica de un evento crítico Comment[et]=Märguandmine kriitilisest sündmusest Comment[fi]=Ilmoittaa kriittisestä tapahtumasta Comment[fr]=Notifie un évènement critique Comment[gl]=Notifica un suceso crítico Comment[hu]=Kritikus fontosságú üzenetet jelez Comment[ia]=Il notifica un evento critic Comment[id]=Pemberitahu kejadian kritis Comment[it]=Notifica un evento critico Comment[ja]=重大なイベントを通知します Comment[ko]=치명적인 사건을 알림 Comment[lt]=Perspėja apie kritinį įvykį Comment[nb]=Varsler om en kritisk hendelse Comment[nds]=Gifft över en kritisch Begeefnis bescheed Comment[nl]=Meldt een kritieke gebeurtenis Comment[nn]=Varslar om noko viktig Comment[pa]=ਇੱਕ ਨਾਜ਼ੁਕ ਈਵੈਂਟ ਲਈ ਸੂਚਨਾ Comment[pl]=Powiadomienie o zdarzeniu krytycznym Comment[pt]=Notifica um evento crítico Comment[pt_BR]=Notifica um evento crítico Comment[ro]=Notifică un eveniment critic Comment[ru]=Уведомление о критическом событии Comment[sk]=Upozorňuje na kritickú udalosť Comment[sl]=Obvestilo o kritičnem dogodku Comment[sr]=Обавештава о критичном догађају Comment[sr@ijekavian]=Обавјештава о критичном догађају Comment[sr@ijekavianlatin]=Obavještava o kritičnom događaju Comment[sr@latin]=Obaveštava o kritičnom događaju Comment[sv]=Underrättar om en kritisk händelse Comment[tr]=Kritik bir durumu bildirir Comment[uk]=Сповіщає про критичну подію Comment[x-test]=xxNotifies a critical eventxx Comment[zh_CN]=危急事件通知 Comment[zh_TW]=通知緊急事件 [Event/lowbattery] Name=Battery Low Name[ar]=البطارية منخفضة Name[ast]=Batería baxa Name[bs]=Nizak nivo baterije Name[ca]=Bateria baixa Name[ca@valencia]=Bateria baixa Name[cs]=Baterie je téměř vybitá Name[da]=Lavt batteri Name[de]=Akku-Ladestand niedrig Name[el]=Μπαταρία χαμηλή Name[en_GB]=Battery Low Name[es]=Batería baja Name[et]=Aku laetus on madal Name[fi]=Akku vähissä Name[fr]=Batterie faible Name[gl]=Batería baixa Name[hu]=Az akkumulátor gyenge Name[ia]=Batteria basse Name[id]=Baterai Lemah Name[it]=Batteria a livello basso Name[ko]=배터리 부족 Name[lt]=Akumuliatorius ištuštėjęs Name[nb]=Lavt batteri Name[nds]=Batterie siet Name[nl]=Accu op laag niveau Name[nn]=Lågt batterinivå Name[pa]=ਘੱਟ ਬੈਟਰੀ Name[pl]=Bateria na niskim poziomie Name[pt]=Bateria Fraca Name[pt_BR]=Bateria fraca Name[ro]=Acumulator scăzut Name[ru]=Низкий уровень заряда батареи Name[sk]=Batéria je slabá Name[sl]=Nizka raven baterije Name[sr]=Батерија при крају Name[sr@ijekavian]=Батерија при крају Name[sr@ijekavianlatin]=Baterija pri kraju Name[sr@latin]=Baterija pri kraju Name[sv]=Dåligt batteri Name[tr]=Pil Düşük Name[uk]=Низький рівень заряду Name[x-test]=xxBattery Lowxx Name[zh_CN]=电池电量低 Name[zh_TW]=電池電力偏低 Comment=Your battery has reached low level Comment[ar]=وصلت بطاريتك إلى مستوى منخفض Comment[ast]=La to batería algamó'l nivel baxu Comment[bs]=Baterija je dosegla nizak nivo Comment[ca]=La bateria ha arribat al nivell baix Comment[ca@valencia]=La bateria ha arribat al nivell baix Comment[cs]=Baterie dosáhla nízké úrovně Comment[da]=Dit batteri har nået lavt niveau Comment[de]=Der Ladestand Ihres Akkus hat einen niedrigen Wert erreicht. Comment[el]=Η μπαταρία σας έχει βρεθεί σε χαμηλή στάθμη ενέργειας Comment[en_GB]=Your battery has reached low level Comment[es]=La batería ha alcanzado un nivel bajo Comment[et]=Aku täituvus on madal Comment[fi]=Akku on vähissä Comment[fr]=Votre batterie a atteint un niveau bas Comment[gl]=A batería acadou o nivel de carga baixa Comment[hu]=A telepek feltöltöttsége alacsony szintű Comment[ia]=Tu batteria ha attingite nivello basse Comment[id]=Baterai anda telah mencapai level rendah Comment[it]=La batteria ha raggiunto un livello di carica basso Comment[ja]=バッテリ残量が低レベルに達しました Comment[ko]=배터리에 남은 용량이 적습니다 Comment[lt]=Jūsų akumuliatorius pasiekė žemą lygmenį Comment[nb]=Batteriet har nådd lavt nivå Comment[nds]=Dien Batteriestoop is nu "Siet" Comment[nl]=Uw accu heeft het lage niveau bereikt Comment[nn]=Batterinivået er lågt Comment[pa]=ਤੁਹਾਡੀ ਬੈਟਰੀ ਘੱਟ ਲੈਵਲ ਤੱਕ ਅੱਪੜ ਗਈ ਹੈ Comment[pl]=Bateria osiągnęła niski poziom naładowania Comment[pt]=A sua bateria atingiu um nível baixo Comment[pt_BR]=Sua bateria atingiu um nível baixo Comment[ro]=Acumulatorul a atins un nivel scăzut Comment[ru]=Низкий уровень заряда батареи Comment[sk]=Batéria dosiahla nízku úroveň Comment[sl]=Baterija je dosegla nizko raven napolnjenosti Comment[sr]=Попуњеност батерије пала је низак ниво Comment[sr@ijekavian]=Попуњеност батерије пала је низак ниво Comment[sr@ijekavianlatin]=Popunjenost baterije pala je nizak nivo Comment[sr@latin]=Popunjenost baterije pala je nizak nivo Comment[sv]=Batteriet har nått en låg nivå Comment[tr]=Piliniz düşük seviyeye ulaştı Comment[uk]=У вашому акумуляторі закінчується заряд Comment[x-test]=xxYour battery has reached low levelxx Comment[zh_CN]=电池电量过低 Comment[zh_TW]=您的電池電力已達不足的程度 Contexts=warningnot Sound=Oxygen-Sys-Warning.ogg Action=Sound|Popup IconName=battery-caution [Event/criticalbattery] Name=Battery Critical Name[ar]=البطارية حَرِجة Name[ast]=Batería crítica Name[bs]=Baterija kritična Name[ca]=Bateria crítica Name[ca@valencia]=Bateria crítica Name[cs]=Baterie na kritické úrovni Name[da]=Kritisk batteri Name[de]=Akku-Ladestand kritisch Name[el]=Μπαταρία κρίσιμη Name[en_GB]=Battery Critical Name[es]=Batería en nivel crítico Name[et]=Aku kriitiline tase Name[fi]=Akku kriittisellä tasolla Name[fr]=Batterie critique Name[gl]=Batería no nivel crítico Name[hu]=Kritikus lemerültség Name[ia]=Batteria critic Name[id]=Baterai Kritis Name[it]=Batteria a livello critico Name[ko]=배터리 바닥남 Name[lt]=Akumuliatoriaus kritinis lygmuo Name[nb]=Batteri på kritisk nivå Name[nds]=Batterie kritisch Name[nl]=Accu op kritiek niveau Name[nn]=Kritisk lågt batterinivå Name[pa]=ਬੈਟਰੀ ਨਾਜ਼ੁਕ ਲੈਵਲ Name[pl]=Bateria na poziomie krytycznym Name[pt]=Bateria Crítica Name[pt_BR]=Bateria em nível crítico Name[ro]=Acumulator critic Name[ru]=Критический уровень заряда батареи Name[sk]=Kritická úroveň batérie Name[sl]=Kritična raven baterije Name[sr]=Батерија критична Name[sr@ijekavian]=Батерија критична Name[sr@ijekavianlatin]=Baterija kritična Name[sr@latin]=Baterija kritična Name[sv]=Kritiskt batteri Name[tr]=Pil Kritik Name[uk]=Заряд на критичному рівні Name[x-test]=xxBattery Criticalxx Name[zh_CN]=电池电量危急 Name[zh_TW]=電池電力嚴重不足 Comment=Your battery has reached critical level. This notification triggers a countdown before doing the configured action, hence it is strongly advised to leave that on. Comment[ar]=وصلت بطاريتك إلى مستوى حرج. يُفعِّل هذا التنبيه عدًّا تنازليًّا قبل تنفيذ حَدَث، حيث يُنصّح بشدّة إبقاء هذا الخيار مفعّلاً. Comment[bs]=Popunjenost baterija je spala na kritičan nivo. Ovo obavještenje okida odbrojavanje prije izvođenja podešene radnje, stoga vam ozbiljno savetujemo da ga ostavite uključenim. Comment[ca]=La bateria ha arribat al nivell crític. Aquesta notificació activa un compte enrere abans d'efectuar l'acció configurada, per tant, es recomana deixar-ho actiu. Comment[ca@valencia]=La bateria ha arribat al nivell crític. Esta notificació activa un compte arrere abans d'efectuar l'acció configurada, per tant, es recomana deixar-ho actiu. Comment[cs]=Baterie dosáhla kritické úrovně. Tímto upozorněním se spustí odpočet a následně se provede nastavená činnost, proto je doporučeno nezasahovat. Comment[da]=Dit batteri har nået kritisk niveau. Denne bekendtgørelse udløser en nedtælling før den konfigurerede handling udføres, derfor anbefales det kraftigt at lade den være slået til. Comment[de]=Der Ladestand Ihres Akkus hat einen kritischen Wert erreicht. Diese Benachrichtigung löst einen Rückwärtszähler aus, bevor die eingestellte Aktion ausgeführt wird. Es wird dringend empfohlen, diese Einstellung aktiviert zu lassen. Comment[el]=Η μπαταρία σας βρίσκεται σε κρίσιμη στάθμη ενέργειας. Η ειδοποίηση αυτή ενεργοποιεί μια αντίστροφη μέτρηση πριν την εκτέλεση της διαμορφωμένης ενέργειας. Συστήνεται έντονα η ενεργοποίηση αυτής της λειτουργίας. Comment[en_GB]=Your battery has reached critical level. This notification triggers a countdown before doing the configured action, hence it is strongly advised to leave that on. Comment[es]=La batería ha alcanzado un nivel crítico. Esta notificación inicia una cuenta atrás antes de realizar las acciones configuradas, por lo que se le recomienda encarecidamente que la mantenga activada. Comment[et]=Aku täituvus on jõudnud kriitilisele tasemele. See märguanne toob teatava aja pärast kaasa seadistatud toimingu, mistõttu see on väga soovitatav jätta sisselülitatuks. Comment[fi]=Akkusi varaus on kriittisen vähissä. Tämä ilmoitus käynnistää lähtölaskennan ennen asetetun toiminnon tekemistä, joten on hyvin suositeltavaa jättää tämä päälle. Comment[fr]=Votre batterie a atteint un niveau critique. Cette notification déclenche un compte à rebours avant de lancer l'action configurée. Il est par conséquent fortement recommandé de laisser cette fonction active. Comment[gl]=A batería acadou o nivel crítico. Esta notificación inicia unha conta-atrás previa a realizar a acción configurada, polo que se recomenda que a deixe seguir. Comment[hu]=A telepek kritikus szintre merültek, visszaszámlálás után a rendszer végrehajtja a beállított műveletet (kérjük ne zárja be a számlálót). Comment[ia]=Tu batteria ha attingite nivello critic. Iste notification pone in marcha un computo reverso ante que facer le action configurate, dunque tu es fortemente avisate de lassar lo connectite. Comment[id]=Baterai Anda telah mencapai tingkat kritis. Pemberitahuan ini memicuhitungan mundur sebelum melakukan aksi yang telah diatur, maka sangat disarankanuntuk menanggalkannya. Comment[it]=La batteria ha raggiunto il livello critico. Questa notifica attiva un conto alla rovescia prima di svolgere l'azione configurata, quindi si consiglia di lasciarla attiva. Comment[ja]=バッテリ残量が危険レベルに達しました。この通知によって、このレベルに設定されているアクションのカウントダウンが開始されるので、有効にしておくことを強くお勧めします。 Comment[ko]=배터리가 부족합니다. 설정된 동작을 실행할 때까지 잠깐 동안의 여유가 있으며, 그 시간 동안 작업을 정리하십시오. Comment[lt]=Jūsų akumuliatoriaus įkrova pasiekė kritinį lygmenį. Šis perspėjimas sužadina atvirkštinį skaičiavimą, kuriam pasibaigus bus atliekamas konfigūruotas veiksmas, tad primygtinai siūlome palikti šį nustatymą įjungtą Comment[nb]=Batteriet har nådd kritisk nivå. Denne varslingen utløser en nedtelling før den innstilte handlinga utføres, så det tilrådes sterkt å la den stå på. Comment[nds]=Dien Batterie is bi de kritische Stoop ankamen. Disse Bescheed tellt en Tiet daal, ehr he de instellte Akschoon utföhrt, laat em also beter an. Comment[nl]=Uw accu heeft het kritieke niveau bereikt. Deze melding activeert een aftelling voordat de ingestelde actie zal worden uitgevoerd. Het wordt ten zeerste aanbevolen dit ingeschakeld te laten. Comment[nn]=Batterinivået er kritisk lågt. Denne varslinga startar ei nedteljing før ho køyrer den valde handlinga, og du er sterkt råda til å la ho stå på. Comment[pa]=ਤੁਹਾਡੀ ਬੈਟਰੀ ਨਾਜ਼ੁਕ ਲੈਵਲ ਤੱਕ ਘੱਟ ਗਈ ਹੈ। ਇਹ ਨੋਟੀਫਿਕੇਸ਼ਨ ਸੰਰਚਿਤ ਕੀਤੇ ਐਕਸ਼ਨ ਕਰਨ ਤੋਂ ਪਹਿਲਾਂ ਉਲਟੀ-ਗਿਣਟੀ ਸ਼ੁਰੂ ਕਰਦਾ ਹੈ, ਇਸਕਰਕੇ ਇਸ ਨੂੰ ਚੱਲਣ ਦੀ ਸਲਾਹ ਦਿੱਤੀ ਜਾਂਦੀ ਹੈ। Comment[pl]=Bateria osiągnęła krytyczny poziom. To powiadomienie rozpoczyna także odliczanie przed wykonaniem ustawionego działania, więc dobrze jest je zostawić. Comment[pt]=A sua bateria atingiu um nível crítico. Esta notificação despoleta uma contagem decrescente antes de executar a acção configurada, pelo que é altamente recomendado que deixe esta opção ligada. Comment[pt_BR]=Sua bateria atingiu um nível crítico. Esta notificação aciona uma contagem antes de realizar a ação configurada. Por isso, recomenda-se deixar a opção ativada. Comment[ro]=Acumulatorul a atins nivelul critic. Această notificare declanșează o numărătoare inversă până la executarea acțiunii implicite, deci se recomandă să îl lăsați activat. Comment[ru]=Заряд батареи достиг критического уровня. Это уведомление добавляет задержку перед выполнением выбранного действия, потому желательно его оставить включённым. Comment[sk]=Vaša batéria dosiahla kritickú úroveň nabitia. Toto upozornenie spustí odpočítavanie pred vykonaním prednastavenej akcie, preto je vysoko doporučené nechať ho zapnuté. Comment[sl]=Baterija je dosegla kritično raven izpraznjenosti. To obvestilo sproži odštevanje do izvedbe nastavljenega dejanja, zato močno priporočamo, da to pustite omogočeno. Comment[sr]=Попуњеност батерија је спала на критичан ниво. Ово обавештење окида одбројавање пре извођења подешене радње, стога вам озбиљно саветујемо да га оставите укљученим. Comment[sr@ijekavian]=Попуњеност батерија је спала на критичан ниво. Ово обавјештење окида одбројавање прије извођења подешене радње, стога вам озбиљно савјетујемо да га оставите укљученим. Comment[sr@ijekavianlatin]=Popunjenost baterija je spala na kritičan nivo. Ovo obavještenje okida odbrojavanje prije izvođenja podešene radnje, stoga vam ozbiljno savjetujemo da ga ostavite uključenim. Comment[sr@latin]=Popunjenost baterija je spala na kritičan nivo. Ovo obaveštenje okida odbrojavanje pre izvođenja podešene radnje, stoga vam ozbiljno savetujemo da ga ostavite uključenim. Comment[sv]=Batteriet har nått kritisk nivå. Den här underrättelsen utlöser en nerräkning innan den inställda åtgärden utförs, därmed råds du att lämna den på. Comment[tr]=Piliniz kritik düzeye ulaştı. Bu bildirim yapılandırılmış bir işlemi gerçekleştirecek bir sayacı tetikler; bu nedenle etkin bırakmanız önerilir. Comment[uk]=Заряд акумулятора вашого комп’ютера досяг критичного рівня. За цим сповіщенням буде почато відлік часу до виконання відповідної налаштованої дії, отже, ми наполегливо рекомендуємо вам не вимикати цей пункт. Comment[x-test]=xxYour battery has reached critical level. This notification triggers a countdown before doing the configured action, hence it is strongly advised to leave that on.xx Comment[zh_CN]=电池电量达到危急等级。系统通知将会在一次倒计时后执行您配置的动作,强烈建议您保留此设定为开启。 Comment[zh_TW]=您的電池電力已到嚴重警告區。這個通知發出後將會開始倒數計時,時間到後就會進行設定好的動作。建議您保持此項開啟。 Contexts=warningnot Sound=Oxygen-Sys-App-Error-Critical.ogg Action=Sound|Popup IconName=dialog-warning [Event/fullbattery] Name=Charge Complete Name[ar]=تمَّ الشحن Name[ast]=Carga completa Name[bs]=Gotovo punjenje Name[ca]=Càrrega completada Name[ca@valencia]=Càrrega completada Name[cs]=Nabití bylo dokončeno Name[da]=Opladning fuldført Name[de]=Vollständig geladen Name[el]=Φόρτιση πλήρης Name[en_GB]=Charge Complete Name[es]=Carga completa Name[et]=Laadimine on tehtud Name[fi]=Lataus valmis Name[fr]=Charge terminée Name[gl]=Carga completa Name[hu]=Töltés befejezve Name[ia]=Cargamento completate Name[id]=Pengisian Cukup Name[it]=Carica completa Name[ko]=충전 완료됨 Name[lt]=Įkrovimas baigtas Name[nb]=Fullført lading Name[nds]=Opladen afslaten Name[nl]=Laden voltooid Name[nn]=Fullført lading Name[pa]=ਚਾਰਜ ਪੂਰਾ Name[pl]=Ukończono ładowanie Name[pt]=Carga Completa Name[pt_BR]=Carga completa Name[ro]=Încărcare finalizată Name[ru]=Зарядка завершена Name[sk]=Nabíjanie ukončené Name[sl]=Polnjenje zaključeno Name[sr]=Пуњење довршено Name[sr@ijekavian]=Пуњење довршено Name[sr@ijekavianlatin]=Punjenje dovršeno Name[sr@latin]=Punjenje dovršeno Name[sv]=Laddning klar Name[tr]=Şarj Tamamlandı Name[uk]=Заряджання завершено Name[x-test]=xxCharge Completexx Name[zh_CN]=充电完成 Name[zh_TW]=充電完成 Comment=The battery is fully charged Comment[ar]=البطارية مشحونة بالكامل Comment[ast]=La batería cargóse dafechu Comment[bs]=Baterija je potpuno puna Comment[ca]=La bateria està totalment carregada Comment[ca@valencia]=La bateria està totalment carregada Comment[cs]=Baterie je plně nabitá Comment[da]=Batteriet er fuldt opladet Comment[de]=Der Akku ist nun vollständig geladen Comment[el]=Η μπαταρία έχει φορτιστεί πλήρως Comment[en_GB]=The battery is fully charged Comment[es]=La batería está completamente cargada Comment[et]=Aku on täielikult laetud Comment[fi]=Akku on ladattu täyteen Comment[fr]=La batterie est totalement chargée Comment[gl]=A batería ten a carga completa Comment[hu]=Az akkumulátor teljesen feltöltve Comment[ia]=Le batteria es cargate completemente Comment[id]=Baterai sudah terisi penuh Comment[it]=La batteria è completamente carica Comment[ko]=배터리가 완전히 충전됨 Comment[lt]=Akumuliatorius pilnai įkrautas Comment[nb]=Batteriet er fullt ladet Comment[nds]=De Batterie is heel laadt Comment[nl]=De accu is volledig geladen Comment[nn]=Batteriet er fullada Comment[pa]=ਬੈਟਰੀ ਪੂਰੀ ਚਾਰਜ ਹੈ Comment[pl]=Bateria jest w pełni naładowana Comment[pt]=A bateria está completamente carregada Comment[pt_BR]=A bateria está completamente carregada Comment[ro]=Acumulatorul este încărcat complet Comment[ru]=Батарея полностью заряжена Comment[sk]=Batéria je plne nabitá Comment[sl]=Baterija je povsem napolnjena Comment[sr]=Батерија је потпуно напуњена Comment[sr@ijekavian]=Батерија је потпуно напуњена Comment[sr@ijekavianlatin]=Baterija je potpuno napunjena Comment[sr@latin]=Baterija je potpuno napunjena Comment[sv]=Batteriet är fulladdat Comment[tr]=Piliniz tamamiyle şarj edildi. Comment[uk]=Акумулятор повністю заряджено Comment[x-test]=xxThe battery is fully chargedxx Comment[zh_CN]=电池已充满 Comment[zh_TW]=電池已充飽 Contexts=stdnot Sound=Oxygen-Sys-App-Positive.ogg Action= IconName=battery-100 +[Event/lowperipheralbattery] +Name=Peripheral Battery Low +Comment=The battery in a connected device, such as mouse or keyboard, is low +Contexts=warningnot +Sound=Oxygen-Sys-Warning.ogg +Action=Sound|Popup +IconName=battery-caution + [Event/pluggedin] Name=AC adaptor plugged in Name[ar]=وُصِلَ محوِّل الكهرباء Name[ast]=Enchufóse l'adautador AC Name[bs]=AC adapter utaknut Name[ca]=Adaptador de CA endollat Name[ca@valencia]=Adaptador de CA endollat Name[cs]=AC adaptér zapojen Name[da]=Strømforsyning tilsluttet Name[de]=Netzkabel angeschlossen Name[el]=Σύνδεση με μετασχηματιστή AC Name[en_GB]=AC adaptor plugged in Name[es]=Se ha conectado el adaptador de alimentación Name[et]=Ühendati elektrivõrku Name[fi]=Kytkettiin verkkovirtaan Name[fr]=Adaptateur secteur branché Name[gl]=Enchufouse a alimentación externa Name[hu]=Tápcsatlakozó bedugva Name[ia]=Adaptator AC connectite Name[id]=Adaptor AC ditancapkan Name[it]=Alimentatore collegato Name[ja]=AC アダプタが接続されました Name[ko]=AC 어댑터 연결됨 Name[lt]=Prijungtas AC adapteris Name[nb]=Strømadapteret er koblet til Name[nds]=Stroomkavel tokoppelt Name[nl]=Netstroomadapter aangesloten Name[nn]=Straum kopla til Name[pa]=AC ਐਡਪਟਰ ਪਲੱਗ ਲੱਗਾ ਹੈ Name[pl]=Podłączono zasilanie zewnętrzne Name[pt]=Ligado à corrente Name[pt_BR]=Adaptador de energia conectado Name[ro]=Adaptor de curent alternativ atașat Name[ru]=Подключён к электрической сети Name[sk]=Napájanie zo siete pripojené Name[sl]=Napajanje iz električnega omrežja Name[sr]=АЦ адаптер утакнут Name[sr@ijekavian]=АЦ адаптер утакнут Name[sr@ijekavianlatin]=AC adapter utaknut Name[sr@latin]=AC adapter utaknut Name[sv]=Nätadapter inkopplad Name[tr]=Güç adaptörü takıldı Name[uk]=Увімкнено живлення від мережі Name[x-test]=xxAC adaptor plugged inxx Name[zh_CN]=已插入交流适配器 Name[zh_TW]=AC 電源已插入 Comment=The power adaptor has been plugged in Comment[ar]=تم توصيل محوِّل الكهرباء Comment[ast]=Enchufóse l'adautador d'enerxía Comment[bs]=Utaknut je adapter napajanja Comment[ca]=L'adaptador de corrent s'ha endollat Comment[ca@valencia]=L'adaptador de corrent s'ha endollat Comment[cs]=Zdroj napájení byl připojen Comment[da]=Strømforsyningen er blevet tilsluttet Comment[de]=Das Netzkabel ist angeschlossen worden. Comment[el]=Ο μετασχηματιστής ρεύματος συνδέθηκε Comment[en_GB]=The power adaptor has been plugged in Comment[es]=Se ha conectado el adaptador de alimentación de energía Comment[et]=Arvuti ühendati elektrivõrku Comment[fi]=Tietokone kytkettiin verkkovirtaan Comment[fr]=L'adaptateur secteur a été branché Comment[gl]=Enchufouse o transformador de corrente Comment[hu]=Az áramellátást biztosító tápcsatlakozó bedugva Comment[ia]=Le adaptator de energia ha essite connectite Comment[id]=Adaptor daya telah ditancapkan Comment[it]=È stata collegata l'alimentazione elettrica Comment[ja]=電源アダプタが接続されました Comment[ko]=AC 어댑터가 연결되었습니다 Comment[lt]=Kintamosios srovės adapteris buvo prijungtas Comment[nb]=Strømadapteret er koblet til Comment[nds]=Dat Stroomkavel wöör tokoppelt Comment[nl]=De netstroomadapter is aangesloten Comment[nn]=Straumkabelen vart kopla til Comment[pa]=ਪਾਵਰ ਐਡਪਟਰ ਦਾ ਪਲੱਗ ਲਗਾਇਆ ਗਿਆ Comment[pl]=Podłączono zasilanie zewnętrzne Comment[pt]=Ligou o computador à tomada de corrente Comment[pt_BR]=O adaptador de energia foi conectado Comment[ro]=Adaptorul de alimentare a fost atașat Comment[ru]=Ноутбук подключён к электрической сети Comment[sk]=Napájanie zo siete bolo pripojené Comment[sl]=Priključeno je bilo napajanje iz električnega omrežja Comment[sr]=Утакнут је адаптер спољашњег напајања Comment[sr@ijekavian]=Утакнут је адаптер спољашњег напајања Comment[sr@ijekavianlatin]=Utaknut je adapter spoljašnjeg napajanja Comment[sr@latin]=Utaknut je adapter spoljašnjeg napajanja Comment[sv]=Nätadaptern har kopplats in Comment[tr]=Güç adaptörü bilgisayara takıldı Comment[uk]=Було увімкнено живлення від мережі Comment[x-test]=xxThe power adaptor has been plugged inxx Comment[zh_CN]=已插入电源适配器 Comment[zh_TW]=市電電源已插上 Contexts=stdnot Sound=Oxygen-Sys-App-Positive.ogg Action=None IconName=battery-charging-low [Event/unplugged] Name=AC adaptor unplugged Name[ar]=فُصِل محوِّل الكهرباء Name[ast]=Desenchufóse l'adautador AC Name[bs]=AC adapter izvučen Name[ca]=Adaptador de CA desendollat Name[ca@valencia]=Adaptador de CA desendollat Name[cs]=AC adaptér odpojen Name[da]=Strømforsyning frakoblet Name[de]=Netzkabel entfernt Name[el]=Ο μετασχηματιστής ρεύματος AC αποσυνδέθηκε Name[en_GB]=AC adaptor unplugged Name[es]=Se ha desconectado el adaptador de alimentación Name[et]=Lahutati elektrivõrgust Name[fi]=Poistuttiin verkkovirrasta Name[fr]=Adaptateur secteur débranché Name[gl]=Desenchufouse a alimentación externa Name[hu]=Tápcsatlakozó kihúzva Name[ia]=Adaptator de AC disconnectite Name[id]=Adaptor AC dicabut Name[it]=Alimentatore scollegato Name[ja]=AC アダプタが取り外されました Name[ko]=AC 어댑터 연결 끊김 Name[lt]=Atjungtas AC adapteris Name[nb]=Strømadapteret er dratt ut Name[nds]=Stroomkavel ruttrocken Name[nl]=Netstroomadapter niet aangesloten Name[nn]=Straum kopla frå Name[pa]=AC ਐਡਪਟਰ ਦਾ ਪਲੱਗ ਕੱਢਿਆ Name[pl]=Odłączono zasilanie zewnętrzne Name[pt]=Desligado da corrente Name[pt_BR]=Adaptador de energia desconectado Name[ro]=Adaptor de curent alternativ detașat Name[ru]=Отключение от электрической сети Name[sk]=Napájanie zo siete odpojené Name[sl]=Konec napajanja iz električnega omrežja Name[sr]=АЦ адаптер извучен Name[sr@ijekavian]=АЦ адаптер извучен Name[sr@ijekavianlatin]=AC adapter izvučen Name[sr@latin]=AC adapter izvučen Name[sv]=Nätadapter frånkopplad Name[tr]=Güç adaptörü çıkarıldı Name[uk]=Вимкнено живлення від мережі Name[x-test]=xxAC adaptor unpluggedxx Name[zh_CN]=已拔出交流适配器 Name[zh_TW]=AC 電源已拔除 Comment=The power adaptor has been unplugged Comment[ar]=تم فصل محوِّل الكهرباء Comment[ast]=Desenchufóse l'adautador d'enerxía Comment[bs]=Izvučen je adapter napajanja Comment[ca]=L'adaptador de corrent s'ha desendollat Comment[ca@valencia]=L'adaptador de corrent s'ha desendollat Comment[cs]=Zdroj napájení byl odpojen Comment[da]=Strømforsyningen er blevet frakoblet Comment[de]=Das Netzkabel ist vom Rechner getrennt worden. Comment[el]=Ο μετασχηματιστής ρεύματος αποσυνδέθηκε Comment[en_GB]=The power adaptor has been unplugged Comment[es]=Se ha desconectado el adaptador de alimentación de energía Comment[et]=Arvuti lahutati elektrivõrgust Comment[fi]=Tietokone otettiin pois verkkovirrasta Comment[fr]=L'adaptateur secteur a été débranché Comment[gl]=Desenchufouse a fonte de alimentación Comment[hu]=Az áramellátást biztosító tápcsatlakozó kihúzva Comment[ia]=Le adaptator de energia ha essite disconnectite Comment[id]=Adaptor daya telah dicabut Comment[it]=È stata scollegata l'alimentazione elettrica Comment[ja]=電源アダプタが取り外されました Comment[ko]=AC 어댑터의 연결이 해제되었습니다 Comment[lt]=Kintamosios srovės adapteris buvo atjungtas Comment[nb]=Strømadapteret er koblet fra Comment[nds]=Dat Stroomkavel wöör ruttrocken Comment[nl]=De netstroomadapter is losgekoppeld Comment[nn]=Straumkabelen vart kopla frå Comment[pa]=ਪਾਵਰ ਐਡਪਟਰ ਦਾ ਪਲੱਗ ਕੱਢਿਆ Comment[pl]=Odłączono zasilanie zewnętrzne Comment[pt]=Desligou o sistema da tomada Comment[pt_BR]=O adaptador de energia foi desconectado Comment[ro]=Adaptorul de alimentare a fost detașat Comment[ru]=Ноутбук отключён от электрической сети Comment[sk]=Napájanie zo siete bolo odpojené Comment[sl]=Napajanje iz električnega omrežja je bilo prekinjeno Comment[sr]=Извучен је адаптер спољашњег напајања Comment[sr@ijekavian]=Извучен је адаптер спољашњег напајања Comment[sr@ijekavianlatin]=Izvučen je adapter spoljašnjeg napajanja Comment[sr@latin]=Izvučen je adapter spoljašnjeg napajanja Comment[sv]=Nätadaptern har kopplats från Comment[tr]=Güç adaptörü bilgisayarınızdan çıkarıldı Comment[uk]=Було вимкнено живлення від мережі Comment[x-test]=xxThe power adaptor has been unpluggedxx Comment[zh_CN]=已拔出电源适配器 Comment[zh_TW]=市電電源已拔除 Contexts=stdnot Sound=Oxygen-Sys-App-Negative.ogg Action=Sound IconName=battery-low [Event/powerdevilerror] Name=Internal Error Name[ar]=خطأ داخليّ Name[ast]=Fallu internu Name[bs]=Unutrašnja greška Name[ca]=Error intern Name[ca@valencia]=Error intern Name[cs]=Vnitřní chyba Name[da]=Intern fejl Name[de]=Interner Fehler Name[el]=Εσωτερικό σφάλμα Name[en_GB]=Internal Error Name[es]=Error interno Name[et]=Sisemine tõrge Name[fi]=Sisäinen virhe Name[fr]=Erreur interne Name[gl]=Erro interno Name[hu]=Belső hiba Name[ia]=Error Interne Name[id]=Galat Internal Name[it]=Errore interno Name[ko]=내부 오류 Name[lt]=Vidinė klaida Name[nb]=Intern feil Name[nds]=Intern Fehler Name[nl]=Interne fout Name[nn]=Intern feil Name[pa]=ਅੰਦਰੂਨੀ ਗਲਤੀ Name[pl]=Błąd wewnętrzny Name[pt]=Erro Interno Name[pt_BR]=Erro interno Name[ro]=Eroare internă Name[ru]=Внутренняя ошибка Name[sk]=Interná chyba Name[sl]=Notranja napaka Name[sr]=Унутрашња грешка Name[sr@ijekavian]=Унутрашња грешка Name[sr@ijekavianlatin]=Unutrašnja greška Name[sr@latin]=Unutrašnja greška Name[sv]=Internt fel Name[tr]=İç Hata Name[uk]=Внутрішня помилка Name[x-test]=xxInternal Errorxx Name[zh_CN]=内部错误 Name[zh_TW]=內部錯誤 Comment=The KDE Power Management System has triggered an internal error Comment[ar]=حدث خطأ داخليّ في مدير طاقة كدي Comment[ast]=El sistema de xestión d'enerxía KDE disparó un fallu internu Comment[bs]=Unutrašnja greška u KDE‑ovom sistemu za upravljanje napajanjem Comment[ca]=El sistema de gestió d'energia del KDE ha activat un error intern Comment[ca@valencia]=El sistema de gestió d'energia del KDE ha activat un error intern Comment[cs]=Systém správy napájení KDE vyvolal interní chybu Comment[da]=KDE's strømstyringssystem har udløst en intern fejl Comment[de]=Das KDE-Energieverwaltungssystem hat einen internen Fehler ausgelöst. Comment[el]=Ο διαχειριστής ενέργειας συστήματος του KDE προκάλεσε ένα εσωτερικό σφάλμα Comment[en_GB]=The KDE Power Management System has triggered an internal error Comment[es]=El sistema de gestión de energía de KDE ha desencadenado un error interno Comment[et]=KDE toitehalduse süsteemi tabas sisemine tõrge Comment[fi]=KDE:n virranhallintajärjestelmä on kohdannut sisäisen virheen Comment[fr]=Le système de gestion de l'énergie de KDE a déclenché une erreur interne Comment[gl]=O sistema de xestión da enerxía de KDE disparou un erro interno Comment[hu]=A KDE Energiakezelő rendszere belső hibát okozott Comment[ia]=Le systema de gestion de energia de KDE ha generate un error interne Comment[id]=Sistem Manajemen Daya KDE telah memicu kesalahan internal Comment[it]=Il sistema di gestione energetica di KDE ha causato un errore interno Comment[ja]=KDE 電源管理に内部エラーが発生しました Comment[ko]=KDE 전원 관리 시스템에서 내부 오류가 발생했습니다 Comment[lt]=KDE energijos valdymo sistema sužadino vidinę klaidą Comment[nb]=KDE strømstyringssystem har utløst en intern feil Comment[nds]=Dat KDE-Stroomkuntrullsysteem hett en intern Fehler hatt. Comment[nl]=Het KDE-energiebeheersysteem activeerde een interne fout Comment[nn]=Det oppstod ein internfeil i KDE-straumstyringa Comment[pa]=KDE ਪਾਵਰ ਮੈਨਜੇਮੈਂਟ ਸਿਸਟਮ ਨੇ ਅੰਦਰੂਨੀ ਗਲਤੀ Comment[pl]=Wystąpił wewnętrzny błąd systemu zarządzania energią KDE Comment[pt]=O Sistema de Gestão de Energia do KDE despoletou um erro interno Comment[pt_BR]=Ocorreu um erro interno no Sistema de Gerenciamento de Energia do KDE Comment[ro]=Sistemul KDE de gestiune a alimentării a declanșat o eroare internă Comment[ru]=Произошла внутренняя ошибка системы управления питанием KDE Comment[sk]=Systém správy napájania KDE vyvolal internú chybu Comment[sl]=V KDE-jevem sistemu za upravljanje z energijo je prišlo do notranje napake Comment[sr]=Унутрашња грешка у КДЕ‑овом систему за управљање напајањем Comment[sr@ijekavian]=Унутрашња грешка у КДЕ‑овом систему за управљање напајањем Comment[sr@ijekavianlatin]=Unutrašnja greška u KDE‑ovom sistemu za upravljanje napajanjem Comment[sr@latin]=Unutrašnja greška u KDE‑ovom sistemu za upravljanje napajanjem Comment[sv]=KDE:s strömsparhanteringssystem har orsakat ett internt fel Comment[tr]=KDE Güç Yönetimi Sistemi bir iç hata ile karşılaştı Comment[uk]=У системі керування живленням KDE сталася внутрішня помилка Comment[x-test]=xxThe KDE Power Management System has triggered an internal errorxx Comment[zh_CN]=KDE 电源管理系统触发了内部错误 Comment[zh_TW]=KDE 電源管理系統觸發了一個內部錯誤 Contexts=criticalnot Sound=Oxygen-Sys-App-Error-Critical.ogg Action=Sound|Popup IconName=dialog-error