2019-12-21 19:53:02 +03:00
/*
2021-05-27 18:01:00 +03:00
SPDX - FileCopyrightText : 2019 Michail Vourlakos < mvourlakos @ gmail . com >
SPDX - License - Identifier : GPL - 2.0 - or - later
2019-12-21 19:53:02 +03:00
*/
# include "containmentinterface.h"
// local
# include "view.h"
# include "../lattecorona.h"
2020-04-08 15:22:38 +03:00
# include "../layout/genericlayout.h"
2021-12-11 18:39:44 +03:00
# include "../layouts/importer.h"
2020-08-19 17:10:00 +03:00
# include "../layouts/storage.h"
2019-12-21 19:53:02 +03:00
# include "../settings/universalsettings.h"
// Qt
# include <QDebug>
2021-12-11 18:39:44 +03:00
# include <QDir>
2021-05-22 01:00:42 +03:00
# include <QLatin1String>
2019-12-21 19:53:02 +03:00
// Plasma
# include <Plasma/Applet>
# include <Plasma/Containment>
2020-04-08 14:39:12 +03:00
# include <PlasmaQuick/AppletQuickItem>
2019-12-21 19:53:02 +03:00
// KDE
2021-01-22 20:09:12 +03:00
# include <KDesktopFile>
2019-12-21 19:53:02 +03:00
# include <KLocalizedString>
# include <KPluginMetaData>
2021-12-11 18:39:44 +03:00
# include <KDeclarative/ConfigPropertyMap>
2019-12-21 19:53:02 +03:00
namespace Latte {
namespace ViewPart {
ContainmentInterface : : ContainmentInterface ( Latte : : View * parent )
: QObject ( parent ) ,
m_view ( parent )
{
m_corona = qobject_cast < Latte : : Corona * > ( m_view - > corona ( ) ) ;
2020-04-08 15:22:38 +03:00
2020-05-18 18:45:12 +03:00
m_latteTasksModel = new TasksModel ( this ) ;
2020-05-18 19:04:02 +03:00
m_plasmaTasksModel = new TasksModel ( this ) ;
2020-04-16 19:37:40 +03:00
2020-04-08 15:22:38 +03:00
m_appletsExpandedConnectionsTimer . setInterval ( 2000 ) ;
m_appletsExpandedConnectionsTimer . setSingleShot ( true ) ;
2021-12-11 18:39:44 +03:00
m_appletDelayedConfigurationTimer . setInterval ( 1000 ) ;
m_appletDelayedConfigurationTimer . setSingleShot ( true ) ;
connect ( & m_appletDelayedConfigurationTimer , & QTimer : : timeout , this , & ContainmentInterface : : updateAppletDelayedConfiguration ) ;
2020-04-16 19:37:40 +03:00
connect ( & m_appletsExpandedConnectionsTimer , & QTimer : : timeout , this , & ContainmentInterface : : updateAppletsTracking ) ;
2020-04-08 15:22:38 +03:00
connect ( m_view , & View : : containmentChanged
, this , [ & ] ( ) {
if ( m_view - > containment ( ) ) {
2020-08-20 19:58:45 +03:00
connect ( m_view - > containment ( ) , & Plasma : : Containment : : appletAdded , this , & ContainmentInterface : : onAppletAdded ) ;
2020-04-08 15:22:38 +03:00
m_appletsExpandedConnectionsTimer . start ( ) ;
}
} ) ;
2020-05-18 19:14:35 +03:00
connect ( m_latteTasksModel , & TasksModel : : countChanged , this , & ContainmentInterface : : onLatteTasksCountChanged ) ;
connect ( m_plasmaTasksModel , & TasksModel : : countChanged , this , & ContainmentInterface : : onPlasmaTasksCountChanged ) ;
2019-12-21 19:53:02 +03:00
}
ContainmentInterface : : ~ ContainmentInterface ( )
{
}
2020-05-22 13:59:31 +03:00
void ContainmentInterface : : identifyShortcutsHost ( )
2019-12-21 19:53:02 +03:00
{
2020-05-22 13:59:31 +03:00
if ( m_shortcutsHost ) {
2019-12-21 19:53:02 +03:00
return ;
}
if ( QQuickItem * graphicItem = m_view - > containment ( ) - > property ( " _plasma_graphicObject " ) . value < QQuickItem * > ( ) ) {
const auto & childItems = graphicItem - > childItems ( ) ;
for ( QQuickItem * item : childItems ) {
2021-05-22 01:00:42 +03:00
if ( item - > objectName ( ) = = QLatin1String ( " containmentViewLayout " ) ) {
2020-05-22 13:59:31 +03:00
for ( QQuickItem * subitem : item - > childItems ( ) ) {
2021-05-22 01:00:42 +03:00
if ( subitem - > objectName ( ) = = QLatin1String ( " PositionShortcutsAbilityHost " ) ) {
2020-05-22 13:59:31 +03:00
m_shortcutsHost = subitem ;
identifyMethods ( ) ;
return ;
}
}
2019-12-21 19:53:02 +03:00
}
}
}
}
void ContainmentInterface : : identifyMethods ( )
{
2020-05-22 13:59:31 +03:00
int aeIndex = m_shortcutsHost - > metaObject ( ) - > indexOfMethod ( " activateEntryAtIndex(QVariant) " ) ;
int niIndex = m_shortcutsHost - > metaObject ( ) - > indexOfMethod ( " newInstanceForEntryAtIndex(QVariant) " ) ;
int sbIndex = m_shortcutsHost - > metaObject ( ) - > indexOfMethod ( " setShowAppletShortcutBadges(QVariant,QVariant,QVariant,QVariant) " ) ;
int afiIndex = m_shortcutsHost - > metaObject ( ) - > indexOfMethod ( " appletIdForIndex(QVariant) " ) ;
m_activateEntryMethod = m_shortcutsHost - > metaObject ( ) - > method ( aeIndex ) ;
m_appletIdForIndexMethod = m_shortcutsHost - > metaObject ( ) - > method ( afiIndex ) ;
m_newInstanceMethod = m_shortcutsHost - > metaObject ( ) - > method ( niIndex ) ;
m_showShortcutsMethod = m_shortcutsHost - > metaObject ( ) - > method ( sbIndex ) ;
2019-12-21 19:53:02 +03:00
}
2020-01-10 18:58:34 +03:00
bool ContainmentInterface : : applicationLauncherHasGlobalShortcut ( ) const
{
if ( ! containsApplicationLauncher ( ) ) {
return false ;
}
2020-03-14 15:41:07 +03:00
uint launcherAppletId = applicationLauncherId ( ) ;
2020-01-10 18:58:34 +03:00
const auto applets = m_view - > containment ( ) - > applets ( ) ;
for ( auto applet : applets ) {
if ( applet - > id ( ) = = launcherAppletId ) {
return ! applet - > globalShortcut ( ) . isEmpty ( ) ;
}
}
return false ;
}
2019-12-21 20:08:33 +03:00
bool ContainmentInterface : : applicationLauncherInPopup ( ) const
{
if ( ! containsApplicationLauncher ( ) ) {
return false ;
}
2020-03-14 15:41:07 +03:00
uint launcherAppletId = applicationLauncherId ( ) ;
2019-12-21 20:08:33 +03:00
const auto applets = m_view - > containment ( ) - > applets ( ) ;
2021-10-15 01:08:26 +03:00
PlasmaQuick : : AppletQuickItem * appLauncherItem { nullptr } ;
2019-12-21 20:08:33 +03:00
for ( auto applet : applets ) {
if ( applet - > id ( ) = = launcherAppletId ) {
2021-10-15 01:08:26 +03:00
appLauncherItem = applet - > property ( " _plasma_graphicObject " ) . value < PlasmaQuick : : AppletQuickItem * > ( ) ;
2019-12-21 20:08:33 +03:00
}
}
2021-10-15 01:08:26 +03:00
return appLauncherItem & & appletIsExpandable ( appLauncherItem ) ;
2019-12-21 20:08:33 +03:00
}
2019-12-21 19:53:02 +03:00
bool ContainmentInterface : : containsApplicationLauncher ( ) const
{
2020-01-10 18:58:34 +03:00
return ( applicationLauncherId ( ) > = 0 ) ;
2019-12-21 19:53:02 +03:00
}
2020-01-10 18:58:34 +03:00
bool ContainmentInterface : : isCapableToShowShortcutBadges ( )
2019-12-21 19:53:02 +03:00
{
2020-05-22 13:59:31 +03:00
identifyShortcutsHost ( ) ;
2020-01-10 18:58:34 +03:00
2020-05-18 19:17:11 +03:00
if ( ! hasLatteTasks ( ) & & hasPlasmaTasks ( ) ) {
2019-12-21 19:53:02 +03:00
return false ;
}
return m_showShortcutsMethod . isValid ( ) ;
}
2021-01-22 20:09:12 +03:00
bool ContainmentInterface : : isApplication ( const QUrl & url ) const
{
if ( ! url . isValid ( ) | | ! url . isLocalFile ( ) ) {
return false ;
}
const QString & localPath = url . toLocalFile ( ) ;
if ( ! KDesktopFile : : isDesktopFile ( localPath ) ) {
return false ;
}
KDesktopFile desktopFile ( localPath ) ;
return desktopFile . hasApplicationType ( ) ;
}
2019-12-21 19:53:02 +03:00
int ContainmentInterface : : applicationLauncherId ( ) const
{
const auto applets = m_view - > containment ( ) - > applets ( ) ;
2020-01-10 18:58:34 +03:00
auto launcherId { - 1 } ;
2019-12-21 19:53:02 +03:00
for ( auto applet : applets ) {
const auto provides = applet - > kPackage ( ) . metadata ( ) . value ( QStringLiteral ( " X-Plasma-Provides " ) ) ;
if ( provides . contains ( QLatin1String ( " org.kde.plasma.launchermenu " ) ) ) {
2020-01-10 18:58:34 +03:00
if ( ! applet - > globalShortcut ( ) . isEmpty ( ) ) {
return applet - > id ( ) ;
} else if ( launcherId = = - 1 ) {
launcherId = applet - > id ( ) ;
}
2019-12-21 19:53:02 +03:00
}
}
2020-01-10 18:58:34 +03:00
return launcherId ;
2019-12-21 19:53:02 +03:00
}
bool ContainmentInterface : : updateBadgeForLatteTask ( const QString identifier , const QString value )
{
2020-05-18 19:17:11 +03:00
if ( ! hasLatteTasks ( ) ) {
2019-12-21 19:53:02 +03:00
return false ;
}
const auto & applets = m_view - > containment ( ) - > applets ( ) ;
for ( auto * applet : applets ) {
KPluginMetaData meta = applet - > kPackage ( ) . metadata ( ) ;
2021-05-22 01:00:42 +03:00
if ( meta . pluginId ( ) = = QLatin1String ( " org.kde.latte.plasmoid " ) ) {
2019-12-21 19:53:02 +03:00
if ( QQuickItem * appletInterface = applet - > property ( " _plasma_graphicObject " ) . value < QQuickItem * > ( ) ) {
const auto & childItems = appletInterface - > childItems ( ) ;
if ( childItems . isEmpty ( ) ) {
continue ;
}
for ( QQuickItem * item : childItems ) {
if ( auto * metaObject = item - > metaObject ( ) ) {
// not using QMetaObject::invokeMethod to avoid warnings when calling
// this on applets that don't have it or other child items since this
// is pretty much trial and error.
// Also, "var" arguments are treated as QVariant in QMetaObject
int methodIndex = metaObject - > indexOfMethod ( " updateBadge(QVariant,QVariant) " ) ;
if ( methodIndex = = - 1 ) {
continue ;
}
QMetaMethod method = metaObject - > method ( methodIndex ) ;
if ( method . invoke ( item , Q_ARG ( QVariant , identifier ) , Q_ARG ( QVariant , value ) ) ) {
return true ;
}
}
}
}
}
}
return false ;
}
bool ContainmentInterface : : activatePlasmaTask ( const int index )
{
2020-05-18 19:17:11 +03:00
bool containsPlasmaTaskManager { hasPlasmaTasks ( ) & & ! hasLatteTasks ( ) } ;
2019-12-21 19:53:02 +03:00
if ( ! containsPlasmaTaskManager ) {
return false ;
}
const auto & applets = m_view - > containment ( ) - > applets ( ) ;
for ( auto * applet : applets ) {
const auto & provides = KPluginMetaData : : readStringList ( applet - > pluginMetaData ( ) . rawData ( ) , QStringLiteral ( " X-Plasma-Provides " ) ) ;
if ( provides . contains ( QLatin1String ( " org.kde.plasma.multitasking " ) ) ) {
if ( QQuickItem * appletInterface = applet - > property ( " _plasma_graphicObject " ) . value < QQuickItem * > ( ) ) {
const auto & childItems = appletInterface - > childItems ( ) ;
if ( childItems . isEmpty ( ) ) {
continue ;
}
KPluginMetaData meta = applet - > kPackage ( ) . metadata ( ) ;
for ( QQuickItem * item : childItems ) {
if ( auto * metaObject = item - > metaObject ( ) ) {
int methodIndex { metaObject - > indexOfMethod ( " activateTaskAtIndex(QVariant) " ) } ;
if ( methodIndex = = - 1 ) {
continue ;
}
QMetaMethod method = metaObject - > method ( methodIndex ) ;
if ( method . invoke ( item , Q_ARG ( QVariant , index - 1 ) ) ) {
showShortcutBadges ( false , true ) ;
return true ;
}
}
}
}
}
}
return false ;
}
bool ContainmentInterface : : newInstanceForPlasmaTask ( const int index )
{
2020-05-18 19:17:11 +03:00
bool containsPlasmaTaskManager { hasPlasmaTasks ( ) & & ! hasLatteTasks ( ) } ;
2019-12-21 19:53:02 +03:00
if ( ! containsPlasmaTaskManager ) {
return false ;
}
const auto & applets = m_view - > containment ( ) - > applets ( ) ;
for ( auto * applet : applets ) {
const auto & provides = KPluginMetaData : : readStringList ( applet - > pluginMetaData ( ) . rawData ( ) , QStringLiteral ( " X-Plasma-Provides " ) ) ;
if ( provides . contains ( QLatin1String ( " org.kde.plasma.multitasking " ) ) ) {
if ( QQuickItem * appletInterface = applet - > property ( " _plasma_graphicObject " ) . value < QQuickItem * > ( ) ) {
const auto & childItems = appletInterface - > childItems ( ) ;
if ( childItems . isEmpty ( ) ) {
continue ;
}
KPluginMetaData meta = applet - > kPackage ( ) . metadata ( ) ;
for ( QQuickItem * item : childItems ) {
if ( auto * metaObject = item - > metaObject ( ) ) {
2020-05-22 19:11:10 +03:00
int methodIndex { metaObject - > indexOfMethod ( " newInstanceForTaskAtIndex(QVariant) " ) } ;
2019-12-21 19:53:02 +03:00
if ( methodIndex = = - 1 ) {
continue ;
}
QMetaMethod method = metaObject - > method ( methodIndex ) ;
if ( method . invoke ( item , Q_ARG ( QVariant , index - 1 ) ) ) {
showShortcutBadges ( false , true ) ;
return true ;
}
}
}
}
}
}
return false ;
}
bool ContainmentInterface : : activateEntry ( const int index )
{
2020-05-22 13:59:31 +03:00
identifyShortcutsHost ( ) ;
2019-12-21 19:53:02 +03:00
if ( ! m_activateEntryMethod . isValid ( ) ) {
return false ;
}
2020-05-22 13:59:31 +03:00
return m_activateEntryMethod . invoke ( m_shortcutsHost , Q_ARG ( QVariant , index ) ) ;
2019-12-21 19:53:02 +03:00
}
bool ContainmentInterface : : newInstanceForEntry ( const int index )
{
2020-05-22 13:59:31 +03:00
identifyShortcutsHost ( ) ;
2019-12-21 19:53:02 +03:00
if ( ! m_newInstanceMethod . isValid ( ) ) {
return false ;
}
2020-05-22 13:59:31 +03:00
return m_newInstanceMethod . invoke ( m_shortcutsHost , Q_ARG ( QVariant , index ) ) ;
2019-12-21 19:53:02 +03:00
}
bool ContainmentInterface : : hideShortcutBadges ( )
{
2020-05-22 13:59:31 +03:00
identifyShortcutsHost ( ) ;
2019-12-21 19:53:02 +03:00
if ( ! m_showShortcutsMethod . isValid ( ) ) {
return false ;
}
2020-05-22 13:59:31 +03:00
return m_showShortcutsMethod . invoke ( m_shortcutsHost , Q_ARG ( QVariant , false ) , Q_ARG ( QVariant , false ) , Q_ARG ( QVariant , false ) , Q_ARG ( QVariant , - 1 ) ) ;
2019-12-21 19:53:02 +03:00
}
bool ContainmentInterface : : showOnlyMeta ( )
{
if ( ! m_corona - > universalSettings ( ) - > kwin_metaForwardedToLatte ( ) ) {
return false ;
}
return showShortcutBadges ( false , true ) ;
}
bool ContainmentInterface : : showShortcutBadges ( const bool showLatteShortcuts , const bool showMeta )
{
2020-05-22 13:59:31 +03:00
identifyShortcutsHost ( ) ;
2019-12-21 19:53:02 +03:00
2020-04-21 01:45:07 +03:00
if ( ! m_showShortcutsMethod . isValid ( ) | | ! isCapableToShowShortcutBadges ( ) ) {
2019-12-21 19:53:02 +03:00
return false ;
}
int appLauncherId = m_corona - > universalSettings ( ) - > kwin_metaForwardedToLatte ( ) & & showMeta ? applicationLauncherId ( ) : - 1 ;
2020-05-22 13:59:31 +03:00
return m_showShortcutsMethod . invoke ( m_shortcutsHost , Q_ARG ( QVariant , showLatteShortcuts ) , Q_ARG ( QVariant , true ) , Q_ARG ( QVariant , showMeta ) , Q_ARG ( QVariant , appLauncherId ) ) ;
2019-12-21 19:53:02 +03:00
}
2020-05-19 18:41:49 +03:00
int ContainmentInterface : : appletIdForVisualIndex ( const int index )
2019-12-21 20:08:33 +03:00
{
2020-05-22 13:59:31 +03:00
identifyShortcutsHost ( ) ;
2019-12-21 20:08:33 +03:00
if ( ! m_appletIdForIndexMethod . isValid ( ) ) {
2021-05-13 20:09:05 +03:00
return - 1 ;
2019-12-21 20:08:33 +03:00
}
QVariant appletId { - 1 } ;
2020-05-22 13:59:31 +03:00
m_appletIdForIndexMethod . invoke ( m_shortcutsHost , Q_RETURN_ARG ( QVariant , appletId ) , Q_ARG ( QVariant , index ) ) ;
2019-12-21 20:08:33 +03:00
return appletId . toInt ( ) ;
}
2020-04-08 14:39:12 +03:00
void ContainmentInterface : : deactivateApplets ( )
{
2020-05-08 10:16:26 +03:00
if ( ! m_view - > containment ( ) | | ! m_view - > inReadyState ( ) ) {
2020-04-08 14:39:12 +03:00
return ;
}
for ( const auto applet : m_view - > containment ( ) - > applets ( ) ) {
PlasmaQuick : : AppletQuickItem * ai = applet - > property ( " _plasma_graphicObject " ) . value < PlasmaQuick : : AppletQuickItem * > ( ) ;
if ( ai ) {
ai - > setExpanded ( false ) ;
}
}
}
2021-10-15 01:08:26 +03:00
bool ContainmentInterface : : appletIsExpandable ( const int id ) const
2020-04-08 15:22:38 +03:00
{
2020-05-08 10:16:26 +03:00
if ( ! m_view - > containment ( ) | | ! m_view - > inReadyState ( ) ) {
2020-04-08 15:22:38 +03:00
return false ;
}
for ( const auto applet : m_view - > containment ( ) - > applets ( ) ) {
2020-05-08 10:16:26 +03:00
if ( applet & & applet - > id ( ) = = ( uint ) id ) {
2021-12-11 18:39:44 +03:00
if ( Layouts : : Storage : : self ( ) - > isSubContainment ( m_view - > corona ( ) , applet ) ) {
2020-04-08 15:22:38 +03:00
return true ;
}
PlasmaQuick : : AppletQuickItem * ai = applet - > property ( " _plasma_graphicObject " ) . value < PlasmaQuick : : AppletQuickItem * > ( ) ;
if ( ai ) {
2020-04-19 02:24:56 +03:00
return appletIsExpandable ( ai ) ;
2020-04-08 15:22:38 +03:00
}
}
}
return false ;
}
2021-10-15 01:08:26 +03:00
bool ContainmentInterface : : appletIsExpandable ( PlasmaQuick : : AppletQuickItem * appletQuickItem ) const
2020-04-19 02:24:56 +03:00
{
2020-05-08 10:16:26 +03:00
if ( ! appletQuickItem | | ! m_view - > inReadyState ( ) ) {
2020-04-19 02:24:56 +03:00
return false ;
}
2021-05-08 19:21:24 +03:00
return ( ( appletQuickItem - > fullRepresentation ( ) ! = nullptr
& & appletQuickItem - > preferredRepresentation ( ) ! = appletQuickItem - > fullRepresentation ( ) )
2021-12-11 18:39:44 +03:00
| | Latte : : Layouts : : Storage : : self ( ) - > isSubContainment ( m_view - > corona ( ) , appletQuickItem - > applet ( ) ) ) ;
2020-04-19 02:24:56 +03:00
}
2021-10-15 01:38:24 +03:00
bool ContainmentInterface : : appletIsActivationTogglesExpanded ( const int id ) const
{
if ( ! m_view - > containment ( ) | | ! m_view - > inReadyState ( ) ) {
return false ;
}
for ( const auto applet : m_view - > containment ( ) - > applets ( ) ) {
if ( applet & & applet - > id ( ) = = ( uint ) id ) {
2021-12-11 18:39:44 +03:00
if ( Layouts : : Storage : : self ( ) - > isSubContainment ( m_view - > corona ( ) , applet ) ) {
2021-10-15 01:38:24 +03:00
return true ;
}
PlasmaQuick : : AppletQuickItem * ai = applet - > property ( " _plasma_graphicObject " ) . value < PlasmaQuick : : AppletQuickItem * > ( ) ;
if ( ai ) {
return ai - > isActivationTogglesExpanded ( ) ;
}
}
}
return false ;
}
2020-04-08 15:22:38 +03:00
bool ContainmentInterface : : hasExpandedApplet ( ) const
{
return m_expandedAppletIds . count ( ) > 0 ;
}
2020-05-18 19:14:35 +03:00
bool ContainmentInterface : : hasLatteTasks ( ) const
{
return ( m_latteTasksModel - > count ( ) > 0 ) ;
}
bool ContainmentInterface : : hasPlasmaTasks ( ) const
{
return ( m_plasmaTasksModel - > count ( ) > 0 ) ;
}
2021-12-11 18:39:44 +03:00
int ContainmentInterface : : indexOfApplet ( const int & id )
{
if ( m_appletOrder . contains ( id ) ) {
return m_appletOrder . indexOf ( id ) ;
} else if ( m_appletData . contains ( id ) ) {
return m_appletData [ id ] . lastValidIndex ;
}
return - 1 ;
}
ViewPart : : AppletInterfaceData ContainmentInterface : : appletDataAtIndex ( const int & index )
{
ViewPart : : AppletInterfaceData data ;
if ( index < 0 | | ( index > ( m_appletOrder . count ( ) - 1 ) ) ) {
return data ;
}
return m_appletData [ m_appletOrder [ index ] ] ;
}
ViewPart : : AppletInterfaceData ContainmentInterface : : appletDataForId ( const int & id )
{
ViewPart : : AppletInterfaceData data ;
if ( ! m_appletData . contains ( id ) ) {
return data ;
}
return m_appletData [ id ] ;
}
QObject * ContainmentInterface : : plasmoid ( ) const
{
return m_plasmoid ;
}
void ContainmentInterface : : setPlasmoid ( QObject * plasmoid )
{
if ( m_plasmoid = = plasmoid ) {
return ;
}
m_plasmoid = plasmoid ;
if ( m_plasmoid ) {
m_configuration = qobject_cast < KDeclarative : : ConfigPropertyMap * > ( m_plasmoid - > property ( " configuration " ) . value < QObject * > ( ) ) ;
if ( m_configuration ) {
connect ( m_configuration , & QQmlPropertyMap : : valueChanged , this , & ContainmentInterface : : containmentConfigPropertyChanged ) ;
}
}
emit plasmoidChanged ( ) ;
}
QObject * ContainmentInterface : : layoutManager ( ) const
{
return m_layoutManager ;
}
void ContainmentInterface : : setLayoutManager ( QObject * manager )
{
if ( m_layoutManager = = manager ) {
return ;
}
m_layoutManager = manager ;
// applets order
int metaorderindex = m_layoutManager - > metaObject ( ) - > indexOfProperty ( " order " ) ;
if ( metaorderindex > = 0 ) {
QMetaProperty metaorder = m_layoutManager - > metaObject ( ) - > property ( metaorderindex ) ;
if ( metaorder . hasNotifySignal ( ) ) {
QMetaMethod metaorderchanged = metaorder . notifySignal ( ) ;
QMetaMethod metaupdateappletorder = this - > metaObject ( ) - > method ( this - > metaObject ( ) - > indexOfSlot ( " updateAppletsOrder() " ) ) ;
connect ( m_layoutManager , metaorderchanged , this , metaupdateappletorder ) ;
updateAppletsOrder ( ) ;
}
}
// applets in locked zoom
metaorderindex = m_layoutManager - > metaObject ( ) - > indexOfProperty ( " lockedZoomApplets " ) ;
if ( metaorderindex > = 0 ) {
QMetaProperty metaorder = m_layoutManager - > metaObject ( ) - > property ( metaorderindex ) ;
if ( metaorder . hasNotifySignal ( ) ) {
QMetaMethod metaorderchanged = metaorder . notifySignal ( ) ;
QMetaMethod metaupdateapplets = this - > metaObject ( ) - > method ( this - > metaObject ( ) - > indexOfSlot ( " updateAppletsInLockedZoom() " ) ) ;
connect ( m_layoutManager , metaorderchanged , this , metaupdateapplets ) ;
updateAppletsInLockedZoom ( ) ;
}
}
// applets disabled their autocoloring
metaorderindex = m_layoutManager - > metaObject ( ) - > indexOfProperty ( " userBlocksColorizingApplets " ) ;
if ( metaorderindex > = 0 ) {
QMetaProperty metaorder = m_layoutManager - > metaObject ( ) - > property ( metaorderindex ) ;
if ( metaorder . hasNotifySignal ( ) ) {
QMetaMethod metaorderchanged = metaorder . notifySignal ( ) ;
QMetaMethod metaupdateapplets = this - > metaObject ( ) - > method ( this - > metaObject ( ) - > indexOfSlot ( " updateAppletsDisabledColoring() " ) ) ;
connect ( m_layoutManager , metaorderchanged , this , metaupdateapplets ) ;
updateAppletsDisabledColoring ( ) ;
}
}
emit layoutManagerChanged ( ) ;
}
void ContainmentInterface : : addApplet ( const QString & pluginId )
{
if ( pluginId . isEmpty ( ) ) {
return ;
}
QStringList paths = Latte : : Layouts : : Importer : : standardPaths ( ) ;
QString pluginpath ;
for ( int i = 0 ; i < paths . count ( ) ; + + i ) {
QString cpath = paths [ i ] + " /plasma/plasmoids/ " + pluginId ;
if ( QDir ( cpath ) . exists ( ) ) {
pluginpath = cpath ;
break ;
}
}
if ( ! pluginpath . isEmpty ( ) ) {
m_view - > containment ( ) - > createApplet ( pluginId ) ;
}
}
void ContainmentInterface : : addApplet ( QObject * metadata , int x , int y )
{
int processmimedataindex = m_plasmoid - > metaObject ( ) - > indexOfMethod ( " processMimeData(QObject*,int,int) " ) ;
QMetaMethod processmethod = m_plasmoid - > metaObject ( ) - > method ( processmimedataindex ) ;
processmethod . invoke ( m_plasmoid ,
Q_ARG ( QObject * , metadata ) ,
Q_ARG ( int , x ) ,
Q_ARG ( int , y ) ) ;
}
2020-08-01 20:40:23 +03:00
void ContainmentInterface : : addExpandedApplet ( PlasmaQuick : : AppletQuickItem * appletQuickItem )
2020-04-08 15:22:38 +03:00
{
2020-08-01 20:40:23 +03:00
if ( appletQuickItem & & m_expandedAppletIds . contains ( appletQuickItem ) & & appletIsExpandable ( appletQuickItem ) ) {
2020-04-08 15:22:38 +03:00
return ;
}
bool isExpanded = hasExpandedApplet ( ) ;
2020-08-01 20:40:23 +03:00
m_expandedAppletIds [ appletQuickItem ] = appletQuickItem - > applet ( ) - > id ( ) ;
2020-04-08 15:22:38 +03:00
if ( isExpanded ! = hasExpandedApplet ( ) ) {
emit hasExpandedAppletChanged ( ) ;
}
emit expandedAppletStateChanged ( ) ;
}
2020-08-01 20:40:23 +03:00
void ContainmentInterface : : removeExpandedApplet ( PlasmaQuick : : AppletQuickItem * appletQuickItem )
2020-04-08 15:22:38 +03:00
{
2020-08-01 20:40:23 +03:00
if ( ! m_expandedAppletIds . contains ( appletQuickItem ) ) {
2020-04-08 15:22:38 +03:00
return ;
}
bool isExpanded = hasExpandedApplet ( ) ;
2020-08-01 20:40:23 +03:00
m_expandedAppletIds . remove ( appletQuickItem ) ;
2020-04-08 15:22:38 +03:00
if ( isExpanded ! = hasExpandedApplet ( ) ) {
emit hasExpandedAppletChanged ( ) ;
}
emit expandedAppletStateChanged ( ) ;
}
2020-05-18 18:45:12 +03:00
QAbstractListModel * ContainmentInterface : : latteTasksModel ( ) const
2020-04-16 19:37:40 +03:00
{
2020-05-18 18:45:12 +03:00
return m_latteTasksModel ;
2020-04-16 19:37:40 +03:00
}
2020-05-18 19:04:02 +03:00
QAbstractListModel * ContainmentInterface : : plasmaTasksModel ( ) const
{
return m_plasmaTasksModel ;
}
2020-08-20 19:58:45 +03:00
void ContainmentInterface : : onAppletExpandedChanged ( )
2020-04-08 15:22:38 +03:00
{
PlasmaQuick : : AppletQuickItem * appletItem = static_cast < PlasmaQuick : : AppletQuickItem * > ( QObject : : sender ( ) ) ;
if ( appletItem ) {
2021-02-06 13:32:54 +03:00
bool added { false } ;
2020-04-08 15:22:38 +03:00
if ( appletItem - > isExpanded ( ) ) {
2021-02-06 13:32:54 +03:00
if ( appletItem - > switchWidth ( ) > 0 & & appletItem - > switchHeight ( ) > 0 ) {
added = ( ( appletItem - > width ( ) < = appletItem - > switchWidth ( ) )
& & ( appletItem - > height ( ) < = appletItem - > switchHeight ( ) ) ) ;
} else {
added = true ;
}
}
2021-05-08 14:48:10 +03:00
if ( added & & appletIsExpandable ( appletItem ) ) {
2020-08-01 20:40:23 +03:00
addExpandedApplet ( appletItem ) ;
2020-04-08 15:22:38 +03:00
} else {
2020-08-01 20:40:23 +03:00
removeExpandedApplet ( appletItem ) ;
2020-04-08 15:22:38 +03:00
}
}
}
2021-12-11 18:39:44 +03:00
QList < int > ContainmentInterface : : appletsOrder ( ) const
{
return m_appletOrder ;
}
void ContainmentInterface : : updateAppletsOrder ( )
{
if ( ! m_layoutManager ) {
return ;
}
QList < int > neworder = m_layoutManager - > property ( " order " ) . value < QList < int > > ( ) ;
if ( m_appletOrder = = neworder ) {
return ;
}
m_appletOrder = neworder ;
//! update applets last recorded index, this is needed for example when an applet is removed
//! to know in which index was located before the removal
for ( const auto & id : m_appletOrder ) {
if ( m_appletData . contains ( id ) ) {
m_appletData [ id ] . lastValidIndex = m_appletOrder . indexOf ( id ) ;
}
}
emit appletsOrderChanged ( ) ;
}
void ContainmentInterface : : updateAppletsInLockedZoom ( )
{
if ( ! m_layoutManager ) {
return ;
}
QList < int > appletslockedzoom = m_layoutManager - > property ( " lockedZoomApplets " ) . value < QList < int > > ( ) ;
if ( m_appletsInLockedZoom = = appletslockedzoom ) {
return ;
}
m_appletsInLockedZoom = appletslockedzoom ;
emit appletsInLockedZoomChanged ( m_appletsInLockedZoom ) ;
}
void ContainmentInterface : : updateAppletsDisabledColoring ( )
{
if ( ! m_layoutManager ) {
return ;
}
QList < int > appletsdisabledcoloring = m_layoutManager - > property ( " userBlocksColorizingApplets " ) . value < QList < int > > ( ) ;
if ( m_appletsDisabledColoring = = appletsdisabledcoloring ) {
return ;
}
m_appletsDisabledColoring = appletsdisabledcoloring ;
emit appletsDisabledColoringChanged ( appletsdisabledcoloring ) ;
}
2020-05-18 19:14:35 +03:00
void ContainmentInterface : : onLatteTasksCountChanged ( )
{
if ( ( m_hasLatteTasks & & m_latteTasksModel - > count ( ) > 0 )
| | ( ! m_hasLatteTasks & & m_latteTasksModel - > count ( ) = = 0 ) ) {
return ;
}
m_hasLatteTasks = ( m_latteTasksModel - > count ( ) > 0 ) ;
emit hasLatteTasksChanged ( ) ;
}
void ContainmentInterface : : onPlasmaTasksCountChanged ( )
{
if ( ( m_hasPlasmaTasks & & m_plasmaTasksModel - > count ( ) > 0 )
| | ( ! m_hasPlasmaTasks & & m_plasmaTasksModel - > count ( ) = = 0 ) ) {
return ;
}
m_hasPlasmaTasks = ( m_plasmaTasksModel - > count ( ) > 0 ) ;
emit hasPlasmaTasksChanged ( ) ;
}
2021-10-15 01:08:26 +03:00
bool ContainmentInterface : : appletIsExpanded ( const int id ) const
2020-04-08 15:22:38 +03:00
{
2020-08-01 20:40:23 +03:00
return m_expandedAppletIds . values ( ) . contains ( id ) ;
2020-04-08 15:22:38 +03:00
}
void ContainmentInterface : : toggleAppletExpanded ( const int id )
{
2020-05-08 10:16:26 +03:00
if ( ! m_view - > containment ( ) | | ! m_view - > inReadyState ( ) ) {
2020-04-08 15:22:38 +03:00
return ;
}
for ( const auto applet : m_view - > containment ( ) - > applets ( ) ) {
2021-12-11 18:39:44 +03:00
if ( applet - > id ( ) = = ( uint ) id & & ! Layouts : : Storage : : self ( ) - > isSubContainment ( m_view - > corona ( ) , applet ) /*block for sub-containments*/ ) {
2020-04-08 15:22:38 +03:00
PlasmaQuick : : AppletQuickItem * ai = applet - > property ( " _plasma_graphicObject " ) . value < PlasmaQuick : : AppletQuickItem * > ( ) ;
if ( ai ) {
2021-05-08 14:48:10 +03:00
emit applet - > activated ( ) ;
2020-04-08 15:22:38 +03:00
}
}
}
}
2021-12-11 18:39:44 +03:00
void ContainmentInterface : : removeApplet ( const int & id )
{
if ( ! m_appletData . contains ( id ) ) {
return ;
}
auto applet = m_appletData [ id ] . applet ;
emit applet - > appletDeleted ( applet ) ; //! this signal should be part of Plasma Frameworks AppletPrivate::destroy() function...
applet - > destroy ( ) ;
}
void ContainmentInterface : : setAppletsOrder ( const QList < int > & order )
{
QMetaObject : : invokeMethod ( m_layoutManager ,
" requestAppletsOrder " ,
Qt : : DirectConnection ,
Q_ARG ( QList < int > , order ) ) ;
}
void ContainmentInterface : : setAppletsInLockedZoom ( const QList < int > & applets )
{
QMetaObject : : invokeMethod ( m_layoutManager ,
" requestAppletsInLockedZoom " ,
Qt : : DirectConnection ,
Q_ARG ( QList < int > , applets ) ) ;
}
void ContainmentInterface : : setAppletsDisabledColoring ( const QList < int > & applets )
{
QMetaObject : : invokeMethod ( m_layoutManager ,
" requestAppletsDisabledColoring " ,
Qt : : DirectConnection ,
Q_ARG ( QList < int > , applets ) ) ;
}
void ContainmentInterface : : setAppletInScheduledDestruction ( const int & id , const bool & enabled )
{
QMetaObject : : invokeMethod ( m_layoutManager ,
" setAppletInScheduledDestruction " ,
Qt : : DirectConnection ,
Q_ARG ( int , id ) ,
Q_ARG ( bool , enabled ) ) ;
}
void ContainmentInterface : : updateContainmentConfigProperty ( const QString & key , const QVariant & value )
{
if ( ! m_configuration | | ! m_configuration - > keys ( ) . contains ( key ) ) {
}
if ( m_configuration - > keys ( ) . contains ( key )
& & ( * m_configuration ) [ key ] ! = value ) {
m_configuration - > insert ( key , value ) ;
emit m_configuration - > valueChanged ( key , value ) ;
}
}
void ContainmentInterface : : updateAppletConfigProperty ( const int & id , const QString & key , const QVariant & value )
{
if ( ! m_appletData . contains ( id ) | | ! m_appletData [ id ] . configuration | | ! m_appletData [ id ] . configuration - > keys ( ) . contains ( key ) ) {
return ;
}
if ( m_appletData [ id ] . configuration - > keys ( ) . contains ( key )
& & ( * m_appletData [ id ] . configuration ) [ key ] ! = value ) {
m_appletData [ id ] . configuration - > insert ( key , value ) ;
emit m_appletData [ id ] . configuration - > valueChanged ( key , value ) ;
}
}
2020-04-16 19:37:40 +03:00
void ContainmentInterface : : updateAppletsTracking ( )
2020-04-08 15:22:38 +03:00
{
if ( ! m_view - > containment ( ) ) {
return ;
}
for ( const auto applet : m_view - > containment ( ) - > applets ( ) ) {
2020-08-20 19:58:45 +03:00
onAppletAdded ( applet ) ;
2020-05-18 19:04:02 +03:00
}
2021-12-11 18:39:44 +03:00
emit initializationCompleted ( ) ;
}
void ContainmentInterface : : updateAppletDelayedConfiguration ( )
{
for ( const auto id : m_appletData . keys ( ) ) {
if ( ! m_appletData [ id ] . configuration ) {
m_appletData [ id ] . configuration = appletConfiguration ( m_appletData [ id ] . applet ) ;
if ( m_appletData [ id ] . configuration ) {
qDebug ( ) < < " org.kde.sync delayed applet configuration was successful for : " < < id ;
initAppletConfigurationSignals ( id , m_appletData [ id ] . configuration ) ;
}
}
}
}
void ContainmentInterface : : initAppletConfigurationSignals ( const int & id , KDeclarative : : ConfigPropertyMap * configuration )
{
if ( ! configuration ) {
return ;
}
connect ( configuration , & QQmlPropertyMap : : valueChanged ,
this , [ & , id ] ( const QString & key , const QVariant & value ) {
//qDebug() << "org.kde.sync applet property changed : " << currentAppletId << " __ " << m_appletData[currentAppletId].plugin << " __ " << key << " __ " << value;
emit appletConfigPropertyChanged ( id , key , value ) ;
} ) ;
}
KDeclarative : : ConfigPropertyMap * ContainmentInterface : : appletConfiguration ( const Plasma : : Applet * applet )
{
if ( ! m_view - > containment ( ) | | ! applet ) {
return nullptr ;
}
PlasmaQuick : : AppletQuickItem * ai = applet - > property ( " _plasma_graphicObject " ) . value < PlasmaQuick : : AppletQuickItem * > ( ) ;
bool isSubContainment = Layouts : : Storage : : self ( ) - > isSubContainment ( m_view - > corona ( ) , applet ) ; //we use corona() to make sure that returns true even when it is first created from user
int currentAppletId = applet - > id ( ) ;
KDeclarative : : ConfigPropertyMap * configuration { nullptr } ;
//! set configuration object properly for applets and subcontainments
if ( ! isSubContainment ) {
int metaconfigindex = ai - > metaObject ( ) - > indexOfProperty ( " configuration " ) ;
if ( metaconfigindex > = 0 ) {
configuration = qobject_cast < KDeclarative : : ConfigPropertyMap * > ( ( ai - > property ( " configuration " ) ) . value < QObject * > ( ) ) ;
}
} else {
Plasma : : Containment * subcontainment = Layouts : : Storage : : self ( ) - > subContainmentOf ( m_view - > corona ( ) , applet ) ;
if ( subcontainment ) {
PlasmaQuick : : AppletQuickItem * subcai = subcontainment - > property ( " _plasma_graphicObject " ) . value < PlasmaQuick : : AppletQuickItem * > ( ) ;
if ( subcai ) {
int metaconfigindex = subcai - > metaObject ( ) - > indexOfProperty ( " configuration " ) ;
if ( metaconfigindex > = 0 ) {
configuration = qobject_cast < KDeclarative : : ConfigPropertyMap * > ( ( subcai - > property ( " configuration " ) ) . value < QObject * > ( ) ) ;
}
}
}
}
return configuration ;
2020-05-18 19:04:02 +03:00
}
2020-04-08 15:22:38 +03:00
2020-08-20 19:58:45 +03:00
void ContainmentInterface : : onAppletAdded ( Plasma : : Applet * applet )
2020-05-18 19:04:02 +03:00
{
if ( ! m_view - > containment ( ) | | ! applet ) {
return ;
}
2020-04-08 15:22:38 +03:00
2021-12-11 18:39:44 +03:00
PlasmaQuick : : AppletQuickItem * ai = applet - > property ( " _plasma_graphicObject " ) . value < PlasmaQuick : : AppletQuickItem * > ( ) ;
bool isSubContainment = Layouts : : Storage : : self ( ) - > isSubContainment ( m_view - > corona ( ) , applet ) ; //we use corona() to make sure that returns true even when it is first created from user
int currentAppletId = applet - > id ( ) ;
//! Track expanded/able applets and Tasks applets
if ( isSubContainment ) {
2020-05-18 19:04:02 +03:00
//! internal containment case
2021-12-11 18:39:44 +03:00
Plasma : : Containment * subContainment = Layouts : : Storage : : self ( ) - > subContainmentOf ( m_view - > corona ( ) , applet ) ;
PlasmaQuick : : AppletQuickItem * contAi = ai ;
2020-04-08 15:22:38 +03:00
2020-05-18 19:04:02 +03:00
if ( contAi & & ! m_appletsExpandedConnections . contains ( contAi ) ) {
2020-08-20 19:58:45 +03:00
m_appletsExpandedConnections [ contAi ] = connect ( contAi , & PlasmaQuick : : AppletQuickItem : : expandedChanged , this , & ContainmentInterface : : onAppletExpandedChanged ) ;
2020-04-08 15:22:38 +03:00
2020-05-18 19:04:02 +03:00
connect ( contAi , & QObject : : destroyed , this , [ & , contAi ] ( ) {
m_appletsExpandedConnections . remove ( contAi ) ;
2020-08-01 20:40:23 +03:00
removeExpandedApplet ( contAi ) ;
2020-05-18 19:04:02 +03:00
} ) ;
}
2020-04-17 17:05:35 +03:00
2020-08-02 01:22:25 +03:00
for ( const auto internalApplet : subContainment - > applets ( ) ) {
2020-05-18 19:04:02 +03:00
PlasmaQuick : : AppletQuickItem * ai = internalApplet - > property ( " _plasma_graphicObject " ) . value < PlasmaQuick : : AppletQuickItem * > ( ) ;
2020-04-08 15:22:38 +03:00
2020-05-18 19:04:02 +03:00
if ( ai & & ! m_appletsExpandedConnections . contains ( ai ) ) {
2020-08-20 19:58:45 +03:00
m_appletsExpandedConnections [ ai ] = connect ( ai , & PlasmaQuick : : AppletQuickItem : : expandedChanged , this , & ContainmentInterface : : onAppletExpandedChanged ) ;
2020-04-08 15:22:38 +03:00
connect ( ai , & QObject : : destroyed , this , [ & , ai ] ( ) {
m_appletsExpandedConnections . remove ( ai ) ;
2020-08-01 20:40:23 +03:00
removeExpandedApplet ( ai ) ;
2020-04-08 15:22:38 +03:00
} ) ;
}
}
2021-12-11 18:39:44 +03:00
} else if ( ai ) {
2020-05-18 19:04:02 +03:00
KPluginMetaData meta = applet - > kPackage ( ) . metadata ( ) ;
const auto & provides = KPluginMetaData : : readStringList ( meta . rawData ( ) , QStringLiteral ( " X-Plasma-Provides " ) ) ;
2021-05-22 01:00:42 +03:00
if ( meta . pluginId ( ) = = QLatin1String ( " org.kde.latte.plasmoid " ) ) {
2020-05-18 19:04:02 +03:00
//! populate latte tasks applet
m_latteTasksModel - > addTask ( ai ) ;
} else if ( provides . contains ( QLatin1String ( " org.kde.plasma.multitasking " ) ) ) {
//! populate plasma tasks applet
m_plasmaTasksModel - > addTask ( ai ) ;
} else if ( ! m_appletsExpandedConnections . contains ( ai ) ) {
2020-08-20 19:58:45 +03:00
m_appletsExpandedConnections [ ai ] = connect ( ai , & PlasmaQuick : : AppletQuickItem : : expandedChanged , this , & ContainmentInterface : : onAppletExpandedChanged ) ;
2020-05-18 19:04:02 +03:00
connect ( ai , & QObject : : destroyed , this , [ & , ai ] ( ) {
m_appletsExpandedConnections . remove ( ai ) ;
2020-08-01 20:40:23 +03:00
removeExpandedApplet ( ai ) ;
2020-05-18 19:04:02 +03:00
} ) ;
}
2020-04-08 15:22:38 +03:00
}
2020-05-18 19:04:02 +03:00
2021-12-11 18:39:44 +03:00
//! Track All Applets, for example to support syncing between different docks and panels
if ( ai ) {
bool initializing { ! m_appletData . contains ( currentAppletId ) } ;
KPluginMetaData meta = applet - > kPackage ( ) . metadata ( ) ;
ViewPart : : AppletInterfaceData data ;
data . id = currentAppletId ;
data . plugin = meta . pluginId ( ) ;
data . applet = applet ;
data . plasmoid = ai ;
data . lastValidIndex = m_appletOrder . indexOf ( data . id ) ;
//! set configuration object properly for applets and subcontainments
data . configuration = appletConfiguration ( applet ) ;
//! track property changes in applets
if ( data . configuration ) {
initAppletConfigurationSignals ( data . id , data . configuration ) ;
} else {
qDebug ( ) < < " org.kde.sync Unfortunately configuration syncing for :: " < < currentAppletId < < " was not established, configuration object was missing! " ;
m_appletDelayedConfigurationTimer . start ( ) ;
}
if ( initializing ) {
//! track applet destroyed flag
connect ( applet , & Plasma : : Applet : : destroyedChanged , this , [ & , currentAppletId ] ( bool destroyed ) {
emit appletInScheduledDestructionChanged ( currentAppletId , destroyed ) ;
} ) ;
//! remove on applet destruction
connect ( applet , & QObject : : destroyed , this , [ & , data ] ( ) {
emit appletRemoved ( data . id ) ;
//qDebug() << "org.kde.sync: removing applet ::: " << data.id << " __ " << data.plugin << " remained : " << m_appletData.keys();
m_appletData . remove ( data . id ) ;
} ) ;
}
m_appletData [ data . id ] = data ;
emit appletDataCreated ( data . id ) ;
}
}
QList < int > ContainmentInterface : : toIntList ( const QVariantList & list )
{
QList < int > converted ;
for ( const QVariant & item : list ) {
converted < < item . toInt ( ) ;
}
return converted ;
2020-04-08 15:22:38 +03:00
}
2019-12-21 19:53:02 +03:00
}
}