00001
00002
00003
00004
00005
00006
00007
00008
00009 #include <qapplication.h>
00010 #include <qcursor.h>
00011 #include <qpainter.h>
00012 #include <qaction.h>
00013 #include <qlabel.h>
00014 #include "git.h"
00015 #include "domain.h"
00016 #include "mainimpl.h"
00017 #include "treeview.h"
00018
00019 using namespace QGit;
00020
00021 QString FileItem::fullName() const {
00022
00023 QListViewItem* p = parent();
00024 QString s(p ? text(0) : "");
00025 while (p && p->parent()) {
00026 s.prepend(p->text(0) + '/');
00027 p = p->parent();
00028 }
00029 return s;
00030 }
00031
00032 void FileItem::paintCell(QPainter* p, const QColorGroup& cg, int col, int wdt, int ali) {
00033
00034 p->save();
00035 if (isModified) {
00036 QFont f(p->font());
00037 f.setBold(true);
00038 p->setFont(f);
00039 }
00040 QListViewItem::paintCell(p, cg, col, wdt, ali);
00041 p->restore();
00042 }
00043
00044 DirItem::DirItem(DirItem* p, SCRef ts, SCRef nm, TreeView* t) : FileItem(p, nm), treeSha(ts),
00045 tv(t), isWorkingDir(p->isWorkingDir) { setPixmap(0, *tv->folderClosed); }
00046
00047 DirItem::DirItem(QListView* p, SCRef ts, SCRef nm, TreeView* t) : FileItem(p, nm), treeSha(ts),
00048 tv(t), isWorkingDir(ts == ZERO_SHA) {}
00049
00050 void DirItem::setup() {
00051
00052 setExpandable(true);
00053 QListViewItem::setup();
00054 }
00055
00056 bool TreeView::getTree(SCRef treeSha, SList names, SList shas,
00057 SList types, bool wd, SCRef treePath) {
00058
00059
00060 treeIsValid = git->getTree(treeSha, names, shas, types, wd, treePath);
00061 return treeIsValid;
00062 }
00063
00064 void DirItem::setOpen(bool b) {
00065
00066 setPixmap(0, b ? *tv->folderOpen : *tv->folderClosed);
00067
00068 bool alreadyWaiting = false;
00069 if (QApplication::overrideCursor())
00070 alreadyWaiting = (QApplication::overrideCursor()->shape() == Qt::WaitCursor);
00071
00072 if (!alreadyWaiting)
00073 QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
00074
00075 if (b && !childCount()) {
00076
00077 QStringList names, types, shas;
00078 if (!tv->getTree(treeSha, names, shas, types, isWorkingDir, fullName()))
00079 return;
00080
00081 if (!names.empty()) {
00082 QStringList::const_iterator it(names.constBegin());
00083 QStringList::const_iterator itSha(shas.constBegin());
00084 QStringList::const_iterator itTypes(types.constBegin());
00085 while (it != names.constEnd()) {
00086
00087 if (*itTypes == "tree") {
00088 DirItem* item = new DirItem(this, *itSha, *it, tv);
00089 item->setModified(tv->isModified(item->fullName(), true));
00090 } else {
00091 FileItem* item = new FileItem(this, *it);
00092 item->setPixmap(0, *tv->mimePix(*it));
00093 item->setModified(tv->isModified(item->fullName()));
00094 }
00095 ++it;
00096 ++itSha;
00097 ++itTypes;
00098 }
00099 }
00100 }
00101 QListViewItem::setOpen(b);
00102 if (!alreadyWaiting)
00103 QApplication::restoreOverrideCursor();
00104 }
00105
00106
00107
00108 TreeView::TreeView(Domain* dm, Git* g, QListView* lv) : QObject(dm),
00109 d(dm), git(g), listView(lv), treeIsValid(false) {
00110
00111 st = &(d->st);
00112 ignoreCurrentChanged = false;
00113
00114 initMimePix();
00115
00116 connect(listView, SIGNAL(currentChanged(QListViewItem*)),
00117 this, SLOT(on_currentChanged(QListViewItem*)));
00118
00119 connect(listView, SIGNAL(contextMenuRequested(QListViewItem*, const QPoint&, int)),
00120 this, SLOT(on_contextMenuRequested(QListViewItem*, const QPoint&, int)));
00121 }
00122
00123 void TreeView::initMimePix() {
00124
00125 MainImpl* m = d->m();
00126
00127 setMimePix("#FOLDER_CLOSED", m->lblFolder->pixmap());
00128 setMimePix("#FOLDER_OPEN", m->lblFolderOpen->pixmap());
00129 setMimePix("#DEFAULT", m->lblFile->pixmap());
00130 setMimePix("c", m->lblC->pixmap());
00131 setMimePix("cpp", m->lblCpp->pixmap());
00132 setMimePix("h", m->lblH->pixmap());
00133 setMimePix("txt", m->lblTxt->pixmap());
00134 setMimePix("sh", m->lblSh->pixmap());
00135 setMimePix("perl", m->lblPl->pixmap());
00136 setMimePix("pl", m->lblPl->pixmap());
00137 setMimePix("py", m->lblPy->pixmap());
00138 setMimePix("java", m->lblJava->pixmap());
00139 setMimePix("jar", m->lblJava->pixmap());
00140 setMimePix("tar", m->lblTar->pixmap());
00141 setMimePix("gz", m->lblTar->pixmap());
00142 setMimePix("tgz", m->lblTar->pixmap());
00143 setMimePix("zip", m->lblTar->pixmap());
00144 setMimePix("bz", m->lblTar->pixmap());
00145 setMimePix("bz2", m->lblTar->pixmap());
00146 setMimePix("html", m->lblHtml->pixmap());
00147 setMimePix("xml", m->lblHtml->pixmap());
00148
00149 m->lblFolder->hide();
00150 m->lblFolderOpen->hide();
00151 m->lblFile->hide();
00152 m->lblC->hide();
00153 m->lblCpp->hide();
00154 m->lblH->hide();
00155 m->lblTxt->hide();
00156 m->lblSh->hide();
00157 m->lblPl->hide();
00158 m->lblPy->hide();
00159 m->lblJava->hide();
00160 m->lblTar->hide();
00161 m->lblHtml->hide();
00162 }
00163
00164 void TreeView::on_currentChanged(QListViewItem* item) {
00165
00166 if (item) {
00167 SCRef fn = ((FileItem*)item)->fullName();
00168 if (!ignoreCurrentChanged && fn != st->fileName()) {
00169 st->setFileName(fn);
00170 st->setSelectItem(true);
00171 UPDATE_DOMAIN(d);
00172 }
00173 }
00174 }
00175
00176 void TreeView::on_contextMenuRequested(QListViewItem* item, const QPoint&,int) {
00177
00178 if (item)
00179 emit contextMenu(fullName(item), POPUP_TREE_EV);
00180 }
00181
00182 void TreeView::clear() {
00183
00184 rootName = "";
00185 listView->clear();
00186 }
00187
00188 bool TreeView::isModified(SCRef path, bool isDir) {
00189
00190 if (isDir)
00191 return (modifiedDirs.findIndex(path) != -1);
00192
00193 return (modifiedFiles.findIndex(path) != -1);
00194 }
00195
00196 bool TreeView::isDir(SCRef fileName) {
00197
00198
00199
00200
00201 FileItem* item = static_cast<FileItem*>(listView->currentItem());
00202 if (item == NULL || item->fullName() != fileName)
00203 return false;
00204
00205 return dynamic_cast<DirItem*>(item);
00206 }
00207
00208 const QString TreeView::fullName(QListViewItem* item) {
00209
00210 FileItem* f = static_cast<FileItem*>(item);
00211 return (item ? f->fullName() : "");
00212 }
00213
00214 void TreeView::getTreeSelectedItems(QStringList& selectedItems) {
00215
00216 selectedItems.clear();
00217 QListViewItemIterator it(listView);
00218 while (it.current()) {
00219 FileItem* f = static_cast<FileItem*>(it.current());
00220 if (f->isSelected())
00221 selectedItems.append(f->fullName());
00222 ++it;
00223 }
00224 }
00225
00226 void TreeView::setMimePix(SCRef ext, QPixmap* pix) {
00227
00228
00229 if (ext == "#FOLDER_CLOSED")
00230 folderClosed = pix;
00231
00232 else if (ext == "#FOLDER_OPEN")
00233 folderOpen = pix;
00234
00235 else if (ext == "#DEFAULT")
00236 fileDefault = pix;
00237
00238
00239 else if (!mimePixMap.find(ext))
00240 mimePixMap.insert(ext, pix);
00241 }
00242
00243 const QPixmap* TreeView::mimePix(SCRef fileName) {
00244
00245 SCRef ext = fileName.section('.', -1, -1);
00246 QPixmap* pix = mimePixMap.find(ext);
00247 return (pix ? pix : fileDefault);
00248 }
00249
00250 void TreeView::setTree(SCRef treeSha) {
00251
00252 if (listView->childCount() == 0)
00253
00254 git->getWorkDirFiles(modifiedFiles, modifiedDirs, RevFile::ANY);
00255
00256 listView->clear();
00257 treeIsValid = true;
00258
00259 if (!treeSha.isEmpty()) {
00260
00261 DirItem* root = new DirItem(listView, treeSha, rootName, this);
00262 root->setOpen(true);
00263 }
00264 }
00265
00266 void TreeView::update() {
00267
00268 if (st->sha().isEmpty())
00269 return;
00270
00271
00272
00273 ignoreCurrentChanged = true;
00274 QApplication::setOverrideCursor(Qt::WaitCursor);
00275
00276 bool newTree = true;
00277 DirItem* root = static_cast<DirItem*>(listView->firstChild());
00278 if (root && treeIsValid)
00279 newTree = (root->treeSha != st->sha());
00280
00281 if ( newTree
00282 && treeIsValid
00283 && root
00284 && st->sha() != ZERO_SHA
00285 && root->treeSha != ZERO_SHA)
00286
00287
00288
00289
00290
00291
00292 if (st->sha(true) != st->sha(false))
00293 newTree = !git->isSameFiles(st->sha(false), st->sha(true));
00294 else
00295 newTree = !git->isSameFiles(root->treeSha, st->sha(true));
00296
00297 if (newTree)
00298 setTree(st->sha());
00299 else {
00300 FileItem* f = static_cast<FileItem*>(listView->currentItem());
00301 if (f && f->fullName() == st->fileName()) {
00302
00303 restoreStuff();
00304 return;
00305 }
00306 }
00307 if (st->fileName().isEmpty()) {
00308 restoreStuff();
00309 return;
00310 }
00311 listView->setUpdatesEnabled(false);
00312 const QStringList lst(QStringList::split("/", st->fileName()));
00313 QListViewItem* item = listView->firstChild();
00314 item = item->itemBelow();
00315 FOREACH_SL (it, lst) {
00316 while (item && treeIsValid) {
00317 if (item->text(0) == *it) {
00318
00319
00320
00321 if (st->fileName().startsWith(((FileItem*)item)->fullName())) {
00322 item->setOpen(true);
00323 break;
00324 }
00325 }
00326 item = item->itemBelow();
00327 }
00328 }
00329
00330 if (item && treeIsValid) {
00331 listView->clearSelection();
00332 listView->setSelected(item, true);
00333 listView->setCurrentItem(item);
00334 listView->ensureItemVisible(item);
00335 }
00336 listView->setUpdatesEnabled(true);
00337 listView->triggerUpdate();
00338 restoreStuff();
00339 }
00340
00341 void TreeView::restoreStuff() {
00342
00343 ignoreCurrentChanged = false;
00344 QApplication::restoreOverrideCursor();
00345 }