File indexing completed on 2024-10-13 04:22:11

0001 /*
0002     SPDX-FileCopyrightText: 1998-2007 Sebastian Trueg <trueg@k3b.org>
0003     SPDX-License-Identifier: GPL-2.0-or-later
0004 */
0005 
0006 #include "k3blsofwrapperdialog.h"
0007 #include "k3blsofwrapper.h"
0008 
0009 #include "k3bdevice.h"
0010 
0011 #include <KGuiItem>
0012 #include <KLocalizedString>
0013 #include <KMessageBox>
0014 
0015 #include <QDebug>
0016 #include <QList>
0017 #include <QDialogButtonBox>
0018 #include <QLabel>
0019 #include <QPushButton>
0020 #include <QVBoxLayout>
0021 
0022 #include <sys/types.h>
0023 #include <signal.h>
0024 
0025 
0026 static QString joinProcessNames( const QList<K3b::LsofWrapper::Process>& apps )
0027 {
0028     QStringList l;
0029     for( QList<K3b::LsofWrapper::Process>::const_iterator it = apps.begin();
0030          it != apps.end(); ++it )
0031         l.append( (*it).name );
0032     return l.join( ", " );
0033 }
0034 
0035 
0036 K3b::LsofWrapperDialog::LsofWrapperDialog( QWidget* parent )
0037     : QDialog( parent)
0038 {
0039     setWindowTitle(i18n("Device in use"));
0040     setModal(true);
0041 
0042     m_label = new QLabel( this );
0043     m_label->setWordWrap( true );
0044 
0045     QDialogButtonBox* buttonBox = new QDialogButtonBox( this );
0046     QPushButton* continueButton = buttonBox->addButton( i18n("Continue"), QDialogButtonBox::AcceptRole );
0047     continueButton->setDefault( true );
0048     connect( buttonBox, SIGNAL(accepted()), SLOT(accept()) );
0049 
0050     QPushButton* quitButton = buttonBox->addButton( i18n("Quit the other applications"), QDialogButtonBox::NoRole );
0051     connect( quitButton, SIGNAL(clicked()), SLOT(slotQuitOtherApps()) );
0052 
0053     QPushButton* checkButton = buttonBox->addButton( i18n("Check again"), QDialogButtonBox::NoRole );
0054     connect( checkButton, SIGNAL(clicked()), SLOT(slotCheckDevice()) );
0055 
0056     QVBoxLayout* layout = new QVBoxLayout( this );
0057     layout->addWidget( m_label );
0058     layout->addWidget( buttonBox );
0059 }
0060 
0061 
0062 K3b::LsofWrapperDialog::~LsofWrapperDialog()
0063 {
0064 }
0065 
0066 
0067 bool K3b::LsofWrapperDialog::slotCheckDevice()
0068 {
0069     K3b::LsofWrapper lsof;
0070     if( lsof.checkDevice( m_device ) ) {
0071         const QList<K3b::LsofWrapper::Process>& apps = lsof.usingApplications();
0072         if( apps.count() > 0 ) {
0073             m_label->setText( i18n("<p>Device <b>'%1'</b> is already in use by other applications "
0074                                    "(<em>%2</em>)."
0075                                    "<p>It is highly recommended to quit those before continuing. "
0076                                    "Otherwise K3b might not be able to fully access the device."
0077                                    "<p><em>Hint: Sometimes shutting down an application does not "
0078                                    "happen instantly. In that case you might have to use the '%3' "
0079                                    "button."
0080                                    ,m_device->vendor() + " - " + m_device->description()
0081                                    , joinProcessNames(apps)
0082                                    , i18n( "Check again" ) ) );
0083             return true;
0084         }
0085     }
0086 
0087     // once no apps are running we can close the dialog
0088     close();
0089 
0090     return false;
0091 }
0092 
0093 
0094 void K3b::LsofWrapperDialog::slotQuitOtherApps()
0095 {
0096     K3b::LsofWrapper lsof;
0097     if( lsof.checkDevice( m_device ) ) {
0098         const QList<K3b::LsofWrapper::Process>& apps = lsof.usingApplications();
0099         if( apps.count() > 0 ) {
0100             KGuiItem w(i18n("www"));
0101             if( KMessageBox::warningTwoActions( this,
0102                                                 i18n("<p>Do you really want K3b to kill the following processes: <em>%1</em>?</p>", joinProcessNames(apps)),
0103                                                 i18n("Kill the processes?"),
0104                                                 KGuiItem(i18n("Kill")),
0105                                                 KStandardGuiItem::cancel()) == KMessageBox::PrimaryAction ) {
0106                 for( QList<K3b::LsofWrapper::Process>::const_iterator it = apps.begin();
0107                      it != apps.end(); ++it )
0108                     ::kill( (*it).pid, SIGTERM );
0109             }
0110             else
0111                 return;
0112         }
0113     }
0114 
0115     // after quitting the other applications recheck for running ones
0116     slotCheckDevice();
0117 }
0118 
0119 
0120 void K3b::LsofWrapperDialog::checkDevice( K3b::Device::Device* dev, QWidget* parent )
0121 {
0122     K3b::LsofWrapperDialog dlg( parent );
0123     dlg.m_device = dev;
0124     if( dlg.slotCheckDevice() )
0125         dlg.exec();
0126 }
0127 
0128 #include "moc_k3blsofwrapperdialog.cpp"