Commit 2725ea70 authored by Yew Ming Chen's avatar Yew Ming Chen
Browse files

7zip-plugin support overwrite dialog when extracting files.

svn path=/trunk/KDE/kdeutils/ark/; revision=887841
parent a0ce7728
......@@ -54,19 +54,25 @@ namespace Kerfuffle
//---
OverwriteQuery::OverwriteQuery( QString filename)
OverwriteQuery::OverwriteQuery( QString filename) : m_noRenameMode(false)
{
m_data["filename"] = filename;
}
void OverwriteQuery::execute()
{
KIO::RenameDialog_Mode mode = (KIO::RenameDialog_Mode)(KIO::M_OVERWRITE | KIO::M_MULTI | KIO::M_SKIP);
if (m_noRenameMode)
{
mode = (KIO::RenameDialog_Mode)(mode | KIO::M_NORENAME);
}
KIO::RenameDialog dialog(
NULL,
i18n("File already exists"),
KUrl(m_data.value("filename").toString()),
KUrl(m_data.value("filename").toString()),
(KIO::RenameDialog_Mode)(KIO::M_OVERWRITE | KIO::M_MULTI | KIO::M_SKIP));
mode);
dialog.exec();
m_data["newFilename"] = dialog.newDestUrl().path();
......@@ -101,6 +107,17 @@ namespace Kerfuffle
{
return m_data.value("newFilename").toString();
}
void OverwriteQuery::setNoRenameMode(bool enableNoRenameMode)
{
m_noRenameMode = enableNoRenameMode;
}
bool OverwriteQuery::noRenameMode()
{
return m_noRenameMode;
}
PasswordNeededQuery::PasswordNeededQuery(QString archiveFilename, bool incorrectTryAgain)
{
......
......@@ -82,6 +82,11 @@ namespace Kerfuffle
bool responseRename();
bool responseSkip();
QString newFilename();
void setNoRenameMode(bool enableNoRenameMode);
bool noRenameMode();
private:
bool m_noRenameMode;
};
class KERFUFFLE_EXPORT PasswordNeededQuery : public Query
......
......@@ -80,7 +80,7 @@ bool p7zipInterface::list()
m_process = &kp;
connect( m_process, SIGNAL( started() ), SLOT( started() ) );
connect( m_process, SIGNAL( readyReadStandardOutput() ), SLOT( readFromStdout() ) );
connect( m_process, SIGNAL( readyReadStandardOutput() ), SLOT( listReadStdout() ) );
connect( m_process, SIGNAL( readyReadStandardError() ), SLOT( readFromStderr() ) );
qRegisterMetaType<QProcess::ExitStatus>("QProcess::ExitStatus");
......@@ -118,7 +118,7 @@ void p7zipInterface::started()
m_state = 0;
}
void p7zipInterface::readFromStdout()
void p7zipInterface::listReadStdout()
{
if ( !m_process )
return;
......@@ -131,13 +131,13 @@ void p7zipInterface::readFromStdout()
QStringList lines = leftString.split( "\n", QString::SkipEmptyParts );
foreach(const QString &line, lines)
{
processLine(m_state, line);
listProcessLine(m_state, line);
}
m_stdOutData.remove(0, indx + 1);
kDebug( 1601 ) << "leftOver" << m_stdOutData;
if (m_stdOutData.contains("Enter password"))
if (m_stdOutData.startsWith("Enter password (will not be echoed) :"))
{
Kerfuffle::PasswordNeededQuery query(filename());
emit userQuery(&query);
......@@ -159,6 +159,9 @@ void p7zipInterface::readFromStderr()
return;
m_stdErrData += m_process->readAllStandardError();
kDebug( 1601 ) << "ERROR:" << m_stdErrData;
if ( !m_stdErrData.isEmpty() )
{
m_process->kill();
......@@ -189,7 +192,7 @@ void p7zipInterface::writeToProcess( const QByteArray &data )
#endif
}
void p7zipInterface::processLine(int& state, const QString& line)
void p7zipInterface::listProcessLine(int& state, const QString& line)
{
switch (state)
{
......@@ -281,13 +284,63 @@ bool p7zipInterface::copyFiles( const QList<QVariant> & files, const QString & d
{
const bool preservePaths = flags & Archive::PreservePaths;
kDebug( 1601 ) << files << destinationDirectory << (preservePaths? " with paths":"");
kDebug( 1601 ) << "extract" << files << "to" << destinationDirectory << (preservePaths? " with paths":"");
if (m_exepath.isNull())
{
return false;
}
QList<QString> overwriteList;
bool overwriteAll = false;
if (files.count() == 0)
{
overwriteAll = true;
}
else
{
for (int i = 0; i < files.count(); i++)
{
if (overwriteAll)
{
overwriteList << files[i].toString();
}
else
{
QString filepath(destinationDirectory + '/' + files[i].toString());
kDebug( 1601 ) << "checking" << filepath;
if (QFile::exists(filepath))
{
Kerfuffle::OverwriteQuery query(filepath);
query.setNoRenameMode(true);
emit userQuery(&query);
query.waitForResponse();
if (query.responseOverwrite())
{
overwriteList << files[i].toString();
}
else if (query.responseSkip())
{
// do not add to overwriteList
}
else if (query.responseOverwriteAll())
{
overwriteAll = true;
overwriteList << files[i].toString();
}
else if (query.responseCancelled())
{
return false;
}
}
else
{
overwriteList << files[i].toString();
}
}
}
}
#if defined(Q_OS_WIN)
KProcess kp(QThread::currentThread());
kp.setOutputChannelMode( KProcess::MergedChannels );
......@@ -299,7 +352,7 @@ bool p7zipInterface::copyFiles( const QList<QVariant> & files, const QString & d
m_process = &kp;
connect( m_process, SIGNAL( started() ), SLOT( started() ) );
connect( m_process, SIGNAL( readyReadStandardOutput() ), SLOT( readFromStdout() ) );
connect( m_process, SIGNAL( readyReadStandardOutput() ), SLOT( copyReadStdout() ) );
connect( m_process, SIGNAL( readyReadStandardError() ), SLOT( readFromStderr() ) );
qRegisterMetaType<QProcess::ExitStatus>("QProcess::ExitStatus");
......@@ -309,10 +362,22 @@ bool p7zipInterface::copyFiles( const QList<QVariant> & files, const QString & d
if (preservePaths)
{
args << "x";
} else
}
else
{
args << "e";
}
if (overwriteAll || overwriteList.count() > 0)
{
args << "-y";
}
else
{
// nothing to extract, just return
return true;
}
args << "-bd";
if ( !password().isEmpty() ) args << "-p" + password();
......@@ -320,9 +385,9 @@ bool p7zipInterface::copyFiles( const QList<QVariant> & files, const QString & d
args << "-o" + destinationDirectory;
args << m_filename;
foreach( const QVariant& file, files )
foreach( const QString& file, overwriteList )
{
args << file.toString().trimmed();
args << file.trimmed();
}
#if defined(Q_OS_WIN)
......@@ -342,6 +407,46 @@ bool p7zipInterface::copyFiles( const QList<QVariant> & files, const QString & d
return !ret;
}
void p7zipInterface::copyReadStdout()
{
if ( !m_process )
return;
m_stdOutData += m_process->readAllStandardOutput();
// process all lines until the last '\n'
int indx = m_stdOutData.lastIndexOf('\n');
QString leftString = QString::fromLocal8Bit(m_stdOutData.left(indx + 1));
QStringList lines = leftString.split( '\n', QString::SkipEmptyParts );
//kDebug( 1601 ) << "lines:" << lines;
for (int i = 0; i < lines.size(); i++)
{
const QString &line = lines[i];
if (line.startsWith("Extracting"))
{
// TODO: update progress
}
}
m_stdOutData.remove(0, indx + 1);
if (m_stdOutData.startsWith("Enter password (will not be echoed) :"))
{
Kerfuffle::PasswordNeededQuery query(filename());
emit userQuery(&query);
query.waitForResponse();
if (query.responseCancelled()) {
error(i18n("Password input cancelled by user."));
m_process->kill();
return;
}
setPassword(query.password());
writeToProcess(password().toLocal8Bit().append('\r'));
}
}
bool p7zipInterface::addFiles( const QStringList & files, const CompressionOptions& options )
{
kDebug( 1601 ) << "Will try to add files " << files << " to " << m_filename << " using " << m_exepath;
......
......@@ -45,7 +45,7 @@ class p7zipInterface: public ReadWriteArchiveInterface
bool deleteFiles( const QList<QVariant> & files );
private:
void processLine(int& state, const QString& line);
void listProcessLine(int& state, const QString& line);
void writeToProcess( const QByteArray &data );
QString m_filename;
QString m_exepath;
......@@ -55,7 +55,6 @@ class p7zipInterface: public ReadWriteArchiveInterface
QEventLoop *m_loop;
int m_state;
#if defined(Q_OS_WIN)
KProcess *m_process;
#else
......@@ -64,7 +63,8 @@ class p7zipInterface: public ReadWriteArchiveInterface
private slots:
void started();
void readFromStdout();
void listReadStdout();
void copyReadStdout();
void readFromStderr();
void finished( int exitCode, QProcess::ExitStatus exitStatus );
};
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment