1
/******************************************************************************
2
 * Copyright (c) 2005,2006 Jeff Mitchell <kde-dev@emailgoeshere.com>          *
3
 *           (c) 2006 Martin Aumueller <aumuell@reserv.at>                    *
4
 *                                                                            *
5
 * This program is free software; you can redistribute it and/or              *
6
 * modify it under the terms of the GNU General Public License as             *
7
 * published by the Free Software Foundation; either version 2 of             *
8
 * the License, or (at your option) any later version.                        *
9
 *                                                                            *
10
 * This program is distributed in the hope that it will be useful,            *
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of             *
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the              *
13
 * GNU General Public License for more details.                               *
14
 *                                                                            *
15
 * You should have received a copy of the GNU General Public License          *
16
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.      *
17
 ******************************************************************************/
18
19
#include "MediaDevicePluginManager.h"
20
21
#include "Amarok.h"
22
#include "Debug.h"
23
#include "deviceconfiguredialog.h"
24
#include "hintlineedit.h"
25
#include "mediabrowser.h"
26
#include "MediaDeviceCache.h"
27
#include "plugin/pluginconfig.h"
28
#include "PluginManager.h"
29
#include "statusbar/StatusBar.h"
30
31
#include <KComboBox>
32
#include <KConfig>
33
#include <KLocale>
34
#include <KPushButton>
35
#include <KVBox>
36
#include <Solid/Device>
37
#include <Solid/StorageAccess>
38
39
#include <QFile>
40
#include <QGroupBox>
41
#include <QHeaderView>
42
#include <QLabel>
43
#include <KMessageBox>
44
#include <QTableWidget>
45
#include <QWhatsThis>
46
47
MediaDevicePluginManagerDialog::MediaDevicePluginManagerDialog()
48
        : KDialog( Amarok::mainWindow() )
49
        , m_genericDevices( 0 )
50
        , m_addButton( 0 )
51
        , m_devicesBox( 0 )
52
        , m_location( 0 )
53
        , m_manager( 0 )
54
{
55
    setObjectName( "mediadevicepluginmanagerdialog" );
56
    setModal( false );
57
    setButtons( Ok | Cancel );
58
    setDefaultButton( Ok );
59
60
    kapp->setTopWidget( this );
61
    setCaption( KDialog::makeStandardCaption( i18n( "Manage Devices and Plugins" ) ) );
62
63
    KVBox *vbox = new KVBox( this );
64
    setMainWidget( vbox );
65
66
    vbox->setSpacing( KDialog::spacingHint() );
67
    vbox->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding ) );
68
69
    m_location = new QGroupBox( i18n( "Devices" ), vbox );
70
    m_location->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Preferred ) );
71
    m_devicesBox = new KVBox( m_location );
72
    m_devicesBox->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding ) );
73
74
    m_manager = new MediaDevicePluginManager( m_devicesBox );
75
76
    KHBox *hbox = new KHBox( vbox );
77
    m_genericDevices = new KPushButton( i18n( "Generic Devices and Volumes..." ), hbox);
78
    m_genericDevices->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
79
    connect( m_genericDevices, SIGNAL( clicked() ), m_manager, SLOT( slotGenericVolumes() ) );
80
81
    m_addButton = new KPushButton( i18n( "Add Device..." ), hbox );
82
    m_addButton->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
83
    connect( m_addButton, SIGNAL( clicked() ), m_manager, SLOT( slowNewDevice() ) );
84
    connect( this, SIGNAL( okClicked() ), this, SLOT( slotOk() ) );
85
}
86
87
MediaDevicePluginManagerDialog::~MediaDevicePluginManagerDialog()
88
{
89
    disconnect( m_genericDevices, SIGNAL( clicked() ), m_manager, SLOT( slotGenericVolumes() ) );
90
    disconnect( m_addButton, SIGNAL( clicked() ), m_manager, SLOT( slotNewDevice() ) );
91
    delete m_manager;
92
}
93
94
void
95
MediaDevicePluginManagerDialog::slotOk()
96
{
97
    m_manager->finished();
98
    disconnect( this, SIGNAL( okClicked() ), this, SLOT( slotOk() ) );
99
}
100
101
MediaDevicePluginManager::MediaDevicePluginManager( QWidget *widget )
102
        : m_widget( widget )
103
{
104
    detectDevices();
105
106
    connect( this, SIGNAL( selectedPlugin( const QString &, const QString & ) ), MediaBrowser::instance(), SLOT( pluginSelected( const QString &, const QString & ) ) );
107
    connect( MediaDeviceCache::instance(), SIGNAL( deviceAdded(const QString &) ), this, SLOT( slotSolidDeviceAdded(const QString &) ) );
108
    connect( MediaDeviceCache::instance(), SIGNAL( deviceRemoved(const QString &) ), this, SLOT( slotSolidDeviceRemoved(const QString &) ) );
109
}
110
111
MediaDevicePluginManager::~MediaDevicePluginManager()
112
{
113
    foreach( MediaDeviceConfig* mdc, m_deviceList )
114
        disconnect( mdc, SIGNAL(deleteDevice(const QString &)), this, SLOT(slotDeleteDevice(const QString &)) );
115
    disconnect( this, SIGNAL( selectedPlugin( const QString &, const QString & ) ), MediaBrowser::instance(), SLOT( pluginSelected( const QString &, const QString & ) ) );
116
    disconnect( MediaDeviceCache::instance(), SIGNAL( deviceAdded(const QString &) ), this, SLOT( slotSolidDeviceAdded(const QString &) ) );
117
    disconnect( MediaDeviceCache::instance(), SIGNAL( deviceRemoved(const QString &) ), this, SLOT( slotSolidDeviceRemoved(const QString &) ) );
118
}
119
120
void
121
MediaDevicePluginManager::slotGenericVolumes()
122
{
123
    MediaDeviceVolumeMarkerDialog *mdvmd = new MediaDeviceVolumeMarkerDialog();
124
    mdvmd->exec();
125
    const QStringList addedList = mdvmd->getAddedList();
126
    const QStringList removedList = mdvmd->getRemovedList();
127
    delete mdvmd;
128
    foreach( const QString &udi, addedList )
129
        MediaBrowser::instance()->deviceAdded( udi );
130
    foreach( const QString &udi, removedList )
131
        MediaBrowser::instance()->deviceRemoved( udi );
132
    detectDevices();
133
}
134
135
bool
136
MediaDevicePluginManager::detectDevices()
137
{
138
    DEBUG_BLOCK
139
    bool foundNew = false;
140
    KConfigGroup config = Amarok::config( "PortableDevices" );
141
    MediaDeviceCache::instance()->refreshCache();
142
    QStringList udiList = MediaDeviceCache::instance()->getAll();
143
    foreach( const QString &udi, udiList )
144
    {
145
        debug() << "Checking device udi " << udi;
146
147
        bool skipflag = false;
148
149
        foreach( MediaDeviceConfig* mediadevice, m_deviceList )
150
        {
151
            if( udi == mediadevice->udi() )
152
            {
153
                skipflag = true;
154
                debug() << "skipping: already listed";
155
                if( MediaDeviceCache::instance()->deviceType( udi ) == MediaDeviceCache::SolidVolumeType &&
156
                        !MediaDeviceCache::instance()->isGenericEnabled( udi ) )
157
                    slotDeleteDevice( udi );
158
            }
159
        }
160
161
        if( skipflag )
162
            continue;
163
164
        if( MediaDeviceCache::instance()->deviceType( udi ) == MediaDeviceCache::SolidVolumeType &&
165
                !MediaDeviceCache::instance()->isGenericEnabled( udi ) )
166
        {
167
            debug() << "Device generic but not enabled, skipping.";
168
            continue;
169
        }
170
        else
171
            slotAddDevice( udi );
172
    }
173
    return foundNew;
174
}
175
176
void
177
MediaDevicePluginManager::slotSolidDeviceAdded( const QString &udi )
178
{
179
    foreach( MediaDeviceConfig* mediadevice, m_deviceList )
180
    {
181
        if( udi == mediadevice->udi() )
182
        {
183
            debug() << "skipping: already listed";
184
            return;
185
        }
186
    }
187
    int deviceType = MediaDeviceCache::instance()->deviceType( udi );
188
    if( deviceType == MediaDeviceCache::SolidPMPType ||
189
            ( deviceType == MediaDeviceCache::SolidVolumeType &&
190
              MediaDeviceCache::instance()->isGenericEnabled( udi ) ) )
191
    {
192
        MediaDeviceConfig *dev = new MediaDeviceConfig( udi, m_widget );
193
        m_deviceList.append( dev );
194
        connect( dev, SIGNAL(deleteDevice(const QString &)), this, SLOT(slotDeleteDevice(const QString&)) );
195
    }
196
    else
197
    {
198
        debug() << "device was not PMP, or was volume but not enabled" << endl;
199
    }
200
}
201
202
void
203
MediaDevicePluginManager::slotSolidDeviceRemoved( const QString &udi )
204
{
205
    DEBUG_BLOCK
206
    debug() << "Trying to remove udi " << udi;
207
    for( int i = 0; i < m_deviceList.size(); ++i )
208
    {
209
        if( i < m_deviceList.size() && m_deviceList[i] && m_deviceList[i]->udi() == udi )
210
        {
211
            MediaDeviceConfig* config = m_deviceList[i];
212
            m_deviceList.removeAt( i );
213
            delete config;
214
            --i;
215
        }
216
    }
217
}
218
219
void
220
MediaDevicePluginManager::slotDeleteDevice( const QString &udi )
221
{
222
    DEBUG_BLOCK
223
    for( int i = 0; i < m_deviceList.size(); ++i )
224
    {
225
        if( i < m_deviceList.size() && m_deviceList[i] && m_deviceList[i]->udi() == udi )
226
        {
227
            debug() << "putting device " << udi << " on deleted map";
228
            m_deletedList.append( udi );
229
            MediaDeviceConfig *config = m_deviceList[i];
230
            m_deviceList.removeAt( i );
231
            delete config;
232
            --i;
233
        }
234
    }
235
}
236
237
void
238
MediaDevicePluginManager::slotAddDevice( const QString &udi )
239
{
240
    DEBUG_BLOCK
241
    MediaDeviceConfig *dev = new MediaDeviceConfig( udi, m_widget );
242
    m_deviceList.append( dev );
243
    connect( dev, SIGNAL(deleteDevice(const QString &)), this, SLOT(slotDeleteDevice(const QString &)) );
244
}
245
246
void
247
MediaDevicePluginManager::finished()
248
{
249
    DEBUG_BLOCK
250
    foreach( MediaDeviceConfig* device, m_deviceList )
251
    {
252
        int deviceType = MediaDeviceCache::instance()->deviceType( device->udi() );
253
        if( deviceType == MediaDeviceCache::SolidPMPType || deviceType == MediaDeviceCache::SolidVolumeType )
254
            continue;
255
        debug() << "checking device " << device->udi();
256
        debug() << "plugin = " << device->plugin();
257
        debug() << "oldPlugin = " << device->oldPlugin();
258
        device->setOldPlugin( device->plugin() );
259
        emit selectedPlugin( device->udi(), device->plugin() );
260
    }
261
262
    KConfigGroup config = Amarok::config( "PortableDevices" );
263
    foreach( const QString &udi, m_deletedList )
264
    {
265
        config.deleteEntry( udi );
266
        emit selectedPlugin( udi, "dummy" );
267
    }
268
    MediaDeviceCache::instance()->refreshCache();
269
    m_deletedList.clear();
270
}
271
272
void
273
MediaDevicePluginManager::slotNewDevice()
274
{
275
    DEBUG_BLOCK
276
    ManualDeviceAdder* mda = new ManualDeviceAdder();
277
    int accepted = mda->exec();
278
    if( accepted == QDialog::Accepted && mda->successful() )
279
    {
280
        if( !Amarok::config( "PortableDevices" ).readEntry( mda->getId(), QString() ).isNull() )
281
        {
282
            //abort!  Can't have the same device defined twice...should never
283
            //happen due to name checking earlier...right?
284
            The::statusBar()->longMessage( i18n("Cannot define two devices\n"
285
                                                                       "with the same name and mountpoint.") );
286
        }
287
        else
288
        {
289
            Amarok::config( "PortableDevices" ).writeEntry( mda->getId(), mda->getPlugin() );
290
            MediaDeviceCache::instance()->refreshCache();
291
            detectDevices();
292
        }
293
    }
294
    delete mda;
295
}
296
297
/////////////////////////////////////////////////////////////////////
298
299
ManualDeviceAdder::ManualDeviceAdder()
300
: KDialog( Amarok::mainWindow() )
301
{
302
    setObjectName( "manualdeviceadder" );
303
    setModal( true );
304
    setButtons( Ok | Cancel );
305
    setDefaultButton( Ok );
306
307
308
    m_successful = false;
309
    m_newId.clear();
310
311
    kapp->setTopWidget( this );
312
    setCaption( KDialog::makeStandardCaption( i18n( "Add New Device") ) );
313
314
    KHBox* hbox = new KHBox( this );
315
    setMainWidget( hbox );
316
    hbox->setSpacing( KDialog::spacingHint() );
317
318
    KVBox* vbox1 = new KVBox( hbox );
319
320
    new QLabel( i18n( "Select the plugin to use with this device:"), vbox1 );
321
    m_mdaCombo = new KComboBox( false, vbox1 );
322
    m_mdaCombo->setObjectName( "m_mdacombo" );
323
    KService::List::ConstIterator end = MediaBrowser::instance()->getPlugins().constEnd();
324
    for( KService::List::ConstIterator it = MediaBrowser::instance()->getPlugins().constBegin();
325
            it != end;
326
            ++it )
327
        m_mdaCombo->addItem( (*it)->name() );
328
    if( m_mdaCombo->count() > 0 )
329
        m_selectedPlugin = MediaBrowser::instance()->getInternalPluginName( m_mdaCombo->itemText( 0 ) );
330
331
    new QLabel( "", vbox1 );
332
    QLabel* nameLabel = new QLabel( vbox1 );
333
    nameLabel->setText( i18n( "Enter a &name for this device (required):" ) );
334
    m_mdaName = new HintLineEdit( QString(), vbox1);
335
    nameLabel->setBuddy( m_mdaName );
336
    m_mdaName->setHint( i18n( "Example: My_Ipod" ) );
337
    m_mdaName->setToolTip( i18n( "Enter a name for the device.  The name must be unique across all manually added devices.  It must not contain the pipe ( | ) character." ) );
338
339
    new QLabel( "", vbox1 );
340
    QLabel* mpLabel = new QLabel( vbox1 );
341
    mpLabel->setText( i18n( "Enter the &mount point of the device, if applicable:" ) );
342
    m_mdaMountPoint = new HintLineEdit( QString(), vbox1);
343
    mpLabel->setBuddy( m_mdaMountPoint );
344
    m_mdaMountPoint->setHint( i18n( "Example: /mnt/ipod" ) );
345
    m_mdaMountPoint->setToolTip( i18n( "Enter the device's mount point.  Some devices (such as MTP 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." ) );
346
347
    connect( m_mdaCombo, SIGNAL( activated(const QString&) ), this, SLOT( slotComboChanged(const QString&) ) );
348
}
349
350
ManualDeviceAdder::~ManualDeviceAdder()
351
{
352
    disconnect( m_mdaCombo, SIGNAL( activated(const QString&) ), this, SLOT( slotComboChanged(const QString&) ) );
353
    delete m_mdaCombo;
354
    delete m_mdaName;
355
    delete m_mdaMountPoint;
356
}
357
358
void
359
ManualDeviceAdder::slotButtonClicked( int button )
360
{
361
    DEBUG_BLOCK
362
    if( button != KDialog::Ok )
363
    {
364
        debug() << "mda dialog canceled";
365
        KDialog::slotButtonClicked( button );
366
    }
367
    if( !getId( true ).isEmpty() &&
368
            MediaDeviceCache::instance()->deviceType( m_newId ) == MediaDeviceCache::InvalidType )
369
    {
370
        debug() << "returning with m_successful = true";
371
        m_successful = true;
372
        KDialog::slotButtonClicked( button );
373
    }
374
    else
375
    {
376
        The::statusBar()->longMessage( i18n("Every device must have a name, and\n"
377
                                              "two devices cannot have the same\n"
378
                                              "name. These names must be unique\n"
379
                                              "across auto-detected devices as well.\n") );
380
    }
381
}
382
383
void
384
ManualDeviceAdder::slotComboChanged( const QString &string )
385
{
386
    DEBUG_BLOCK
387
    //best thing to do here would be to find out if the plugin selected
388
    //has m_hasMountPoint set to false...but any way to do this
389
    //without instantiating it?  This way will suffice for now...
390
    if( MediaBrowser::instance()->getInternalPluginName( string ) == "ifp-mediadevice" ||
391
            MediaBrowser::instance()->getInternalPluginName( string ) == "daap-mediadevice" ||
392
            MediaBrowser::instance()->getInternalPluginName( string ) == "mtp-mediadevice" ||
393
            MediaBrowser::instance()->getInternalPluginName( string ) == "njb-mediadevice" )
394
    {
395
        m_mountPointOldText = m_mdaMountPoint->text();
396
        m_mdaMountPoint->setText( i18n("No mount point needed") );
397
        m_mdaMountPoint->setEnabled(false);
398
    }
399
    else if( m_mdaMountPoint->isEnabled() == false )
400
    {
401
        m_mdaMountPoint->setText( m_mountPointOldText );
402
        m_mdaMountPoint->setEnabled(true);
403
    }
404
    m_selectedPlugin = MediaBrowser::instance()->getInternalPluginName( string );
405
    debug() << "Selected plugin = " << m_selectedPlugin;
406
}
407
408
QString
409
ManualDeviceAdder::getId( bool recreate )
410
{
411
    DEBUG_BLOCK
412
    if( !recreate )
413
    {
414
        debug() << "No recreate, returning " << m_newId;
415
        return m_newId;
416
    }
417
418
    if( !m_newId.isEmpty() && recreate )
419
    {
420
        m_newId.clear();
421
    }
422
423
    if( m_mdaMountPoint->isEnabled() == false && m_mdaName->text().isNull() )
424
    {
425
        debug() << "Mount point not enabled, device name is null";
426
        return QString();
427
    }
428
    if( m_mdaMountPoint->text().isNull() && m_mdaName->text().isNull() )
429
    {
430
        debug() << "Mount point text is null and device name is null";
431
        return QString();
432
    }
433
    if( m_mdaName->text().count( '|' ) )
434
    {
435
        The::statusBar()->longMessage( i18n( "The device name cannot contain the '|' character" ) );
436
        return QString();
437
    }
438
    m_newId = "manual|" + m_mdaName->text() + '|' +
439
        ( m_mdaMountPoint->text().isNull() ||
440
        m_mdaMountPoint->isEnabled() == false ?
441
            "(none)" : m_mdaMountPoint->text() );
442
    debug() << "returning id = " << m_newId;
443
    return m_newId;
444
}
445
446
MediaDeviceConfig::MediaDeviceConfig( QString udi, QWidget *parent, const char *name )
447
    : KHBox( parent )
448
    , m_udi( udi )
449
    , m_name( MediaDeviceCache::instance()->deviceName( udi ) )
450
    , m_oldPlugin( QString() )
451
    , m_details( QString() )
452
    , m_pluginCombo( 0 )
453
    , m_removeButton( 0 )
454
    , m_label_details( 0 )
455
    , m_new( true )
456
{
457
    DEBUG_BLOCK
458
    setObjectName( name );
459
460
    KConfigGroup config = Amarok::config( "PortableDevices" );
461
    m_oldPlugin = config.readEntry( m_udi, QString() );
462
    debug() << "oldPlugin = " << m_oldPlugin;
463
    if( !m_oldPlugin.isEmpty() )
464
        m_new = false;
465
466
    setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
467
    setSpacing( 5 );
468
469
    QString row = "<tr><td>%1</td><td>%2</td></tr>";
470
    QString table;
471
    int deviceType = MediaDeviceCache::instance()->deviceType( m_udi );
472
    table += row.arg( Qt::escape( i18n( "Autodetected:" ) ),
473
            Qt::escape( deviceType == MediaDeviceCache::SolidPMPType || deviceType == MediaDeviceCache::SolidVolumeType ? i18n("Yes") : i18n("No") ) );
474
    table += row.arg( Qt::escape( i18n( "Unique ID:" ) ),
475
            Qt::escape( m_udi ) );
476
    if( deviceType == MediaDeviceCache::SolidPMPType || deviceType == MediaDeviceCache::SolidVolumeType )
477
    {
478
        Solid::Device device( m_udi );
479
        if( device.isValid() )
480
        {
481
            if( deviceType == MediaDeviceCache::SolidPMPType )
482
            {
483
                if( !device.vendor().isEmpty() )
484
                    table += row.arg( Qt::escape( i18n( "Vendor:" ) ),
485
                        Qt::escape( device.vendor() ) );
486
                if( !device.product().isEmpty() )
487
                    table += row.arg( Qt::escape( i18n( "Product:" ) ),
488
                        Qt::escape( device.product() ) );
489
            }
490
            else if( deviceType == MediaDeviceCache::SolidVolumeType )
491
            {
492
                if( !device.parent().vendor().isEmpty() )
493
                    table += row.arg( Qt::escape( i18n( "Vendor:" ) ),
494
                        Qt::escape( device.parent().vendor() ) );
495
                if( !device.parent().product().isEmpty() )
496
                    table += row.arg( Qt::escape( i18n( "Product:" ) ),
497
                        Qt::escape( device.parent().product() ) );
498
                Solid::StorageAccess *ssa = device.as<Solid::StorageAccess>();
499
                if( ssa )
500
                    table += row.arg( Qt::escape( i18n( "Mount Point:" ) ),
501
                            ( ssa->isAccessible() ?
502
                                Qt::escape( ssa->filePath() ) :
503
                                Qt::escape( i18n( "Not Mounted" ) ) ) );
504
            }
505
        }
506
    }
507
508
    QString title = Qt::escape( i18n( "Device information for " ) ) + "<b>" + m_udi + "</b>";
509
    m_details = QString( "<em>%1</em><br />" "<table>%2</table>" ).arg( title, table );
510
511
    QLabel* label_name = new QLabel( i18n("Name: "), this );
512
    Q_UNUSED( label_name );
513
    QLabel* label_devicename = new QLabel( m_name, this );
514
    Q_UNUSED( label_devicename );
515
    QLabel* m_label_details = new QLabel( "<qt>(<a href='details'>" + i18n( "Details" ) + "</a>)</qt>", this );
516
    m_label_details->setTextInteractionFlags( Qt::LinksAccessibleByMouse | Qt::LinksAccessibleByKeyboard );
517
    debug() << "Making link activated, m_label_details = " << m_label_details;
518
    connect( m_label_details, SIGNAL( linkActivated(const QString &) ), this, SLOT( slotDetailsActivated(const QString &) ) );
519
520
    QLabel* label_plugin = new QLabel( i18n("Plugin:"), this );
521
    Q_UNUSED( label_plugin );
522
    m_pluginCombo = new KComboBox( false, this );
523
524
    if( deviceType == MediaDeviceCache::SolidPMPType )
525
    {
526
        debug() << "sending to getDisplayPluginName: " << MediaBrowser::instance()->deviceFromId( m_udi )->type();
527
        QString name = MediaBrowser::instance()->getDisplayPluginName( MediaBrowser::instance()->deviceFromId( m_udi )->type() );
528
        debug() << "name of protocol from Solid is: " << name;
529
        if( name.isEmpty() )
530
        {
531
            m_pluginCombo->addItem( i18n( "Unknown" ) );
532
        }
533
        else
534
        {
535
            debug() << "Adding " << name << " to pluginCombo";
536
            m_pluginCombo->addItem( name );
537
        }
538
    }
539
    else if( deviceType == MediaDeviceCache::SolidVolumeType )
540
    {
541
        m_pluginCombo->addItem( i18n( "Generic Audio Player" ) );
542
    }
543
    else
544
    {
545
        m_pluginCombo->addItem( i18n( "Do not handle" ) );
546
        KService::List::ConstIterator end = MediaBrowser::instance()->getPlugins().constEnd();
547
        for( KService::List::ConstIterator it = MediaBrowser::instance()->getPlugins().constBegin();
548
                it != end;
549
                ++it ){
550
            m_pluginCombo->addItem( (*it)->name() );
551
            if ( (*it)->property( "X-KDE-Amarok-name" ).toString() == config.readEntry( m_udi, QString() ) )
552
                m_pluginCombo->setCurrentItem( (*it)->name() );
553
        }
554
    }
555
    m_pluginCombo->setEnabled( deviceType == MediaDeviceCache::ManualType );
556
557
    m_removeButton = new KPushButton( i18n( "Remove" ), this );
558
    connect( m_removeButton, SIGNAL(clicked()), this, SLOT(slotDeleteDevice()) );
559
    m_removeButton->setToolTip( i18n( "Remove entries corresponding to this device from configuration file" ) );
560
    m_removeButton->setEnabled( deviceType == MediaDeviceCache::ManualType );
561
}
562
563
MediaDeviceConfig::~MediaDeviceConfig()
564
{
565
    DEBUG_BLOCK
566
    debug() << "null here? m_label_details = " << m_label_details;
567
    disconnect( m_label_details, SIGNAL( linkActivated(const QString &) ), this, SLOT( slotDetailsActivated(const QString &) ) );
568
    debug() << "or here?";
569
    disconnect( m_removeButton, SIGNAL(clicked()), this, SLOT(slotDeleteDevice()) );
570
}
571
572
void
573
MediaDeviceConfig::slotConfigureDevice() //slot
574
{
575
    MediaDevice *device = MediaBrowser::instance()->deviceFromId( m_udi );
576
    if( device )
577
    {
578
        DeviceConfigureDialog* dcd = new DeviceConfigureDialog( device );
579
        dcd->exec();
580
        delete dcd;
581
    }
582
    else
583
        debug() << "Could not show the configuration dialog because the device could not be found.";
584
}
585
586
void
587
MediaDeviceConfig::slotDeleteDevice() //slot
588
{
589
    DEBUG_BLOCK
590
    emit deleteDevice( m_udi );
591
}
592
593
void
594
MediaDeviceConfig::slotDetailsActivated( const QString &link ) //slot
595
{
596
    Q_UNUSED( link );
597
    QWhatsThis::showText( QCursor::pos(), "<qt>" + m_details + "</qt>", Amarok::mainWindow() );
598
}
599
600
QString
601
MediaDeviceConfig::plugin()
602
{
603
    return MediaBrowser::instance()->getInternalPluginName( m_pluginCombo->currentText() );
604
}
605
606
MediaDeviceVolumeMarkerDialog::MediaDeviceVolumeMarkerDialog()
607
        : KDialog( Amarok::mainWindow() )
608
        , m_mountPointBox( 0 )
609
        , m_table( 0 )
610
{
611
    setObjectName( "mediadevicevolumemarkerdialog" );
612
    setModal( true );
613
    setButtons( Ok | Cancel );
614
    setDefaultButton( Ok );
615
616
    kapp->setTopWidget( this );
617
    setCaption( KDialog::makeStandardCaption( i18n( "Mark Volumes as Media Devices" ) ) );
618
619
    m_mountPointBox = new KVBox( this );
620
    m_mountPointBox->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding ) );
621
    setMainWidget( m_mountPointBox );
622
623
    KHBox *hbox = new KHBox( m_mountPointBox );
624
    m_table = new QTableWidget( 0, 2, hbox );
625
    QStringList headerlabels;
626
    headerlabels << i18n( "Mount Point:" ) << i18n( "Mark?" );
627
    m_table->setHorizontalHeaderLabels( headerlabels );
628
    m_table->verticalHeader()->hide();
629
    m_table->horizontalHeader()->setResizeMode(0, QHeaderView::Stretch);
630
    m_table->setShowGrid( false );
631
632
    connect( this, SIGNAL( okClicked() ), this, SLOT( slotOk() ) );
633
634
    MediaDeviceCache::instance()->refreshCache();
635
    QStringList udiList = MediaDeviceCache::instance()->getAll();
636
    foreach( const QString &udi, udiList )
637
    {
638
        if( !MediaDeviceCache::instance()->deviceType( udi ) == MediaDeviceCache::SolidVolumeType ||
639
                MediaDeviceCache::instance()->volumeMountPoint( udi ).isEmpty() )
640
        {
641
            debug() << "udi " << udi << " is not a volume, or mount point detected as empty";
642
            continue;
643
        }
644
        int row = m_table->rowCount();
645
        m_table->insertRow( row );
646
        QString mountPoint = MediaDeviceCache::instance()->volumeMountPoint( udi );
647
        QTableWidgetItem *item = new QTableWidgetItem( mountPoint );
648
        m_table->setItem( row, 0, item );
649
        item = new QTableWidgetItem();
650
        item->setFlags( Qt::ItemIsEnabled | Qt::ItemIsUserCheckable );
651
        if( QFile::exists( mountPoint + "/.is_audio_player" ) )
652
            item->setCheckState( Qt::Checked );
653
        else
654
            item->setCheckState( Qt::Unchecked );
655
        m_table->setItem( row, 1, item );
656
    }
657
    m_table->setSortingEnabled( true );
658
}
659
660
MediaDeviceVolumeMarkerDialog::~MediaDeviceVolumeMarkerDialog()
661
{
662
}
663
664
void
665
MediaDeviceVolumeMarkerDialog::slotOk()
666
{
667
    QStringList udiList = MediaDeviceCache::instance()->getAll();
668
    for( int row = 0; row < m_table->rowCount(); row++ )
669
    {
670
        QString mountPoint = m_table->item( row, 0 )->text();
671
        bool checkedState = m_table->item( row, 1 )->checkState() == Qt::Checked ? true : false;
672
        bool initialState = QFile::exists( mountPoint + "/.is_audio_player" );
673
        if( initialState == checkedState )
674
            continue;
675
        if( initialState == false )
676
        {
677
            //attempt to write the file
678
            QFile file( mountPoint + "/.is_audio_player" );
679
            if( file.open( QIODevice::WriteOnly ) )
680
            {
681
                file.close();
682
                foreach( const QString &udi, udiList )
683
                {
684
                    if( MediaDeviceCache::instance()->volumeMountPoint( udi ) == mountPoint )
685
                        m_addedList.append( udi );
686
                }
687
            }
688
            else
689
                KMessageBox::sorry( this,
690
                                    i18n( "Could not create the marking file at %1.\n"
691
                                          "Ensure that you have the correct permissions\n"
692
                                          "to create that file.",
693
                                          QString( mountPoint + "/.is_audio_player" ) ),
694
                                    i18n( "Error Creating File" )
695
                                  );
696
        }
697
        else
698
        {
699
            //attempt to delete the file
700
            bool success = QFile::remove( mountPoint + "/.is_audio_player" );
701
            if( !success )
702
            {
703
                KMessageBox::sorry( this,
704
                                    i18n( "Could not remove the marking file at %1.\n"
705
                                          "Ensure that you have the correct permissions\n"
706
                                          "to remove that file.",
707
                                          QString( mountPoint + "/.is_audio_player" ) ),
708
                                    i18n( "Error Removing File" )
709
                                  );
710
            }
711
            else
712
            {
713
                foreach( const QString &udi, udiList )
714
                {
715
                    if( MediaDeviceCache::instance()->volumeMountPoint( udi ) == mountPoint )
716
                        m_removedList.append( udi );
717
                }
718
            }
719
        }
720
    }
721
    disconnect( this, SIGNAL( okClicked() ), this, SLOT( slotOk() ) );
722
}
723
724
#include "MediaDevicePluginManager.moc"