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"