Adding upstream version 0.11.0.

upstream/0.11.0
Alf Gaida 8 years ago
parent 9bfd04616c
commit fa6e16c643

4
.gitignore vendored

@ -0,0 +1,4 @@
build
*.kdev4
CMakeLists.txt.user
*/translations/lxqt-panel

File diff suppressed because it is too large Load Diff

@ -3,6 +3,7 @@ project(lxqt-panel)
option(UPDATE_TRANSLATIONS "Update source translation translations/*.ts files" OFF)
option(PULL_TRANSLATIONS "Pull translations" ON)
option(WITH_SCREENSAVER_FALLBACK "Include support for converting the deprecated 'screensaver' plugin to 'quicklaunch'. This requires the lxqt-leave (lxqt-session) to be installed in runtime." ON)
# additional cmake files
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
@ -98,14 +99,11 @@ setByDefault(CPULOAD_PLUGIN Yes)
if(CPULOAD_PLUGIN)
find_library(STATGRAB_LIB statgrab)
if(NOT(${STATGRAB_LIB} MATCHES "NOTFOUND"))
list(APPEND ENABLED_PLUGINS "Cpu Load")
add_subdirectory(plugin-cpuload)
else()
message(STATUS "")
message(STATUS "CPU Load plugin requires libstatgrab")
message(STATUS "")
if(NOT STATGRAB_LIB)
message(FATAL_ERROR "CPU Load plugin requires libstatgrab")
endif()
list(APPEND ENABLED_PLUGINS "Cpu Load")
add_subdirectory(plugin-cpuload)
endif()
setByDefault(DIRECTORYMENU_PLUGIN Yes)
@ -156,24 +154,15 @@ if(QUICKLAUNCH_PLUGIN)
add_subdirectory(plugin-quicklaunch)
endif()
setByDefault(SCREENSAVER_PLUGIN Yes)
if(SCREENSAVER_PLUGIN)
list(APPEND ENABLED_PLUGINS "Screensaver")
add_subdirectory(plugin-screensaver)
endif()
setByDefault(SENSORS_PLUGIN Yes)
if(SENSORS_PLUGIN)
find_library(SENSORS_LIB sensors)
if(NOT(${SENSORS_LIB} MATCHES "NOTFOUND"))
list(APPEND ENABLED_PLUGINS "Sensors")
add_subdirectory(plugin-sensors)
else()
message(STATUS "")
message(STATUS "Sensors plugin requires lm_sensors")
message(STATUS "")
if(NOT SENSORS_LIB)
message(FATAL_ERROR "Sensors plugin requires lm_sensors")
endif()
list(APPEND ENABLED_PLUGINS "Sensors")
add_subdirectory(plugin-sensors)
endif()
setByDefault(SHOWDESKTOP_PLUGIN Yes)
@ -188,14 +177,11 @@ setByDefault(NETWORKMONITOR_PLUGIN Yes)
if(NETWORKMONITOR_PLUGIN)
find_library(STATGRAB_LIB statgrab)
if(NOT(${STATGRAB_LIB} MATCHES "NOTFOUND"))
list(APPEND ENABLED_PLUGINS "Network Monitor")
add_subdirectory(plugin-networkmonitor)
else()
message(STATUS "")
message(STATUS "Network Monitor plugin requires libstatgrab")
message(STATUS "")
if(NOT STATGRAB_LIB)
message(FATAL_ERROR "Network Monitor plugin requires libstatgrab")
endif()
list(APPEND ENABLED_PLUGINS "Network Monitor")
add_subdirectory(plugin-networkmonitor)
endif()
setByDefault(SYSSTAT_PLUGIN Yes)
@ -234,27 +220,25 @@ setByDefault(VOLUME_USE_ALSA Yes)
if(VOLUME_PLUGIN)
if (VOLUME_USE_PULSEAUDIO)
find_package(PulseAudio)
if (NOT PULSEAUDIO_FOUND)
message(FATAL_ERROR "PulseAudio not found, but required (VOLUME_USE_PULSEAUDIO) for Volume plugin!")
endif ()
endif(VOLUME_USE_PULSEAUDIO)
if(VOLUME_USE_ALSA)
find_package(ALSA)
if (NOT ALSA_FOUND)
message(FATAL_ERROR "ALSA not found, but required (VOLUME_USE_ALSA) for Volume plugin!")
endif ()
endif()
if(PULSEAUDIO_FOUND OR ALSA_FOUND)
list(APPEND ENABLED_PLUGINS "Volume")
message(STATUS "")
message(STATUS "Volume plugin will be built")
message(STATUS " ALSA: ${ALSA_FOUND}")
message(STATUS " PulseAudio: ${PULSEAUDIO_FOUND}")
message(STATUS "")
add_subdirectory(plugin-volume)
else()
message(STATUS "")
message(STATUS "Volume plugin requires pulseaudio or alsa")
message(STATUS " ALSA: ${ALSA_FOUND}")
message(STATUS " PulseAudio: ${PULSEAUDIO_FOUND}")
message(STATUS "")
endif()
list(APPEND ENABLED_PLUGINS "Volume")
message(STATUS "")
message(STATUS "Volume plugin will be built")
message(STATUS " ALSA: ${ALSA_FOUND}")
message(STATUS " PulseAudio: ${PULSEAUDIO_FOUND}")
message(STATUS "")
add_subdirectory(plugin-volume)
endif()
setByDefault(WORLDCLOCK_PLUGIN Yes)

@ -0,0 +1,61 @@
# lxqt-panel
## Overview
`lxqt-panel` represents the taskbar of LXQt.
The elements available in lxqt-panel are called "plugin" technically. This applies e. g. to the source code where they reside in directories `./plugin-<plugin>` like `plugin-mainmenu`. In contrast to this they are called "widgets" by the configuration GUI so far. Also, a more descriptive term is used to refer to distinct plugins within the GUI. E. g. the aforementioned `plugin-mainmenu` is called "Application menu" that way.
Configuration dialogue "Add Plugins", see [below](https://github.com/pmattern/lxqt-panel/tree/readme#customizing), is listing all available plugins plus a short description and hence provides an overview of the available ones.
Notes on some of the plugins, sorted by terms used within the GUI in alphabetical order, technical term in parenthesis:
#### Date & time (plugin-clock) / World clock (plugin-worldclock)
Both provide clock and calendar functionality. plugin-worldclock can display various time zones in addition but lacks a tooltip displaying current date und time upon hovering.
These plugins will probably be merged into one, see https://github.com/lxde/lxqt/issues/312.
#### Quick launch (plugin-quicklaunch)
A plugin to launch applications from the panel. By default it is empty and displays a message "Drop application icons here". Applications need to be available in panel's main menu and can be included into plugin-quicklaunch by drag & drop.
#### Status Notifier Plugin (plugin-statusnotifier) / System Tray (plugin-tray)
Both provide a notification area within the panel, that is an area where arbitrary applications can place informational icons. This is frequently used e. g. by chat or mail clients to inform about incoming messages or tools configuring the network to inform about connections. (So it's some kind of counterpart to the desktop notifications displayed by [lxqt-notificationd](https://github.com/lxde/lxqt-notificationd)).
The difference between the two plugins is a technical one. **plugin-tray** is implementing the so-called [System Tray Protocol](https://www.freedesktop.org/wiki/Specifications/systemtray-spec). It's a specification that has been around for years but has some serious technical limitations and in particular won't work under Wayland. **plugin-statusnotifier** on the other hand is implementing the so-called [StatusNotifierItem (SNI)](https://www.freedesktop.org/wiki/Specifications/StatusNotifierItem) specification which can be considered a successor of the System Tray Protocol.
Both plugins are maintained in parallel as not all relevant applications are compatible with SNI so far. In particular both Qt 4 and all GTK applications need some kind of wrapper to deal with it. Both plugins can be used in parallel without any issue, applications supporting both specifications will normally chose to display their icons in plugin-statusnotifier.
#### Volume control (plugin-volume)
As indicated by the name, a volume control. Technically Alsa, OSS and PulseAudio can be used as backend. The plugin itself is providing a control to adjust the main volume only but it allows for launching specific UIs of the backend in use like e. g. [pavucontrol-qt](https://github.com/lxde/pavucontrol-qt) to adjust PulseAudio.
## Installation
### Compiling source code
The runtime dependencies are libxcomposite, libdbusmenu-qt5, KGuiAddons, KWindowSystem, Solid, menu-cache, lxmenu-data, [liblxqt](https://github.com/lxde/liblxqt) and [lxqt-globalkeys](https://github.com/lxde/lxqt-globalkeys).
Several plugins or features thereof are optional and need additional runtime dependencies. Namely these are (plugin / feature in parenthesis) Alsa library (Alsa support in plugin-volume), PulseAudio client library (PulseAudio support in plugin-volume), lm-sensors (plugin-sensors), libstatgrab (plugin-cpuload, plugin-networkmonitor), [libsysstat](https://github.com/lxde/libsysstat) (plugin-sysstat). All of them are enabled by default and have to be disabled by CMake variables as required, see below.
In addition CMake is a mandatory build dependency. Git is optionally needed to pull latest VCS checkouts. The localization files were outsourced to repository [lxqt-l10n](https://github.com/lxde/lxqt-l10n) so the corresponding dependencies are needed, too. Please refer to this repository's `README.md` for further information.
Code configuration is handled by CMake. CMake variable `CMAKE_INSTALL_PREFIX` has to be set to `/usr` on most operating systems, depending on the way library paths are dealt with on 64bit systems variables like CMAKE_INSTALL_LIBDIR may have to be set as well.
By default all available plugins and features thereof are built and CMake fails when dependencies aren't met. Building particular plugins can be disabled by boolean CMake variables `<plugin>_PLUGIN` where the plugin is referred by its technical term like e. g. in `SYSSTAT_PLUGIN`. Alsa and PulseAudio support in plugin-volume can be disabled by boolean CMake variables `VOLUME_USE_ALSA` and `VOLUME_USE_PULSEAUDIO`.
To build run `make`, to install `make install` which accepts variable `DESTDIR` as usual.
### Binary packages
Official binary packages are provided by all major Linux distributions like Arch Linux, Debian (as of Debian stretch only), Fedora and openSUSE. Just use your package manager to search for string `lxqt-panel`.
## Configuration, Usage
### Launching
The panel is run as a daemon-like [LXQt Module](https://github.com/lxde/lxqt-session#lxqt-modules) the launch of which can be adjusted in section "Basic Settings" of configuration dialogue [LXQt Session Settings](https://github.com/lxde/lxqt-session#lxqt-session-settings) of [lxqt-session](https://github.com/lxde/lxqt-session).
### Customizing
To customize the panel itself there's a context menu, that is a menu opened by right-clicking the pointer device. It is comprising sections "\<plugin\>" and "Panel" which allow for configuring the plugin the pointer is currently over and the panel as a whole respectively.
In section "Panel" topics "Configure Panel" and "Manage Widgets" open different panes of a dialogue "Configure Panel" which allow for configuring the panel as a whole and the various plugins respectively.
Pane "Widgets" allows for configuring and removing all plugins currently included in lxqt-panel. The plus sign opens another dialogue "Add plugins" which is used to add plugins. It comes with a list of all plugins plus some short descriptions and can hence serve as overview what plugins are available.
Sometimes right-clicking over particular plugins may bring up a context menu dealing with the respective plugin's functionality *only* which means the plugin in question cannot be configured the usual way. This affects e. g. plugin-quicklaunch as soon as items were added (the context menu is limited to topics dealing with the items included in plugin-quicklaunch).
Currently there are two ways to deal with this. Some themes like e. g. `Frost` come with handles at the plugins' left end providing the regular context menu. Also, it can be assumed at least one plugin is included in the panel that's always featuring the regular context menu like e. g. plugin-mainmenu. Either way pane "Widgets" of "Configure Panel" can be accessed and used to configure the particular plugin.

@ -64,6 +64,11 @@ add_definitions(-DCOMPILE_LXQT_PANEL)
set(PLUGIN_DESKTOPS_DIR "${CMAKE_INSTALL_FULL_DATAROOTDIR}/lxqt/${PROJECT}")
add_definitions(-DPLUGIN_DESKTOPS_DIR=\"${PLUGIN_DESKTOPS_DIR}\")
if (WITH_SCREENSAVER_FALLBACK)
message(STATUS "Building with conversion of deprecated 'screensaver' plugin")
add_definitions(-DWITH_SCREENSAVER_FALLBACK "-DLXQT_LOCK_DESKTOP=\"${CMAKE_INSTALL_FULL_DATAROOTDIR}/applications/lxqt-lockscreen.desktop\"")
endif ()
project(${PROJECT})
set(QTX_LIBRARIES Qt5::Widgets Qt5::Xml Qt5::DBus)

@ -171,7 +171,6 @@ LXQtPanel::LXQtPanel(const QString &configGroup, LXQt::Settings *settings, QWidg
//LXQtPanel (inherits QFrame) -> lav (QGridLayout) -> LXQtPanelWidget (QFrame) -> LXQtPanelLayout
LXQtPanelWidget = new QFrame(this);
LXQtPanelWidget->setObjectName("BackgroundWidget");
LXQtPanelWidget->setAutoFillBackground(true);
QGridLayout* lav = new QGridLayout();
lav->setContentsMargins(0, 0, 0, 0);
setLayout(lav);

@ -233,6 +233,25 @@ void PanelPluginsModel::loadPlugins(QStringList const & desktopDirs)
qWarning() << QString("Section \"%1\" not found in %2.").arg(name, mPanel->settings()->fileName());
continue;
}
#ifdef WITH_SCREENSAVER_FALLBACK
if (QStringLiteral("screensaver") == type)
{
//plugin-screensaver was dropped
//convert settings to plugin-quicklaunch
const QString & lock_desktop = QStringLiteral(LXQT_LOCK_DESKTOP);
qWarning().noquote() << "Found deprecated plugin of type 'screensaver', migrating to 'quicklaunch' with '" << lock_desktop << '\'';
type = QStringLiteral("quicklaunch");
LXQt::Settings * settings = mPanel->settings();
settings->beginGroup(name);
settings->remove(QString{});//remove all existing keys
settings->setValue(QStringLiteral("type"), type);
settings->beginWriteArray(QStringLiteral("apps"), 1);
settings->setArrayIndex(0);
settings->setValue(QStringLiteral("desktop"), lock_desktop);
settings->endArray();
settings->endGroup();
}
#endif
LXQt::PluginInfoList list = LXQt::PluginInfo::search(desktopDirs, "LXQtPanel/Plugin", QString("%1.desktop").arg(type));
if( !list.count())

@ -443,7 +443,7 @@ void Plugin::showConfigureDialog()
if (!mConfigDialog)
return;
connect(this, &Plugin::destroyed, mConfigDialog, &QWidget::close);
connect(this, &Plugin::destroyed, mConfigDialog.data(), &QWidget::close);
mPanel->willShowWindow(mConfigDialog);
mConfigDialog->show();
mConfigDialog->raise();

@ -1,12 +1,2 @@
[Desktop Entry]
Type=Service
ServiceTypes=LXQtPanel/Plugin
Name=Date & time
Comment=Displays the current time. Comes with a calendar.
#TRANSLATIONS_DIR=../translations
# Translations
Comment[ar]=السَّاعة والتَّقويم
Name[ar]=السَّاعة
Name[ar]=التّاريخ والوقت
Comment[ar]=تعرض الوقت الحاليّ. فيها تقويم.

@ -0,0 +1,2 @@
Name[ar]=لاقط الألوان
Comment[ar]=اعرف اللون تحت المؤشّر. لمطوّري الوِبّ.

@ -1,13 +1,2 @@
[Desktop Entry]
Type=Service
ServiceTypes=LXQtPanel/Plugin
Name=Cpu monitor
Comment=Displays the current CPU load.
# Translations
Comment[ar]=مُراقب عبء المعالج
Name[ar]=عبء المعالج
Name[ar]=مرقاب المعالج
Comment[ar]=تعرض حمل المعالج الحاليّ.

@ -1,12 +1,2 @@
[Desktop Entry]
Type=Service
ServiceTypes=LXQtPanel/Plugin
Name=Desktop switcher
Comment=Allows easy switching between virtual desktops.
#TRANSLATIONS_DIR=../translations
# Translations
Comment[ar]=السماح بتغيير أسطح المكتب اﻻفتراضيَّة
Name[ar]=مفتاح تبديل سطح المكتب
Name[ar]=مبدّل سطح المكتب
Comment[ar]=تسمح بالتّبديل السهل بين أسطح المكتب الوهميّة.

@ -0,0 +1,2 @@
Name[ar]=قائمة الأدلّة
Comment[ar]=تعرض قائمة تظهر محتويات الدّليل

@ -0,0 +1,2 @@
Name[ar]=شجرة DOM للّوحة
Comment[ar]=تُظهر شجرة DOM للوحة لكسكيوت.

@ -35,6 +35,7 @@ pkg_check_modules(XKB_COMMON_X11 QUIET xkbcommon-x11)
if(XKB_COMMON_X11_FOUND)
message(STATUS "XkbCommon X11 was found")
include_directories(${XKB_COMMON_X11_INCLUDE_DIRS})
find_package(Qt5 COMPONENTS X11Extras Xml)
pkg_check_modules(XCB xcb)
pkg_check_modules(XCB_XKB xcb-xkb)

@ -0,0 +1,2 @@
Name[ar]=مؤشّر حالة لوحة المفاتيح
Comment[ar]=ملحقة لمؤشّر حالة لوحة المفاتيح وتبديل اللغات.

@ -146,6 +146,7 @@ void ActionView::addAction(QAction * action)
item->setData(all, FilterRole);
mModel->appendRow(item);
connect(action, &QObject::destroyed, this, &ActionView::onActionDestroyed);
}
bool ActionView::existsAction(QAction const * action) const
@ -233,15 +234,14 @@ void ActionView::onActivated(QModelIndex const & index)
void ActionView::onActionDestroyed()
{
QAction * const action = qobject_cast<QAction *>(sender());
QObject * const action = sender();
Q_ASSERT(nullptr != action);
for (int i = mModel->rowCount(); 0 <= i; --i)
for (int i = mModel->rowCount() - 1; 0 <= i; --i)
{
QStandardItem * item = mModel->item(i);
if (action == item->data(ActionRole).value<QAction *>())
if (action == item->data(ActionRole).value<QObject *>())
{
mModel->removeRow(i);
delete item;
break;
}
}

@ -331,49 +331,50 @@ void LXQtMainMenu::setSearchFocus(QAction *action)
************************************************/
void LXQtMainMenu::buildMenu()
{
if(mMenu)
{
mMenu->removeAction(mSearchEditAction);
mMenu->removeAction(mSearchViewAction);
delete mMenu;
}
#ifdef HAVE_MENU_CACHE
XdgCachedMenu* menu = new XdgCachedMenu(mMenuCache, &mButton);
mMenu = new XdgCachedMenu(mMenuCache, &mButton);
#else
XdgMenuWidget *menu = new XdgMenuWidget(mXdgMenu, "", &mButton);
mMenu = new XdgMenuWidget(mXdgMenu, "", &mButton);
#endif
menu->setObjectName("TopLevelMainMenu");
menu->setStyle(&mTopMenuStyle);
mMenu->setObjectName("TopLevelMainMenu");
// Note: the QWidget::ensurePolished() workarounds problem with transparent
// QLineEdit (mSearchEditAction) in menu with Breeze style
// https://bugs.kde.org/show_bug.cgi?id=368048
mMenu->ensurePolished();
mMenu->setStyle(&mTopMenuStyle);
menu->addSeparator();
mMenu->addSeparator();
Q_FOREACH(QAction* action, menu->actions())
Q_FOREACH(QAction* action, mMenu->actions())
{
if (action->menu())
action->menu()->installEventFilter(this);
}
menu->installEventFilter(this);
connect(menu, &QMenu::aboutToHide, &mHideTimer, static_cast<void (QTimer::*)()>(&QTimer::start));
connect(menu, &QMenu::aboutToShow, &mHideTimer, &QTimer::stop);
mMenu->installEventFilter(this);
connect(mMenu, &QMenu::aboutToHide, &mHideTimer, static_cast<void (QTimer::*)()>(&QTimer::start));
connect(mMenu, &QMenu::aboutToShow, &mHideTimer, &QTimer::stop);
menu->addSeparator();
if(mMenu)
{
mMenu->removeAction(mSearchEditAction);
mMenu->removeAction(mSearchViewAction);
}
menu->addAction(mSearchViewAction);
menu->addAction(mSearchEditAction);
connect(menu, &QMenu::hovered, this, &LXQtMainMenu::setSearchFocus);
mMenu->addSeparator();
mMenu->addAction(mSearchViewAction);
mMenu->addAction(mSearchEditAction);
connect(mMenu, &QMenu::hovered, this, &LXQtMainMenu::setSearchFocus);
//Note: setting readOnly to true to avoid wake-ups upon the Qt's internal "blink" cursor timer
//(if the readOnly is not set, the "blink" timer is active also in case the menu is not shown ->
//QWidgetLineControl::updateNeeded is performed w/o any need)
//https://bugreports.qt.io/browse/QTBUG-52021
connect(menu, &QMenu::aboutToHide, [this] { mSearchEdit->setReadOnly(true); });
connect(mMenu, &QMenu::aboutToHide, [this] { mSearchEdit->setReadOnly(true); });
mSearchEdit->setVisible(mFilterMenu || mFilterShow);
mSearchEditAction->setVisible(mFilterMenu || mFilterShow);
mSearchView->fillActions(menu);
QMenu *oldMenu = mMenu;
mMenu = menu;
if(oldMenu)
delete oldMenu;
mSearchView->fillActions(mMenu);
searchTextChanged(mSearchEdit->text());
setMenuFontSize();
}
@ -453,8 +454,6 @@ bool LXQtMainMenu::eventFilter(QObject *obj, QEvent *event)
// the application is given a new QStyle
if(event->type() == QEvent::StyleChange)
{
// reset proxy style for the menus so they can apply the new styles
mTopMenuStyle.setBaseStyle(NULL);
setMenuFontSize();
setButtonIcon();
}

@ -1,12 +1,2 @@
[Desktop Entry]
Type=Service
ServiceTypes=LXQtPanel/Plugin
Name=Application menu
Comment=A menu of all your applications.
#TRANSLATIONS_DIR=../translations
# Translations
Comment[ar]=بادئ التطبيقات المعتمد على قائمة
Name[ar]=قائمة التطبيقات
Comment[ar]=قائمة لكلّ تطبيقاتك
Name[ar]=قائمة التّطبيقات

@ -1,12 +1,2 @@
[Desktop Entry]
Type=Service
ServiceTypes=LXQtPanel/Plugin
Name=Removable media
Comment=Easy mounting and unmounting of USB and optical drives.
#TRANSLATIONS_DIR=../translations
# Translations
Comment[ar]=معالج الوسائط القابلة للفصل (يو إس بي و أقراص مدمجة...)
Name[ar]=الوسائط القابلة للفصل
Comment[ar]=لضمّ أو إزالة ضمّ أصابع USB أو الأجهزة البصريّة.
Name[ar]=الوسائط المنفصلة

@ -0,0 +1,2 @@
Name[ar]=مرقاب الشّبكة
Comment[ar]=تعرض حالة الشّبكة ونشاطها

@ -1,12 +1,2 @@
[Desktop Entry]
Type=Service
ServiceTypes=LXQtPanel/Plugin
Name=Quick launch
Comment=Easy access to your favourite applications.
#TRANSLATIONS_DIR=../translations
# Translations
Comment[ar]=إطلاق تطبيقاتك المفضَّلة
Name[ar]=البدء السريع
Comment[ar]=نفاذ مباشر لتطبيقاتك المفضّلة.
Name[ar]=إطلاق سريع

@ -1,16 +0,0 @@
set(PLUGIN "screensaver")
set(HEADERS
panelscreensaver.h
)
set(SOURCES
panelscreensaver.cpp
)
set(LIBRARIES
${LIBRARIES}
lxqt-globalkeys
)
BUILD_LXQT_PLUGIN(${PLUGIN})

@ -1,73 +0,0 @@
/* BEGIN_COMMON_COPYRIGHT_HEADER
* (c)LGPL2+
*
* LXDE-Qt - a lightweight, Qt based, desktop toolset
* http://razor-qt.org
*
* Copyright: 2010-2011 Razor team
* Authors:
* Petr Vanek <petr@scribus.info>
*
* This program or library is free software; you can redistribute it
* and/or modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
* You should have received a copy of the GNU Lesser General
* Public License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA
*
* END_COMMON_COPYRIGHT_HEADER */
#include <QMessageBox>
#include <QHBoxLayout>
#include <LXQt/ScreenSaver>
#include <LXQt/Notification>
#include <lxqt-globalkeys.h>
#include "panelscreensaver.h"
#include "../panel/pluginsettings.h"
#define DEFAULT_SHORTCUT "Control+Alt+L"
PanelScreenSaver::PanelScreenSaver(const ILXQtPanelPluginStartupInfo &startupInfo) :
QObject(),
ILXQtPanelPlugin(startupInfo)
{
mButton.setAutoRaise(true);
mSaver = new LXQt::ScreenSaver(this);
QList<QAction*> actions = mSaver->availableActions();
if (!actions.empty())
mButton.setDefaultAction(actions.first());
//mButton->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
mShortcutKey = GlobalKeyShortcut::Client::instance()->addAction(QString(), QString("/panel/%1/lock").arg(settings()->group()), tr("Lock Screen"), this);
if (mShortcutKey)
{
connect(mShortcutKey, &GlobalKeyShortcut::Action::registrationFinished, this, &PanelScreenSaver::shortcutRegistered);
connect(mShortcutKey, SIGNAL(activated()), mSaver, SLOT(lockScreen()));
}
}
void PanelScreenSaver::shortcutRegistered()
{
if (mShortcutKey->shortcut().isEmpty())
{
mShortcutKey->changeShortcut(DEFAULT_SHORTCUT);
if (mShortcutKey->shortcut().isEmpty())
{
LXQt::Notification::notify(tr("Panel Screensaver: Global shortcut '%1' cannot be registered").arg(DEFAULT_SHORTCUT));
}
}
}
#undef DEFAULT_SHORTCUT

@ -1,75 +0,0 @@
/* BEGIN_COMMON_COPYRIGHT_HEADER
* (c)LGPL2+
*
* LXDE-Qt - a lightweight, Qt based, desktop toolset
* http://razor-qt.org
*
* Copyright: 2010-2011 Razor team
* Authors:
* Petr Vanek <petr@scribus.info>
*
* This program or library is free software; you can redistribute it
* and/or modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
* You should have received a copy of the GNU Lesser General
* Public License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA
*
* END_COMMON_COPYRIGHT_HEADER */
#ifndef PANELSCREENSAVER_H
#define PANELSCREENSAVER_H
#include "../panel/ilxqtpanelplugin.h"
#include <QToolButton>
namespace LXQt {
class ScreenSaver;
}
namespace GlobalKeyShortcut
{
class Action;
}
class PanelScreenSaver : public QObject, public ILXQtPanelPlugin
{
Q_OBJECT
public:
PanelScreenSaver(const ILXQtPanelPluginStartupInfo &startupInfo);
virtual QWidget *widget() { return &mButton; }
virtual QString themeId() const { return "PanelScreenSaver"; }
private slots:
void shortcutRegistered();
private:
QToolButton mButton;
LXQt::ScreenSaver * mSaver;
GlobalKeyShortcut::Action * mShortcutKey;
};
class PanelScreenSaverLibrary: public QObject, public ILXQtPanelPluginLibrary
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "lxde-qt.org/Panel/PluginInterface/3.0")
Q_INTERFACES(ILXQtPanelPluginLibrary)
public:
ILXQtPanelPlugin *instance(const ILXQtPanelPluginStartupInfo &startupInfo) const
{
return new PanelScreenSaver(startupInfo);
}
};
#endif

@ -1,8 +0,0 @@
[Desktop Entry]
Type=Service
ServiceTypes=LXQtPanel/Plugin
Name=Launch screensaver
Comment=Activate a screensaver and/or lock the screen
Icon=system-lock-screen
#TRANSLATIONS_DIR=../translations

@ -1,12 +0,0 @@
[Desktop Entry]
Type=Service
ServiceTypes=LXQtPanel/Plugin
Name=Launch screensaver
Comment=Activate a screensaver and/or lock the screen
#TRANSLATIONS_DIR=../translations
# Translations
Comment[ar]=تفعيل حافظ الشَّاشة و/أو قفل الشَّاشة
Name[ar]=حافظ الشَّاشة

@ -1,12 +0,0 @@
[Desktop Entry]
Type=Service
ServiceTypes=LXQtPanel/Plugin
Name=Launch screensaver
Comment=Activate a screensaver and/or lock the screen
#TRANSLATIONS_DIR=../translations
# Translations
Comment[cs]=Zapne šetřič obrazovky a/nebo zamkne obrazovku
Name[cs]=Šetřič obrazovky

@ -1,12 +0,0 @@
[Desktop Entry]
Type=Service
ServiceTypes=LXQtPanel/Plugin
Name=Launch screensaver
Comment=Activate a screensaver and/or lock the screen
#TRANSLATIONS_DIR=../translations
# Translations
Comment[cs_CZ]=Zapnout šetřič obrazovky a/nebo zamknout obrazovku
Name[cs_CZ]=Šetřič obrazovky

@ -1,12 +0,0 @@
[Desktop Entry]
Type=Service
ServiceTypes=LXQtPanel/Plugin
Name=Launch screensaver
Comment=Activate a screensaver and/or lock the screen
#TRANSLATIONS_DIR=../translations
# Translations
Comment[da]=Aktiverer en pauseskærm og/eller låser skærmen
Name[da]=Pauseskærm

@ -1,12 +0,0 @@
[Desktop Entry]
Type=Service
ServiceTypes=LXQtPanel/Plugin
Name=Launch screensaver
Comment=Activate a screensaver and/or lock the screen
#TRANSLATIONS_DIR=../translations
# Translations
Comment[da_DK]=Aktiverer pauseskærm og/eller låser skærmen
Name[da_DK]=Pauseskærm

@ -1,2 +0,0 @@
Name[de]=Bildschirmschoner
Comment[de]=Bildschirmschoner aktivieren und/oder Bildschirm sperren

@ -1,2 +0,0 @@
Name[el]=Προφύλαξη οθόνης
Comment[el]=Ενεργοποίηση της προφύλαξης οθόνης και/ή κλείδωμα της οθόνης

@ -1,12 +0,0 @@
[Desktop Entry]
Type=Service
ServiceTypes=LXQtPanel/Plugin
Name=Launch screensaver
Comment=Activate a screensaver and/or lock the screen
#TRANSLATIONS_DIR=../translations
# Translations
Comment[eo]=Enŝalti ekrankurtenon kaj/aŭ ŝlosi la ekranon
Name[eo]=Ekrankurteno

@ -1,12 +0,0 @@
[Desktop Entry]
Type=Service
ServiceTypes=LXQtPanel/Plugin
Name=Launch screensaver
Comment=Activate a screensaver and/or lock the screen
#TRANSLATIONS_DIR=../translations
# Translations
Comment[es]=Activa el salvapantallas y/o bloquea la pantalla
Name[es]=Salvapantallas

@ -1,12 +0,0 @@
[Desktop Entry]
Type=Service
ServiceTypes=LXQtPanel/Plugin
Name=Launch screensaver
Comment=Activate a screensaver and/or lock the screen
#TRANSLATIONS_DIR=../translations
# Translations
Comment[es_VE]=Activar el salvapantallas y/o bloquear la pantalla
Name[es_VE]=SalvaPantallas

@ -1,12 +0,0 @@
[Desktop Entry]
Type=Service
ServiceTypes=LXQtPanel/Plugin
Name=Launch screensaver
Comment=Activate a screensaver and/or lock the screen
#TRANSLATIONS_DIR=../translations
# Translations
Comment[eu]=Aktibatu pantaila-babeslea eta/edo blokeatu pantaila
Name[eu]=Pantaila-babeslea

@ -1,12 +0,0 @@
[Desktop Entry]
Type=Service
ServiceTypes=LXQtPanel/Plugin
Name=Launch screensaver
Comment=Activate a screensaver and/or lock the screen
#TRANSLATIONS_DIR=../translations
# Translations
Comment[fi]=Aktivoi näytönsäästäjä ja/tai lukitse näyttö
Name[fi]=Näytönsäästäjä

@ -1,12 +0,0 @@
[Desktop Entry]
Type=Service
ServiceTypes=LXQtPanel/Plugin
Name=Launch screensaver
Comment=Activate a screensaver and/or lock the screen
#TRANSLATIONS_DIR=../translations
# Translations
Comment[fr_FR]=Activer un économiseur d'écran et/ou verrouiller l'écran
Name[fr_FR]=Économiseur d'écran

@ -1,12 +0,0 @@
[Desktop Entry]
Type=Service
ServiceTypes=LXQtPanel/Plugin
Name=Launch screensaver
Comment=Activate a screensaver and/or lock the screen
#TRANSLATIONS_DIR=../translations
# Translations
Comment[hu]=A képernyővédő aktiválása és/vagy a képernyő zárolása
Name[hu]=Képernyővédő

@ -1,10 +0,0 @@
[Desktop Entry]
Type=Service
ServiceTypes=LXQtPanel/Plugin
Name=Screensaver
Comment=Activate a screensaver and/or lock the screen
#TRANSLATIONS_DIR=../translations
# Translations

@ -1,10 +0,0 @@
[Desktop Entry]
Type=Service
ServiceTypes=LXQtPanel/Plugin
Name=Screensaver
Comment=Activate a screensaver and/or lock the screen
#TRANSLATIONS_DIR=../translations
# Translations

@ -1,3 +0,0 @@
Comment[it]=Attiva un salvaschermo e/o blocca lo schermo
Name[it]=Salvaschermo

@ -1,12 +0,0 @@
[Desktop Entry]
Type=Service
ServiceTypes=LXQtPanel/Plugin
Name=Launch screensaver
Comment=Activate a screensaver and/or lock the screen
#TRANSLATIONS_DIR=../translations
# Translations
Comment[ja]=スクリーンセーバーを起動したり、スクリーンをロックしたりします
Name[ja]=スクリーンセーバーの起動

@ -1,10 +0,0 @@
[Desktop Entry]
Type=Service
ServiceTypes=LXQtPanel/Plugin
Name=Screensaver
Comment=Activate a screensaver and/or lock the screen
#TRANSLATIONS_DIR=../translations
# Translations

@ -1,12 +0,0 @@
[Desktop Entry]
Type=Service
ServiceTypes=LXQtPanel/Plugin
Name=Launch screensaver
Comment=Activate a screensaver and/or lock the screen
#TRANSLATIONS_DIR=../translations
# Translations
Comment[lt]=Aktyvuoja ekrano užsklandą ir/arba užrakina ekraną
Name[lt]=Ekrano užsklanda

@ -1,12 +0,0 @@
[Desktop Entry]
Type=Service
ServiceTypes=LXQtPanel/Plugin
Name=Launch screensaver
Comment=Activate a screensaver and/or lock the screen
#TRANSLATIONS_DIR=../translations
# Translations
Comment[nl]=Activeer de schermbeveiliging en/of vergrendel het scherm
Name[nl]=Schermbeveiliging

@ -1,12 +0,0 @@
[Desktop Entry]
Type=Service
ServiceTypes=LXQtPanel/Plugin
Name=Launch screensaver
Comment=Activate a screensaver and/or lock the screen
#TRANSLATIONS_DIR=../translations
# Translations
Comment[pl]=Aktywuje wygaszacz ekranu oraz/albo blokuje ekran
Name[pl]=Wygaszacz ekranu

@ -1,12 +0,0 @@
[Desktop Entry]
Type=Service
ServiceTypes=LXQtPanel/Plugin
Name=Launch screensaver
Comment=Activate a screensaver and/or lock the screen
#TRANSLATIONS_DIR=../translations
# Translations
Comment[pl_PL]=Włącz wygaszacz ekranu i / lub zablokuj ekran.
Name[pl_PL]=Uruchom wygaszacz ekranu

@ -1,11 +0,0 @@
[Desktop Entry]
Type=Service
ServiceTypes=LXQtPanel/Plugin
Name=Launch screensaver
Comment=Activate a screensaver and/or lock the screen
#TRANSLATIONS_DIR=../translations
# Translations
Name[pt]=Proteção de ecrã
Comment[pt]=Ativar uma proteção de ecrã e/ou bloquear o ecrã

@ -1,12 +0,0 @@
[Desktop Entry]
Type=Service
ServiceTypes=LXQtPanel/Plugin
Name=Launch screensaver
Comment=Activate a screensaver and/or lock the screen
#TRANSLATIONS_DIR=../translations
# Translations
Comment[pt_BR]=Ativar o protetor de tela e/ou bloquear a tela
Name[pt_BR]=Protetor De Tela

@ -1,12 +0,0 @@
[Desktop Entry]
Type=Service
ServiceTypes=LXQtPanel/Plugin
Name=Launch screensaver
Comment=Activate a screensaver and/or lock the screen
#TRANSLATIONS_DIR=../translations
# Translations
Comment[ro_RO]=Activează protecția de ecran și/sau blochează ecranul
Name[ro_RO]=Protecție ecran

@ -1,12 +0,0 @@
[Desktop Entry]
Type=Service
ServiceTypes=LXQtPanel/Plugin
Name=Launch screensaver
Comment=Activate a screensaver and/or lock the screen
#TRANSLATIONS_DIR=../translations
# Translations
Comment[ru]=Включить хранитель экрана и/или блокировать экран
Name[ru]=Запустить хранитель экрана

@ -1,12 +0,0 @@
[Desktop Entry]
Type=Service
ServiceTypes=LXQtPanel/Plugin
Name=Launch screensaver
Comment=Activate a screensaver and/or lock the screen
#TRANSLATIONS_DIR=../translations
# Translations
Comment[sk]=Aktivovanie šetriča obrazovky alebo zamknutia obrazovky
Name[sk]=Šetrič obrazovky

@ -1,12 +0,0 @@
[Desktop Entry]
Type=Service
ServiceTypes=LXQtPanel/Plugin
Name=Launch screensaver
Comment=Activate a screensaver and/or lock the screen
#TRANSLATIONS_DIR=../translations
# Translations
Comment[sl]=Vklopite ohranjevalnik zaslona ali pa zaklenite zaslon.
Name[sl]=Ohranjevalnik zaslona

@ -1,12 +0,0 @@
[Desktop Entry]
Type=Service
ServiceTypes=LXQtPanel/Plugin
Name=Launch screensaver
Comment=Activate a screensaver and/or lock the screen
#TRANSLATIONS_DIR=../translations
# Translations
Comment[sr]=Активирајте чувара екрана и/или закључајте екран
Name[sr]=Чувар екрана

@ -1,2 +0,0 @@
Name[sr@ijekavian]=Чувар екрана
Comment[sr@ijekavian]=Активирајте чувара екрана и/или закључајте екран

@ -1,2 +0,0 @@
Name[sr@ijekavianlatin]=Čuvar ekrana
Comment[sr@ijekavianlatin]=Aktivirajte čuvara ekrana i/ili zaključajte ekran

@ -1,12 +0,0 @@
[Desktop Entry]
Type=Service
ServiceTypes=LXQtPanel/Plugin
Name=Launch screensaver
Comment=Activate a screensaver and/or lock the screen
#TRANSLATIONS_DIR=../translations
# Translations
Comment[sr@latin]=Aktivirajte čuvara ekrana i/ili zaključajte ekran
Name[sr@latin]=Čuvar ekrana

@ -1,12 +0,0 @@
[Desktop Entry]
Type=Service
ServiceTypes=LXQtPanel/Plugin
Name=Launch screensaver
Comment=Activate a screensaver and/or lock the screen
#TRANSLATIONS_DIR=../translations
# Translations
Comment[th_TH]=เริ่มงานโปรแกรมรักษาหน้าจอ และ/หรือ ล็อคหน้าจอ
Name[th_TH]=โปรแกรมรักษาหน้าจอ

@ -1,12 +0,0 @@
[Desktop Entry]
Type=Service
ServiceTypes=LXQtPanel/Plugin
Name=Launch screensaver
Comment=Activate a screensaver and/or lock the screen
#TRANSLATIONS_DIR=../translations
# Translations
Comment[tr]=Bir ekran koruyucu etkinleştir ve/veya ekranı kilitle
Name[tr]=Ekran koruyucu

@ -1,12 +0,0 @@
[Desktop Entry]
Type=Service
ServiceTypes=LXQtPanel/Plugin
Name=Launch screensaver
Comment=Activate a screensaver and/or lock the screen
#TRANSLATIONS_DIR=../translations
# Translations
Comment[uk]=Активувати зберігач екрану та/чи заблокувати екран
Name[uk]=Зберігач екрану

@ -1,10 +0,0 @@
[Desktop Entry]
Type=Service
ServiceTypes=LXQtPanel/Plugin
Name=Screensaver
Comment=Activate a screensaver and/or lock the screen
#TRANSLATIONS_DIR=../translations
# Translations

@ -1,12 +0,0 @@
[Desktop Entry]
Type=Service
ServiceTypes=LXQtPanel/Plugin
Name=Launch screensaver
Comment=Activate a screensaver and/or lock the screen
#TRANSLATIONS_DIR=../translations
# Translations
Comment[zh_CN]=启用屏幕保护并锁定屏幕
Name[zh_CN]=屏幕保护

@ -1,12 +0,0 @@
[Desktop Entry]
Type=Service
ServiceTypes=LXQtPanel/Plugin
Name=Launch screensaver
Comment=Activate a screensaver and/or lock the screen
#TRANSLATIONS_DIR=../translations
# Translations
Comment[zh_TW]=啟動螢幕保護程式並/或鎖上螢幕
Name[zh_TW]=螢幕保護程式

@ -34,6 +34,7 @@
#include <QMessageBox>
#include <QPalette>
static constexpr double DEFAULT_MAX = 200; // 200 Celsius
LXQtSensors::LXQtSensors(ILXQtPanelPlugin *plugin, QWidget* parent):
QFrame(parent),
@ -140,6 +141,9 @@ void LXQtSensors::updateSensorReadings()
// Iterator for temperature progress bars
QList<ProgressBar*>::iterator temperatureProgressBarsIt =
mTemperatureProgressBars.begin();
const bool use_fahrenheit = mSettings->value("useFahrenheitScale").toBool();
const bool warn_high = mSettings->value("warningAboutHighTemperature").toBool();
const double default_max = use_fahrenheit ? celsiusToFahrenheit(DEFAULT_MAX) : DEFAULT_MAX;
for (int i = 0; i < mDetectedChips.size(); ++i)
{
@ -151,34 +155,17 @@ void LXQtSensors::updateSensorReadings()
{
tooltip = features[j].getLabel() + " (" + QChar(0x00B0);
if (mSettings->value("useFahrenheitScale").toBool())
{
critTemp = celsiusToFahrenheit(
features[j].getValue(SENSORS_SUBFEATURE_TEMP_CRIT));
maxTemp = celsiusToFahrenheit(
features[j].getValue(SENSORS_SUBFEATURE_TEMP_MAX));
minTemp = celsiusToFahrenheit(
features[j].getValue(SENSORS_SUBFEATURE_TEMP_MIN));
curTemp = celsiusToFahrenheit(
features[j].getValue(SENSORS_SUBFEATURE_TEMP_INPUT));
tooltip += "F)";
}
else
{
critTemp = features[j].getValue(SENSORS_SUBFEATURE_TEMP_CRIT);
maxTemp = features[j].getValue(SENSORS_SUBFEATURE_TEMP_MAX);
minTemp = features[j].getValue(SENSORS_SUBFEATURE_TEMP_MIN);
curTemp = features[j].getValue(SENSORS_SUBFEATURE_TEMP_INPUT);
tooltip += "C)";
}
critTemp = features[j].getValue(SENSORS_SUBFEATURE_TEMP_CRIT);
maxTemp = features[j].getValue(SENSORS_SUBFEATURE_TEMP_MAX);
minTemp = features[j].getValue(SENSORS_SUBFEATURE_TEMP_MIN);
curTemp = features[j].getValue(SENSORS_SUBFEATURE_TEMP_INPUT);
double temp_to_check = maxTemp == 0.0 ? critTemp : maxTemp;
// Check if temperature is too high
if (curTemp >= maxTemp)
if (temp_to_check != 0.0 && curTemp >= temp_to_check)
{
if (mSettings->value("warningAboutHighTemperature").toBool())
if (warn_high)
{
// Add current progress bar to the "warning container"
mHighTemperatureProgressBars.insert(*temperatureProgressBarsIt);
@ -193,8 +180,23 @@ void LXQtSensors::updateSensorReadings()
highTemperature = false;
}
if (use_fahrenheit)
{
critTemp = celsiusToFahrenheit(critTemp);
maxTemp = celsiusToFahrenheit(maxTemp);
minTemp = celsiusToFahrenheit(minTemp);
curTemp = celsiusToFahrenheit(curTemp);
tooltip += "F)";
}
else
{
tooltip += "C)";
}
// Set maximum temperature
(*temperatureProgressBarsIt)->setMaximum(critTemp);
(*temperatureProgressBarsIt)->setMaximum(critTemp == 0.0 ? default_max : critTemp);
// Set minimum temperature
(*temperatureProgressBarsIt)->setMinimum(minTemp);
// Set current temperature

@ -1,10 +1,2 @@
[Desktop Entry]
Type=Service
ServiceTypes=LXQtPanel/Plugin
Name=Sensors
Comment=View readings from hardware sensors.
# Translations
Name[ar]=إستشعار
Comment[ar]=عرض قراءة من إستشعار لأجهزة (حاليا lm_sensors)
Name[ar]=مجسّات
Comment[ar]=تعرض قراءات من مجسّات العتاد.

@ -1,12 +1,2 @@
[Desktop Entry]
Type=Service
ServiceTypes=LXQtPanel/Plugin
Name=Show desktop
Comment=Minimize all windows and show the desktop
#TRANSLATIONS_DIR=../translations
# Translations
Comment[ar]=تصغير كافَّة النَّوافذ وإظهار سطح المكتب
Name[ar]=إظهار سطح المكتب
Comment[ar]=تصغّر كلّ النّوافذ وتُظهر سطح المكتب
Name[ar]=أظهر سطح المكتب

@ -0,0 +1,2 @@
Name[ar]=مُباعد
Comment[ar]=مساحة بين الودجات

@ -73,7 +73,6 @@ StatusNotifierButton::StatusNotifierButton(QString service, QString objectPath,
if (!path.path().isEmpty())
{
mMenu = (new MenuImporter{interface->service(), path.path(), this})->menu();
dynamic_cast<QObject &>(*mMenu).setParent(this);
mMenu->setObjectName(QLatin1String("StatusNotifierMenu"));
}
});

@ -0,0 +1,2 @@
Name[ar]=ملحقة لمُخطر الحالة
Comment[ar]=ملحقة لمُخطر الحالة

@ -0,0 +1,2 @@
Name[ar]=إحصائيّات النّظام
Comment[ar]=ملحقة لإحصائيّات النّظام.

@ -1,12 +1,2 @@
[Desktop Entry]
Type=Service
ServiceTypes=LXQtPanel/Plugin
Name=Task manager
Comment=Switch between running applications
#TRANSLATIONS_DIR=../translations
# Translations
Comment[ar]=التبديل بين التطبيقات الجارية
Comment[ar]=بدّل بين التّطبيقات العاملة
Name[ar]=مدير المهامّ

@ -1,12 +1,2 @@
[Desktop Entry]
Type=Service
ServiceTypes=LXQtPanel/Plugin
Name=System tray
Comment=Display applications minimized to the system tray.
#TRANSLATIONS_DIR=../translations
# Translations
Comment[ar]=الوصول إلى التطبيقات المخفيَّة المصغَّرة في دفَّة النّظام
Name[ar]=دفَّة النِّظام
Comment[ar]=تعرض التّطبيقات مصغّرة إلى صينيّة النّظام.
Name[ar]=صينيّة النّظام

@ -0,0 +1,2 @@
Name[ar]=تحكّم بمستوى الصّوت
Comment[ar]=تحكّم بمستوى صوت النّظام وأطلق المازج المفضّل لك.

@ -0,0 +1,2 @@
Name[ar]=ساعة العالم
Comment[ar]=ملحقة لساعة العالم.
Loading…
Cancel
Save