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.
krusader/krusader/Dialogs/checksumdlg.cpp

604 lines
23 KiB

#include "checksumdlg.h"
#include "../krusader.h"
#include <tdelocale.h>
#include <tqlayout.h>
#include <tqlabel.h>
#include <tqcheckbox.h>
#include <klineedit.h>
#include <tdelistview.h>
#include <tqpixmap.h>
#include <kcursor.h>
#include <tdemessagebox.h>
#include <tqfile.h>
#include <tqtextstream.h>
#include <tdefiledialog.h>
#include <tqframe.h>
#include <kiconloader.h>
#include <kcombobox.h>
#include <tqfileinfo.h>
#include <kurlrequester.h>
#include "../krservices.h"
#include <tqptrlist.h>
#include <tqmap.h>
#include <tdetempfile.h>
#include <kstandarddirs.h>
class CS_Tool; // forward
typedef void PREPARE_PROC_FUNC(TDEProcess& proc, CS_Tool *self, const TQStringList& files,
const TQString checksumFile, bool recursive, const TQString& stdoutFileName,
const TQString& stderrFileName, const TQString& type);
typedef TQStringList GET_FAILED_FUNC(const TQStringList& stdOut, const TQStringList& stdErr);
class CS_Tool {
public:
enum Type {
MD5=0, SHA1, SHA256, TIGER, WHIRLPOOL, SFV, CRC,
SHA224, SHA384, SHA512,
NumOfTypes
};
Type type;
TQString binary;
bool recursive;
bool standardFormat;
PREPARE_PROC_FUNC *create, *verify;
GET_FAILED_FUNC *failed;
};
class CS_ToolByType {
public:
TQPtrList<CS_Tool> tools, r_tools; // normal and recursive tools
};
// handles md5sum and sha1sum
void sumCreateFunc(TDEProcess& proc, CS_Tool *self, const TQStringList& files,
const TQString, bool recursive, const TQString& stdoutFileName,
const TQString& stderrFileName, const TQString&) {
proc.setUseShell(true, "/bin/bash");
proc << KrServices::fullPathName( self->binary );
Q_ASSERT(!recursive);
proc << files << "1>" << stdoutFileName << "2>" << stderrFileName;
}
void sumVerifyFunc(TDEProcess& proc, CS_Tool *self, const TQStringList& /* files */,
const TQString checksumFile, bool recursive, const TQString& stdoutFileName,
const TQString& stderrFileName, const TQString& /* type */) {
proc.setUseShell(true, "/bin/bash");
proc << KrServices::fullPathName( self->binary );
Q_ASSERT(!recursive);
proc << "-c" << checksumFile << "1>" << stdoutFileName << "2>" << stderrFileName;
}
TQStringList sumFailedFunc(const TQStringList& stdOut, const TQStringList& stdErr) {
// md5sum and sha1sum print "...: FAILED" for failed files and display
// the number of failures to stderr. so if stderr is empty, we'll assume all is ok
TQStringList result;
if (stdErr.size()==0) return result;
result += stdErr;
// grep for the ":FAILED" substring
const TQString tmp = TQString(": FAILED").local8Bit();
for (uint i=0; i<stdOut.size();++i) {
if (stdOut[i].find(tmp) != -1)
result += stdOut[i];
}
return result;
}
// handles *deep binaries
void deepCreateFunc(TDEProcess& proc, CS_Tool *self, const TQStringList& files,
const TQString, bool recursive, const TQString& stdoutFileName,
const TQString& stderrFileName, const TQString&) {
proc.setUseShell(true, "/bin/bash");
proc << KrServices::fullPathName( self->binary );
if (recursive) proc << "-r";
proc << "-l" << files << "1>" << stdoutFileName << "2>" << stderrFileName;
}
void deepVerifyFunc(TDEProcess& proc, CS_Tool *self, const TQStringList& files,
const TQString checksumFile, bool recursive, const TQString& stdoutFileName,
const TQString& stderrFileName, const TQString&) {
proc.setUseShell(true, "/bin/bash");
proc << KrServices::fullPathName( self->binary );
if (recursive) proc << "-r";
proc << "-x" << checksumFile << files << "1>" << stdoutFileName << "2>" << stderrFileName;
}
TQStringList deepFailedFunc(const TQStringList& stdOut, const TQStringList&/* stdErr */) {
// *deep dumps (via -x) all failed hashes to stdout
return stdOut;
}
// handles cfv binary
void cfvCreateFunc(TDEProcess& proc, CS_Tool *self, const TQStringList& files,
const TQString, bool recursive, const TQString& stdoutFileName,
const TQString& stderrFileName, const TQString& type) {
proc.setUseShell(true, "/bin/bash");
proc << KrServices::fullPathName( self->binary ) << "-C" << "-VV";
if (recursive) proc << "-rr";
proc << "-t" << type << "-f-" << "-U" << files << "1>" << stdoutFileName << "2>" << stderrFileName;
}
void cfvVerifyFunc(TDEProcess& proc, CS_Tool *self, const TQStringList& /* files */,
const TQString checksumFile, bool recursive, const TQString& stdoutFileName,
const TQString& stderrFileName, const TQString&type) {
proc.setUseShell(true, "/bin/bash");
proc << KrServices::fullPathName( self->binary ) << "-M";
if (recursive) proc << "-rr";
proc << "-U" << "-VV" << "-t" << type << "-f" << checksumFile << "1>" << stdoutFileName << "2>" << stderrFileName;// << files;
}
TQStringList cfvFailedFunc(const TQStringList& /* stdOut */, const TQStringList& stdErr) {
// cfv dumps all failed hashes to stderr
return stdErr;
}
// important: this table should be ordered like so that all md5 tools should be
// one after another, and then all sha1 and so on and so forth. they tools must be grouped,
// since the code in getTools() counts on it!
CS_Tool cs_tools[] = {
// type binary recursive stdFmt create_func verify_func failed_func
{CS_Tool::MD5, "md5sum", false, true, sumCreateFunc, sumVerifyFunc, sumFailedFunc},
{CS_Tool::MD5, "md5deep", true, true, deepCreateFunc, deepVerifyFunc, deepFailedFunc},
{CS_Tool::MD5, "cfv", true, true, cfvCreateFunc, cfvVerifyFunc, cfvFailedFunc},
{CS_Tool::SHA1, "sha1sum", false, true, sumCreateFunc, sumVerifyFunc, sumFailedFunc},
{CS_Tool::SHA1, "sha1deep", true, true, deepCreateFunc, deepVerifyFunc, deepFailedFunc},
{CS_Tool::SHA1, "cfv", true, true, cfvCreateFunc, cfvVerifyFunc, cfvFailedFunc},
{CS_Tool::SHA224, "sha224sum", false, true, sumCreateFunc, sumVerifyFunc, sumFailedFunc},
{CS_Tool::SHA256, "sha256sum", false, true, sumCreateFunc, sumVerifyFunc, sumFailedFunc},
{CS_Tool::SHA256, "sha256deep", true, true, deepCreateFunc, deepVerifyFunc, deepFailedFunc},
{CS_Tool::SHA384, "sha384sum", false, true, sumCreateFunc, sumVerifyFunc, sumFailedFunc},
{CS_Tool::SHA512, "sha512sum", false, true, sumCreateFunc, sumVerifyFunc, sumFailedFunc},
{CS_Tool::TIGER, "tigerdeep", true, true, deepCreateFunc, deepVerifyFunc, deepFailedFunc},
{CS_Tool::WHIRLPOOL, "whirlpooldeep", true, true, deepCreateFunc, deepVerifyFunc, deepFailedFunc},
{CS_Tool::SFV, "cfv", true, false, cfvCreateFunc, cfvVerifyFunc, cfvFailedFunc},
{CS_Tool::CRC, "cfv", true, false, cfvCreateFunc, cfvVerifyFunc, cfvFailedFunc},
};
TQMap<TQString, CS_Tool::Type> cs_textToType;
TQMap<CS_Tool::Type, TQString> cs_typeToText;
void initChecksumModule() {
// prepare the dictionaries - pity it has to be manually
cs_textToType["md5"]=CS_Tool::MD5;
cs_textToType["sha1"]=CS_Tool::SHA1;
cs_textToType["sha256"]=CS_Tool::SHA256;
cs_textToType["sha224"]=CS_Tool::SHA224;
cs_textToType["sha384"]=CS_Tool::SHA384;
cs_textToType["sha512"]=CS_Tool::SHA512;
cs_textToType["tiger"]=CS_Tool::TIGER;
cs_textToType["whirlpool"]=CS_Tool::WHIRLPOOL;
cs_textToType["sfv"]=CS_Tool::SFV;
cs_textToType["crc"]=CS_Tool::CRC;
cs_typeToText[CS_Tool::MD5]="md5";
cs_typeToText[CS_Tool::SHA1]="sha1";
cs_typeToText[CS_Tool::SHA256]="sha256";
cs_typeToText[CS_Tool::SHA224]="sha224";
cs_typeToText[CS_Tool::SHA384]="sha384";
cs_typeToText[CS_Tool::SHA512]="sha512";
cs_typeToText[CS_Tool::TIGER]="tiger";
cs_typeToText[CS_Tool::WHIRLPOOL]="whirlpool";
cs_typeToText[CS_Tool::SFV]="sfv";
cs_typeToText[CS_Tool::CRC]="crc";
// build the checksumFilter (for usage in KRQuery)
TQMap<TQString, CS_Tool::Type>::Iterator it;
for (it=cs_textToType.begin(); it!=cs_textToType.end(); ++it)
MatchChecksumDlg::checksumTypesFilter += ("*."+it.key()+" ");
}
// --------------------------------------------------
// returns a list of tools which can work with recursive or non-recursive mode and are installed
// note: only 1 tool from each type is suggested
static TQPtrList<CS_Tool> getTools(bool folders) {
TQPtrList<CS_Tool> result;
uint i;
for (i=0; i < sizeof(cs_tools)/sizeof(CS_Tool); ++i) {
if (result.last() && result.last()->type == cs_tools[i].type) continue; // 1 from each type please
if (folders && !cs_tools[i].recursive) continue;
if (KrServices::cmdExist(cs_tools[i].binary))
result.append(&cs_tools[i]);
}
return result;
}
// ------------- CreateChecksumDlg
CreateChecksumDlg::CreateChecksumDlg(const TQStringList& files, bool containFolders, const TQString& path):
KDialogBase(Plain, i18n("Create Checksum"), Ok | Cancel, Ok, krApp) {
TQPtrList<CS_Tool> tools = getTools(containFolders);
if (tools.count() == 0) { // nothing was suggested?!
TQString error = i18n("<qt>Can't calculate checksum since no supported tool was found. "
"Please check the <b>Dependencies</b> page in Krusader's settings.</qt>");
if (containFolders)
error += i18n("<qt><b>Note</b>: you've selected directories, and probably have no recursive checksum tool installed."
" Krusader currently supports <i>md5deep, sha1deep, sha256deep, tigerdeep and cfv</i></qt>");
KMessageBox::error(0, error);
return;
}
TQGridLayout *layout = new TQGridLayout( plainPage(), 1, 1,
KDialogBase::marginHint(), KDialogBase::spacingHint());
int row=0;
// title (icon+text)
TQHBoxLayout *hlayout = new TQHBoxLayout(layout, KDialogBase::spacingHint());
TQLabel *p = new TQLabel(plainPage());
p->setPixmap(krLoader->loadIcon("application-octet-stream", TDEIcon::Desktop, 32));
hlayout->addWidget(p);
TQLabel *l1 = new TQLabel(i18n("About to calculate checksum for the following files") +
(containFolders ? i18n(" and folders:") : ":"), plainPage());
hlayout->addWidget(l1);
layout->addMultiCellLayout(hlayout, row, row, 0, 1, TQt::AlignLeft);
++row;
// file list
TDEListBox *lb = new TDEListBox(plainPage());
lb->insertStringList(files);
layout->addMultiCellWidget(lb, row, row, 0, 1);
++row;
// checksum method
TQHBoxLayout *hlayout2 = new TQHBoxLayout(layout, KDialogBase::spacingHint());
TQLabel *l2 = new TQLabel(i18n("Select the checksum method:"), plainPage());
hlayout2->addWidget(l2);
KComboBox *method = new KComboBox(plainPage());
// -- fill the combo with available methods
uint i;
for ( i=0; i<tools.count(); ++i )
method->insertItem( cs_typeToText[tools.at(i)->type], i);
method->setFocus();
hlayout2->addWidget(method);
layout->addMultiCellLayout(hlayout2, row, row, 0, 1, TQt::AlignLeft);
++row;
if (exec() != Accepted) return;
// else implied: run the process
tmpOut = new KTempFile(locateLocal("tmp", "krusader"), ".stdout" );
tmpErr = new KTempFile(locateLocal("tmp", "krusader"), ".stderr" );
TDEProcess proc;
CS_Tool *mytool = tools.at(method->currentItem());
mytool->create(proc, mytool, KrServices::quote(files), TQString(), containFolders,
tmpOut->name(), tmpErr->name(), method->currentText());
krApp->startWaiting(i18n("Calculating checksums ..."), 0, true);
TQApplication::setOverrideCursor( KCursor::waitCursor() );
bool r = proc.start(TDEProcess::NotifyOnExit, TDEProcess::AllOutput);
if (r) while ( proc.isRunning() ) {
usleep( 500 );
tqApp->processEvents();
if (krApp->wasWaitingCancelled()) { // user cancelled
proc.kill();
TQApplication::restoreOverrideCursor();
return;
}
};
krApp->stopWait();
TQApplication::restoreOverrideCursor();
if (!r || !proc.normalExit()) {
KMessageBox::error(0, i18n("<qt>There was an error while running <b>%1</b>.</qt>").arg(mytool->binary));
return;
}
// suggest a filename
TQString suggestedFilename = path + '/';
if (files.count() > 1) suggestedFilename += ("checksum." + cs_typeToText[mytool->type]);
else suggestedFilename += (files[0] + '.' + cs_typeToText[mytool->type]);
// send both stdout and stderr
TQStringList stdOut, stdErr;
if (!KrServices::fileToStringList(tmpOut->textStream(), stdOut) ||
!KrServices::fileToStringList(tmpErr->textStream(), stdErr)) {
KMessageBox::error(krApp, i18n("Error reading stdout or stderr"));
return;
}
ChecksumResultsDlg dlg( stdOut, stdErr, suggestedFilename, mytool->binary, cs_typeToText[mytool->type], mytool->standardFormat);
tmpOut->unlink(); delete tmpOut;
tmpErr->unlink(); delete tmpErr;
}
// ------------- MatchChecksumDlg
TQString MatchChecksumDlg::checksumTypesFilter;
MatchChecksumDlg::MatchChecksumDlg(const TQStringList& files, bool containFolders,
const TQString& path, const TQString& checksumFile):
KDialogBase(Plain, i18n("Verify Checksum"), Ok | Cancel, Ok, krApp) {
TQPtrList<CS_Tool> tools = getTools(containFolders);
if (tools.count() == 0) { // nothing was suggested?!
TQString error = i18n("<qt>Can't verify checksum since no supported tool was found. "
"Please check the <b>Dependencies</b> page in Krusader's settings.</qt>");
if (containFolders)
error += i18n("<qt><b>Note</b>: you've selected directories, and probably have no recursive checksum tool installed."
" Krusader currently supports <i>md5deep, sha1deep, sha256deep, tigerdeep and cfv</i></qt>");
KMessageBox::error(0, error);
return;
}
TQGridLayout *layout = new TQGridLayout( plainPage(), 1, 1,
KDialogBase::marginHint(), KDialogBase::spacingHint());
int row=0;
// title (icon+text)
TQHBoxLayout *hlayout = new TQHBoxLayout(layout, KDialogBase::spacingHint());
TQLabel *p = new TQLabel(plainPage());
p->setPixmap(krLoader->loadIcon("application-octet-stream", TDEIcon::Desktop, 32));
hlayout->addWidget(p);
TQLabel *l1 = new TQLabel(i18n("About to verify checksum for the following files") +
(containFolders ? i18n(" and folders:") : ":"), plainPage());
hlayout->addWidget(l1);
layout->addMultiCellLayout(hlayout, row, row, 0, 1, TQt::AlignLeft);
++row;
// file list
TDEListBox *lb = new TDEListBox(plainPage());
lb->insertStringList(files);
layout->addMultiCellWidget(lb, row, row, 0, 1);
++row;
// checksum file
TQHBoxLayout *hlayout2 = new TQHBoxLayout(layout, KDialogBase::spacingHint());
TQLabel *l2 = new TQLabel(i18n("Checksum file:"), plainPage());
hlayout2->addWidget(l2);
KURLRequester *checksumFileReq = new KURLRequester( plainPage() );
if (!checksumFile.isEmpty())
checksumFileReq->setURL(checksumFile);
checksumFileReq->fileDialog()->setURL(path);
checksumFileReq->setFocus();
hlayout2->addWidget(checksumFileReq);
layout->addMultiCellLayout(hlayout2, row, row, 0, 1, TQt::AlignLeft);
if (exec() != Accepted) return;
TQString file = checksumFileReq->url();
TQString extension;
if (!verifyChecksumFile(file, extension)) {
KMessageBox::error(0, i18n("<qt>Error reading checksum file <i>%1</i>.<br />Please specify a valid checksum file.</qt>").arg(file));
return;
}
// do we have a tool for that extension?
uint i;
CS_Tool *mytool = 0;
for ( i=0; i < tools.count(); ++i )
if (cs_typeToText[tools.at(i)->type] == extension.lower()) {
mytool = tools.at(i);
break;
}
if (!mytool) {
KMessageBox::error(0, i18n("<qt>Krusader can't find a checksum tool that handles %1 on your system. Please check the <b>Dependencies</b> page in Krusader's settings.</qt>").arg(extension));
return;
}
// else implied: run the process
tmpOut = new KTempFile(locateLocal("tmp", "krusader"), ".stdout" );
tmpErr = new KTempFile(locateLocal("tmp", "krusader"), ".stderr" );
TDEProcess proc;
mytool->verify(proc, mytool, KrServices::quote(files), KrServices::quote(file), containFolders, tmpOut->name(), tmpErr->name(), extension);
krApp->startWaiting(i18n("Verifying checksums ..."), 0, true);
TQApplication::setOverrideCursor( KCursor::waitCursor() );
bool r = proc.start(TDEProcess::NotifyOnExit, TDEProcess::AllOutput);
if (r) while ( proc.isRunning() ) {
usleep( 500 );
tqApp->processEvents();
if (krApp->wasWaitingCancelled()) { // user cancelled
proc.kill();
TQApplication::restoreOverrideCursor();
return;
}
};
if (!r || !proc.normalExit()) {
KMessageBox::error(0, i18n("<qt>There was an error while running <b>%1</b>.</qt>").arg(mytool->binary));
return;
}
TQApplication::restoreOverrideCursor();
krApp->stopWait();
// send both stdout and stderr
TQStringList stdOut,stdErr;
if (!KrServices::fileToStringList(tmpOut->textStream(), stdOut) ||
!KrServices::fileToStringList(tmpErr->textStream(), stdErr)) {
KMessageBox::error(krApp, i18n("Error reading stdout or stderr"));
return;
}
VerifyResultDlg dlg(mytool->failed(stdOut, stdErr));
tmpOut->unlink(); delete tmpOut;
tmpErr->unlink(); delete tmpErr;
}
bool MatchChecksumDlg::verifyChecksumFile(TQString path, TQString& extension) {
TQFileInfo f(path);
if (!f.exists() || f.isDir()) return false;
// find the extension
extension = path.mid(path.findRev(".")+1);
// TODO: do we know the extension? if not, ask the user for one
return true;
}
// ------------- VerifyResultDlg
VerifyResultDlg::VerifyResultDlg(const TQStringList& failed):
KDialogBase(Plain, i18n("Verify Checksum"), Close, Close, krApp) {
TQGridLayout *layout = new TQGridLayout( plainPage(), 1, 1,
KDialogBase::marginHint(), KDialogBase::spacingHint());
bool errors = failed.size()>0;
int row = 0;
// create the icon and title
TQHBoxLayout *hlayout = new TQHBoxLayout(layout, KDialogBase::spacingHint());
TQLabel p(plainPage());
p.setPixmap(krLoader->loadIcon(errors ? "messagebox_critical" : "messagebox_info", TDEIcon::Desktop, 32));
hlayout->addWidget(&p);
TQLabel *l1 = new TQLabel((errors ? i18n("Errors were detected while verifying the checksums") :
i18n("Checksums were verified successfully")), plainPage());
hlayout->addWidget(l1);
layout->addMultiCellLayout(hlayout,row,row,0,1, TQt::AlignLeft);
++row;
if (errors) {
TQLabel *l3 = new TQLabel(i18n("The following files have failed:"), plainPage());
layout->addMultiCellWidget(l3, row, row, 0, 1);
++row;
TDEListBox *lb2 = new TDEListBox(plainPage());
lb2->insertStringList(failed);
layout->addMultiCellWidget(lb2, row, row, 0, 1);
++row;
}
exec();
}
// ------------- ChecksumResultsDlg
ChecksumResultsDlg::ChecksumResultsDlg(const TQStringList& stdOut, const TQStringList& stdErr,
const TQString& suggestedFilename, const TQString& binary, const TQString& /* type */, bool standardFormat):
KDialogBase(Plain, i18n("Create Checksum"), Ok | Cancel, Ok, krApp), _binary(binary) {
TQGridLayout *layout = new TQGridLayout( plainPage(), 1, 1,
KDialogBase::marginHint(), KDialogBase::spacingHint());
// md5 tools display errors into stderr, so we'll use that to determine the result of the job
bool errors = stdErr.size()>0;
bool successes = stdOut.size()>0;
int row = 0;
// create the icon and title
TQHBoxLayout *hlayout = new TQHBoxLayout(layout, KDialogBase::spacingHint());
TQLabel p(plainPage());
p.setPixmap(krLoader->loadIcon(errors ? "messagebox_critical" : "messagebox_info", TDEIcon::Desktop, 32));
hlayout->addWidget(&p);
TQLabel *l1 = new TQLabel((errors ? i18n("Errors were detected while creating the checksums") :
i18n("Checksums were created successfully")), plainPage());
hlayout->addWidget(l1);
layout->addMultiCellLayout(hlayout,row,row,0,1, TQt::AlignLeft);
++row;
if (successes) {
if (errors) {
TQLabel *l2 = new TQLabel(i18n("Here are the calculated checksums:"), plainPage());
layout->addMultiCellWidget(l2, row, row, 0, 1);
++row;
}
TDEListView *lv = new TDEListView(plainPage());
if(standardFormat){
lv->addColumn(i18n("Hash"));
lv->addColumn(i18n("File"));
lv->setAllColumnsShowFocus(true);
} else {
lv->addColumn(i18n("File and hash"));
}
for ( TQStringList::ConstIterator it = stdOut.begin(); it != stdOut.end(); ++it ) {
TQString line = (*it);
if(standardFormat) {
int space = line.find(' ');
new TDEListViewItem(lv, line.left(space), line.mid(space+2));
} else {
new TDEListViewItem(lv, line);
}
}
layout->addMultiCellWidget(lv, row, row, 0, 1);
++row;
}
if (errors) {
TQFrame *line1 = new TQFrame( plainPage() );
line1->setGeometry( TQRect( 60, 210, 501, 20 ) );
line1->setFrameShape( TQFrame::HLine );
line1->setFrameShadow( TQFrame::Sunken );
layout->addMultiCellWidget(line1, row, row, 0, 1);
++row;
TQLabel *l3 = new TQLabel(i18n("Here are the errors received:"), plainPage());
layout->addMultiCellWidget(l3, row, row, 0, 1);
++row;
TDEListBox *lb = new TDEListBox(plainPage());
lb->insertStringList(stdErr);
layout->addMultiCellWidget(lb, row, row, 0, 1);
++row;
}
// save checksum to disk, if any hashes are found
KURLRequester *checksumFile=0;
TQCheckBox *saveFileCb=0;
if (successes) {
TQHBoxLayout *hlayout2 = new TQHBoxLayout(layout, KDialogBase::spacingHint());
saveFileCb = new TQCheckBox(i18n("Save checksum to file:"), plainPage());
saveFileCb->setChecked(true);
hlayout2->addWidget(saveFileCb);
checksumFile = new KURLRequester( suggestedFilename, plainPage() );
hlayout2->addWidget(checksumFile, TQt::AlignLeft);
layout->addMultiCellLayout(hlayout2, row, row,0,1, TQt::AlignLeft);
++row;
connect(saveFileCb, TQ_SIGNAL(toggled(bool)), checksumFile, TQ_SLOT(setEnabled(bool)));
checksumFile->setFocus();
}
TQCheckBox *onePerFile=0;
if (stdOut.size() > 1 && standardFormat) {
onePerFile = new TQCheckBox(i18n("Checksum file for each source file"), plainPage());
onePerFile->setChecked(false);
// clicking this, disables the 'save as' part
connect(onePerFile, TQ_SIGNAL(toggled(bool)), saveFileCb, TQ_SLOT(toggle()));
connect(onePerFile, TQ_SIGNAL(toggled(bool)), saveFileCb, TQ_SLOT(setDisabled(bool)));
connect(onePerFile, TQ_SIGNAL(toggled(bool)), checksumFile, TQ_SLOT(setDisabled(bool)));
layout->addMultiCellWidget(onePerFile, row, row,0,1, TQt::AlignLeft);
++row;
}
if (exec() == Accepted && successes) {
if (stdOut.size()>1 && standardFormat && onePerFile->isChecked()) {
savePerFile(stdOut, suggestedFilename.mid(suggestedFilename.findRev('.')));
} else if (saveFileCb->isEnabled() && saveFileCb->isChecked() && !checksumFile->url().simplifyWhiteSpace().isEmpty()) {
saveChecksum(stdOut, checksumFile->url());
}
}
}
bool ChecksumResultsDlg::saveChecksum(const TQStringList& data, TQString filename) {
if (TQFile::exists(filename) &&
KMessageBox::warningContinueCancel(this,
i18n("File %1 already exists.\nAre you sure you want to overwrite it?").arg(filename),
i18n("Warning"), i18n("Overwrite")) != KMessageBox::Continue) {
// find a better name to save to
filename = KFileDialog::getSaveFileName(TQString(), "*", 0, i18n("Select a file to save to"));
if (filename.simplifyWhiteSpace().isEmpty()) return false;
}
TQFile file(filename);
if (!file.open(IO_WriteOnly)) {
KMessageBox::detailedError(0, i18n("Error saving file %1").arg(filename),
file.errorString());
return false;
}
TQTextStream stream(&file);
for ( TQStringList::ConstIterator it = data.constBegin(); it != data.constEnd(); ++it)
stream << *it << "\n";
file.close();
return true;
}
void ChecksumResultsDlg::savePerFile(const TQStringList& data, const TQString& type) {
krApp->startWaiting(i18n("Saving checksum files..."), 0);
for ( TQStringList::ConstIterator it = data.begin(); it != data.end(); ++it ) {
TQString line = (*it);
TQString filename = line.mid(line.find(' ')+2)+type;
if (!saveChecksum(*it, filename)) {
KMessageBox::error(0, i18n("Errors occured while saving multiple checksums. Stopping"));
krApp->stopWait();
return;
}
}
krApp->stopWait();
}