You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
521 lines
17 KiB
521 lines
17 KiB
//
|
|
// 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 either TDEHW or HAL daemon are running\n"
|
|
"and TDE was built with support for them.") );
|
|
}
|
|
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"
|