diff options
author | Michele Calgaro <michele.calgaro@yahoo.it> | 2025-08-28 22:44:34 +0900 |
---|---|---|
committer | Michele Calgaro <michele.calgaro@yahoo.it> | 2025-08-31 23:30:34 +0900 |
commit | f9abd9d505434c9244c03eac708e29a0ca042f6b (patch) | |
tree | 30a197ab4c413849188bc131ff859212e636c821 /src/app/Splitter | |
parent | 14d42d284de233f9937becf3fc9ee0dabede3b21 (diff) | |
download | krusader-r14.1.x.tar.gz krusader-r14.1.x.zip |
Restructure source foldersr14.1.x
Signed-off-by: Michele Calgaro <michele.calgaro@yahoo.it>
(cherry picked from commit 086012dcad8a976a0dabbb7cbc20c9cb612cdfa9)
Diffstat (limited to 'src/app/Splitter')
-rw-r--r-- | src/app/Splitter/Makefile.am | 11 | ||||
-rw-r--r-- | src/app/Splitter/combiner.cpp | 328 | ||||
-rw-r--r-- | src/app/Splitter/combiner.h | 93 | ||||
-rw-r--r-- | src/app/Splitter/crc32.cpp | 69 | ||||
-rw-r--r-- | src/app/Splitter/crc32.h | 48 | ||||
-rw-r--r-- | src/app/Splitter/splitter.cpp | 252 | ||||
-rw-r--r-- | src/app/Splitter/splitter.h | 84 | ||||
-rw-r--r-- | src/app/Splitter/splittergui.cpp | 213 | ||||
-rw-r--r-- | src/app/Splitter/splittergui.h | 180 |
9 files changed, 1278 insertions, 0 deletions
diff --git a/src/app/Splitter/Makefile.am b/src/app/Splitter/Makefile.am new file mode 100644 index 0000000..756ea94 --- /dev/null +++ b/src/app/Splitter/Makefile.am @@ -0,0 +1,11 @@ +noinst_LIBRARIES = libSplitter.a + +INCLUDES = $(all_includes) + +libSplitter_a_METASOURCES = AUTO + +libSplitter_a_SOURCES = \ + crc32.cpp \ + splittergui.cpp \ + splitter.cpp \ + combiner.cpp diff --git a/src/app/Splitter/combiner.cpp b/src/app/Splitter/combiner.cpp new file mode 100644 index 0000000..0053686 --- /dev/null +++ b/src/app/Splitter/combiner.cpp @@ -0,0 +1,328 @@ +/*************************************************************************** + combiner.cpp - description + ------------------- + copyright : (C) 2003 by Csaba Karai + e-mail : krusader@users.sourceforge.net + web site : http://krusader.sourceforge.net + --------------------------------------------------------------------------- + Description + *************************************************************************** + + A + + db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b. + 88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D + 88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY' + 88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b + 88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88. + YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD + + S o u r c e F i l e + + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "combiner.h" +#include "../VFS/vfs.h" +#include <tdelocale.h> +#include <tdemessagebox.h> +#include <tdefileitem.h> +#include <tdeio/job.h> +#include <tqfileinfo.h> + +Combiner::Combiner( TQWidget* parent, KURL baseURLIn, KURL destinationURLIn, bool unixNamingIn ) : + TQProgressDialog( parent, "Krusader::Combiner", true, 0 ), baseURL( baseURLIn ), destinationURL( destinationURLIn ), + hasValidSplitFile( false ), fileCounter ( 0 ), permissions( -1 ), receivedSize( 0 ), + combineReadJob( 0 ), combineWriteJob( 0 ), unixNaming( unixNamingIn ) +{ + crcContext = new CRC32(); + + splitFile = ""; + + setTotalSteps( 100 ); + setAutoClose( false ); /* don't close or reset the dialog automatically */ + setAutoReset( false ); +} + +Combiner::~Combiner() +{ + combineAbortJobs(); + delete crcContext; +} + +void Combiner::combine() +{ + setCaption( i18n("Krusader::Combining...") ); + setLabelText( i18n("Combining the file %1...").arg( vfs::pathOrURL( baseURL ) )); + + /* check whether the .crc file exists */ + splURL = baseURL; + splURL.setFileName( baseURL.fileName() + ".crc" ); + KFileItem file(KFileItem::Unknown, KFileItem::Unknown, splURL ); + file.refresh(); + + if( !file.isReadable() ) + { + int ret = KMessageBox::questionYesNo(0, i18n("The CRC information file (%1) is missing!\n" + "Validity checking is impossible without it. Continue combining?") + .arg( vfs::pathOrURL( splURL ) ) ); + + if( ret == KMessageBox::No ) + { + emit reject(); + return; + } + + openNextFile(); + } + else + { + permissions = file.permissions() | TQFileInfo::WriteUser; + + combineReadJob = TDEIO::get( splURL, false, false ); + + connect(combineReadJob, TQ_SIGNAL(data(TDEIO::Job *, const TQByteArray &)), + this, TQ_SLOT(combineSplitFileDataReceived(TDEIO::Job *, const TQByteArray &))); + connect(combineReadJob, TQ_SIGNAL(result(TDEIO::Job*)), + this, TQ_SLOT(combineSplitFileFinished(TDEIO::Job *))); + } + + exec(); +} + +void Combiner::combineSplitFileDataReceived(TDEIO::Job *, const TQByteArray &byteArray) +{ + splitFile += TQString( byteArray ); +} + +void Combiner::combineSplitFileFinished(TDEIO::Job *job) +{ + combineReadJob = 0; + TQString error; + + if( job->error() ) + error = i18n("Error at reading the CRC file (%1)!").arg( vfs::pathOrURL( splURL ) ); + else + { + splitFile.remove( '\r' ); // Windows compatibility + TQStringList splitFileContent = TQStringList::split( '\n', splitFile ); + + bool hasFileName = false, hasSize = false, hasCrc = false; + + for(unsigned int i = 0; i != splitFileContent.count(); i++ ) + { + int ndx = splitFileContent[i].find( '=' ); + if( ndx == -1 ) + continue; + TQString token = splitFileContent[i].left( ndx ).stripWhiteSpace(); + TQString value = splitFileContent[i].mid( ndx + 1 ); + + if( token == "filename" ) + { + expectedFileName = value; + hasFileName = true; + } + else if( token == "size" ) + { + sscanf( value.stripWhiteSpace().ascii(), "%llu", &expectedSize ); + hasSize = true; + } + if( token == "crc32" ) + { + expectedCrcSum = value.stripWhiteSpace().rightJustify( 8, '0' ); + hasCrc = true; + } + } + + if( !hasFileName || !hasSize || !hasCrc ) + error = i18n("Not a valid CRC file!"); + else + hasValidSplitFile = true; + } + + if( !error.isEmpty() ) + { + int ret = KMessageBox::questionYesNo( 0, error+ "\n" + + i18n("Validity checking is impossible without a good CRC file. Continue combining?") ); + if( ret == KMessageBox::No ) + { + emit reject(); + return; + } + } + + openNextFile(); +} + +void Combiner::openNextFile() +{ + if( unixNaming ) + { + if( readURL.isEmpty() ) + readURL = baseURL; + else + { + TQString name = readURL.fileName(); + int pos = name.length()-1; + TQChar ch; + + do + { + ch = name.at( pos ).latin1() + 1; + if( ch == TQChar( 'Z' + 1 ) ) + ch = 'A'; + if( ch == TQChar( 'z' + 1 ) ) + ch = 'a'; + name[ pos ] = ch; + pos--; + } while( pos >=0 && ch.upper() == TQChar( 'A' ) ); + + readURL.setFileName( name ); + } + } + else + { + TQString index( "%1" ); /* determining the filename */ + index = index.arg(++fileCounter).rightJustify( 3, '0' ); + readURL = baseURL; + readURL.setFileName( baseURL.fileName() + "." + index ); + } + + /* creating a write job */ + combineReadJob = TDEIO::get( readURL, false, false ); + + connect(combineReadJob, TQ_SIGNAL(data(TDEIO::Job *, const TQByteArray &)), + this, TQ_SLOT(combineDataReceived(TDEIO::Job *, const TQByteArray &))); + connect(combineReadJob, TQ_SIGNAL(result(TDEIO::Job*)), + this, TQ_SLOT(combineReceiveFinished(TDEIO::Job *))); + if( hasValidSplitFile ) + connect(combineReadJob, TQ_SIGNAL(percent (TDEIO::Job *, unsigned long)), + this, TQ_SLOT(combineWritePercent(TDEIO::Job *, unsigned long))); + +} + +void Combiner::combineDataReceived(TDEIO::Job *, const TQByteArray &byteArray) +{ + if( byteArray.size() == 0 ) + return; + + crcContext->update( (unsigned char *)byteArray.data(), byteArray.size() ); + transferArray = byteArray.copy(); + + receivedSize += byteArray.size(); + + if( combineWriteJob == 0 ) + { + writeURL = destinationURL; + writeURL.addPath( baseURL.fileName() ); + if( hasValidSplitFile ) + writeURL.setFileName( expectedFileName ); + else if( unixNaming ) + writeURL.setFileName( baseURL.fileName() + ".out" ); + + combineWriteJob = TDEIO::put( writeURL, permissions, true, false, false ); + + connect(combineWriteJob, TQ_SIGNAL(dataReq(TDEIO::Job *, TQByteArray &)), + this, TQ_SLOT(combineDataSend(TDEIO::Job *, TQByteArray &))); + connect(combineWriteJob, TQ_SIGNAL(result(TDEIO::Job*)), + this, TQ_SLOT(combineSendFinished(TDEIO::Job *))); + } + + if( combineWriteJob ) + { + if( combineReadJob ) combineReadJob->suspend(); /* start writing */ + combineWriteJob->resume(); + } +} + +void Combiner::combineReceiveFinished(TDEIO::Job *job) +{ + combineReadJob = 0; /* TDEIO automatically deletes the object after Finished signal */ + + if( job->error() ) + { + if( combineWriteJob ) /* write out the remaining part of the file */ + combineWriteJob->resume(); + + if( fileCounter == 1 ) + { + combineAbortJobs(); + KMessageBox::questionYesNo(0, i18n("Can't open the first split file of %1!") + .arg( vfs::pathOrURL( baseURL ) ) ); + emit reject(); + return; + } + + if( hasValidSplitFile ) + { + TQString crcResult = TQString( "%1" ).arg( crcContext->result(), 0, 16 ).upper().stripWhiteSpace() + .rightJustify(8, '0'); + + if( receivedSize != expectedSize ) + error = i18n("Incorrect filesize! The file might have been corrupted!"); + else if ( crcResult != expectedCrcSum.upper().stripWhiteSpace() ) + error = i18n("Incorrect CRC checksum! The file might have been corrupted!"); + } + return; + } + openNextFile(); +} + +void Combiner::combineDataSend(TDEIO::Job *, TQByteArray &byteArray) +{ + byteArray = transferArray; + transferArray = TQByteArray(); + + if( combineReadJob ) + { + combineReadJob->resume(); /* start reading */ + combineWriteJob->suspend(); + } +} + +void Combiner::combineSendFinished(TDEIO::Job *job) +{ + combineWriteJob = 0; /* TDEIO automatically deletes the object after Finished signal */ + + if( job->error() ) /* any error occurred? */ + { + combineAbortJobs(); + KMessageBox::error(0, i18n("Error writing file %1!").arg( vfs::pathOrURL( writeURL ) ) ); + emit reject(); + return; + } + + if( !error.isEmpty() ) /* was any error message at reading ? */ + { + combineAbortJobs(); /* we cannot write out it in combineReceiveFinished */ + KMessageBox::error(0, error ); /* because emit accept closes it in this function */ + emit reject(); + return; + } + + emit accept(); +} + +void Combiner::combineAbortJobs() +{ + if( combineReadJob ) + combineReadJob->kill(); + if( combineWriteJob ) + combineWriteJob->kill(); + + combineReadJob = combineWriteJob = 0; +} + +void Combiner::combineWritePercent(TDEIO::Job *, unsigned long) +{ + int percent = (int)((((double)receivedSize / expectedSize ) * 100. ) + 0.5 ); + setProgress( percent ); +} + +#include "combiner.moc" diff --git a/src/app/Splitter/combiner.h b/src/app/Splitter/combiner.h new file mode 100644 index 0000000..10abb0f --- /dev/null +++ b/src/app/Splitter/combiner.h @@ -0,0 +1,93 @@ +/*************************************************************************** + combiner.h - description + ------------------- + copyright : (C) 2003 by Csaba Karai + e-mail : krusader@users.sourceforge.net + web site : http://krusader.sourceforge.net + --------------------------------------------------------------------------- + Description + *************************************************************************** + + A + + db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b. + 88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D + 88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY' + 88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b + 88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88. + YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD + + H e a d e r F i l e + + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef __COMBINER_H__ +#define __COMBINER_H__ + +#include "crc32.h" +#include <tqstring.h> +#include <tqprogressdialog.h> +#include <kurl.h> +#include <tdeio/jobclasses.h> + +class Combiner : public TQProgressDialog +{ + TQ_OBJECT + + +private: + KURL splURL; + KURL readURL; + KURL writeURL; + + KURL baseURL; + KURL destinationURL; + CRC32 *crcContext; + TQByteArray transferArray; + + TQString splitFile; + TQString error; + + + bool hasValidSplitFile; + TQString expectedFileName; + TDEIO::filesize_t expectedSize; + TQString expectedCrcSum; + + int fileCounter; + int permissions; + TDEIO::filesize_t receivedSize; + + TDEIO::TransferJob *combineReadJob; + TDEIO::TransferJob *combineWriteJob; + + bool unixNaming; + +public: + Combiner( TQWidget* parent, KURL baseURLIn, KURL destinationURLIn, bool unixNamingIn=false ); + ~Combiner(); + + void combine(); + +public slots: + void combineSplitFileDataReceived(TDEIO::Job *, const TQByteArray &byteArray); + void combineSplitFileFinished(TDEIO::Job *job); + void combineDataReceived(TDEIO::Job *, const TQByteArray &); + void combineReceiveFinished(TDEIO::Job *); + void combineDataSend(TDEIO::Job *, TQByteArray &); + void combineSendFinished(TDEIO::Job *); + void combineWritePercent(TDEIO::Job *, unsigned long); + +private: + void openNextFile(); + void combineAbortJobs(); +}; + +#endif /* __COMBINER_H__ */ diff --git a/src/app/Splitter/crc32.cpp b/src/app/Splitter/crc32.cpp new file mode 100644 index 0000000..b6b807b --- /dev/null +++ b/src/app/Splitter/crc32.cpp @@ -0,0 +1,69 @@ +/*************************************************************************** + crc32.cpp - description + ------------------- + copyright : (C) 2003 by Csaba Karai + e-mail : krusader@users.sourceforge.net + web site : http://krusader.sourceforge.net + --------------------------------------------------------------------------- + Description + *************************************************************************** + + A + + db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b. + 88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D + 88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY' + 88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b + 88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88. + YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD + + S o u r c e F i l e + + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "crc32.h" + +#define MASK1 0x00FFFFFF +#define MASK2 0xFFFFFFFF +#define POLYNOMIAL 0xEDB88320 + +bool CRC32::crc_initialized = false; +unsigned long CRC32::crc_table[ 256 ]; + +CRC32::CRC32( unsigned long initialValue ) +{ + crc_accum = initialValue; + + if( !crc_initialized ) + { + for( int byte = 0; byte != 256; byte++ ) + { + unsigned long data = byte; + + for( int i = 8; i > 0 ; --i ) + data = data & 1 ? ( data >> 1 ) ^ POLYNOMIAL : data >> 1; + + crc_table[ byte ] = data; + } + + crc_initialized = true; + } +} + +void CRC32::update( unsigned char *buffer, int bufferLen ) +{ + while( bufferLen-- > 0 ) + crc_accum = ( (crc_accum >> 8) & MASK1 ) ^ crc_table[ (crc_accum & 0xff) ^ *buffer++ ]; +} + +unsigned long CRC32::result() +{ + return ( ~crc_accum ) & MASK2; +} diff --git a/src/app/Splitter/crc32.h b/src/app/Splitter/crc32.h new file mode 100644 index 0000000..696603a --- /dev/null +++ b/src/app/Splitter/crc32.h @@ -0,0 +1,48 @@ +/*************************************************************************** + crc32.h - description + ------------------- + copyright : (C) 2003 by Csaba Karai + e-mail : krusader@users.sourceforge.net + web site : http://krusader.sourceforge.net + --------------------------------------------------------------------------- + Description + *************************************************************************** + + A + + db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b. + 88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D + 88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY' + 88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b + 88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88. + YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD + + H e a d e r F i l e + + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef __CRC32_H__ +#define __CRC32_H__ + +class CRC32 +{ +private: + unsigned long crc_accum; + static unsigned long crc_table[ 256 ]; + static bool crc_initialized; + +public: + CRC32( unsigned long initialValue = (unsigned long)-1 ); + + void update( unsigned char *buffer, int bufferLen ); + unsigned long result(); +}; + +#endif /* __CRC32_H__ */ diff --git a/src/app/Splitter/splitter.cpp b/src/app/Splitter/splitter.cpp new file mode 100644 index 0000000..c67e2d9 --- /dev/null +++ b/src/app/Splitter/splitter.cpp @@ -0,0 +1,252 @@ +/*************************************************************************** + splitter.cpp - description + ------------------- + copyright : (C) 2003 by Csaba Karai + e-mail : krusader@users.sourceforge.net + web site : http://krusader.sourceforge.net + --------------------------------------------------------------------------- + Description + *************************************************************************** + + A + + db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b. + 88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D + 88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY' + 88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b + 88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88. + YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD + + S o u r c e F i l e + + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "splitter.h" +#include "../VFS/vfs.h" +#include <tqlayout.h> +#include <tdelocale.h> +#include <tdemessagebox.h> +#include <tdeio/job.h> +#include <tdefileitem.h> +#include <tqfileinfo.h> + +Splitter::Splitter( TQWidget* parent, KURL fileNameIn, KURL destinationDirIn ) : + TQProgressDialog( parent, "Krusader::Splitter", true, 0 ), splitSize( 0 ) +{ + fileName = fileNameIn; + + destinationDir = destinationDirIn; + + crcContext = new CRC32(); + + setTotalSteps( 100 ); + setAutoClose( false ); /* don't close or reset the dialog automatically */ + setAutoReset( false ); +} + +Splitter::~Splitter() +{ + splitAbortJobs(); + delete crcContext; +} + +void Splitter::split( TDEIO::filesize_t splitSizeIn ) +{ + KFileItem file(KFileItem::Unknown, KFileItem::Unknown, fileName ); + file.refresh(); + + permissions = file.permissions() | TQFileInfo::WriteUser; + + splitSize = splitSizeIn; + + setCaption( i18n("Krusader::Splitting...") ); + setLabelText( i18n("Splitting the file %1...").arg( vfs::pathOrURL( fileName ) ) ); + + if( file.isDir() ) + { + KMessageBox::error(0, i18n("Can't split a directory!")); + return; + } + + fileSize = 0; + fileNumber = 0; + + splitReadJob = TDEIO::get( fileName, false, false ); + + connect(splitReadJob, TQ_SIGNAL(data(TDEIO::Job *, const TQByteArray &)), + this, TQ_SLOT(splitDataReceived(TDEIO::Job *, const TQByteArray &))); + connect(splitReadJob, TQ_SIGNAL(result(TDEIO::Job*)), + this, TQ_SLOT(splitReceiveFinished(TDEIO::Job *))); + connect(splitReadJob, TQ_SIGNAL(percent (TDEIO::Job *, unsigned long)), + this, TQ_SLOT(splitReceivePercent(TDEIO::Job *, unsigned long))); + + splitWriteJob = 0; + noValidWriteJob = true; + + exec(); +} + +void Splitter::splitDataReceived(TDEIO::Job *, const TQByteArray &byteArray) +{ + if( byteArray.size() == 0 ) + return; + + crcContext->update( (unsigned char *)byteArray.data(), byteArray.size() ); + fileSize += byteArray.size(); + + if( noValidWriteJob ) + splitCreateWriteJob(); + + transferArray = byteArray.copy(); + if(splitWriteJob) + { + splitReadJob->suspend(); /* start writing */ + splitWriteJob->resume(); + } +} + +void Splitter::splitReceiveFinished(TDEIO::Job *job) +{ + splitReadJob = 0; /* TDEIO automatically deletes the object after Finished signal */ + + if( splitWriteJob ) /* write out the end of the file */ + splitWriteJob->resume(); + + if( job->error() ) /* any error occurred? */ + { + splitAbortJobs(); + KMessageBox::error(0, i18n("Error reading file %1!").arg( vfs::pathOrURL( fileName ) ) ); + emit reject(); + return; + } + + TQString crcResult = TQString( "%1" ).arg( crcContext->result(), 0, 16 ).upper().stripWhiteSpace() + .rightJustify(8, '0'); + + splitFile = TQString( "filename=%1\n" ).arg( fileName.fileName() )+ + TQString( "size=%1\n" ) .arg( TDEIO::number( fileSize ) )+ + TQString( "crc32=%1\n" ) .arg( crcResult ); +} + +void Splitter::splitReceivePercent (TDEIO::Job *, unsigned long percent) +{ + setProgress( percent ); +} + +void Splitter::splitCreateWriteJob() +{ + TQString index( "%1" ); /* making the splitted filename */ + index = index.arg(++fileNumber).rightJustify( 3, '0' ); + TQString outFileName = fileName.fileName() + "." + index; + + writeURL = destinationDir; + writeURL.addPath( outFileName ); + + /* creating a write job */ + splitWriteJob = TDEIO::put( writeURL, permissions, true, false, false ); + outputFileSize = 0; + connect(splitWriteJob, TQ_SIGNAL(dataReq(TDEIO::Job *, TQByteArray &)), + this, TQ_SLOT(splitDataSend(TDEIO::Job *, TQByteArray &))); + connect(splitWriteJob, TQ_SIGNAL(result(TDEIO::Job*)), + this, TQ_SLOT(splitSendFinished(TDEIO::Job *))); + noValidWriteJob = false; +} + +void Splitter::splitDataSend(TDEIO::Job *, TQByteArray &byteArray) +{ + int bufferLen = transferArray.size(); + + if( noValidWriteJob ) /* splitted file should be closed ? */ + { + byteArray = TQByteArray(); /* giving empty buffer which indicates closing */ + } + else if( outputFileSize + bufferLen > splitSize ) /* maximum length reached? */ + { + int shortLen = splitSize - outputFileSize; + + byteArray.duplicate( transferArray.data(), shortLen ); + transferArray.duplicate( transferArray.data() + shortLen, bufferLen - shortLen ); + + noValidWriteJob = true; /* close the current segment */ + } + else + { + outputFileSize += bufferLen; /* write the whole buffer out to the split file */ + + byteArray = transferArray; + transferArray = TQByteArray(); + + if(splitReadJob) + { + splitReadJob->resume(); /* start reading */ + splitWriteJob->suspend(); + } + } +} + +void Splitter::splitSendFinished(TDEIO::Job *job) +{ + splitWriteJob = 0; /* TDEIO automatically deletes the object after Finished signal */ + + if( job->error() ) /* any error occurred? */ + { + splitAbortJobs(); + KMessageBox::error(0, i18n("Error writing file %1!").arg( vfs::pathOrURL( writeURL ) ) ); + emit reject(); + return; + } + + if( transferArray.size() ) /* any data remained in the transfer buffer? */ + splitCreateWriteJob(); /* create a new write job */ + else + { + /* writing the split information file out */ + writeURL = destinationDir; + writeURL.addPath( fileName.fileName() + ".crc" ); + splitWriteJob = TDEIO::put( writeURL, permissions, true, false, false ); + connect(splitWriteJob, TQ_SIGNAL(dataReq(TDEIO::Job *, TQByteArray &)), + this, TQ_SLOT(splitFileSend(TDEIO::Job *, TQByteArray &))); + connect(splitWriteJob, TQ_SIGNAL(result(TDEIO::Job*)), + this, TQ_SLOT(splitFileFinished(TDEIO::Job *))); + } +} + +void Splitter::splitAbortJobs() +{ + if( splitReadJob ) + splitReadJob->kill(); + if( splitWriteJob ) + splitWriteJob->kill(); + + splitReadJob = splitWriteJob = 0; +} + +void Splitter::splitFileSend(TDEIO::Job *, TQByteArray &byteArray) +{ + const char *content = splitFile.ascii(); + byteArray.duplicate( content, strlen ( content ) ); + splitFile = ""; +} + +void Splitter::splitFileFinished(TDEIO::Job *job) +{ + splitWriteJob = 0; /* TDEIO automatically deletes the object after Finished signal */ + + if( job->error() ) /* any error occurred? */ + { + KMessageBox::error(0, i18n("Error at writing file %1!").arg( vfs::pathOrURL( writeURL ) ) ); + emit reject(); + return; + } + + emit accept(); +} + +#include "splitter.moc" diff --git a/src/app/Splitter/splitter.h b/src/app/Splitter/splitter.h new file mode 100644 index 0000000..ce10f4f --- /dev/null +++ b/src/app/Splitter/splitter.h @@ -0,0 +1,84 @@ +/*************************************************************************** + splitter.h - description + ------------------- + copyright : (C) 2003 by Csaba Karai + e-mail : krusader@users.sourceforge.net + web site : http://krusader.sourceforge.net + --------------------------------------------------------------------------- + Description + *************************************************************************** + + A + + db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b. + 88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D + 88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY' + 88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b + 88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88. + YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD + + H e a d e r F i l e + + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef __SPLITTER_H__ +#define __SPLITTER_H__ + +#include "crc32.h" +#include <tqstring.h> +#include <tqprogressdialog.h> +#include <kurl.h> +#include <tdeio/jobclasses.h> + +class Splitter : public TQProgressDialog +{ + TQ_OBJECT + + +private: + KURL fileName; + KURL destinationDir; + TDEIO::filesize_t splitSize; + + TDEIO::filesize_t fileSize; + int permissions; + TQString splitFile; + + KURL writeURL; + int fileNumber; + TDEIO::filesize_t outputFileSize; + bool noValidWriteJob; + CRC32 *crcContext; + TQByteArray transferArray; + + TDEIO::TransferJob *splitReadJob; + TDEIO::TransferJob *splitWriteJob; + +public: + Splitter( TQWidget* parent, KURL fileNameIn, KURL destinationDirIn ); + ~Splitter(); + + void split( TDEIO::filesize_t splitSizeIn ); + +private: + void splitCreateWriteJob(); + void splitAbortJobs(); + +public slots: + void splitDataReceived(TDEIO::Job *, const TQByteArray &); + void splitDataSend(TDEIO::Job *, TQByteArray &); + void splitSendFinished(TDEIO::Job *); + void splitReceiveFinished(TDEIO::Job *); + void splitReceivePercent (TDEIO::Job *, unsigned long); + void splitFileSend(TDEIO::Job *, TQByteArray &); + void splitFileFinished(TDEIO::Job *); +}; + +#endif /* __SPLITTER_H__ */ diff --git a/src/app/Splitter/splittergui.cpp b/src/app/Splitter/splittergui.cpp new file mode 100644 index 0000000..d2a4def --- /dev/null +++ b/src/app/Splitter/splittergui.cpp @@ -0,0 +1,213 @@ +/*************************************************************************** + splittergui.cpp - description + ------------------- + copyright : (C) 2003 by Csaba Karai + e-mail : krusader@users.sourceforge.net + web site : http://krusader.sourceforge.net + --------------------------------------------------------------------------- + Description + *************************************************************************** + + A + + db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b. + 88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D + 88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY' + 88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b + 88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88. + YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD + + S o u r c e F i l e + + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "splittergui.h" +#include "../VFS/vfs.h" +#include <tdelocale.h> +#include <tqlayout.h> +#include <tqlabel.h> +#include <tdemessagebox.h> + +PredefinedDevice SplitterGUI::predefinedDevices[] = { + {i18n( "1.44 MB (3.5\")" ), 1457664}, + {i18n( "1.2 MB (5.25\")" ), 1213952}, + {i18n( "720 kB (3.5\")" ), 730112}, + {i18n( "360 kB (5.25\")" ), 362496}, + {i18n( "100 MB (ZIP)" ), 100431872}, + {i18n( "250 MB (ZIP)" ), 250331136}, + {i18n( "650 MB (CD-R)" ), 650*0x100000}, + {i18n( "700 MB (CD-R)" ), 700*0x100000} + }; + +SplitterGUI::SplitterGUI( TQWidget* parent, KURL fileURL, KURL defaultDir ) : + TQDialog( parent, "Krusader::SplitterGUI", true, 0 ), + userDefinedSize ( 0x100000 ), lastSelectedDevice( 0 ), resultCode( TQDialog::Rejected ) +{ + predefinedDeviceNum = sizeof( predefinedDevices ) / sizeof( PredefinedDevice ); + + TQGridLayout *grid = new TQGridLayout( this ); + grid->setSpacing( 6 ); + grid->setMargin( 11 ); + + TQLabel *splitterLabel = new TQLabel( this, "SplitterLabel" ); + splitterLabel->setText( i18n( "Split the file %1 to directory:" ).arg( vfs::pathOrURL( fileURL ) ) ); + splitterLabel->setMinimumWidth( 400 ); + grid->addWidget( splitterLabel,0 ,0 ); + + urlReq = new KURLRequester( this, "DestinationDirectory" ); + urlReq->setURL( vfs::pathOrURL( defaultDir ) ); + urlReq->setMode( KFile::Directory ); + grid->addWidget( urlReq, 1 ,0 ); + + TQHBox *splitSizeLine = new TQHBox( this, "splitSizeLine" ); + + deviceCombo = new TQComboBox( splitSizeLine, "deviceCombo" ); + for( int i=0; i != predefinedDeviceNum; i++ ) + deviceCombo->insertItem( predefinedDevices[i].name ); + deviceCombo->insertItem( i18n( "User Defined" ) ); + + TQLabel *spacer = new TQLabel( splitSizeLine ); + spacer->setText( " " ); + spacer->setSizePolicy( TQSizePolicy::Expanding, TQSizePolicy::Minimum ); + + TQLabel *bytesPerFile = new TQLabel( splitSizeLine, "BytesPerFile" ); + bytesPerFile->setText( i18n( "Max file size:" ) ); + + spinBox = new SplitterSpinBox( splitSizeLine, "spinbox" ); + spinBox->setMinimumWidth( 85 ); + spinBox->setEnabled( false ); + + sizeCombo = new TQComboBox( splitSizeLine, "sizeCombo" ); + sizeCombo->insertItem( i18n( "Byte" ) ); + sizeCombo->insertItem( i18n( "kByte" ) ); + sizeCombo->insertItem( i18n( "MByte" ) ); + sizeCombo->insertItem( i18n( "GByte" ) ); + + grid->addWidget( splitSizeLine,2 ,0 ); + + TQFrame *separator = new TQFrame( this, "separatorLine" ); + separator->setFrameStyle( TQFrame::HLine | TQFrame::Sunken ); + separator->setFixedHeight( separator->sizeHint().height() ); + + grid->addWidget( separator,3 ,0 ); + + TQHBoxLayout *splitButtons = new TQHBoxLayout; + splitButtons->setSpacing( 6 ); + splitButtons->setMargin( 0 ); + + TQSpacerItem* spacer2 = new TQSpacerItem( 0, 0, TQSizePolicy::Expanding, TQSizePolicy::Minimum ); + splitButtons->addItem( spacer2 ); + + TQPushButton *splitBtn = new TQPushButton( this, "splitBtn" ); + splitBtn->setText( i18n("&Split") ); + splitButtons->addWidget( splitBtn ); + + TQPushButton *cancelBtn = new TQPushButton( this, "cancelBtn" ); + cancelBtn->setText( i18n("&Cancel") ); + splitButtons->addWidget( cancelBtn ); + + grid->addLayout( splitButtons,4 ,0 ); + + setCaption(i18n("Krusader::Splitter")); + + connect( sizeCombo, TQ_SIGNAL( activated(int) ), this, TQ_SLOT( sizeComboActivated( int ) ) ); + connect( deviceCombo, TQ_SIGNAL( activated(int) ), this, TQ_SLOT( predefinedComboActivated( int ) ) ); + connect( cancelBtn, TQ_SIGNAL( clicked() ), this, TQ_SLOT( reject() ) ); + connect( splitBtn , TQ_SIGNAL( clicked() ), this, TQ_SLOT( splitPressed() ) ); + + predefinedComboActivated( 0 ); + resultCode = exec(); +} + +void SplitterGUI::sizeComboActivated( int item ) +{ + switch ( item ) + { + case 0: + spinBox->setDivision( 1 ); /* byte */ + break; + case 1: + spinBox->setDivision( 0x400 ); /* kbyte */ + break; + case 2: + spinBox->setDivision( 0x100000 ); /* Mbyte */ + break; + case 3: + spinBox->setDivision( 0x40000000 ); /* Gbyte */ + break; + } +} + +void SplitterGUI::predefinedComboActivated( int item ) +{ + int capacity = userDefinedSize; + + if( item < predefinedDeviceNum ) + { + if( lastSelectedDevice == predefinedDeviceNum ) + userDefinedSize = spinBox->longValue(); + + spinBox->setEnabled( false ); + capacity = predefinedDevices[item].capacity; + } + else + spinBox->setEnabled( true ); + + spinBox->setLongValue( capacity ); + + if( capacity >= 0x40000000 ) /* Gbyte */ + { + sizeCombo->setCurrentItem( 3 ); + spinBox->setDivision( 0x40000000 ); + } + else if( capacity >= 0x100000 ) /* Mbyte */ + { + sizeCombo->setCurrentItem( 2 ); + spinBox->setDivision( 0x100000 ); + } + else if( capacity >= 0x400 ) /* kbyte */ + { + sizeCombo->setCurrentItem( 1 ); + spinBox->setDivision( 0x400 ); + } + else + { + sizeCombo->setCurrentItem( 0 ); /* byte */ + spinBox->setDivision( 1 ); + } + + lastSelectedDevice = item; +} + +void SplitterGUI::splitPressed() +{ + if( !vfs::fromPathOrURL( urlReq->url() ).isValid() ) + { + KMessageBox::error( this, i18n("The directory path URL is malformed!") ); + return; + } + + emit accept(); +} + +void SplitterGUI::keyPressEvent( TQKeyEvent *e ) +{ + switch ( e->key() ) + { + case Key_Enter : + case Key_Return : + emit splitPressed(); + return; + default: + TQDialog::keyPressEvent( e ); + } +} + +#include "splittergui.moc" diff --git a/src/app/Splitter/splittergui.h b/src/app/Splitter/splittergui.h new file mode 100644 index 0000000..10f23bc --- /dev/null +++ b/src/app/Splitter/splittergui.h @@ -0,0 +1,180 @@ +/*************************************************************************** + splittergui.h - description + ------------------- + copyright : (C) 2003 by Csaba Karai + e-mail : krusader@users.sourceforge.net + web site : http://krusader.sourceforge.net + --------------------------------------------------------------------------- + Description + *************************************************************************** + + A + + db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b. + 88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D + 88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY' + 88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b + 88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88. + YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD + + H e a d e r F i l e + + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef __SPLITTERGUI_H__ +#define __SPLITTERGUI_H__ + +#include <tqdialog.h> +#include <tqstring.h> +#include <tqspinbox.h> +#include <tqvalidator.h> +#include <tqcombobox.h> +#include <kurlrequester.h> +#include <tdeio/global.h> + +#include "../VFS/vfs.h" + +struct PredefinedDevice +{ + TQString name; + TDEIO::filesize_t capacity; +}; + + class SplitterSpinBox : public TQSpinBox + { + TQ_OBJECT + + private: + TDEIO::filesize_t division; + TDEIO::filesize_t value; + + public: + SplitterSpinBox ( TQWidget * parent = 0, const char * name = 0 ) : TQSpinBox( parent, name ), division( 1 ), value( 1 ) + { + setMaxValue( 0x7FFFFFFF ); /* setting the minimum and maximum values */ + setMinValue( 1 ); + TQDoubleValidator *dval = new TQDoubleValidator( this ); + setValidator ( dval ); + } + + void setLongValue( TDEIO::filesize_t valueIn ) { + value = valueIn; + if( value == 0 ) + value++; + updateDisplay(); + } + + TDEIO::filesize_t longValue() { + TDEIO::filesize_t val = (TDEIO::filesize_t)( division * text().toDouble() + 0.5 ) ; + if( val == 0 ) + val++; + return val; + } + + TQString mapValueToText( int ) + { + TQString frac(""); + + TDEIO::filesize_t int_part = value / division; + TDEIO::filesize_t frac_mod = value % division; + + if( frac_mod ) + { + TDEIO::filesize_t frac_part = (TDEIO::filesize_t)((1000. * frac_mod) /division + 0.5); + + if( frac_part ) + { + frac = TQString( "%1" ).arg( frac_part ).rightJustify( 3, '0' ); + frac = "." + frac; + while( frac.endsWith("0") ) + frac.truncate( frac.length() - 1 ); + } + } + + return TQString( "%1%2" ).arg( int_part ).arg( frac ); + } + + int mapTextToValue( bool * ) + { + value = longValue(); + + if( value > 0x7FFFFFFF ) + return 0x7FFFFFFF; + else + return value; + } + + void setDivision( TDEIO::filesize_t div ) + { + division = div; + updateDisplay(); + } + + public slots: + + void stepUp() + { + value = longValue(); + + if( value + division > value ) + value += division; + updateDisplay(); + } + + void stepDown() + { + value = longValue(); + + if( value < division + 1 ) + value = 1; + else + value -= division; + updateDisplay(); + } + }; + +class SplitterGUI : TQDialog +{ + TQ_OBJECT + + +private: + int predefinedDeviceNum; + TDEIO::filesize_t userDefinedSize; + int lastSelectedDevice; + int resultCode; + + static PredefinedDevice predefinedDevices[]; + + SplitterSpinBox *spinBox; + TQComboBox *deviceCombo; + TQComboBox *sizeCombo; + KURLRequester *urlReq; + +public: + SplitterGUI( TQWidget* parent, KURL fileURL, KURL defaultDir ); + + KURL getDestinationDir() {return vfs::fromPathOrURL( urlReq->url() );} + TDEIO::filesize_t getSplitSize() {return spinBox->longValue();} + int result() {return resultCode;} + +public slots: + virtual void sizeComboActivated( int item ); + virtual void predefinedComboActivated( int item ); + virtual void splitPressed(); + +protected: + virtual void keyPressEvent( TQKeyEvent *e ); + +public: + +}; + +#endif /* __SPLITTERGUI_H__ */ |