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>
pull/1/head
Alexander Golubev 8 years ago committed by Michele Calgaro
parent 058176316e
commit 8cf274c35a

@ -72,13 +72,13 @@ int FileLVI::compare( TQListViewItem * i, int column, bool ascending ) const
if ( ( this->childCount() > 0 ) && ( item->childCount() == 0 ) )
return -1;
if ( ( this->childCount() == 0 ) && ( item->childCount() > 0 ) )
return 1;
if ( column == 0 )
return TDEListViewItem::compare( i, column, ascending );
columnName colName = ( static_cast< FileListView * > ( listView() ) )->nameOfColumn( column );
switch ( colName )
{
@ -170,6 +170,17 @@ void FileLVI::setText( int column, const TQString &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 )
{
FileLVI *folder = new FileLVI( parent );
@ -383,7 +394,7 @@ FileListView::item(const TQString& filename) const
return 0;
}
void FileListView::addItem( const TQStringList & entries )
FileLVI *FileListView::addItem( const TQStringList & entries )
{
FileLVI *flvi, *parent = findParent( entries[0] );
if ( parent )
@ -391,72 +402,23 @@ void FileListView::addItem( const TQStringList & entries )
else
flvi = new FileLVI( this );
int i = 0;
for (TQStringList::ConstIterator it = entries.begin(); it != entries.end(); ++it)
{
flvi->setText(i, *it);
++i;
}
flvi->setItemData (entries);
KMimeType::Ptr mimeType = KMimeType::findByPath( entries.first(), 0, true );
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] );
// Checks if the listview contains the first item in the list of ancestors
TQListViewItem *item = firstChild();
while ( item )
{
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();
FileLVI *flvi = item ( entries[0] );
if (flvi) {
flvi->setItemData (entries);
return flvi;
} else {
return addItem (entries);
}
int i = 0;
for (TQStringList::ConstIterator it = entries.begin(); it != entries.end(); ++it)
{
item->setText(i, *it);
++i;
}
item->setOpen( true );
}
void FileListView::selectAll()
@ -481,7 +443,7 @@ void FileListView::setHeaders( const ColumnList& columns )
int colnum = addColumn( pair.first );
setColumnAlignment( colnum, pair.second );
}
setResizeMode( TQListView::LastColumn );
header()->show();

@ -60,6 +60,8 @@ class FileLVI : public TDEListViewItem
int compare ( TQListViewItem * i, int col, bool ascending ) const;
virtual TQString key( int column, bool ) const;
virtual void setText( int column, const TQString &text );
/// Set the data for model entry all at once
void setItemData( const TQStringList &entryData );
private:
TDEIO::filesize_t m_fileSize;
@ -74,7 +76,7 @@ typedef TQValueList< TQPair< TQString, TQt::AlignmentFlags > > ColumnList;
class FileListView: public TDEListView
{
Q_OBJECT
public:
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
* @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.
* @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.
*/

@ -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 );
}

Loading…
Cancel
Save