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>

(cherry picked from commit 8cf274c35a)
pull/30/head
Alexander Golubev 9 years ago committed by Michele Calgaro
parent 1ac492f796
commit 711e6bf0e6

@ -72,13 +72,13 @@ int FileLVI::compare( TQListViewItem * i, int column, bool ascending ) const
if ( ( this->childCount() > 0 ) && ( item->childCount() == 0 ) ) if ( ( this->childCount() > 0 ) && ( item->childCount() == 0 ) )
return -1; return -1;
if ( ( this->childCount() == 0 ) && ( item->childCount() > 0 ) ) if ( ( this->childCount() == 0 ) && ( item->childCount() > 0 ) )
return 1; return 1;
if ( column == 0 ) if ( column == 0 )
return TDEListViewItem::compare( i, column, ascending ); return TDEListViewItem::compare( i, column, ascending );
columnName colName = ( static_cast< FileListView * > ( listView() ) )->nameOfColumn( column ); columnName colName = ( static_cast< FileListView * > ( listView() ) )->nameOfColumn( column );
switch ( colName ) switch ( colName )
{ {
@ -170,6 +170,17 @@ void FileLVI::setText( int column, const TQString &text )
TQListViewItem::setText(column, text); TQListViewItem::setText(column, text);
} }
void FileLVI::setItemData( const TQStringList &entryData )
{
int i = 0;
for (TQStringList::ConstIterator it = entryData.begin(); it != entryData.end(); ++it)
{
this->setText(i, *it);
++i;
}
}
static FileLVI* folderLVI( TDEListViewItem *parent, const TQString& name ) static FileLVI* folderLVI( TDEListViewItem *parent, const TQString& name )
{ {
FileLVI *folder = new FileLVI( parent ); FileLVI *folder = new FileLVI( parent );
@ -383,7 +394,7 @@ FileListView::item(const TQString& filename) const
return 0; return 0;
} }
void FileListView::addItem( const TQStringList & entries ) FileLVI *FileListView::addItem( const TQStringList & entries )
{ {
FileLVI *flvi, *parent = findParent( entries[0] ); FileLVI *flvi, *parent = findParent( entries[0] );
if ( parent ) if ( parent )
@ -391,72 +402,23 @@ void FileListView::addItem( const TQStringList & entries )
else else
flvi = new FileLVI( this ); flvi = new FileLVI( this );
flvi->setItemData (entries);
int i = 0;
for (TQStringList::ConstIterator it = entries.begin(); it != entries.end(); ++it)
{
flvi->setText(i, *it);
++i;
}
KMimeType::Ptr mimeType = KMimeType::findByPath( entries.first(), 0, true ); KMimeType::Ptr mimeType = KMimeType::findByPath( entries.first(), 0, true );
flvi->setPixmap( 0, mimeType->pixmap( TDEIcon::Small ) ); flvi->setPixmap( 0, mimeType->pixmap( TDEIcon::Small ) );
return flvi;
} }
void FileListView::updateItem( const TQStringList &entries ) FileLVI *FileListView::addOrUpdateItem( const TQStringList &entries )
{ {
TQStringList ancestorList = TQStringList::split( '/', entries[0] ); FileLVI *flvi = item ( entries[0] );
if (flvi) {
// Checks if the listview contains the first item in the list of ancestors flvi->setItemData (entries);
TQListViewItem *item = firstChild(); return flvi;
while ( item ) } else {
{ return addItem (entries);
if ( item->text( 0 ) == ancestorList[0] || item->text( 0 ) == ancestorList[0].stripWhiteSpace())
break;
item = item->nextSibling();
}
// If the list view does not contain the item ...
if ( !item )
{
kdError( 1601 ) << ancestorList[0] << " not found" << endl;
return;
}
// We've already dealt with the first item, remove it
ancestorList.pop_front();
while ( ancestorList.count() > 0 )
{
TQString name = ancestorList[0];
FileLVI *parent = static_cast< FileLVI*>( item );
item = parent->firstChild();
while ( item )
{
if ( item->text(0) == name )
break;
item = item->nextSibling();
}
if ( !item )
{
kdError( 1601 ) << name << " not found" << endl;
return;
}
ancestorList.pop_front();
} }
int i = 0;
for (TQStringList::ConstIterator it = entries.begin(); it != entries.end(); ++it)
{
item->setText(i, *it);
++i;
}
item->setOpen( true );
} }
void FileListView::selectAll() void FileListView::selectAll()
@ -481,7 +443,7 @@ void FileListView::setHeaders( const ColumnList& columns )
int colnum = addColumn( pair.first ); int colnum = addColumn( pair.first );
setColumnAlignment( colnum, pair.second ); setColumnAlignment( colnum, pair.second );
} }
setResizeMode( TQListView::LastColumn ); setResizeMode( TQListView::LastColumn );
header()->show(); header()->show();

@ -60,6 +60,8 @@ class FileLVI : public TDEListViewItem
int compare ( TQListViewItem * i, int col, bool ascending ) const; int compare ( TQListViewItem * i, int col, bool ascending ) const;
virtual TQString key( int column, bool ) const; virtual TQString key( int column, bool ) const;
virtual void setText( int column, const TQString &text ); virtual void setText( int column, const TQString &text );
/// Set the data for model entry all at once
void setItemData( const TQStringList &entryData );
private: private:
TDEIO::filesize_t m_fileSize; TDEIO::filesize_t m_fileSize;
@ -74,7 +76,7 @@ typedef TQValueList< TQPair< TQString, TQt::AlignmentFlags > > ColumnList;
class FileListView: public TDEListView class FileListView: public TDEListView
{ {
Q_OBJECT Q_OBJECT
public: public:
FileListView( TQWidget *parent = 0, const char* name = 0 ); FileListView( TQWidget *parent = 0, const char* name = 0 );
@ -109,15 +111,17 @@ class FileListView: public TDEListView
/** /**
* Adds a file and stats to the file listing * Adds a file and stats to the file listing
* @param entries A stringlist of the entries for each column of the list. * @param entries A stringlist of the entries for each column of the list.
* @return The newly added FileLVI
*/ */
void addItem( const TQStringList& entries ); FileLVI* addItem( const TQStringList& entries );
/** /**
* Updates a file or folder item already included in the listview * Adds a file and stats if it doesn't exists or updates the existing one
* @param entries A stringlist of the updated entries for each column of the list. * @param entries A stringlist of the updated entries for each column of the list.
* @return The newly added or the updated FileLVI
*/ */
void updateItem( const TQStringList& entries ); FileLVI* addOrUpdateItem( const TQStringList& entries );
/** /**
* Returns the number of files in the archive. * Returns the number of files in the archive.
*/ */

@ -30,6 +30,8 @@
#include <string> #include <string>
// QT includes // QT includes
#include <tqstring.h>
#include <tqregexp.h>
#include <tqfile.h> #include <tqfile.h>
#include <tqdir.h> #include <tqdir.h>
#include <tqtextcodec.h> #include <tqtextcodec.h>
@ -39,6 +41,7 @@
#include <tdeglobal.h> #include <tdeglobal.h>
#include <tdelocale.h> #include <tdelocale.h>
#include <tdemessagebox.h> #include <tdemessagebox.h>
#include <kmimetype.h>
#include <kpassdlg.h> #include <kpassdlg.h>
#include <kprocess.h> #include <kprocess.h>
#include <kstandarddirs.h> #include <kstandarddirs.h>
@ -83,94 +86,96 @@ RarArch::RarArch( ArkWidget *_gui, const TQString & _fileName )
verifyUncompressUtilityIsAvailable( m_unarchiver_program ); verifyUncompressUtilityIsAvailable( m_unarchiver_program );
setReadOnly( true ); setReadOnly( true );
} }
m_headerString = "";
} }
bool RarArch::processLine( const TQCString &line ) bool RarArch::processLine( const TQCString &line )
{ {
TQString unicode_line; TQString uline = TQTextCodec::codecForLocale()->toUnicode(line);
TQTextCodec *codec = TQTextCodec::codecForLocale(); // Look for rar/unrar version first
unicode_line = codec->toUnicode( line ); if (!m_version)
// 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)
{ {
m_entryFilename = TQString::fromLocal8Bit( line ); TQRegExp versionRegExp (TQString::fromLatin1 ("RAR\\s(\\d+)\\.(\\S+)\\s.*"));
m_entryFilename.remove( 0, 1 );
m_isFirstLine = false; if (versionRegExp.exactMatch (uline))
return true; {
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 entry;
TQStringList l2 = TQStringList::split( ' ', line ); 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 // Note: don't use parsedData for names due to they may contain trailing spaces
list << l2[ 0 ]; // size TQRegExp nameRegExp (TQString::fromLatin1 ("\\s*(\\S+\\s+){6}\\S+ (.*)"));
list << l2[ 1 ]; // packed
list << l2[ 2 ]; // ratio if (parsedData.size() >= 8 && nameRegExp.exactMatch (uline)) {
m_entryFilename = nameRegExp.capturedTexts()[2];
TQStringList date = TQStringList::split( '-', l2[ 3 ] );
list << ArkUtils::fixYear( date[ 2 ].latin1() ) + '-' + date[ 1 ] + '-' + date [ 0 ] + ' ' + l2[4]; // date entry << m_entryFilename; // filename
list << l2[ 5 ]; // attributes entry << parsedData[ 1 ]; // size
list << l2[ 6 ]; // crc entry << parsedData[ 2 ]; // packed
list << l2[ 7 ]; // method entry << parsedData[ 3 ]; // ratio
list << l2[ 8 ]; // Version
entry << parsedData[ 4 ] + " " + parsedData[ 5 ]; // date and time
m_isFirstLine = true; entry << parsedData[ 0 ]; // attributes
} entry << parsedData[ 6 ]; // crc
else } else {
{ kdError ( 1601 ) << "Failed to parse rar-5+ output string: \"" << uline << "\"" << endl;
m_entryFilename = line.mid(line.find(l2[7])); return false;
list << m_entryFilename; // filename }
list << l2[ 1 ]; // size }
list << l2[ 2 ]; // packed
list << l2[ 3 ]; // ratio // send to GUI
// Use addOrUpdateItem() rather than addItem() due to recent RAR version
TQStringList date = TQStringList::split('-', l2[4]); // place directories in archive after their content.
list << l2[ 4 ] + " " + l2[ 5 ]; // date and time FileLVI *item = m_gui->fileList()->addOrUpdateItem( entry );
list << l2[ 0 ]; // attributes
list << l2[ 6 ]; // crc // But archives packaged with older versions of ark may have directories
} // entries first, so make sure they will get an appropriate icon
// send to GUI if (item && entry[5].find('d', 0, false) != -1) {
if ( l2[6] == "00000000" ) // check attr's for d (case insensitive to handle windows archives)
{ item->setPixmap( 0, KMimeType::mimeType( "inode/directory" )->pixmap( TDEIcon::Small ) );
// 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 );
return true; return true;
} }
@ -216,9 +221,9 @@ void RarArch::setHeaders()
list.append( CRC_COLUMN ); list.append( CRC_COLUMN );
if (m_version < VERSION_5) if (m_version < VERSION_5)
{ {
list.append( METHOD_COLUMN ); list.append( METHOD_COLUMN );
list.append( VERSION_COLUMN ); list.append( VERSION_COLUMN );
} }
emit headers( list ); emit headers( list );
} }

Loading…
Cancel
Save