filemanager/src/filemanager/src/fmfindresultmodel.cpp
changeset 37 15bc28c9dd51
parent 16 ada7962b4308
child 46 d58987eac7e8
equal deleted inserted replaced
16:ada7962b4308 37:15bc28c9dd51
    16  *     The find result model source file of file manager
    16  *     The find result model source file of file manager
    17  */
    17  */
    18 
    18 
    19 #include "fmfindresultmodel.h"
    19 #include "fmfindresultmodel.h"
    20 #include "fmfindthread.h"
    20 #include "fmfindthread.h"
       
    21 #include "fmfileiconprovider.h"
    21 
    22 
    22 #include <QDateTime>
    23 #include <QDateTime>
    23 #include <QFileIconProvider>
    24 
       
    25 #include <hbglobal.h>
       
    26 
       
    27 /*!
       
    28     \fn void finished()
       
    29     This signal is emitted when find is finished.
       
    30 */
       
    31 
       
    32 /*!
       
    33     \fn void modelCountChanged( int count )
       
    34     This signal is emitted when data count in model is changed
       
    35     \a count is current data count in model.
       
    36     Currently only start find and get more find result will emit this signal.
       
    37 */
    24 
    38 
    25 FmFindResultModel::FmFindResultModel( QObject *parent )
    39 FmFindResultModel::FmFindResultModel( QObject *parent )
    26     : QAbstractListModel( parent )
    40     : QAbstractListModel( parent )
    27 {
    41 {
    28     init();
    42     init();
    29     connect( mFindThread, SIGNAL(finished()), this, SIGNAL(finished()) );
    43     connect( mFindThread, SIGNAL(finished()), this, SIGNAL(finished()) );
    30 	connect( mFindThread, SIGNAL(found(int)), this, SLOT(on_findThread_found( int) ), Qt::BlockingQueuedConnection ); 
    44 	connect( mFindThread, SIGNAL(found(QStringList)), this, SLOT(on_findThread_found( QStringList) ), Qt::BlockingQueuedConnection ); 
    31 }
    45 }
    32 
    46 
    33 FmFindResultModel::~FmFindResultModel()
    47 FmFindResultModel::~FmFindResultModel()
    34 {
    48 {
    35 	delete mIconProvider;
    49 	delete mIconProvider;
    36 }
    50 }
    37 
    51 
       
    52 /*!
       
    53     Returns the number of rows in the model. This value corresponds to the
       
    54     number of items in the model's internal string list.
       
    55 
       
    56     The optional \a parent argument is in most models used to specify
       
    57     the parent of the rows to be counted. Because this is a list if a
       
    58     valid parent is specified, the result will always be 0.
       
    59 
       
    60     \sa insertRows(), removeRows(), QAbstractItemModel::rowCount()
       
    61 */
    38 int FmFindResultModel::rowCount( const QModelIndex &parent ) const
    62 int FmFindResultModel::rowCount( const QModelIndex &parent ) const
    39 {
    63 {
    40     if (!parent.isValid())
    64     if ( !parent.isValid() )
    41         return mFindResult.size();
    65         return mFindResult.count();
    42 
    66 
    43     return 0;
    67     return 0;
    44 }
    68 }
    45 
    69 
    46 int FmFindResultModel::columnCount( const QModelIndex &parent ) const
    70 int FmFindResultModel::columnCount( const QModelIndex &parent ) const
    47 {
    71 {
    48     if (!parent.isValid())
    72     if ( !parent.isValid() )
    49         return 4;
    73         return 4;
    50     
    74     
    51     return 0;
    75     return 0;
    52 }
    76 }
    53 
    77 
    91     if (orientation == Qt::Horizontal) {
   115     if (orientation == Qt::Horizontal) {
    92         if (role != Qt::DisplayRole)
   116         if (role != Qt::DisplayRole)
    93             return QVariant();
   117             return QVariant();
    94 
   118 
    95         switch (section) {
   119         switch (section) {
    96             case 0: return tr("Name");
   120             case 0: return hbTrId("Name");
    97             case 1: return tr("Size");
   121             case 1: return hbTrId("Size");
    98             case 2: return tr("Type");
   122             case 2: return hbTrId("Type");
    99             case 3: return tr("Date Modified");
   123             case 3: return hbTrId("Date Modified");
   100             default: return QVariant();
   124             default: return QVariant();
   101         }
   125         }
   102     }
   126     }
   103 
   127 
   104     return QAbstractItemModel::headerData( section, orientation, role );
   128     return QAbstractItemModel::headerData( section, orientation, role );
   105 }
   129 }
   106 
   130 
   107 bool FmFindResultModel::insertRows( int row, int count, const QModelIndex &parent )
   131 /*!
   108 {
   132     Inserts \a dataList into the model, beginning at the given \a row.
   109     Q_UNUSED( parent );
   133 
   110 	if (row < 0 || count < 1)
   134     The \a parent index of the rows is optional and is only used for
       
   135     consistency with QAbstractItemModel. By default, a null index is
       
   136     specified, indicating that the rows are inserted in the top level of
       
   137     the model.
       
   138 
       
   139     \sa QAbstractItemModel::insertRows()
       
   140 */
       
   141 
       
   142 bool FmFindResultModel::insertRows( int row, const QStringList &dataList, const QModelIndex &parent )
       
   143 {
       
   144     if ( row < 0 || dataList.count() < 1 || row > rowCount(parent) )
   111 		return false;
   145 		return false;
   112 
   146 
   113 	beginInsertRows( QModelIndex(), row, row + count - 1 );
   147     beginInsertRows( QModelIndex(), row, row + dataList.count() - 1 );
   114 
   148     mFindResult.append( dataList );
   115 	endInsertRows();
   149     endInsertRows();
   116 
   150 
   117 	return true;
   151     // emit modelCountChanged could let FmFindWidget switch style between EmptyTipWidget and ResultListview
   118 }
   152     // FmFindWidget will show an empty tip widget such as "No found files or folderss" if set 0 as parameter
   119 
   153     emit modelCountChanged( rowCount() );
       
   154 
       
   155     return true;
       
   156 }
       
   157 
       
   158 /*!
       
   159     Removes \a count rows from the model, beginning at the given \a row.
       
   160 
       
   161     The \a parent index of the rows is optional and is only used for
       
   162     consistency with QAbstractItemModel. By default, a null index is
       
   163     specified, indicating that the rows are removed in the top level of
       
   164     the model.
       
   165 
       
   166     \sa QAbstractItemModel::removeRows()
       
   167 */
   120 bool FmFindResultModel::removeRows( int row, int count, const QModelIndex &parent )
   168 bool FmFindResultModel::removeRows( int row, int count, const QModelIndex &parent )
   121 {
   169 {   
   122     Q_UNUSED( parent );
   170 	if (row < 0 || count < 1 || (row + count) > rowCount(parent) )
   123     
       
   124 	if (row < 0 || count < 1 || row + count > mFindResult.size())
       
   125 		return false;
   171 		return false;
   126 
   172 
   127 	beginRemoveRows( QModelIndex(), row, row + count - 1 );
   173 	beginRemoveRows( QModelIndex(), row, row + count - 1 );
   128 
   174 
   129 	for (int i = 0; i < count; ++i)
   175 	for (int i = 0; i < count; ++i)
   130 		mFindResult.removeAt(row);
   176 		mFindResult.removeAt(row);
   131 
   177 
   132 	endRemoveRows();
   178 	endRemoveRows();
   133 	
   179 
       
   180     // emit modelCountChanged could let FmFindWidget switch style between EmptyTipWidget and  ResultListview
       
   181     // FmFindWidget will show an empty tip widget such as "No found files or folderss" if set 0 as parameter
       
   182     emit modelCountChanged( rowCount() );
       
   183 
   134 	return true;
   184 	return true;
   135 }
   185 }
   136 
   186 
   137 QFileInfo FmFindResultModel::fileInfo( const QModelIndex &index ) const
   187 QFileInfo FmFindResultModel::fileInfo( const QModelIndex &index ) const
   138 {
   188 {
   162     mFindThread->setPattern( regExp );
   212     mFindThread->setPattern( regExp );
   163 }
   213 }
   164 
   214 
   165 void FmFindResultModel::find()
   215 void FmFindResultModel::find()
   166 {
   216 {
   167 	if (mFindThread->isRunning())
   217 	if(mFindThread->isRunning())
   168 		return;
   218 		return;
   169 
   219 
   170     if( findPath().isEmpty() ){
   220     if( findPath().isEmpty() ){
   171         mFindThread->setLastResult( mFindResult );
   221         mFindThread->setLastResult( mFindResult );
   172     }
   222     }
   173 	removeRows( 0, mFindResult.size() );
   223 	removeRows( 0, rowCount() );
   174     emit modelCountChanged( mFindResult.size() );
       
   175     mFindThread->start();
   224     mFindThread->start();
   176 }
   225 }
   177 
   226 
   178 void FmFindResultModel::stop()
   227 void FmFindResultModel::stop()
   179 {
   228 {
   184 bool FmFindResultModel::isFinding() const
   233 bool FmFindResultModel::isFinding() const
   185 {
   234 {
   186     return mFindThread->isRunning();
   235     return mFindThread->isRunning();
   187 }
   236 }
   188 
   237 
   189 void FmFindResultModel::on_findThread_found( int count )
   238 /*
   190 {
   239     Receive \a dataList as some found result
   191     int size = mFindResult.size();
   240     Then insert dataList to model
   192     insertRows( mFindResult.size() - count, count );
   241 */
   193     emit modelCountChanged( mFindResult.size() );
   242 void FmFindResultModel::on_findThread_found( const QStringList &dataList )
       
   243 {
       
   244     if( dataList.isEmpty() ) {
       
   245 		return;
       
   246     }
       
   247     insertRows( rowCount(), dataList );
   194 }
   248 }
   195 
   249 
   196 bool FmFindResultModel::indexValid( const QModelIndex &index ) const
   250 bool FmFindResultModel::indexValid( const QModelIndex &index ) const
   197 {
   251 {
   198     Q_UNUSED( index );
   252     Q_UNUSED( index );
   199     return true;
   253     return true;
   200 }
   254 }
   201 
   255 
   202 void FmFindResultModel::init()
   256 void FmFindResultModel::init()
   203 {
   257 {
   204     mFindThread = new FmFindThread( &mFindResult, this );
   258     mFindThread = new FmFindThread( this );
   205     mFindThread->setObjectName( "findThread" );
   259     mFindThread->setObjectName( "findThread" );
   206     mIconProvider = new QFileIconProvider();
   260     mIconProvider = new FmFileIconProvider();
   207 }
   261 }
   208 
   262 
   209 bool FmFindResultModel::caseNameLessThan(const QString &s1, const QString &s2)
   263 bool FmFindResultModel::caseNameLessThan(const QPair<QString,int> &s1,
   210 {
   264                                          const QPair<QString,int> &s2)
   211     QFileInfo info1( s1 );
   265 {
   212     QFileInfo info2( s2 );
   266     QFileInfo info1( s1.first );
       
   267     QFileInfo info2( s2.first );
   213     
   268     
   214     return info1.fileName() < info2.fileName();
   269     return info1.fileName() < info2.fileName();
   215 }
   270 }
   216 
   271 
   217 bool FmFindResultModel::caseTimeLessThan(const QString &s1, const QString &s2)
   272 bool FmFindResultModel::caseTimeLessThan(const QPair<QString,int> &s1,
   218 {
   273                                          const QPair<QString,int> &s2)
   219     QFileInfo info1( s1 );
   274 {
   220     QFileInfo info2( s2 );
   275     QFileInfo info1( s1.first );
       
   276     QFileInfo info2( s2.first );
   221     
   277     
   222     return info1.lastModified() < info2.lastModified();
   278     return info1.lastModified() < info2.lastModified();
   223 }
   279 }
   224 
   280 
   225 bool FmFindResultModel::caseSizeLessThan(const QString &s1, const QString &s2)
   281 bool FmFindResultModel::caseSizeLessThan(const QPair<QString,int> &s1,
   226 {
   282                                          const QPair<QString,int> &s2)
   227     QFileInfo info1( s1 );
   283 {
   228     QFileInfo info2( s2 );
   284     QFileInfo info1( s1.first );
       
   285     QFileInfo info2( s2.first );
   229     
   286     
   230     return info1.size() < info2.size();
   287     return info1.size() < info2.size();
   231 }
   288 }
   232 
   289 
   233 bool FmFindResultModel::caseTypeLessThan(const QString &s1, const QString &s2)
   290 bool FmFindResultModel::caseTypeLessThan(const QPair<QString,int> &s1,
   234 {
   291                                          const QPair<QString,int> &s2)
   235     QFileInfo info1( s1 );
   292 {
   236     QFileInfo info2( s2 );
   293     QFileInfo info1( s1.first );
       
   294     QFileInfo info2( s2.first );
   237     
   295     
   238     if( info1.isDir() != info2.isDir() ){
   296     if( info1.isDir() != info2.isDir() ){
   239         return info1.isDir();
   297         return info1.isDir();
   240     }
   298     }
   241     else{
   299     else{
   242         return info1.suffix().toLower() < info2.suffix().toLower();   
   300         return info1.suffix().toLower() < info2.suffix().toLower();   
   243     }
   301     }
   244 }
   302 }
   245 
   303 
   246 
   304 /*!
       
   305   \reimp
       
   306   Sort by \a column, which is aligned to \a SortFlag
       
   307   \sa SortFlag
       
   308 */
   247 void FmFindResultModel::sort ( int column, Qt::SortOrder order )
   309 void FmFindResultModel::sort ( int column, Qt::SortOrder order )
   248 {  
   310 {  
       
   311     // Sort algorithm comes from
       
   312     // void QListModel::sort(int column, Qt::SortOrder order)
       
   313 
   249     Q_UNUSED( order );
   314     Q_UNUSED( order );
   250            
   315     emit layoutAboutToBeChanged();
   251 //    emit  layoutAboutToBeChanged();
   316 
   252     
   317     // store value and row pair.
   253     switch( ( SortFlag )column )
   318     QVector < QPair<QString,int> > sorting(mFindResult.count());
       
   319     for (int i = 0; i < mFindResult.count(); ++i) {
       
   320         QString item = mFindResult.at(i);
       
   321         sorting[i].first = item;
       
   322         sorting[i].second = i;
       
   323     }
       
   324 
       
   325     // sort in "sorting"
       
   326    switch( ( SortFlag )column )
   254     {
   327     {
   255     case Name:
   328     case Name:
   256         qSort( mFindResult.begin(), mFindResult.end(), caseNameLessThan );
   329         qSort( sorting.begin(), sorting.end(), caseNameLessThan );
   257         break;
   330         break;
   258     case Time:
   331     case Time:
   259         qSort( mFindResult.begin(), mFindResult.end(), caseTimeLessThan );
   332         qSort( sorting.begin(), sorting.end(), caseTimeLessThan );
   260         break;
   333         break;
   261     case Size:
   334     case Size:
   262         qSort( mFindResult.begin(), mFindResult.end(), caseSizeLessThan );
   335         qSort( sorting.begin(), sorting.end(), caseSizeLessThan );
   263         break;
   336         break;
   264     case Type:
   337     case Type:
   265         qSort( mFindResult.begin(), mFindResult.end(), caseTypeLessThan );
   338         qSort( sorting.begin(), sorting.end(), caseTypeLessThan );
   266         break;
   339         break;
   267     }
   340     }
   268 //    emit layoutChanged();
   341 
   269     emit refresh();
   342     // create from Indexes and toIndexes, then set sorted data back to mFindResult
   270 }
   343     QModelIndexList fromIndexes;
       
   344     QModelIndexList toIndexes;
       
   345     for (int r = 0; r < sorting.count(); ++r) {
       
   346         QString item = sorting.at(r).first;
       
   347         toIndexes.append(createIndex(r, 0));
       
   348         fromIndexes.append(createIndex(sorting.at(r).second, 0));
       
   349         mFindResult[r] = sorting.at(r).first;
       
   350     }
       
   351     changePersistentIndexList(fromIndexes, toIndexes);
       
   352 
       
   353     emit layoutChanged();
       
   354 }