summaryrefslogtreecommitdiffstats
path: root/ark/rar.cpp
diff options
context:
space:
mode:
authorAlexander Golubev <fatzer2@gmail.com>2016-05-07 13:20:21 +1000
committerMichele Calgaro <michele.calgaro@yahoo.it>2016-05-07 13:20:21 +1000
commit8cf274c35a83bf829a54cf22f0c82fdbfb333c03 (patch)
tree6b10045d63fe191bae8dcdcaa3b3a89507a9c570 /ark/rar.cpp
parent058176316ee0b92a9d50d0c842690869af09e3de (diff)
downloadtdeutils-8cf274c35a83bf829a54cf22f0c82fdbfb333c03.tar.gz
tdeutils-8cf274c35a83bf829a54cf22f0c82fdbfb333c03.zip
Removed crappy FileListView::updateItem() method and replace it with addOrUpdateItem()
Enhanced in several ways parsing of rar-5+ output (fixes a crash and several potential issues) Spacing fixes Minor modification: replace assert with if() Signed-off-by: Michele Calgaro <michele.calgaro@yahoo.it>
Diffstat (limited to 'ark/rar.cpp')
-rw-r--r--ark/rar.cpp169
1 files changed, 87 insertions, 82 deletions
diff --git a/ark/rar.cpp b/ark/rar.cpp
index 103f4ce..02600d5 100644
--- a/ark/rar.cpp
+++ b/ark/rar.cpp
@@ -30,6 +30,8 @@
#include <string>
// QT includes
+#include <tqstring.h>
+#include <tqregexp.h>
#include <tqfile.h>
#include <tqdir.h>
#include <tqtextcodec.h>
@@ -39,6 +41,7 @@
#include <tdeglobal.h>
#include <tdelocale.h>
#include <tdemessagebox.h>
+#include <kmimetype.h>
#include <kpassdlg.h>
#include <kprocess.h>
#include <kstandarddirs.h>
@@ -83,94 +86,96 @@ RarArch::RarArch( ArkWidget *_gui, const TQString & _fileName )
verifyUncompressUtilityIsAvailable( m_unarchiver_program );
setReadOnly( true );
}
-
- m_headerString = "";
}
bool RarArch::processLine( const TQCString &line )
{
- TQString unicode_line;
-
- TQTextCodec *codec = TQTextCodec::codecForLocale();
- unicode_line = codec->toUnicode( line );
-
- // Look for rar/unrar version first
- if (!m_version)
- {
- if (line.left(3) == "RAR")
- {
- bool ok_flag = false;
- short version = line.mid(4, 1).toShort(&ok_flag);
- if (ok_flag)
- {
- m_version = version;
- if (m_version < VERSION_5)
- {
- m_headerString = "-------------------------------------------------------------------------------";
- m_isFirstLine = true;
- }
- else
- {
- m_headerString = "----------- --------- -------- ----- ---------- ----- -------- ----";
- }
- setHeaders();
- return true;
- }
- }
- return false;
- }
-
- if (m_version < VERSION_5 && m_isFirstLine)
+ TQString uline = TQTextCodec::codecForLocale()->toUnicode(line);
+
+ // Look for rar/unrar version first
+ if (!m_version)
{
- m_entryFilename = TQString::fromLocal8Bit( line );
- m_entryFilename.remove( 0, 1 );
- m_isFirstLine = false;
- return true;
+ TQRegExp versionRegExp (TQString::fromLatin1 ("RAR\\s(\\d+)\\.(\\S+)\\s.*"));
+
+ if (versionRegExp.exactMatch (uline))
+ {
+ m_version = versionRegExp.capturedTexts()[1].toShort ();
+
+ if (m_version < VERSION_5) {
+ m_headerString = "-------------------------------------------------------------------------------";
+ m_isFirstLine = true;
+ } else {
+ m_headerString = "----------- --------- -------- ----- ---------- ----- -------- ----";
+ }
+ setHeaders(); //< Note: header order for version 5 is different, but keep the old one for consistency
+ return true;
+ }
+ return false;
}
- TQStringList list;
- TQStringList l2 = TQStringList::split( ' ', line );
+ TQStringList entry;
+ TQStringList parsedData = TQStringList::split(QChar(' '), uline);
- if (m_version < VERSION_5)
+ if (m_version < VERSION_5) {
+ if (m_isFirstLine)
+ {
+ m_entryFilename = uline.remove( 0, 1 );
+ m_isFirstLine = false;
+ return true;
+ }
+
+ if (parsedData.size() < 9) {
+ kdError ( 1601 ) << "Failed to parse rar<5 output string: \"" << uline << "\"" << endl;
+ }
+
+ entry << m_entryFilename; // filename
+ entry << parsedData[ 0 ]; // size
+ entry << parsedData[ 1 ]; // packed
+ entry << parsedData[ 2 ]; // ratio
+
+ TQStringList date = TQStringList::split( '-', parsedData[ 3 ] );
+ entry << ArkUtils::fixYear( date[ 2 ].latin1() ) + '-' + date[ 1 ] + '-' + date [ 0 ] + ' ' + parsedData[4]; // date
+ entry << parsedData[ 5 ]; // attributes
+ entry << parsedData[ 6 ]; // crc
+ entry << parsedData[ 7 ]; // method
+ entry << parsedData[ 8 ]; // Version
+
+ m_isFirstLine = true;
+ }
+ else
{
- list << m_entryFilename; // filename
- list << l2[ 0 ]; // size
- list << l2[ 1 ]; // packed
- list << l2[ 2 ]; // ratio
-
- TQStringList date = TQStringList::split( '-', l2[ 3 ] );
- list << ArkUtils::fixYear( date[ 2 ].latin1() ) + '-' + date[ 1 ] + '-' + date [ 0 ] + ' ' + l2[4]; // date
- list << l2[ 5 ]; // attributes
- list << l2[ 6 ]; // crc
- list << l2[ 7 ]; // method
- list << l2[ 8 ]; // Version
-
- m_isFirstLine = true;
- }
- else
- {
- m_entryFilename = line.mid(line.find(l2[7]));
- list << m_entryFilename; // filename
- list << l2[ 1 ]; // size
- list << l2[ 2 ]; // packed
- list << l2[ 3 ]; // ratio
-
- TQStringList date = TQStringList::split('-', l2[4]);
- list << l2[ 4 ] + " " + l2[ 5 ]; // date and time
- list << l2[ 0 ]; // attributes
- list << l2[ 6 ]; // crc
- }
- // send to GUI
- if ( l2[6] == "00000000" )
- {
- // folders have CRC equal to 00000000
- // RAR utilities show the folders at the end of the listing so the folders
- // have been already added to the listview at this point without specifying
- // all the columns but the name. Update the item with the missing info
- m_gui->fileList()->updateItem( list );
- }
- else
- m_gui->fileList()->addItem( list );
+ // Note: don't use parsedData for names due to they may contain trailing spaces
+ TQRegExp nameRegExp (TQString::fromLatin1 ("\\s*(\\S+\\s+){6}\\S+ (.*)"));
+
+ if (parsedData.size() >= 8 && nameRegExp.exactMatch (uline)) {
+ m_entryFilename = nameRegExp.capturedTexts()[2];
+
+ entry << m_entryFilename; // filename
+ entry << parsedData[ 1 ]; // size
+ entry << parsedData[ 2 ]; // packed
+ entry << parsedData[ 3 ]; // ratio
+
+ entry << parsedData[ 4 ] + " " + parsedData[ 5 ]; // date and time
+ entry << parsedData[ 0 ]; // attributes
+ entry << parsedData[ 6 ]; // crc
+ } else {
+ kdError ( 1601 ) << "Failed to parse rar-5+ output string: \"" << uline << "\"" << endl;
+ return false;
+ }
+ }
+
+ // send to GUI
+ // Use addOrUpdateItem() rather than addItem() due to recent RAR version
+ // place directories in archive after their content.
+ FileLVI *item = m_gui->fileList()->addOrUpdateItem( entry );
+
+ // But archives packaged with older versions of ark may have directories
+ // entries first, so make sure they will get an appropriate icon
+ if (item && entry[5].find('d', 0, false) != -1) {
+ // check attr's for d (case insensitive to handle windows archives)
+ item->setPixmap( 0, KMimeType::mimeType( "inode/directory" )->pixmap( TDEIcon::Small ) );
+ }
+
return true;
}
@@ -216,9 +221,9 @@ void RarArch::setHeaders()
list.append( CRC_COLUMN );
if (m_version < VERSION_5)
{
- list.append( METHOD_COLUMN );
- list.append( VERSION_COLUMN );
- }
+ list.append( METHOD_COLUMN );
+ list.append( VERSION_COLUMN );
+ }
emit headers( list );
}