00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <QList>
00025 #include <QMap>
00026 #include <QAbstractItemView>
00027 #include <QAbstractItemModel>
00028
00029 #include "klfitemviewsearchtarget.h"
00030 #include "klfitemviewsearchtarget_p.h"
00031
00032
00033 struct KLFItemViewSearchTargetPrivate {
00034 KLF_PRIVATE_HEAD(KLFItemViewSearchTarget)
00035 {
00036 view = NULL;
00037 olddelegate = NULL;
00038 klfdelegate = new KLFSearchItemDelegate(K);
00039 }
00040
00041 QAbstractItemView * view;
00042
00043 QAbstractItemDelegate * olddelegate;
00044 KLFSearchItemDelegate * klfdelegate;
00045
00046 void resetDelegate();
00047
00048 QList<int> columnlist;
00049 QMap<int,int> nextcolumn;
00050 QMap<int,int> prevcolumn;
00051
00052 int next_valid_column(int c, bool forward = true)
00053 {
00054 if (columnlist.isEmpty())
00055 return -1;
00056
00057 while (c >= 0 && c < columnlist.last() && !columnlist.contains(c))
00058 c = c + (forward ? +1 : -1);
00059 if (c >= columnlist.last())
00060 c = -1;
00061 return c;
00062 }
00063
00064 QModelIndex advance_iter_helper(const QModelIndex& pos, bool explorechildren = true)
00065 {
00066 KLF_ASSERT_NOT_NULL(view, "View is NULL!", return QModelIndex(); );
00067 QAbstractItemModel *model = view->model();
00068 KLF_ASSERT_NOT_NULL(model, "View's model is NULL!", return QModelIndex(); );
00069
00070 if (columnlist.isEmpty())
00071 return QModelIndex();
00072
00073 if (explorechildren && model->hasChildren(pos)) {
00074
00075 return model->index(0, columnlist[0], pos);
00076 }
00077
00078 int nextcol = nextcolumn.value(next_valid_column(pos.column()), -1);
00079 if (nextcol >= 0) {
00080
00081 return model->index(pos.row(), nextcol, pos.parent());
00082 }
00083
00084 if (pos.row() < model->rowCount(pos.parent())) {
00085 return pos.sibling(pos.row()+1, columnlist[0]);
00086 }
00087
00088
00089 if (pos.parent() != QModelIndex()) {
00090 return advance_iter_helper(pos.parent(), false);
00091 }
00092
00093 return QModelIndex();
00094 }
00095
00096 QModelIndex last_child_index(const QModelIndex& pos)
00097 {
00098 KLF_ASSERT_NOT_NULL(view, "View is NULL!", return QModelIndex(); );
00099 QAbstractItemModel *model = view->model();
00100 KLF_ASSERT_NOT_NULL(model, "View's model is NULL!", return QModelIndex(); );
00101
00102 if (!model->hasChildren(pos))
00103 return pos;
00104
00105
00106 return last_child_index(model->index(model->rowCount(pos)-1, columnlist.last(), pos));
00107 }
00108
00109 QModelIndex advance_iter_back_helper(const QModelIndex& pos)
00110 {
00111 KLF_ASSERT_NOT_NULL(view, "View is NULL!", return QModelIndex(); );
00112 QAbstractItemModel *model = view->model();
00113 KLF_ASSERT_NOT_NULL(model, "View's model is NULL!", return QModelIndex(); );
00114
00115
00116 int prevcol = prevcolumn.value(next_valid_column(pos.column(), false), -1);
00117 if (prevcol >= 0) {
00118 return last_child_index(pos.sibling(pos.row(), prevcol));
00119 }
00120 if (pos.row() >= 1) {
00121
00122 return last_child_index(pos.sibling(pos.row()-1, columnlist.last()));
00123 }
00124
00125 return pos.parent();
00126 }
00127 };
00128
00129
00130 KLFItemViewSearchTarget::KLFItemViewSearchTarget(QAbstractItemView *view, QObject *parent)
00131 : QObject(parent), KLFIteratorSearchable<QModelIndex>()
00132 {
00133 KLF_INIT_PRIVATE(KLFItemViewSearchTarget) ;
00134 setSearchView(view);
00135 }
00136 KLFItemViewSearchTarget::~KLFItemViewSearchTarget()
00137 {
00138 KLF_DELETE_PRIVATE ;
00139 }
00140
00141
00142 QAbstractItemView * KLFItemViewSearchTarget::view()
00143 {
00144 return d->view;
00145 }
00146 QList<int> KLFItemViewSearchTarget::searchColumns()
00147 {
00148 return d->columnlist;
00149 }
00150
00151
00152
00153
00154 QModelIndex KLFItemViewSearchTarget::searchIterAdvance(const QModelIndex& pos, bool forward)
00155 {
00156 if (forward)
00157 return d->advance_iter_helper(pos);
00158
00159 return d->advance_iter_back_helper(pos);
00160 }
00161 QModelIndex KLFItemViewSearchTarget::searchIterBegin()
00162 {
00163 return d->advance_iter_helper(QModelIndex());
00164 }
00165 QModelIndex KLFItemViewSearchTarget::searchIterEnd()
00166 {
00167 return QModelIndex();
00168 }
00169 bool KLFItemViewSearchTarget::searchIterMatches(const QModelIndex &pos, const QString &queryString)
00170 {
00171 KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ;
00172
00173 QList<KLFSearchItemDelegate::Match> mlist
00174 = KLFSearchItemDelegate::matches(pos.data().toString(), queryString, false);
00175 return mlist.size();
00176 }
00177 void KLFItemViewSearchTarget::searchPerformed(const QModelIndex& resultMatchPosition, bool found,
00178 const QString& queryString)
00179 {
00180 KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ;
00181
00182 Q_UNUSED(resultMatchPosition);
00183 Q_UNUSED(found);
00184
00185
00186
00187
00188
00189
00190
00191 KLF_ASSERT_NOT_NULL(d->view, "View is NULL!", return ; );
00192 QAbstractItemDelegate *delegate = d->view->itemDelegate();
00193 KLF_ASSERT_NOT_NULL(delegate, "Delegate is NULL!", return ; );
00194 if (delegate != d->klfdelegate) {
00195 d->olddelegate = delegate;
00196 d->view->setItemDelegate(d->klfdelegate);
00197 }
00198
00199 d->klfdelegate->setSearchString(queryString);
00200 d->view->repaint();
00201 }
00202 void KLFItemViewSearchTargetPrivate::resetDelegate()
00203 {
00204 KLF_ASSERT_NOT_NULL(view, "View is NULL!", return ; );
00205 QAbstractItemDelegate *delegate = view->itemDelegate();
00206 KLF_ASSERT_NOT_NULL(delegate, "Delegate is NULL!", return ; );
00207 if (delegate == klfdelegate && olddelegate != NULL) {
00208 view->setItemDelegate(olddelegate);
00209 }
00210 view->repaint();
00211 }
00212 void KLFItemViewSearchTarget::searchAborted()
00213 {
00214 KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ;
00215 KLFIteratorSearchable<QModelIndex>::searchAborted();
00216
00217 d->resetDelegate();
00218 }
00219 void KLFItemViewSearchTarget::searchReinitialized()
00220 {
00221 KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ;
00222 KLFIteratorSearchable<QModelIndex>::searchReinitialized();
00223
00224 d->resetDelegate();
00225 }
00226
00227 void KLFItemViewSearchTarget::searchMoveToIterPos(const QModelIndex& pos)
00228 {
00229 KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ;
00230
00231 KLF_ASSERT_NOT_NULL(d->view, "View is NULL!", return ; );
00232 d->view->setCurrentIndex(pos);
00233 d->view->selectionModel()->select(pos, QItemSelectionModel::ClearAndSelect);
00234 }
00235
00236 void KLFItemViewSearchTarget::setSearchView(QAbstractItemView *view)
00237 {
00238 KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ;
00239
00240 d->view = view;
00241
00242 if (d->columnlist.isEmpty()) {
00243
00244 setSearchColumns(QList<int>());
00245 }
00246 }
00247
00248 void KLFItemViewSearchTarget::setSearchColumns(const QList<int>& columnList)
00249 {
00250 KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ;
00251
00252 KLF_ASSERT_NOT_NULL(d->view, "View is NULL!", return ; );
00253 QAbstractItemModel * model = d->view->model();
00254 KLF_ASSERT_NOT_NULL(model, "View has NULL model!!!", return ; ) ;
00255
00256
00257 d->columnlist = columnList.toSet().toList();
00258 qSort(d->columnlist);
00259 d->nextcolumn.clear();
00260 d->prevcolumn.clear();
00261 if (d->columnlist.isEmpty()) {
00262 for (int k = 0; k < model->columnCount(); ++k)
00263 d->columnlist << k;
00264 }
00265 if (d->columnlist.isEmpty())
00266 return;
00267 int k;
00268
00269 for (k = 0; k < (d->columnlist.size()-1); ++k) {
00270 d->nextcolumn[d->columnlist[k]] = d->columnlist[k+1];
00271 d->prevcolumn[d->columnlist[k+1]] = d->columnlist[k];
00272 }
00273 d->nextcolumn[d->columnlist[k]] = -1;
00274 d->prevcolumn[d->columnlist[0]] = -1;
00275 }
00276
00277
00278