//
// C++ Implementation: mediumpluginmanager
//
// Description:
//
//
// Authors: Jeff Mitchell <kde-dev@emailgoeshere.com>, (C) 2005, 2006
// Martin Aumueller <aumuell@reserv.at>, (C) 2006
//
// Copyright: See COPYING file that comes with this distribution
//
//
# include "amarok.h"
# include "debug.h"
# include "deviceconfiguredialog.h"
# include "mediadevicemanager.h"
# include "devicemanager.h"
# include "hintlineedit.h"
# include "mediabrowser.h"
# include "medium.h"
# include "mediumpluginmanager.h"
# include "plugin/pluginconfig.h"
# include "pluginmanager.h"
# include "statusbar.h"
# include <tqgroupbox.h>
# include <tqlabel.h>
# include <tqlayout.h>
# include <tqsignalmapper.h>
# include <tqtooltip.h>
# include <tqvbox.h>
# include <tdeapplication.h>
# include <kactivelabel.h>
# include <kcombobox.h>
# include <tdeconfig.h>
# include <kiconloader.h>
# include <klineedit.h>
# include <tdelocale.h>
# include <kpushbutton.h>
using Amarok : : escapeHTML ;
using Amarok : : escapeHTMLAttr ;
typedef TQMap < TQString , Medium * > MediumMap ;
MediumPluginManagerDialog : : MediumPluginManagerDialog ( )
: KDialogBase ( Amarok : : mainWindow ( ) , " mediumpluginmanagerdialog " , false , TQString ( ) , Ok | Cancel , Ok )
{
kapp - > setTopWidget ( this ) ;
setCaption ( kapp - > makeStdCaption ( i18n ( " Manage Devices and Plugins " ) ) ) ;
TQVBox * vbox = makeVBoxMainWidget ( ) ;
vbox - > setSpacing ( KDialog : : spacingHint ( ) ) ;
vbox - > setSizePolicy ( TQSizePolicy ( TQSizePolicy : : Expanding , TQSizePolicy : : Expanding ) ) ;
m_location = new TQGroupBox ( 1 , Qt : : Vertical , i18n ( " Devices " ) , vbox ) ;
m_location - > setSizePolicy ( TQSizePolicy ( TQSizePolicy : : Expanding , TQSizePolicy : : Preferred ) ) ;
m_devicesBox = new TQVBox ( m_location ) ;
m_devicesBox - > setSizePolicy ( TQSizePolicy ( TQSizePolicy : : Expanding , TQSizePolicy : : Expanding ) ) ;
m_manager = new MediumPluginManager ( m_devicesBox ) ;
TQHBox * hbox = new TQHBox ( vbox ) ;
KPushButton * detectDevices = new KPushButton ( i18n ( " Autodetect Devices " ) , hbox ) ;
detectDevices - > setSizePolicy ( TQSizePolicy ( TQSizePolicy : : Expanding , TQSizePolicy : : Fixed ) ) ;
connect ( detectDevices , TQT_SIGNAL ( clicked ( ) ) , m_manager , TQT_SLOT ( redetectDevices ( ) ) ) ;
KPushButton * addButton = new KPushButton ( i18n ( " Add Device... " ) , hbox ) ;
addButton - > setSizePolicy ( TQSizePolicy ( TQSizePolicy : : Expanding , TQSizePolicy : : Fixed ) ) ;
connect ( addButton , TQT_SIGNAL ( clicked ( ) ) , m_manager , TQT_SLOT ( newDevice ( ) ) ) ;
}
MediumPluginManagerDialog : : ~ MediumPluginManagerDialog ( )
{
delete m_manager ;
}
void
MediumPluginManagerDialog : : slotOk ( )
{
m_manager - > finished ( ) ;
KDialogBase : : slotOk ( ) ;
}
MediumPluginManager : : MediumPluginManager ( TQWidget * widget , const bool nographics )
: m_widget ( widget )
{
detectDevices ( false , nographics ) ;
connect ( this , TQT_SIGNAL ( selectedPlugin ( const Medium * , const TQString ) ) , MediaBrowser : : instance ( ) , TQT_SLOT ( pluginSelected ( const Medium * , const TQString ) ) ) ;
}
MediumPluginManager : : ~ MediumPluginManager ( )
{
}
bool
MediumPluginManager : : hasChanged ( )
{
bool temp = m_hasChanged ;
m_hasChanged = false ;
return temp ;
}
void
MediumPluginManager : : slotChanged ( ) //slot
{
m_hasChanged = true ;
emit changed ( ) ;
}
bool
MediumPluginManager : : detectDevices ( const bool redetect , const bool nographics )
{
bool foundNew = false ;
TDEConfig * config = Amarok : : config ( " MediaBrowser " ) ;
if ( redetect )
DeviceManager : : instance ( ) - > reconcileMediumMap ( ) ;
MediumMap mmap = MediaDeviceManager : : instance ( ) - > getMediumMap ( ) ;
for ( MediumMap : : Iterator it = mmap . begin ( ) ; it ! = mmap . end ( ) ; it + + )
{
if ( ! config - > readEntry ( ( * it ) - > id ( ) ) . isEmpty ( ) & &
config - > readEntry ( ( * it ) - > id ( ) ) = = " deleted " & & ! redetect )
{
debug ( ) < < " skipping: deleted " < < endl ;
continue ;
}
bool skipflag = false ;
for ( DeviceList : : Iterator dit = m_deviceList . begin ( ) ;
dit ! = m_deviceList . end ( ) ;
dit + + )
{
if ( ( * it ) - > id ( ) = = ( * dit ) - > medium ( ) - > id ( ) )
{
skipflag = true ;
debug ( ) < < " skipping: already listed " < < endl ;
}
}
if ( m_deletedMap . contains ( ( * it ) - > id ( ) ) & & ! ( * it ) - > isAutodetected ( ) )
{
skipflag = true ;
debug ( ) < < " skipping: deleted & not autodetect " < < endl ;
}
if ( skipflag )
continue ;
if ( m_deletedMap . contains ( ( * it ) - > id ( ) ) )
m_deletedMap . remove ( ( * it ) - > id ( ) ) ;
MediaDeviceConfig * dev = new MediaDeviceConfig ( * it , this , nographics , m_widget ) ;
m_deviceList . append ( dev ) ;
connect ( dev , TQT_SIGNAL ( deleteMedium ( Medium * ) ) , TQT_SLOT ( deleteMedium ( Medium * ) ) ) ;
foundNew = true ;
}
return foundNew ;
}
void
MediumPluginManager : : redetectDevices ( )
{
if ( ! detectDevices ( true ) )
{
Amarok : : StatusBar : : instance ( ) - > longMessageThreadSafe ( i18n ( " No new media devices were found. If you feel this is an \n "
" error, ensure that the DBUS and HAL daemons are running \n "
" and KDE was built with support for them. You can test this \n "
" by running \n "
" \" dcop kded mediamanager fullList \" \n "
" in a Konsole window. " ) ) ;
}
else
slotChanged ( ) ;
}
void
MediumPluginManager : : deleteMedium ( Medium * medium )
{
for ( DeviceList : : Iterator it = m_deviceList . begin ( ) ;
it ! = m_deviceList . end ( ) ;
it + + )
{
if ( ( * it ) - > medium ( ) = = medium )
{
m_deletedMap [ medium - > id ( ) ] = medium ;
m_deviceList . remove ( * it ) ;
break ;
}
}
slotChanged ( ) ;
}
void
MediumPluginManager : : finished ( )
{
for ( DeviceList : : Iterator it = m_deviceList . begin ( ) ;
it ! = m_deviceList . end ( ) ;
it + + )
{
if ( ( * it ) - > plugin ( ) ! = ( * it ) - > oldPlugin ( ) )
{
( * it ) - > setOldPlugin ( ( * it ) - > plugin ( ) ) ;
emit selectedPlugin ( ( * it ) - > medium ( ) , ( * it ) - > plugin ( ) ) ;
}
( * it ) - > configButton ( ) - > setEnabled ( ( * it ) - > pluginCombo ( ) - > currentText ( ) ! = i18n ( " Do not handle " ) ) ;
}
TDEConfig * config = Amarok : : config ( " MediaBrowser " ) ;
for ( DeletedMap : : Iterator dit = m_deletedMap . begin ( ) ;
dit ! = m_deletedMap . end ( ) ;
+ + dit )
{
if ( dit . data ( ) - > isAutodetected ( ) )
config - > writeEntry ( dit . data ( ) - > id ( ) , " deleted " ) ;
else
config - > deleteEntry ( dit . data ( ) - > id ( ) ) ;
MediaDeviceManager : : instance ( ) - > removeManualDevice ( dit . data ( ) ) ;
}
m_deletedMap . clear ( ) ;
}
void
MediumPluginManager : : newDevice ( )
{
DEBUG_BLOCK
ManualDeviceAdder * mda = new ManualDeviceAdder ( this ) ;
if ( mda - > exec ( ) = = TQDialog : : Accepted & & mda - > successful ( ) )
{
if ( ! Amarok : : config ( " MediaBrowser " ) - > readEntry ( mda - > getMedium ( ) - > id ( ) ) . isNull ( ) )
{
//abort! Can't have the same device defined twice...should never
//happen due to name checking earlier...right?
Amarok : : StatusBar : : instance ( ) - > longMessageThreadSafe ( i18n ( " Sorry, you cannot define two devices \n "
" with the same name and mountpoint! " ) ) ;
}
else
{
Medium * newdev = new Medium ( mda - > getMedium ( ) ) ;
Amarok : : config ( " MediaBrowser " ) - > writeEntry ( newdev - > id ( ) , mda - > getPlugin ( ) ) ;
MediaDeviceManager : : instance ( ) - > addManualDevice ( newdev ) ;
detectDevices ( ) ;
}
}
delete mda ;
slotChanged ( ) ;
}
/////////////////////////////////////////////////////////////////////
ManualDeviceAdder : : ManualDeviceAdder ( MediumPluginManager * mpm )
: KDialogBase ( Amarok : : mainWindow ( ) , " manualdeviceadder " , true , TQString ( ) , Ok | Cancel , Ok )
{
m_mpm = mpm ;
m_successful = false ;
m_newMed = 0 ;
kapp - > setTopWidget ( this ) ;
setCaption ( kapp - > makeStdCaption ( i18n ( " Add New Device " ) ) ) ;
TQHBox * hbox = makeHBoxMainWidget ( ) ;
hbox - > setSpacing ( KDialog : : spacingHint ( ) ) ;
TQVBox * vbox1 = new TQVBox ( hbox ) ;
new TQLabel ( i18n ( " Select the plugin to use with this device: " ) , vbox1 ) ;
m_mdaCombo = new KComboBox ( false , vbox1 , " m_mdacombo " ) ;
m_mdaCombo - > insertItem ( i18n ( " Do not handle " ) ) ;
for ( TDETrader : : OfferList : : ConstIterator it = MediaBrowser : : instance ( ) - > getPlugins ( ) . begin ( ) ;
it ! = MediaBrowser : : instance ( ) - > getPlugins ( ) . end ( ) ;
+ + it )
m_mdaCombo - > insertItem ( ( * it ) - > name ( ) ) ;
new TQLabel ( " " , vbox1 ) ;
TQLabel * nameLabel = new TQLabel ( vbox1 ) ;
nameLabel - > setText ( i18n ( " Enter a &name for this device (required): " ) ) ;
m_mdaName = new HintLineEdit ( TQString ( ) , vbox1 ) ;
nameLabel - > setBuddy ( m_mdaName ) ;
m_mdaName - > setHint ( i18n ( " Example: My_Ipod " ) ) ;
TQToolTip : : add ( m_mdaName , i18n ( " Enter a name for the device. The name must be unique across all devices, including autodetected devices. It must not contain the pipe ( | ) character. " ) ) ;
new TQLabel ( " " , vbox1 ) ;
TQLabel * mpLabel = new TQLabel ( vbox1 ) ;
mpLabel - > setText ( i18n ( " Enter the &mount point of the device, if applicable: " ) ) ;
m_mdaMountPoint = new HintLineEdit ( TQString ( ) , vbox1 ) ;
mpLabel - > setBuddy ( m_mdaMountPoint ) ;
m_mdaMountPoint - > setHint ( i18n ( " Example: /mnt/ipod " ) ) ;
TQToolTip : : add ( m_mdaMountPoint , i18n ( " Enter the device's mount point. Some devices (such as iRiver iFP devices) may not have a mount point and this can be ignored. All other devices (iPods, UMS/VFAT devices) should enter the mount point here. " ) ) ;
connect ( m_mdaCombo , TQT_SIGNAL ( activated ( const TQString & ) ) , this , TQT_SLOT ( comboChanged ( const TQString & ) ) ) ;
}
ManualDeviceAdder : : ~ ManualDeviceAdder ( )
{
delete m_newMed ;
delete m_mdaName ;
delete m_mdaMountPoint ;
}
void
ManualDeviceAdder : : slotCancel ( )
{
KDialogBase : : slotCancel ( ) ;
}
void
ManualDeviceAdder : : slotOk ( )
{
if ( getMedium ( true ) & & ! getMedium ( ) - > name ( ) . isEmpty ( ) & &
MediaDeviceManager : : instance ( ) - > getDevice ( getMedium ( ) - > name ( ) ) = = NULL )
{
m_successful = true ;
KDialogBase : : slotOk ( ) ;
}
else
{
Amarok : : StatusBar : : instance ( ) - > longMessageThreadSafe ( i18n ( " Sorry, every device must have a name and \n "
" you cannot define two devices with the \n "
" same name. These names must be unique \n "
" across autodetected devices as well. \n " ) ) ;
}
}
void
ManualDeviceAdder : : comboChanged ( const TQString & string )
{
//best thing to do here would be to find out if the plugin selected
//has m_hasMountPoint set to false...but any way to do this
//without instantiating it? This way will suffice for now...
if ( MediaBrowser : : instance ( ) - > getInternalPluginName ( string ) = = " ifp-mediadevice " | |
MediaBrowser : : instance ( ) - > getInternalPluginName ( string ) = = " daap-mediadevice " | |
MediaBrowser : : instance ( ) - > getInternalPluginName ( string ) = = " mtp-mediadevice " | |
MediaBrowser : : instance ( ) - > getInternalPluginName ( string ) = = " njb-mediadevice " )
{
m_comboOldText = m_mdaMountPoint - > text ( ) ;
m_mdaMountPoint - > setText ( TQString ( ) ) ;
m_mdaMountPoint - > setEnabled ( false ) ;
}
else if ( m_mdaMountPoint - > isEnabled ( ) = = false )
{
m_mdaMountPoint - > setText ( m_comboOldText ) ;
m_mdaMountPoint - > setEnabled ( true ) ;
}
m_selectedPlugin = MediaBrowser : : instance ( ) - > getInternalPluginName ( string ) ;
}
Medium *
ManualDeviceAdder : : getMedium ( bool recreate )
{
if ( ! recreate )
return m_newMed ;
if ( m_newMed & & recreate )
{
delete m_newMed ;
m_newMed = 0 ;
}
if ( m_mdaMountPoint - > isEnabled ( ) = = false & &
m_mdaName - > text ( ) . isNull ( ) )
return NULL ;
if ( m_mdaMountPoint - > text ( ) . isNull ( ) & &
m_mdaName - > text ( ) . isNull ( ) )
return NULL ;
TQString id = " manual| " + m_mdaName - > text ( ) + ' | ' +
( m_mdaMountPoint - > text ( ) . isNull ( ) | |
m_mdaMountPoint - > isEnabled ( ) = = false ?
" (null) " : m_mdaMountPoint - > text ( ) ) ;
m_newMed = new Medium ( id , m_mdaName - > text ( ) ) ;
m_newMed - > setAutodetected ( false ) ;
m_newMed - > setMountPoint ( m_mdaMountPoint - > text ( ) ) ;
return m_newMed ;
}
MediaDeviceConfig : : MediaDeviceConfig ( Medium * medium , MediumPluginManager * mgr , const bool nographics , TQWidget * parent , const char * name )
: TQHBox ( parent , name )
, m_manager ( mgr )
, m_medium ( medium )
, m_configButton ( 0 )
, m_removeButton ( 0 )
, m_new ( true )
{
if ( ! m_medium )
return ;
TDEConfig * config = Amarok : : config ( " MediaBrowser " ) ;
m_oldPlugin = config - > readEntry ( m_medium - > id ( ) ) ;
if ( ! m_oldPlugin . isEmpty ( ) )
m_new = false ;
setSizePolicy ( TQSizePolicy ( TQSizePolicy : : Expanding , TQSizePolicy : : Fixed ) ) ;
setSpacing ( 5 ) ;
const TQString labelTextNone = i18n ( " (none) " ) ;
TQString row = " <tr><td>%1</td><td>%2</td></tr> " ;
TQString table ;
table + = row . arg ( escapeHTML ( i18n ( " Autodetected: " ) ) ,
escapeHTML ( medium - > isAutodetected ( ) ? i18n ( " Yes " ) : i18n ( " No " ) ) ) ;
table + = row . arg ( escapeHTML ( i18n ( " ID: " ) ) ,
escapeHTML ( medium - > id ( ) ) ) ;
table + = row . arg ( escapeHTML ( i18n ( " Name: " ) ) ,
escapeHTML ( medium - > name ( ) ) ) ;
table + = row . arg ( escapeHTML ( i18n ( " Label: " ) ) ,
escapeHTML ( medium - > label ( ) . isEmpty ( ) ? labelTextNone : medium - > label ( ) ) ) ;
table + = row . arg ( escapeHTML ( i18n ( " User Label: " ) ) ,
escapeHTML ( medium - > userLabel ( ) . isEmpty ( ) ? labelTextNone : medium - > userLabel ( ) ) ) ;
table + = row . arg ( escapeHTML ( i18n ( " Device Node: " ) ) ,
escapeHTML ( medium - > deviceNode ( ) . isEmpty ( ) ? labelTextNone : medium - > deviceNode ( ) ) ) ;
table + = row . arg ( escapeHTML ( i18n ( " Mount Point: " ) ) ,
escapeHTML ( medium - > mountPoint ( ) . isEmpty ( ) ? labelTextNone : medium - > mountPoint ( ) ) ) ;
table + = row . arg ( escapeHTML ( i18n ( " Mime Type: " ) ) ,
escapeHTML ( medium - > mimeType ( ) . isEmpty ( ) ? labelTextNone : medium - > mimeType ( ) ) ) ;
TQString title = escapeHTML ( i18n ( " Device information for %1 " ) . arg ( medium - > name ( ) ) ) ;
TQString details = TQString ( " <em>%1</em><br /> " " <table>%2</table> " ) . arg ( title , table ) ;
( void ) new TQLabel ( i18n ( " Name: " ) , this ) ;
( void ) new TQLabel ( medium - > name ( ) , this ) ;
( void ) new KActiveLabel ( i18n ( " (<a href='whatsthis:%1'>Details</a>) " )
. arg ( Amarok : : escapeHTMLAttr ( details ) ) , this ) ;
( void ) new TQLabel ( i18n ( " Plugin: " ) , this ) ;
m_pluginCombo = new KComboBox ( false , this ) ;
m_pluginCombo - > insertItem ( i18n ( " Do not handle " ) ) ;
for ( TDETrader : : OfferList : : ConstIterator it = MediaBrowser : : instance ( ) - > getPlugins ( ) . begin ( ) ;
it ! = MediaBrowser : : instance ( ) - > getPlugins ( ) . end ( ) ;
+ + it ) {
m_pluginCombo - > insertItem ( ( * it ) - > name ( ) ) ;
if ( ( * it ) - > property ( " X-TDE-Amarok-name " ) . toString ( ) = = config - > readEntry ( medium - > id ( ) ) )
m_pluginCombo - > setCurrentItem ( ( * it ) - > name ( ) ) ;
}
m_configButton = new KPushButton ( SmallIconSet ( Amarok : : icon ( " configure " ) ) , TQString ( ) , this ) ;
connect ( m_configButton , TQT_SIGNAL ( clicked ( ) ) , TQT_SLOT ( configureDevice ( ) ) ) ;
m_configButton - > setEnabled ( ! m_new & & m_pluginCombo - > currentText ( ) ! = i18n ( " Do not handle " ) ) ;
TQToolTip : : add ( m_configButton , i18n ( " Configure device settings " ) ) ;
m_removeButton = new KPushButton ( i18n ( " Remove " ) , this ) ;
connect ( m_removeButton , TQT_SIGNAL ( clicked ( ) ) , TQT_SLOT ( deleteDevice ( ) ) ) ;
TQToolTip : : add ( m_removeButton , i18n ( " Remove entries corresponding to this device from configuration file " ) ) ;
connect ( m_pluginCombo , TQT_SIGNAL ( activated ( const TQString & ) ) , m_manager , TQT_SLOT ( slotChanged ( ) ) ) ;
connect ( this , TQT_SIGNAL ( changed ( ) ) , m_manager , TQT_SLOT ( slotChanged ( ) ) ) ;
if ( ! nographics )
show ( ) ;
}
MediaDeviceConfig : : ~ MediaDeviceConfig ( )
{
}
bool
MediaDeviceConfig : : isNew ( )
{
return m_new ;
}
Medium *
MediaDeviceConfig : : medium ( )
{
return m_medium ;
}
TQString
MediaDeviceConfig : : plugin ( )
{
return MediaBrowser : : instance ( ) - > getInternalPluginName ( m_pluginCombo - > currentText ( ) ) ;
}
TQString
MediaDeviceConfig : : oldPlugin ( )
{
return m_oldPlugin ;
}
void
MediaDeviceConfig : : setOldPlugin ( const TQString & oldPlugin )
{
m_oldPlugin = oldPlugin ;
}
TQButton *
MediaDeviceConfig : : configButton ( )
{
return m_configButton ;
}
TQButton *
MediaDeviceConfig : : removeButton ( )
{
return m_removeButton ;
}
KComboBox *
MediaDeviceConfig : : pluginCombo ( )
{
return m_pluginCombo ;
}
void
MediaDeviceConfig : : configureDevice ( ) //slot
{
DeviceConfigureDialog * dcd = new DeviceConfigureDialog ( m_medium ) ;
dcd - > exec ( ) ;
delete dcd ;
}
void
MediaDeviceConfig : : deleteDevice ( ) //slot
{
//TODO:save something in amarokrc such that it's not shown again until hit autoscan
//m_deletedMap[medium->id()] = medium;
emit deleteMedium ( medium ( ) ) ;
delete this ;
}
# include "mediumpluginmanager.moc"