#include "projectfilesystemwidget.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* class ProjectsModel: public QAbstractItemModel { public: ProjectsModel() {fsm.setRootPath(qApp->applicationDirPath());} QFileInfo fileInfo(const QModelIndex & i) {return fsm.fileInfo(i);} QModelIndex index(const QString & path, int column = 0) const {return fsm.index(path, column);} QModelIndex index(int row, int column, const QModelIndex & parent) const { return fsm.index(row, column, parent); } QModelIndex parent(const QModelIndex & child) const { return fsm.parent(child); } int rowCount(const QModelIndex & parent) const { return fsm.rowCount(parent); } int columnCount(const QModelIndex & parent) const { return fsm.columnCount(parent); } QVariant data(const QModelIndex & index, int role) const { return fsm.data(index, role); } QVariant headerData(int section, Qt::Orientation orientation, int role) const { return fsm.headerData(section, orientation, role); } Qt::ItemFlags flags(const QModelIndex & index) const { return fsm.flags(index); } void sort(int column, Qt::SortOrder order) { fsm.sort(column, order); } QHash roleNames() const { return fsm.roleNames(); } QModelIndex sibling(int row, int column, const QModelIndex & idx) const { return fsm.sibling(row, column, idx); } bool hasChildren(const QModelIndex & parent) const { return fsm.hasChildren(parent); } private: QFileSystemModel fsm; }; */ ProjectFilesystemWidget::ProjectFilesystemWidget(QWidget * parent): QWidget(parent) { setupUi(this); buttonClear->setIcon(Utils::Icons::CLEAN.icon()); buttonExpand->setIcon(Utils::Icons::EXPAND.icon()); buttonCollapse->setIcon(Utils::Icons::COLLAPSE.icon()); actionOpen_here->setIcon(Utils::Icons::OPENFILE.icon()); actionOpen_external->setIcon(Utils::Icons::OPENFILE.icon()); actionShow_external->setIcon(Utils::Icons::DIR.icon()); popup_menu.addActions(QList() << actionOpen_here << actionOpen_external << actionShow_external); proj_plug = 0; /*QList plugs = ExtensionSystem::PluginManager::allObjects(); QStringList sl; foreach (QObject * o, plugs) { ExtensionSystem::IPlugin * p = qobject_cast(o); if (!p) continue; QString cn = QString::fromLatin1(o->metaObject()->className()); if (cn.startsWith("ProjectExplorer")) sl << cn; ExtensionSystem::PluginSpec * ps = p->pluginSpec(); if (!ps) continue; if (ps->name() == "ProjectExplorer") { proj_plug = p; connect(p, SIGNAL(fileListChanged()), this, SLOT(projectsChanged()), Qt::UniqueConnection); break; } }*/ //QMessageBox::information(this, "", sl.join("\n")); //connect(ProjectExplorer::ProjectTree::instance(), SIGNAL(subtreeChanged(ProjectExplorer::FolderNode*)), this, SLOT(projectsChanged())); connect(ProjectExplorer::SessionManager::instance(), SIGNAL(startupProjectChanged(ProjectExplorer::Project *)), this, SLOT(startupProjectChanged())); connect(ProjectExplorer::SessionManager::instance(), SIGNAL(projectAdded(ProjectExplorer::Project*)), this, SLOT(projectsChanged())); connect(ProjectExplorer::SessionManager::instance(), SIGNAL(projectDisplayNameChanged(ProjectExplorer::Project*)), this, SLOT(projectsChanged())); connect(ProjectExplorer::SessionManager::instance(), SIGNAL(projectRemoved(ProjectExplorer::Project*)), this, SLOT(projectsChanged())); //connect(ProjectExplorer::SessionManager::instance(), SIGNAL(), this, SLOT(startupProjectChanged())); connect(Core::EditorManager::instance(), SIGNAL(currentEditorChanged(Core::IEditor*)), this, SLOT(fileChanged())); //model = new ProjectsModel(); //tree->setModel(model); //model.setNameFilterDisables(false); /*for (int i = 1; i < tree->header()->count(); ++i) tree->header()->setSectionHidden(i, true); tree->setHeaderHidden(true);*/ projectsChanged(); } void ProjectFilesystemWidget::setCurrentFilter(const FilterDialog::Filter & v) { cur_filter = v; projectsChanged(); } void ProjectFilesystemWidget::changeEvent(QEvent *e) { QWidget::changeEvent(e); switch (e->type()) { case QEvent::LanguageChange: retranslateUi(this); break; default: break; } } void ProjectFilesystemWidget::createTree(QTreeWidgetItem * ti, const QString & dir) { /*int rc = model.rowCount(dir); QTreeWidgetItem * ni = new QTreeWidgetItem(ti); ni->setText(0, QString::number(rc)); ti->addChild(ni); return;*/ QFileInfoList fl = QDir(dir).entryInfoList(QDir::AllEntries | QDir::NoDotAndDotDot, QDir::LocaleAware | QDir::DirsFirst); for (QFileInfo i: fl) { QString nit = i.fileName(); if (i.isDir()) { if (!cur_filter.filterDir(nit)) continue; } else { if (!cur_filter.filterFile(nit)) continue; } QTreeWidgetItem * ni = new QTreeWidgetItem(); ni->setText(0, nit); ni->setIcon(0, Core::FileIconProvider::icon(i)); ni->setData(0, Qt::UserRole, i.absoluteFilePath()); ni->setData(0, Qt::UserRole + 1, i.isDir()); item_map[i.absoluteFilePath()] = ni; if (i.isDir()) { createTree(ni, dir + QDir::separator() + i.fileName()); } ti->addChild(ni); } //if (ti->childCount() == 0) delete ti; } bool ProjectFilesystemWidget::filterTree(QTreeWidgetItem * ti, const QString & filter) { bool ret = false; for (int i = 0; i < ti->childCount(); ++i) { QTreeWidgetItem * ci = ti->child(i); QString cit = ci->text(0); if (ci->data(0, Qt::UserRole + 1).toBool()) { if (!filterTree(ci, filter)) { ci->setHidden(true); continue; } ci->setHidden(false); ret = true; } else { bool f = false; if (filter.isEmpty()) { f = true; } else { f = f || cit.contains(filter); } ci->setHidden(!f); if (f) ret = true; } } return ret; } void ProjectFilesystemWidget::filter() { QString f = lineFilter->text(); /*QStringList nf; if (!f.isEmpty()) { if (!f.startsWith("*")) f.prepend('*'); if (!f.endsWith("*")) f.append('*'); nf << f; } model.setNameFilters(nf);*/ for (int i = 0; i < tree->topLevelItemCount(); ++i) { QTreeWidgetItem * ti = tree->topLevelItem(i); filterTree(ti, f); } } void ProjectFilesystemWidget::rememberExpanded(QTreeWidgetItem * ti) { //QMessageBox::information(0, ti->data(0, Qt::UserRole).toString(), QString::number(ti->childCount())); for (int i = 0; i < ti->childCount(); ++i) { QTreeWidgetItem * ci = ti->child(i); if (ci->data(0, Qt::UserRole + 1).toBool()) { if (ci->isExpanded()) last_expanded << ci->data(0, Qt::UserRole).toString(); rememberExpanded(ci); } } } void ProjectFilesystemWidget::restoreExpanded(QTreeWidgetItem * ti) { for (int i = 0; i < ti->childCount(); ++i) { QTreeWidgetItem * ci = ti->child(i); if (ci->data(0, Qt::UserRole + 1).toBool()) { if (last_expanded.contains(ci->data(0, Qt::UserRole).toString())) ci->setExpanded(true); restoreExpanded(ci); } } } void ProjectFilesystemWidget::projectsChanged() { last_expanded.clear(); item_map.clear(); int spos = tree->verticalScrollBar()->value(); rememberExpanded(tree->invisibleRootItem()); tree->clear(); QList pl = ProjectExplorer::SessionManager::projects(); for (ProjectExplorer::Project * p: pl) { QTreeWidgetItem * ri = new QTreeWidgetItem(); QString dir = p->projectDirectory().toString(); ri->setText(0, p->displayName()); QFile logo(dir + "/logo.png"); if (logo.exists()) ri->setIcon(0, QIcon(logo.fileName())); else ri->setIcon(0, Core::FileIconProvider::icon(QFileIconProvider::Folder)); ri->setData(0, Qt::UserRole, dir); ri->setData(0, Qt::UserRole + 1, true); createTree(ri, dir); tree->addTopLevelItem(ri); } startupProjectChanged(); fileChanged(); filter(); restoreExpanded(tree->invisibleRootItem()); qApp->processEvents(); tree->verticalScrollBar()->setValue(spos); } void ProjectFilesystemWidget::filterClicked() { filter_dialog.setFilter(cur_filter); if (filter_dialog.exec() == QDialog::Rejected) return; setCurrentFilter(filter_dialog.filter()); } void ProjectFilesystemWidget::fileChanged() { Core::IDocument * cd = Core::EditorManager::instance()->currentDocument(); if (!cd) return; QString np = cd->filePath().toString(); QTreeWidgetItem * ti = item_map.value(np); if (!ti) return; tree->setCurrentItem(ti); tree->expandItem(ti); } void ProjectFilesystemWidget::startupProjectChanged() { ProjectExplorer::Project * sp = ProjectExplorer::SessionManager::startupProject(); QFont f(tree->font()), bf(f); bf.setBold(true); for (int i = 0; i < tree->topLevelItemCount(); ++i) { QTreeWidgetItem * ti = tree->topLevelItem(i); ti->setFont(0, f); if (!sp) continue; if (sp->projectDirectory().toString() == ti->data(0, Qt::UserRole).toString()) ti->setFont(0, bf); } } void ProjectFilesystemWidget::on_tree_doubleClicked(const QModelIndex & index) { /*if (!index.isValid()) return; QFileInfo fi = model->fileInfo(index); QStringList ext_ext; ext_ext << "ui" << "ts"; if (ext_ext.contains(fi.suffix())) QDesktopServices::openUrl(QUrl::fromLocalFile(fi.absoluteFilePath())); else Core::EditorManager::openEditor(fi.absoluteFilePath());*/ } void ProjectFilesystemWidget::on_tree_itemDoubleClicked(QTreeWidgetItem * item, int) { if (!item) return; QString afp = item->data(0, Qt::UserRole).toString(); bool dir = item->data(0, Qt::UserRole + 1).toBool(); if (dir) return; if (afp.isEmpty()) return; Core::EditorManager::openEditor(afp); } void ProjectFilesystemWidget::on_lineFilter_textChanged(const QString & ) { filter(); } void ProjectFilesystemWidget::on_tree_customContextMenuRequested(const QPoint & pos) { menu_target = QFileInfo(); QTreeWidgetItem * item = tree->itemAt(pos); //QMessageBox::information(this, "", QString::number(index.row())); if (!item) return; menu_target = QFileInfo(item->data(0, Qt::UserRole).toString()); actionOpen_here->setEnabled(!menu_target.isDir()); actionOpen_external->setEnabled(!menu_target.isDir()); popup_menu.popup(tree->mapToGlobal(pos)); /*Utils::FileName fileName(menu_target); //Core::ActionManager::actionContainer(ProjectExplorer::Constants::M_FILECONTEXT)->menu()->popup(tree->mapToGlobal(pos)); ProjectExplorer::ProjectExplorerPlugin::updateContextMenuActions(); ProjectExplorer::Node * n = 0;//ProjectExplorer::Internal::ProjectTreeWidget::nodeForFile(Utils::FileName(menu_target)); for (ProjectExplorer::Project * project: ProjectExplorer::SessionManager::projects()) { if (ProjectExplorer::ProjectNode * projectNode = project->rootProjectNode()) { projectNode->forEachGenericNode([&](ProjectExplorer::Node *node) { if (node->filePath() == fileName) { if (!n) { n = node; } } }); if (n) break; } } if (!n) return; ProjectExplorer::Internal::ProjectTreeWidget * ptw = 0; QString ss = QString::fromLatin1("ProjectTreeWidget"); QWidgetList wl = qApp->topLevelWidgets(); for (QWidget * w : wl) { QList ol = w->findChildren(); if (QString::fromLatin1(w->metaObject()->className()).endsWith(ss)) { ptw = (ProjectExplorer::Internal::ProjectTreeWidget *)w; break; } for (QObject * o : ol) { if (QString::fromLatin1(o->metaObject()->className()).endsWith(ss)) { ptw = (ProjectExplorer::Internal::ProjectTreeWidget *)o; break; } } if (ptw) break; } if (!ptw) return; ptw->setFocus(); qApp->processEvents(); ProjectExplorer::ProjectTree::showContextMenu(ptw, tree->mapToGlobal(pos), n);*/ } void ProjectFilesystemWidget::on_actionOpen_here_triggered() { if (menu_target.path().isEmpty()) return; Core::EditorManager::openEditor(menu_target.absoluteFilePath()); } void ProjectFilesystemWidget::on_actionOpen_external_triggered() { if (menu_target.path().isEmpty()) return; QDesktopServices::openUrl(QUrl::fromLocalFile(menu_target.absoluteFilePath())); } void ProjectFilesystemWidget::on_actionShow_external_triggered() { if (menu_target.path().isEmpty()) return; Core::FileUtils::showInGraphicalShell(Core::ICore::mainWindow(), menu_target.absoluteFilePath()); }