|
Cppcheck
|
00001 /* 00002 * Cppcheck - A tool for static C/C++ code analysis 00003 * Copyright (C) 2007-2012 Daniel Marjamäki and Cppcheck team. 00004 * 00005 * This program is free software: you can redistribute it and/or modify 00006 * it under the terms of the GNU General Public License as published by 00007 * the Free Software Foundation, either version 3 of the License, or 00008 * (at your option) any later version. 00009 * 00010 * This program is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 * GNU General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU General Public License 00016 * along with this program. If not, see <http://www.gnu.org/licenses/>. 00017 */ 00018 00019 #include "selectfilesdialog.h" 00020 #include "ui_selectfilesdialog.h" 00021 #include "filelist.h" 00022 00023 #include <QFileSystemModel> 00024 #include <QStringList> 00025 #include <QPushButton> 00026 00027 class SelectFilesModel : public QFileSystemModel { 00028 private: 00029 /** 00030 * paths that are user-checked. on the screen all children 00031 * for these paths will appear to be checked too unless 00032 * they are "unchecked". 00033 */ 00034 QStringList checked; 00035 00036 /** 00037 * paths that are user-unchecked. 00038 */ 00039 QStringList unchecked; 00040 00041 /** 00042 * Get index in stringlist where start of string matches. If 00043 * many strings in the stringlist match then return the index 00044 * for the longest string. 00045 * \param paths stringlist with filepaths 00046 * \param filepath the filepath that is matched against the stringlist 00047 */ 00048 int getindex(const QStringList &paths, const QString &filepath) const { 00049 int matchlen = 0; 00050 int matchindex = -1; 00051 for (int i = 0; i < paths.size(); ++i) { 00052 if (filepath.startsWith(paths[i])) { 00053 // not a real match of paths.. 00054 if (paths[i].size() < filepath.size() && filepath[paths[i].size()] != '/') 00055 continue; 00056 00057 // paths match. the return value is the index for the 00058 // longest match 00059 if (paths[i].size() > matchlen) 00060 matchindex = i; 00061 } 00062 } 00063 return matchindex; 00064 } 00065 00066 /** 00067 * Is filepath partially checked? 00068 * \param filepath the filepath to investigate 00069 * \param checkindex result from getindex(checked,filepath). If not given the getindex will be called. 00070 * \return true if filepath is partially checked 00071 */ 00072 bool partiallyChecked(const QString &filepath, int checkindex = -2) const { 00073 const QString filepath2 = filepath.endsWith("/") ? filepath : (filepath + "/"); 00074 00075 for (int i = 0; i < unchecked.size(); ++i) { 00076 if (unchecked[i].startsWith(filepath2)) { 00077 return true; 00078 } 00079 } 00080 00081 if (checkindex == -2) 00082 checkindex = getindex(checked, filepath); 00083 00084 00085 if (checkindex == -1) { 00086 for (int i = 0; i < checked.size(); ++i) { 00087 if (checked[i].startsWith(filepath2)) { 00088 return true; 00089 } 00090 } 00091 } 00092 00093 return false; 00094 } 00095 00096 public: 00097 SelectFilesModel() : QFileSystemModel() { 00098 class FileLister : private FileList { 00099 public: 00100 static QStringList filters() { 00101 return GetDefaultFilters(); 00102 } 00103 }; 00104 setNameFilters(FileLister::filters()); 00105 setNameFilterDisables(false); 00106 setRootPath("/"); 00107 } 00108 00109 Qt::ItemFlags flags(const QModelIndex& index) const { 00110 if (index.column() == 0) 00111 return QFileSystemModel::flags(index) | Qt::ItemIsUserCheckable; 00112 return QFileSystemModel::flags(index); 00113 } 00114 00115 QVariant data(const QModelIndex& index, int role=Qt::DisplayRole) const { 00116 if (role == Qt::CheckStateRole) { 00117 const QString filepath = filePath(index); 00118 const int checkindex = getindex(checked, filepath); 00119 const int uncheckindex = getindex(unchecked, filepath); 00120 00121 // If some children are not checked then this item should be partially checked.. 00122 if (partiallyChecked(filepath, checkindex)) 00123 return Qt::PartiallyChecked; 00124 00125 // Is item selected but not unselected? 00126 if (checkindex >= 0 && uncheckindex == -1) 00127 return Qt::Checked; 00128 if (checkindex >= 0 && uncheckindex >= 0 && 00129 checked[checkindex].size() > unchecked[uncheckindex].size()) 00130 return Qt::Checked; 00131 00132 // Item is either not selected at all or else it is unselected 00133 return Qt::Unchecked; 00134 } 00135 return QFileSystemModel::data(index, role); 00136 } 00137 00138 bool setData(const QModelIndex& index, const QVariant& value, int role) { 00139 if (role == Qt::CheckStateRole) { 00140 const QString filepath = filePath(index); 00141 00142 bool partiallychecked = partiallyChecked(filepath); 00143 00144 if (unchecked.indexOf(filepath) != -1) { 00145 // remove unchecked path 00146 unchecked.removeAll(filepath); 00147 } else if (partiallychecked || checked.indexOf(filepath) != -1) { 00148 // remove child selected paths 00149 for (int i = checked.size() - 1; i >= 0; --i) { 00150 if (checked[i].startsWith(filepath)) 00151 checked.removeAt(i); 00152 } 00153 00154 // remove child unselected paths 00155 for (int i = unchecked.size() - 1; i >= 0; --i) { 00156 if (unchecked[i].startsWith(filepath)) 00157 unchecked.removeAt(i); 00158 } 00159 00160 // If partialChecked then select this item 00161 if (partiallychecked) 00162 checked.append(filepath); 00163 } else { 00164 const int checkindex = getindex(checked, filepath); 00165 const int uncheckindex = getindex(unchecked, filepath); 00166 if (checkindex == -1) 00167 checked.append(filepath); 00168 else if (uncheckindex >= 0 && checked[checkindex].size() < unchecked[uncheckindex].size()) 00169 checked.append(filepath); 00170 else 00171 unchecked.append(filepath); 00172 } 00173 00174 if (rowCount(index) > 0) 00175 emit(dataChanged(index, index.child(rowCount(index)-1,0))); 00176 00177 // update parents 00178 QModelIndex parent = index.parent(); 00179 while (parent != QModelIndex()) { 00180 emit(dataChanged(parent,parent)); 00181 parent = parent.parent(); 00182 } 00183 00184 return true; 00185 } 00186 return QFileSystemModel::setData(index, value, role); 00187 } 00188 00189 QStringList getFiles() const { 00190 QStringList ret; 00191 00192 // List all files in "checked" folders.. 00193 FileList fileLister; 00194 fileLister.AddPathList(checked); 00195 ret = fileLister.GetFileList(); 00196 00197 // Remove all items from ret that are unchecked but not checked.. 00198 for (int i = ret.size() - 1; i >= 0; i--) { 00199 int uncheckindex = getindex(unchecked, ret[i]); 00200 if (uncheckindex == -1) 00201 continue; 00202 00203 // both checked and unchecked, check which to rely on 00204 int checkindex = getindex(checked, ret[i]); 00205 if (checked[checkindex].size() < unchecked[uncheckindex].size()) 00206 ret.removeAt(i); 00207 } 00208 00209 return ret; 00210 } 00211 }; 00212 00213 00214 00215 SelectFilesDialog::SelectFilesDialog(QWidget *w) : 00216 QDialog(w), 00217 ui(new Ui::SelectFilesDialog) 00218 { 00219 ui->setupUi(this); 00220 00221 selectfilesmodel = new SelectFilesModel; 00222 00223 ui->treeView->setModel(selectfilesmodel); 00224 for (int i = 1; i < 4; ++i) 00225 ui->treeView->setColumnHidden(i, true); 00226 00227 // Change text of "OK" button to "Check" 00228 QPushButton *okbutton = ui->buttonBox->button(QDialogButtonBox::Ok); 00229 if (okbutton) 00230 okbutton->setText(tr("Check")); 00231 } 00232 00233 SelectFilesDialog::~SelectFilesDialog() 00234 { 00235 delete ui; 00236 } 00237 00238 QStringList SelectFilesDialog::getFiles() const 00239 { 00240 return selectfilesmodel->getFiles(); 00241 }
1.7.6.1