2013-06-19 15:15:25 +01:00
/**
* Copyright 2013 Albert Vaca < albertvaka @ gmail . com >
*
* This program is free software ; you can redistribute it and / or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation ; either version 2 of
* the License or ( at your option ) version 3 or any later version
* accepted by the membership of KDE e . V . ( or its successor approved
* by the membership of KDE e . V . ) , which shall act as a proxy
* defined in Section 14 of version 3 of the license .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program . If not , see < http : //www.gnu.org/licenses/>.
*/
# include "kcm.h"
2014-06-16 19:02:07 +01:00
# include <QLabel>
# include <QMenu>
# include <QMenuBar>
# include <QAction>
# include <QStackedLayout>
# include <QListView>
2013-06-25 17:08:34 +01:00
# include <QDBusConnection>
# include <QDBusInterface>
2013-08-15 23:25:13 +01:00
2013-08-13 04:07:32 +01:00
# include <KServiceTypeTrader>
# include <KPluginInfo>
2015-03-19 15:36:53 +00:00
# include <KPluginMetaData>
2013-09-09 17:29:24 +01:00
# include <KPluginFactory>
2014-06-16 19:02:07 +01:00
# include <KAboutData>
# include <KLocalizedString>
2013-09-09 17:29:24 +01:00
# include "ui_kcm.h"
2014-06-14 14:22:40 +01:00
# include "interfaces/dbusinterfaces.h"
# include "interfaces/devicesmodel.h"
2013-09-09 17:29:24 +01:00
# include "devicessortproxymodel.h"
2015-06-20 06:47:40 +01:00
# include "kdeconnect-version.h"
2013-06-19 15:15:25 +01:00
K_PLUGIN_FACTORY ( KdeConnectKcmFactory , registerPlugin < KdeConnectKcm > ( ) ; )
2015-09-11 15:19:07 +01:00
static QString createId ( ) { return QStringLiteral ( " kcm " ) + QString : : number ( QCoreApplication : : applicationPid ( ) ) ; }
2013-06-19 15:15:25 +01:00
KdeConnectKcm : : KdeConnectKcm ( QWidget * parent , const QVariantList & )
2014-06-16 19:02:07 +01:00
: KCModule ( KAboutData : : pluginData ( " kdeconnect-kcm " ) , parent )
2013-06-27 01:13:16 +01:00
, kcmUi ( new Ui : : KdeConnectKcmUi ( ) )
2015-03-02 05:23:05 +00:00
, daemon ( new DaemonDbusInterface ( this ) )
2013-08-15 23:25:13 +01:00
, devicesModel ( new DevicesModel ( this ) )
2015-09-08 09:46:59 +01:00
, currentDevice ( nullptr )
2013-06-19 15:15:25 +01:00
{
2015-06-20 06:47:40 +01:00
KAboutData * about = new KAboutData ( " kdeconnect-kcm " ,
i18n ( " KDE Connect Settings " ) ,
QLatin1String ( KDECONNECT_VERSION_STRING ) ,
i18n ( " KDE Connect Settings module " ) ,
KAboutLicense : : KAboutLicense : : GPL_V2 ,
i18n ( " (C) 2015 Albert Vaca Cintora " ) ,
QString ( ) ,
QLatin1String ( " https://community.kde.org/KDEConnect " )
) ;
about - > addAuthor ( i18n ( " Albert Vaca Cintora " ) ) ;
setAboutData ( about ) ;
2013-06-19 15:15:25 +01:00
2015-06-20 06:47:40 +01:00
kcmUi - > setupUi ( this ) ;
2015-03-02 05:23:05 +00:00
2013-06-27 01:13:16 +01:00
kcmUi - > deviceList - > setIconSize ( QSize ( 32 , 32 ) ) ;
2013-08-15 23:25:13 +01:00
sortProxyModel = new DevicesSortProxyModel ( devicesModel ) ;
kcmUi - > deviceList - > setModel ( sortProxyModel ) ;
2013-06-19 15:15:25 +01:00
2013-07-03 02:52:44 +01:00
kcmUi - > deviceInfo - > setVisible ( false ) ;
2013-08-30 18:10:43 +01:00
kcmUi - > progressBar - > setVisible ( false ) ;
kcmUi - > messages - > setVisible ( false ) ;
2013-06-25 17:08:34 +01:00
2015-03-23 07:39:36 +00:00
//Workaround: If we set this directly (or if we set it in the .ui file), the layout breaks
kcmUi - > noDeviceLinks - > setWordWrap ( false ) ;
QTimer : : singleShot ( 0 , [ this ] { kcmUi - > noDeviceLinks - > setWordWrap ( true ) ; } ) ;
2015-03-02 05:23:05 +00:00
kcmUi - > rename_label - > setText ( daemon - > announcedName ( ) ) ;
kcmUi - > rename_edit - > setText ( daemon - > announcedName ( ) ) ;
setRenameMode ( false ) ;
2015-10-19 02:25:17 +01:00
setButtons ( KCModule : : Help | KCModule : : NoAdditionalButton ) ;
2013-08-13 04:07:32 +01:00
2013-08-15 23:25:13 +01:00
connect ( devicesModel , SIGNAL ( dataChanged ( QModelIndex , QModelIndex ) ) ,
this , SLOT ( resetSelection ( ) ) ) ;
2015-04-09 16:46:13 +01:00
connect ( kcmUi - > deviceList - > selectionModel ( ) , SIGNAL ( currentChanged ( QModelIndex , QModelIndex ) ) ,
2013-08-15 23:25:13 +01:00
this , SLOT ( deviceSelected ( QModelIndex ) ) ) ;
2015-03-01 21:58:40 +00:00
connect ( kcmUi - > pair_button , SIGNAL ( clicked ( ) ) ,
2013-08-30 18:10:43 +01:00
this , SLOT ( requestPair ( ) ) ) ;
2015-03-01 21:58:40 +00:00
connect ( kcmUi - > unpair_button , SIGNAL ( clicked ( ) ) ,
2013-08-30 18:10:43 +01:00
this , SLOT ( unpair ( ) ) ) ;
2015-03-01 21:58:40 +00:00
connect ( kcmUi - > ping_button , SIGNAL ( clicked ( ) ) ,
2013-08-15 23:25:13 +01:00
this , SLOT ( sendPing ( ) ) ) ;
2015-03-01 21:58:40 +00:00
connect ( kcmUi - > refresh_button , SIGNAL ( clicked ( ) ) ,
2014-08-11 17:56:11 +01:00
this , SLOT ( refresh ( ) ) ) ;
2015-03-02 05:23:05 +00:00
connect ( kcmUi - > rename_edit , SIGNAL ( returnPressed ( ) ) ,
this , SLOT ( renameDone ( ) ) ) ;
connect ( kcmUi - > renameDone_button , SIGNAL ( clicked ( ) ) ,
this , SLOT ( renameDone ( ) ) ) ;
connect ( kcmUi - > renameShow_button , SIGNAL ( clicked ( ) ) ,
this , SLOT ( renameShow ( ) ) ) ;
2015-09-11 15:19:07 +01:00
daemon - > acquireDiscoveryMode ( createId ( ) ) ;
2015-03-02 05:23:05 +00:00
}
void KdeConnectKcm : : renameShow ( )
{
setRenameMode ( true ) ;
}
void KdeConnectKcm : : renameDone ( )
{
QString newName = kcmUi - > rename_edit - > text ( ) ;
if ( newName . isEmpty ( ) ) {
//Rollback changes
kcmUi - > rename_edit - > setText ( kcmUi - > rename_label - > text ( ) ) ;
} else {
kcmUi - > rename_label - > setText ( newName ) ;
daemon - > setAnnouncedName ( newName ) ;
}
setRenameMode ( false ) ;
}
void KdeConnectKcm : : setRenameMode ( bool b ) {
kcmUi - > renameDone_button - > setVisible ( b ) ;
kcmUi - > rename_edit - > setVisible ( b ) ;
kcmUi - > renameShow_button - > setVisible ( ! b ) ;
kcmUi - > rename_label - > setVisible ( ! b ) ;
2013-06-19 15:15:25 +01:00
}
KdeConnectKcm : : ~ KdeConnectKcm ( )
{
2015-09-11 15:19:07 +01:00
daemon - > releaseDiscoveryMode ( createId ( ) ) ;
2014-11-10 19:36:12 +00:00
delete kcmUi ;
2013-06-19 15:15:25 +01:00
}
2014-08-11 17:56:11 +01:00
void KdeConnectKcm : : refresh ( )
{
2015-09-11 15:19:07 +01:00
daemon - > acquireDiscoveryMode ( createId ( ) ) ;
2015-03-02 05:23:05 +00:00
daemon - > forceOnNetworkChange ( ) ;
2014-08-11 17:56:11 +01:00
}
2013-08-15 23:25:13 +01:00
void KdeConnectKcm : : resetSelection ( )
{
2015-06-22 03:43:21 +01:00
if ( ! currentDevice ) {
return ;
}
2013-08-15 23:25:13 +01:00
kcmUi - > deviceList - > selectionModel ( ) - > setCurrentIndex ( sortProxyModel - > mapFromSource ( currentIndex ) , QItemSelectionModel : : ClearAndSelect ) ;
}
2013-07-03 02:52:44 +01:00
void KdeConnectKcm : : deviceSelected ( const QModelIndex & current )
2013-06-19 15:15:25 +01:00
{
2013-09-16 15:52:40 +01:00
if ( currentDevice ) {
2015-09-08 19:03:44 +01:00
disconnect ( currentDevice , 0 , this , 0 ) ;
2013-09-16 15:52:40 +01:00
}
2013-08-15 23:25:13 +01:00
//Store previous device config
2013-08-13 04:07:32 +01:00
pluginsConfigChanged ( ) ;
2013-08-18 17:22:54 +01:00
if ( ! current . isValid ( ) ) {
2015-09-08 09:46:59 +01:00
currentDevice = nullptr ;
2013-08-18 17:22:54 +01:00
kcmUi - > deviceInfo - > setVisible ( false ) ;
return ;
}
2013-08-15 23:25:13 +01:00
currentIndex = sortProxyModel - > mapToSource ( current ) ;
2015-04-15 12:00:23 +01:00
currentDevice = devicesModel - > getDevice ( currentIndex . row ( ) ) ;
2013-08-15 23:25:13 +01:00
2015-09-08 19:03:44 +01:00
kcmUi - > noDevicePlaceholder - > setVisible ( false ) ;
2015-09-08 09:46:59 +01:00
bool valid = ( currentDevice ! = nullptr & & currentDevice - > isValid ( ) ) ;
2013-08-15 23:25:13 +01:00
kcmUi - > deviceInfo - > setVisible ( valid ) ;
2013-08-18 17:22:54 +01:00
if ( ! valid ) {
return ;
}
2013-08-15 23:25:13 +01:00
2013-08-30 18:10:43 +01:00
kcmUi - > messages - > setVisible ( false ) ;
2015-12-01 18:45:14 +00:00
kcmUi - > progressBar - > setVisible ( false ) ;
if ( currentDevice - > isTrusted ( ) ) {
kcmUi - > unpair_button - > setVisible ( true ) ;
2013-08-30 18:10:43 +01:00
kcmUi - > pair_button - > setVisible ( false ) ;
2015-12-01 18:45:14 +00:00
kcmUi - > ping_button - > setVisible ( true ) ;
2013-08-30 18:10:43 +01:00
} else {
2015-12-01 18:45:14 +00:00
kcmUi - > unpair_button - > setVisible ( false ) ;
kcmUi - > pair_button - > setVisible ( true ) ;
kcmUi - > ping_button - > setVisible ( false ) ;
2013-08-30 18:10:43 +01:00
}
2015-09-12 18:43:15 +01:00
resetDeviceView ( ) ;
connect ( currentDevice , SIGNAL ( pluginsChanged ( ) ) , this , SLOT ( resetCurrentDevice ( ) ) ) ;
2015-12-17 13:54:37 +00:00
connect ( currentDevice , SIGNAL ( trustedChanged ( bool ) ) , this , SLOT ( trustedChanged ( bool ) ) ) ;
connect ( currentDevice , SIGNAL ( pairingError ( QString ) ) , this , SLOT ( pairingFailed ( QString ) ) ) ;
2015-09-12 18:43:15 +01:00
}
2013-08-30 18:10:43 +01:00
2015-09-12 18:43:15 +01:00
void KdeConnectKcm : : resetCurrentDevice ( )
{
2015-09-12 14:02:59 +01:00
const QStringList unsupportedPluginNames = currentDevice - > unsupportedPlugins ( ) ;
2013-08-13 04:07:32 +01:00
2015-09-12 14:02:59 +01:00
if ( m_oldUnsupportedPluginNames ! = unsupportedPluginNames ) {
2015-09-12 18:43:15 +01:00
resetDeviceView ( ) ;
}
}
void KdeConnectKcm : : resetDeviceView ( )
{
//KPluginSelector has no way to remove a list of plugins and load another, so we need to destroy and recreate it each time
delete kcmUi - > pluginSelector ;
kcmUi - > pluginSelector = new KPluginSelector ( this ) ;
kcmUi - > deviceInfo_layout - > addWidget ( kcmUi - > pluginSelector ) ;
kcmUi - > pluginSelector - > setConfigurationArguments ( QStringList ( currentDevice - > id ( ) ) ) ;
kcmUi - > name_label - > setText ( currentDevice - > name ( ) ) ;
2015-12-01 18:45:14 +00:00
kcmUi - > status_label - > setText ( currentDevice - > isTrusted ( ) ? i18n ( " (trusted) " ) : i18n ( " (not trusted) " ) ) ;
2015-09-07 17:50:26 +01:00
2015-09-12 18:43:15 +01:00
const QList < KPluginInfo > pluginInfo = KPluginInfo : : fromMetaData ( KPluginLoader : : findPlugins ( " kdeconnect/ " ) ) ;
QList < KPluginInfo > availablePluginInfo ;
QList < KPluginInfo > unsupportedPluginInfo ;
2015-09-12 14:02:59 +01:00
2015-09-12 18:43:15 +01:00
m_oldUnsupportedPluginNames = currentDevice - > unsupportedPlugins ( ) ;
for ( auto it = pluginInfo . cbegin ( ) , itEnd = pluginInfo . cend ( ) ; it ! = itEnd ; + + it ) {
if ( m_oldUnsupportedPluginNames . contains ( it - > pluginName ( ) ) ) {
unsupportedPluginInfo . append ( * it ) ;
} else {
availablePluginInfo . append ( * it ) ;
}
2015-09-12 14:02:59 +01:00
}
2013-08-13 04:07:32 +01:00
2015-09-12 18:43:15 +01:00
KSharedConfigPtr deviceConfig = KSharedConfig : : openConfig ( currentDevice - > pluginsConfigFile ( ) ) ;
kcmUi - > pluginSelector - > addPlugins ( availablePluginInfo , KPluginSelector : : ReadConfigFile , i18n ( " Available plugins " ) , QString ( ) , deviceConfig ) ;
kcmUi - > pluginSelector - > addPlugins ( unsupportedPluginInfo , KPluginSelector : : ReadConfigFile , i18n ( " Plugins unsupported by the device " ) , QString ( ) , deviceConfig ) ;
connect ( kcmUi - > pluginSelector , SIGNAL ( changed ( bool ) ) , this , SLOT ( pluginsConfigChanged ( ) ) ) ;
2013-06-19 15:15:25 +01:00
}
2013-08-30 18:10:43 +01:00
void KdeConnectKcm : : requestPair ( )
2013-06-19 15:15:25 +01:00
{
2013-09-16 15:52:40 +01:00
if ( ! currentDevice ) {
return ;
}
2013-08-30 18:10:43 +01:00
kcmUi - > messages - > hide ( ) ;
kcmUi - > pair_button - > setVisible ( false ) ;
kcmUi - > progressBar - > setVisible ( true ) ;
currentDevice - > requestPair ( ) ;
}
void KdeConnectKcm : : unpair ( )
{
2013-09-16 15:52:40 +01:00
if ( ! currentDevice ) {
return ;
}
currentDevice - > unpair ( ) ;
}
2013-08-30 18:10:43 +01:00
void KdeConnectKcm : : pairingFailed ( const QString & error )
{
2013-09-16 14:46:28 +01:00
if ( sender ( ) ! = currentDevice ) return ;
2015-12-17 13:54:37 +00:00
trustedChanged ( false ) ;
2013-09-16 15:52:40 +01:00
2013-09-04 20:19:02 +01:00
kcmUi - > messages - > setText ( i18n ( " Error trying to pair: %1 " , error ) ) ;
2013-08-30 18:10:43 +01:00
kcmUi - > messages - > animatedShow ( ) ;
}
2015-12-17 13:54:37 +00:00
void KdeConnectKcm : : trustedChanged ( bool paired )
2013-08-30 18:10:43 +01:00
{
2013-09-16 15:52:40 +01:00
DeviceDbusInterface * senderDevice = ( DeviceDbusInterface * ) sender ( ) ;
if ( senderDevice ! = currentDevice ) return ;
2013-09-16 14:46:28 +01:00
2015-06-22 03:42:57 +01:00
kcmUi - > pair_button - > setVisible ( ! paired ) ;
kcmUi - > unpair_button - > setVisible ( paired ) ;
2015-12-01 18:45:14 +00:00
kcmUi - > progressBar - > setVisible ( false ) ;
2015-06-22 03:42:57 +01:00
kcmUi - > ping_button - > setVisible ( paired ) ;
kcmUi - > status_label - > setText ( paired ? i18n ( " (paired) " ) : i18n ( " (unpaired) " ) ) ;
2013-08-13 04:07:32 +01:00
}
void KdeConnectKcm : : pluginsConfigChanged ( )
{
//Store previous selection
if ( ! currentDevice ) return ;
2013-08-30 18:10:43 +01:00
DeviceDbusInterface * auxCurrentDevice = currentDevice ;
2015-09-08 09:46:59 +01:00
currentDevice = nullptr ; //HACK to avoid infinite recursion (for some reason calling save on pluginselector emits changed)
2013-08-13 04:07:32 +01:00
kcmUi - > pluginSelector - > save ( ) ;
currentDevice = auxCurrentDevice ;
currentDevice - > reloadPlugins ( ) ;
}
void KdeConnectKcm : : save ( )
{
pluginsConfigChanged ( ) ;
KCModule : : save ( ) ;
2013-06-19 15:15:25 +01:00
}
2013-07-03 02:52:44 +01:00
void KdeConnectKcm : : sendPing ( )
2013-06-19 15:15:25 +01:00
{
2013-08-13 04:07:32 +01:00
if ( ! currentDevice ) return ;
2015-06-13 00:28:36 +01:00
currentDevice - > pluginCall ( " ping " , " sendPing " ) ;
2013-06-19 15:15:25 +01:00
}
2014-06-16 19:02:07 +01:00
2015-03-01 21:59:28 +00:00
QSize KdeConnectKcm : : sizeHint ( ) const
{
return QSize ( 890 , 550 ) ; //Golden ratio :D
}
QSize KdeConnectKcm : : minimumSizeHint ( ) const
{
return QSize ( 500 , 300 ) ;
}
2014-06-16 19:02:07 +01:00
# include "kcm.moc"
# include "moc_kcm.cpp"