summaryrefslogtreecommitdiffstats
path: root/src/app/Splitter
diff options
context:
space:
mode:
Diffstat (limited to 'src/app/Splitter')
-rw-r--r--src/app/Splitter/Makefile.am11
-rw-r--r--src/app/Splitter/combiner.cpp328
-rw-r--r--src/app/Splitter/combiner.h93
-rw-r--r--src/app/Splitter/crc32.cpp69
-rw-r--r--src/app/Splitter/crc32.h48
-rw-r--r--src/app/Splitter/splitter.cpp252
-rw-r--r--src/app/Splitter/splitter.h84
-rw-r--r--src/app/Splitter/splittergui.cpp213
-rw-r--r--src/app/Splitter/splittergui.h180
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__ */