diff --git a/daemon/powerdevilcore.cpp b/daemon/powerdevilcore.cpp index ab7fed7a..de9b98ac 100644 --- a/daemon/powerdevilcore.cpp +++ b/daemon/powerdevilcore.cpp @@ -1,914 +1,896 @@ /*************************************************************************** * 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 #include #include namespace PowerDevil { Core::Core(QObject* parent) : QObject(parent) , m_hasDualGpu(false) , m_backend(nullptr) , m_notificationsWatcher(nullptr) , m_criticalBatteryTimer(new QTimer(this)) , m_activityConsumer(new KActivities::Consumer(this)) , m_pendingWakeupEvent(true) { KAuth::Action discreteGpuAction(QStringLiteral("org.kde.powerdevil.discretegpuhelper.hasdualgpu")); discreteGpuAction.setHelperId(QStringLiteral("org.kde.powerdevil.discretegpuhelper")); KAuth::ExecuteJob *discreteGpuJob = discreteGpuAction.execute(); connect(discreteGpuJob, &KJob::result, this, [this, discreteGpuJob] { if (discreteGpuJob->error()) { qCWarning(POWERDEVIL) << "org.kde.powerdevil.discretegpuhelper.hasdualgpu failed"; qCDebug(POWERDEVIL) << discreteGpuJob->errorText(); return; } m_hasDualGpu = discreteGpuJob->data()[QStringLiteral("hasdualgpu")].toBool(); }); discreteGpuJob->start(); } Core::~Core() { qCDebug(POWERDEVIL) << "Core unloading"; // 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 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 ready, KDE Power Management system initialized"; m_profilesConfig = KSharedConfig::openConfig(QStringLiteral("powermanagementprofilesrc"), KConfig::CascadeConfig); QStringList groups = m_profilesConfig->groupList(); // the "migration" key is for shortcuts migration in added by migratePre512KeyboardShortcuts // and as such our configuration would never be considered empty, ignore it! groups.removeOne(QStringLiteral("migration")); // Is it brand new? if (groups.isEmpty()) { // Generate defaults qCDebug(POWERDEVIL) << "Generating a default configuration"; 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(m_backend, &BackendInterface::aboutToSuspend, this, &Core::onAboutToSuspend); 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(); }); // Bug 354250: Simulate user activity when session becomes inactive, // this keeps us from sending the computer to sleep when switching to an idle session. // (this is just being lazy as it will result in us clearing everything connect(PowerDevil::PolicyAgent::instance(), &PowerDevil::PolicyAgent::sessionActiveChanged, this, [this](bool active) { if (active) { // force reload profile so all actions re-register their idle timeouts loadProfile(true /*force*/); } else { // Bug 354250: Keep us from sending the computer to sleep when switching // to an idle session by removing all idle timeouts KIdleTime::instance()->removeAllIdleTimeouts(); m_registeredActionTimeouts.clear(); } }); // 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(QStringLiteral("org.freedesktop.Notifications"))) { onServiceRegistered(QString()); } else { m_notificationsWatcher = new QDBusServiceWatcher(QStringLiteral("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) << "Currently using 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") == QStringLiteral("ActLike") && activitiesConfig.group(activity).readEntry("actLike", QString()) != QStringLiteral("AC") && activitiesConfig.group(activity).readEntry("actLike", QString()) != QStringLiteral("Battery") && activitiesConfig.group(activity).readEntry("actLike", QString()) != QStringLiteral("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") == QStringLiteral("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_batteriesPercent.isEmpty()) { qCDebug(POWERDEVIL) << "No batteries found, loading AC"; profileId = QStringLiteral("AC"); } else if (activityConfig.readEntry("mode", "None") == QStringLiteral("ActLike")) { if (activityConfig.readEntry("actLike", QString()) == QStringLiteral("AC") || activityConfig.readEntry("actLike", QString()) == QStringLiteral("Battery") || activityConfig.readEntry("actLike", QString()) == QStringLiteral("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 = QStringLiteral("AC"); qCDebug(POWERDEVIL) << "Loading profile for plugged AC"; } else if (percent <= PowerDevilSettings::batteryLowLevel()) { profileId = QStringLiteral("LowBattery"); qCDebug(POWERDEVIL) << "Loading profile for low battery"; } else { profileId = QStringLiteral("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(QStringLiteral("powerdevilerror"), i18n("Profile \"%1\" has been selected " - "but does not exist.\nPlease check your PowerDevil configuration.", - profileId)); + qCWarning(POWERDEVIL) << "Profile " << profileId << "has been selected but does not exist."; 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(); 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(); 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," " a configuration problem, or because 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") == QStringLiteral("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(QStringLiteral("SuspendSession"), behaviorGroup.group("ActionConfig"), this); qCDebug(POWERDEVIL) << "Activity overrides suspend session action"; // debug hence not sleep } if (behaviorGroup.readEntry("noSuspend", false)) { qCDebug(POWERDEVIL) << "Activity triggers a suspend inhibition"; // debug hence not sleep // 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 going to sleep")); 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 // so that "switching profile then closing the lid" has the same result as // "closing lid then switching profile". if (m_backend->isLidClosed()) { Q_EMIT m_backend->buttonPressed(PowerDevil::BackendInterface::LidClose); } } void Core::onDeviceAdded(const QString &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)); if (!b) { return; } - if (!connect(b, &Battery::chargePercentChanged, this, &Core::onBatteryChargePercentChanged) || - !connect(b, &Battery::chargeStateChanged, this, &Core::onBatteryChargeStateChanged)) { - emitNotification(QStringLiteral("powerdevilerror"), i18n("Could not connect to battery interface.\n" - "Please check your system configuration")); - } - qCDebug(POWERDEVIL) << "Battery with UDI" << udi << "was detected"; 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(); // notify the user about the empty mouse/keyboard when plugging it in; don't when // notifications aren't ready yet so we avoid showing them ontop of ksplash; // also we'll notify about all devices when notifications are ready anyway if (m_notificationsReady) { emitBatteryChargePercentNotification(b->chargePercent(), 1000 /* so current is always lower than previous */, udi); } } // 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() && currentChargePercent() > PowerDevilSettings::batteryCriticalLevel()) { m_criticalBatteryTimer->stop(); if (m_criticalBatteryNotification) { m_criticalBatteryNotification->close(); } emitRichNotification(QStringLiteral("pluggedin"), i18n("Extra Battery Added"), i18n("The computer will no longer go to sleep.")); } } void Core::onDeviceRemoved(const QString &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)); disconnect(b, &Battery::chargePercentChanged, this, &Core::onBatteryChargePercentChanged); disconnect(b, &Battery::chargeStateChanged, this, &Core::onBatteryChargeStateChanged); qCDebug(POWERDEVIL) << "Battery with UDI" << udi << "has been removed"; m_batteriesPercent.remove(udi); m_peripheralBatteriesPercent.remove(udi); m_batteriesCharged.remove(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), nullptr, KNotification::CloseOnTimeout, QStringLiteral("powerdevil")); } else { KNotification::event(evid, message, QPixmap(), nullptr, KNotification::CloseOnTimeout, QStringLiteral("powerdevil")); } } void Core::emitNotification(const QString &eventId, const QString &title, const QString &message, const QString &iconName) { KNotification::event(eventId, title, message, iconName, nullptr, KNotification::CloseOnTimeout, QStringLiteral("powerdevil")); } void Core::emitRichNotification(const QString &evid, const QString &title, const QString &message) { KNotification::event(evid, title, message, QPixmap(), nullptr, KNotification::CloseOnTimeout, QStringLiteral("powerdevil")); } 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 you leave the device out of reach or it has not been initialized yet // it won't be "there" and report 0%, don't show anything in this case if (!b->isPresent() || b->chargeState() != Battery::Discharging) { return false; } if (currentPercent <= PowerDevilSettings::peripheralBatteryLowLevel() && previousPercent > PowerDevilSettings::peripheralBatteryLowLevel()) { QString name = device.product(); if (!device.vendor().isEmpty()) { name = i18nc("%1 is vendor name, %2 is product name", "%1 %2", device.vendor(), device.product()); } QString title; QString msg; QString icon; switch(b->type()) { case Battery::MouseBattery: title = i18n("Mouse Battery Low (%1% Remaining)", currentPercent); msg = i18nc("Placeholder is device name", "The battery in (\"%1\") is running low, and the device may turn off at any time. " "Please recharge or replace the battery.", name); icon = QStringLiteral("input-mouse"); break; case Battery::KeyboardBattery: title = i18n("Keyboard Battery Low (%1% Remaining)", currentPercent); msg = i18nc("Placeholder is device name", "The battery in (\"%1\") is running low, and the device may turn off at any time. " "Please recharge or replace the battery.", name); icon = QStringLiteral("input-keyboard"); break; default: title = i18nc("The battery in an external device", "Device Battery Low (%1% Remaining)", currentPercent); msg = i18nc("Placeholder is device name", "The battery in (\"%1\") is running low, and the device may turn off at any time. " "Please recharge or replace the battery.", name); icon = QStringLiteral("battery-caution"); break; } emitNotification(QStringLiteral("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(QStringLiteral("lowbattery"), i18n("Battery Low (%1% Remaining)", currentPercent), i18n("Battery running low - to continue using your computer, plug it in or shut it down and 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(QStringLiteral("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 put system to sleep 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("Battery level critical. Your computer will shut down in 60 seconds.")); m_criticalBatteryNotification->setActions(actions); m_criticalBatteryTimer->start(); break; case PowerDevil::BundledActions::SuspendSession::ToDiskMode: m_criticalBatteryNotification->setText(i18n("Battery level critical. Your computer will enter hibernation mode in 60 seconds.")); m_criticalBatteryNotification->setActions(actions); m_criticalBatteryTimer->start(); break; case PowerDevil::BundledActions::SuspendSession::ToRamMode: m_criticalBatteryNotification->setText(i18n("Battery level critical. Your computer will go to sleep in 60 seconds.")); m_criticalBatteryNotification->setActions(actions); m_criticalBatteryTimer->start(); break; default: m_criticalBatteryNotification->setText(i18n("Battery level critical. Please save your work.")); // 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(QStringLiteral("pluggedin"), i18n("AC Adapter Plugged In"), i18n("The computer will no longer go to sleep.")); } else { emitRichNotification(QStringLiteral("pluggedin"), i18n("Running on AC power"), i18n("The power adapter has been plugged in.")); } } else if (state == BackendInterface::Unplugged) { emitRichNotification(QStringLiteral("unplugged"), i18n("Running on Battery Power"), i18n("The power adapter has been unplugged.")); } } -void Core::onBackendError(const QString& error) -{ - emitNotification(QStringLiteral("powerdevilerror"), i18n("The 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, 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(QStringLiteral("fullbattery"), i18n("Charging Complete"), i18n("Battery 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(QStringLiteral("HandleButtonEvents"), KConfigGroup(), this); if (helperAction) { QVariantMap args; args[QStringLiteral("Button")] = 32; args[QStringLiteral("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 (auto i = m_registeredActionTimeouts.constBegin(), end = m_registeredActionTimeouts.constEnd(); i != end; ++i) { if (i.value().contains(identifier)) { i.key()->onIdleTimeout(msec); // And it will need to be awaken m_pendingResumeFromIdleActions.insert(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::onAboutToSuspend() { if (PowerDevilSettings::pausePlayersOnSuspend()) { qCDebug(POWERDEVIL) << "Pausing all media players before sleep"; QDBusPendingCall listNamesCall = QDBusConnection::sessionBus().interface()->asyncCall(QStringLiteral("ListNames")); QDBusPendingCallWatcher *callWatcher = new QDBusPendingCallWatcher(listNamesCall, this); connect(callWatcher, &QDBusPendingCallWatcher::finished, this, [this](QDBusPendingCallWatcher *watcher) { QDBusPendingReply reply = *watcher; watcher->deleteLater(); if (reply.isError()) { qCWarning(POWERDEVIL) << "Failed to fetch list of DBus service names for pausing players on entering sleep" << reply.error().message(); return; } const QStringList &services = reply.value(); for (const QString &serviceName : services) { if (!serviceName.startsWith(QLatin1String("org.mpris.MediaPlayer2."))) { continue; } qCDebug(POWERDEVIL) << "Pausing media player with service name" << serviceName; QDBusMessage pauseMsg = QDBusMessage::createMethodCall(serviceName, QStringLiteral("/org/mpris/MediaPlayer2"), QStringLiteral("org.mpris.MediaPlayer2.Player"), QStringLiteral("Pause")); QDBusConnection::sessionBus().asyncCall(pauseMsg); } }); } } 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() { KIdleTime::instance()->simulateUserActivity(); // Wake up the actions in which an idle action was triggered std::for_each(m_pendingResumeFromIdleActions.cbegin(), m_pendingResumeFromIdleActions.cend(), std::mem_fn(&PowerDevil::Action::onWakeupFromIdle)); m_pendingResumeFromIdleActions.clear(); } void Core::onNotificationTimeout() { // cannot connect QTimer::singleShot directly to the other method onServiceRegistered(QString()); } void Core::onServiceRegistered(const QString &service) { Q_UNUSED(service); if (m_notificationsReady) { return; } bool needsRefresh = false; // 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)) { needsRefresh = true; } // now also emit notifications for all peripheral batteries for (auto it = m_peripheralBatteriesPercent.constBegin(), end = m_peripheralBatteriesPercent.constEnd(); it != end; ++it) { if (emitBatteryChargePercentNotification(it.value() /*currentPercent*/, 1000, it.key() /*udi*/)) { needsRefresh = true; } } // need to refresh status to prevent the notification from showing again when charge percentage changes if (needsRefresh) { refreshStatus(); } m_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(); } bool Core::hasDualGpu() const { return m_hasDualGpu; } 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 d2ec1fb8..5e29d496 100644 --- a/daemon/powerdevilcore.h +++ b/daemon/powerdevilcore.h @@ -1,162 +1,161 @@ /*************************************************************************** * 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 #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); ~Core() override; 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()); 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); bool hasDualGpu() const; 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; bool m_hasDualGpu; BackendInterface *m_backend; QDBusServiceWatcher *m_notificationsWatcher; bool m_notificationsReady = false; KSharedConfigPtr m_profilesConfig; QString m_currentProfile; 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; QSet 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); void onAboutToSuspend(); }; } #endif // POWERDEVILCORE_H diff --git a/powerdevil.notifyrc b/powerdevil.notifyrc index 94d38843..2af571d4 100644 --- a/powerdevil.notifyrc +++ b/powerdevil.notifyrc @@ -1,1054 +1,956 @@ [Global] -Name=KDE Power Management System +Name=Power Management Name[ar]=نظام إدارة طاقة كدي 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[eu]=KDEren energia kudeatzeko sistema 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[he]=מערכת ניהול צריכת החשמל של KDE Name[hu]=KDE energiakezelő rendszer Name[ia]=Systema de gestion de energia de KDE Name[id]=Sistem Pengelolaan Daya KDE Name[it]=Sistema di gestione energetica di KDE Name[ja]=KDE 電源管理システム Name[ko]=KDE 전원 관리 시스템 Name[lt]=KDE energijos valdymo sistema Name[nb]=KDE-strømstyring 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[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[eu]=Energia kudeatzeko sistema Comment[fi]=Virranhallintajärjestelmä Comment[fr]=Système de gestion de l'énergie Comment[gl]=Sistema de xestión da enerxía Comment[he]=מערכת ניהול חשמל Comment[hu]=Energiakezelő rendszer Comment[ia]=Systema de gestion de energia Comment[id]=Sistem Pengelolaan Daya Comment[it]=Sistema di gestione energetica Comment[ja]=電源管理システム Comment[ko]=전원 관리 시스템 Comment[lt]=Energijos valdymo sistema Comment[nb]=Strømstyring 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[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[eu]=Abisua Name[fi]=Varoitus Name[fr]=Avertissement Name[gl]=Aviso Name[he]=אזהרה 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[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[eu]=Abisu-jakinarazpenetarako erabiltzen da 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[he]=השתמש להתראת אזהרה Comment[hu]=Kezelőprogram figyelmeztető üzenetekhez Comment[ia]=Usate pro notificationes de avisos Comment[id]=Digunakan untuk notifikasi peringatan Comment[it]=Usato per le notifiche di avviso Comment[ja]=注意の通知に使用 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[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[eu]=Jakinarazpena Name[fi]=Ilmoitus Name[fr]=Notification Name[gl]=Notificación Name[he]=התראה Name[hu]=Értesítés Name[ia]=Notification Name[id]=Notifikasi 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[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[eu]=Jakinarazpen estandarretarako erabilia 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[he]=השתמש להתראה רגילה Comment[hu]=Kezelő értesítő üzenetekhez Comment[ia]=Usate pro notificationes standard Comment[id]=Digunakan untuk notifikasi standar Comment[it]=Usato per le notifiche standard Comment[ja]=通常の通知に使用 Comment[ko]=표준 알림에 사용됨 Comment[lt]=Naudojamas standartiniams pranešimams Comment[nb]=Brukt til standardvarslinger 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[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[eu]=Jakinarazpen kritikoa Name[fi]=Kriittinen ilmoitus Name[fr]=Notification critique Name[gl]=Notificación crítica Name[he]=התראה קריטית Name[hu]=Kritikus értesítés Name[ia]=Notification critic Name[id]=Notifikasi 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[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[eu]=Gertaera kritiko baten berri ematen du Comment[fi]=Ilmoittaa kriittisestä tapahtumasta Comment[fr]=Notifie un évènement critique Comment[gl]=Notifica un evento crítico Comment[he]=התרעה התראה קריטית Comment[hu]=Kritikus fontosságú üzenetet jelez Comment[ia]=Il notifica un evento critic Comment[id]=Notifikasi 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[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[eu]=Bateria baxu Name[fi]=Akku vähissä Name[fr]=Batterie faible Name[gl]=Batería baixa Name[he]=סוללה חלשה Name[hu]=Az akkumulátor gyenge Name[ia]=Batteria basse Name[id]=Baterai Lemah Name[it]=Batteria a livello basso Name[ja]=バッテリ残量低 Name[ko]=배터리 부족 Name[lt]=Akumuliatorius ištuštėjęs Name[nb]=Lavt batterinivå 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[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[eu]=Zure bateria maila baxura iritsi da 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[he]=הסוללה עומדת להגמר Comment[hu]=A telepek feltöltöttsége alacsony szintű Comment[ia]=Tu batteria ha attingite nivello basse Comment[id]=Bateraimu telah mencapai tingkat 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]=Batterinivået er lavt 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[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[eu]=Bateria maila-kritikoa Name[fi]=Akku kriittisellä tasolla Name[fr]=Batterie critique Name[gl]=Batería no nivel crítico Name[he]=הסוללה במצב קריטי Name[hu]=Kritikus lemerültség Name[ia]=Batteria critic Name[id]=Baterai Kritis Name[it]=Batteria a livello critico Name[ja]=バッテリ危険レベル Name[ko]=배터리 바닥남 Name[lt]=Akumuliatoriaus kritinis lygmuo Name[nb]=Kritisk lavt batterinivå 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. Aquesta 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[eu]=Bateria maila kritikora iritsi da. Jakinarazpen honek atzekoz aurrerako zenbaketa bat abiarazten du konfiguratutako ekintza egin aurretik; beraz, oso gomendagarria da hori gaituta uztea. 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[he]=אחוז הסוללה שלך במצב קריטי. התראה זו מפעילה ספירה לאחור לפני ביצוע הפעולה המוגדרת, ולכן מומלץ ביותר להשאיר את זה דלוק. 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]=Bateraimu telah mencapai tingkat kritis. Notifikasi ini picuan sebuah hitungan mundur sebelum melakukan aksi yang terkonfigurasi, maka sangat disarankan untuk menanggalkannya. Comment[it]=La batteria ha raggiunto un livello critico. Questa notifica attiva un conto alla rovescia prima di eseguire l'azione configurata, quindi è fortemente consigliato 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]=Batterinivået er kritisk lavt. Denne varslingen utløser en nedtelling før den utfører den valgte handlinga, 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[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[eu]=Karga beteta Name[fi]=Lataus valmis Name[fr]=Charge terminée Name[gl]=Carga completa Name[he]=הטעינה הושלמה Name[hu]=Töltés befejezve Name[ia]=Cargamento completate Name[id]=Pengecasan Selesai Name[it]=Carica completa Name[ja]=充電完了 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[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[eu]=Bateria erabat kargatuta dago 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[he]=הסוללה טעונה במלואה Comment[hu]=Az akkumulátor teljesen feltöltve Comment[ia]=Le batteria es cargate completemente Comment[id]=Baterai sudah tercas penuh Comment[it]=La batteria è completamente carica Comment[ja]=バッテリーは完全に充電されています 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 Name[ca]=Bateria baixa del perifèric Name[ca@valencia]=Bateria baixa del perifèric Name[cs]=Periferní baterie je téměř vybitá Name[da]=Lavt tilkoblingsbatteri Name[de]=Akku-Ladestand angeschlossener Geräte niedrig Name[el]=Χαμηλό επίπεδο περιφερειακής μπαταρίας Name[en_GB]=Peripheral Battery Low Name[es]=Batería de periférico baja Name[et]=Lisaseadme aku laetus on madal Name[eu]=Periferikoaren bateria baxu Name[fi]=Oheislaitteen akku vähissä Name[fr]=Batterie du périphérique faible Name[gl]=Batería de periférico baixa Name[he]=סוללת של ציוד הקפי עומדת להגמר Name[hu]=A periféria akkumulátora gyenge Name[id]=Periferal Baterai Lemah Name[it]=Batteria di una periferica a livello basso Name[ja]=周辺機器のバッテリー低下 Name[ko]=장치 배터리 부족 Name[lt]=Periferijoje baigia išsikrauti akumuliatorius Name[nb]=Lavt batterinivå på tilleggsmaskinvare Name[nl]=Batterij in randapparaat op laag niveau Name[nn]=Lågt batterinivå på tilleggsmaskinvare Name[pa]=ਪੇਰੀਫੇਰਲ ਦੀ ਬੈਟਰੀ ਘੱਟ ਹੈ Name[pl]=Zewnętrzna bateria na niskim poziomie Name[pt]=Bateria do Periférico Fraca Name[pt_BR]=Bateria do periférico fraca Name[ru]=Низкий уровень заряда батареи устройства Name[sk]=Batéria periférií je slabá Name[sl]=Nizka raven baterije zunanje naprave Name[sr]=Периферна батерија при крају Name[sr@ijekavian]=Периферна батерија при крају Name[sr@ijekavianlatin]=Periferna baterija pri kraju Name[sr@latin]=Periferna baterija pri kraju Name[sv]=Dåligt batteri i periferienhet Name[tr]=Çevre Birimi Pili Düşük Name[uk]=Мало заряду у периферійному пристрої Name[x-test]=xxPeripheral Battery Lowxx Name[zh_CN]=外部设备电池电量低 Name[zh_TW]=週邊裝置電池電力偏低 Comment=The battery in a connected device, such as mouse or keyboard, is low Comment[ca]=La bateria en un dispositiu connectat, com un ratolí o teclat, és baixa Comment[ca@valencia]=La bateria en un dispositiu connectat, com un ratolí o teclat, és baixa Comment[cs]=Baterie v připojeném zařízení jako je klávesnice nebo myš je téměř vybitá Comment[da]=Batteriet i en tilsluttet enhed, såsom mus eller tastatur er lavt Comment[de]=Der Akku-Ladestand in einem angeschlossenen Gerät wie zum Beispiel einer Maus oder einer Tastatur ist niedrig Comment[el]=Η μπαταρία σε μια συνδεδεμένη συσκευή, όπως ποντίκι ή πληκτρολόγιο, είναι σε χαμηλό επίπεδο Comment[en_GB]=The battery in a connected device, such as mouse or keyboard, is low Comment[es]=La batería de un dispositivo conectado, como un ratón o un teclado, está baja Comment[et]=Lisaseadme, näiteks hiire või klaviatuuri, aku hakkab tühjaks saama Comment[eu]=Konektatutako gailu baten bateria, saguarena edo teklatuarena esaterako, baxu dago Comment[fi]=Oheislaitteen, kuten hiiren tai näppäimistön, akku on vähissä Comment[fr]=La batterie d'un périphérique connecté, tel qu'une souris ou un clavier, est faible Comment[gl]=A batería dun dispositivo conectado, como pode ser un rato ou un teclado, está baixa. Comment[he]=הסוללה של התקן מחובר, כגון עכשבר ומקלדת, עומדת להגמר Comment[hu]=A csatlakoztatott eszköz (például egér, billentyűzet) akkumulátorának töltöttsége alacsony Comment[id]=Baterai di dalam sebuah perangkat yang terkonek, seperti mouse atau keyboard, telah lemah Comment[it]=Il livello della batteria di un dispositivo collegato, come un mouse o una tastiera, è basso Comment[ja]=マウスやキーボードなどの接続されたデバイスのバッテリーが低下しています Comment[ko]=연결된 마우스나 키보드와 같은 장치 배터리 부족 Comment[lt]=Senka akumuliatorius prijungtame įrenginyje, pvz., pelėje, klaviatūroje Comment[nb]=Batterinivået til en tilkoblet enhet, for eksempel en mus eller et tastatur, er lavt Comment[nl]=De batterij in een verbonden apparaat, zoals een muis of toetsenbord, is op een laag niveau Comment[nn]=Batterinivået til ei tilkoplinga eining, for eksempel ei mus eller eit tastatur, er lågt Comment[pa]=ਕਨੈਕਟ ਹੋਏ ਡਿਵਾਈਸ, ਜਿਵੇਂ ਕਿ ਮਾਊਸ ਜਾਂ ਕੀਬੋਰਡ, ਦੀ ਬੈਟਰੀ ਘੱਟ ਹੈ Comment[pl]=Bateria w podłączonym urządzeniu, takim jak mysz lub klawiatura, jest na niskim poziomie Comment[pt]=A bateria de um dado dispositivo ligado, como o rato ou o teclado, está em baixo Comment[pt_BR]=A bateria em um dispositivo conectado como mouse ou teclado está fraca Comment[ru]=Низкий уровень заряда батареи периферийного устройства (возможно, мыши или клавиатуры). Comment[sk]=Batéria v pripojenom zariadení, ako v myši alebo klávesnici, je vybitá Comment[sl]=Baterija v povezani napravi (npr. miški ali tipkovnici) ima nizko raven napolnjenosti Comment[sr]=Батерија у повезаном уређају, нпр. мишу или тастатури, при крају је. Comment[sr@ijekavian]=Батерија у повезаном уређају, нпр. мишу или тастатури, при крају је. Comment[sr@ijekavianlatin]=Baterija u povezanom uređaju, npr. mišu ili tastaturi, pri kraju je. Comment[sr@latin]=Baterija u povezanom uređaju, npr. mišu ili tastaturi, pri kraju je. Comment[sv]=Batteriet i en ansluten enhet, såsom musen eller tangentbordet, är dåligt Comment[tr]=Fare veya klavye gibi bağlı bir cihazdaki pil düşük Comment[uk]=Заряд акумулятора у з’єднаному пристрої, наприклад миші або клавіатурі, майже вичерпано Comment[x-test]=xxThe battery in a connected device, such as mouse or keyboard, is lowxx Comment[zh_CN]=一个已连接设备的电池如鼠标或键盘的电量低 Comment[zh_TW]=在已連線裝置(如滑鼠或鍵盤等)中的電池電力偏低 Contexts=warningnot Sound=Oxygen-Sys-Warning.ogg Action=Sound|Popup IconName=battery-caution [Event/pluggedin] Name=AC adaptor plugged in Name[ar]=وُصِلَ محوِّل الكهرباء 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[eu]=Korronte alternoko elikagailua konektatuta Name[fi]=Kytkettiin verkkovirtaan Name[fr]=Adaptateur secteur branché Name[gl]=Enchufouse a alimentación externa Name[he]=מחובר לחשמל Name[hu]=Tápcsatlakozó bedugva Name[ia]=Adaptator AC connectite Name[id]=Adaptor AC tercolok Name[it]=Alimentatore collegato Name[ja]=AC アダプタが接続されました Name[ko]=AC 어댑터 연결됨 Name[lt]=Prijungtas AC adapteris Name[nb]=Strøm 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[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[eu]=Elikagailua konektatu da Comment[fi]=Tietokone kytkettiin verkkovirtaan Comment[fr]=L'adaptateur secteur a été branché Comment[gl]=Enchufouse o transformador de corrente Comment[he]=מחובר למטען 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 dicolokkan Comment[it]=Il cavo di alimentazione è stato collegato 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[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[eu]=Korronte alternoko elikagailua konektatu gabe Name[fi]=Poistuttiin verkkovirrasta Name[fr]=Adaptateur secteur débranché Name[gl]=Desenchufouse a alimentación externa Name[he]=המטען נותק Name[hu]=Tápcsatlakozó kihúzva Name[ia]=Adaptator de AC disconnectite Name[id]=Adaptor AC tercabut Name[it]=Alimentatore scollegato Name[ja]=AC アダプタが取り外されました Name[ko]=AC 어댑터 연결 끊김 Name[lt]=Atjungtas AC adapteris Name[nb]=Strøm koblet fra 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[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[eu]=Elikagailua deskonektatu da Comment[fi]=Tietokone otettiin pois verkkovirrasta Comment[fr]=L'adaptateur secteur a été débranché Comment[gl]=Desenchufouse a fonte de alimentación Comment[he]=המטען נותק 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]=Il cavo di alimentazione è stato scollegato 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[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[eu]=Barne-errorea -Name[fi]=Sisäinen virhe -Name[fr]=Erreur interne -Name[gl]=Erro interno -Name[he]=שגיאה פנימית -Name[hu]=Belső hiba -Name[ia]=Error Interne -Name[id]=Error Internal -Name[it]=Errore interno -Name[ja]=内部エラー -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[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[eu]=KDEren energia kudeatzeko sistemak barne-errore bat eragin du -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[he]=קרתה שגיאה פנימית במערכת לניהול צריכת החשמל של KDE -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 Pengelolaan Daya KDE telah dipicu oleh sebuah error internal -Comment[it]=Il sistema di gestione energetica di KDE ha innescato 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